👨‍👦 Minimal Proxy

A clever workaround where you can deploy the same contract thousands of times with minimal deployment costs

Branch Info

Author: Viraz Malhotra Source code: https://github.com/austintgriffith/scaffold-eth/tree/minimal_proxy Intended audience: Beginners/Intermediate Topics: Scaffold-eth basics, Contract Deployment

🏃‍♀️ Quick Start

git clone https://github.com/austintgriffith/scaffold-eth.git
cd scaffold-eth
yarn install
yarn start
in a second terminal window:
yarn chain
in a third terminal window:
yarn deploy
image
If you don't have a proxy created you can simply do it by a click of a button in a secured manne!.
image
Once created you can fund your proxy with Mock DAI and of course eth and any erc20 asset in a mainstream scenario.

What the hell is Minimal Proxy ?

Say you need to deploy a wallet for each user your dApp onboards in a secure way such that say a particular user can only have control of their own wallet.
Deploying large contracts can be quite expensive, there’s a clever workaround through which you can deploy the same contract thousands of times with minimal deployment costs: It’s called EIP 1167, but let’s just call it Minimal Proxy.
If you are interested to know somewhat technical details watch this as I go a bit more technical.

How does it work?

Minimal means minimal. That is, all the proxy contract will do is delegate all calls to the implementation – nothing more, nothing less. Make sure you do not confuse EIP 1167 minimal proxy contracts with the proxy pattern used for contract upgrades.
EIP 1167 has nothing to do with upgradeability nor tries to replace it.
The working of a minimal proxy is as follows sequentially
  • Recieve Encoded Transaction Data with CALLDATACOPY opcode to copy the tx data into memory.
  • Forwards the received data to Implementation Contract i.e the contract with which the user wants to interact with using DELEGATECALL.
  • Retrieve the result of the external call with the help of RETURNDATACOPY opcode.
  • Return data to the caller or revert the transaction with the help of JUMPI, RETURN, REVERT opcodes.

How to interact with a external contract?

So let's say you want to interact with compound finance contracts to open a new position or any other contract via your proxy contract it's not striaghtforward that you call function execute(address _target, bytes memory _data) in your proxy as the owner and pass the external contract's address as the _target address your transaction will fail if you do that since when you interact with any external contract via proxy the storage context will always be that of the proxy contract.
The best way to do it to have a connector contract in between without any storage, so the how this would work is : proxy owner -> proxy -> connector contract -> external contract
Here is an example of a very simple and minimal connector contract I created a long time ago which interact with compound's contracts.

Proxy Deployment and Interaction

The Proxy Factory and Proxy Implementation Contract are deployed on Ropsten, and here is the minimal proxy for a user that was created by calling deploy as you can see it points to the minimal proxy address on etherscan and now once you get yourself one created by deploy() you can make your own connector contract and use delegate call.