EIP-1167: Minimal Proxy Contract

https://solidity-by-example.org/app/minimal-proxy/

EIP-1167, which is also referred to as the minimal proxy contract, is a commonly used solidity pattern for cheaply creating proxy clones.

Why a minimal proxy?

  • For instances when you need to deploy the same contract multiple times.

  • The initialization data could be different for each individual contract, but the code would be the same.

  • Because deploying large contracts can be quite expensive, instead of deploying a huge contract multiple times, we just deploy a super-cheap minimal proxy contract that points to the huge contract already on chain.

circle-info

The cost to this pattern is that every execution has a delegate call overhead.

What does minimal proxy do?

  • All the proxy/clone contract will do is delegate all calls to the implementation

  • State is updated on the proxy, while the master contract holds the necessary logic

  • Several clones can point to the same implementation contract. Clones cannot be upgraded.

  • The address of the implementation contract is stored in the bytecode. This saves gas compared to storage and prevents the clone from pointing to another implementation.

circle-info

EIP 1167 has nothing to do with upgradeability nor tries to replace it.

How does it look like?

EVM bytecode
  • The dummy address 0xbebebebebebebebebebebebebebebebebebebebe is replaced with the implementation contract address.

  • bytecode is 55 bytes in size, or 0x37

Essentially, the minimal proxy contract looks like this in pseudocode:

Implementation in Solidity

  • we have to create the proxy/clone contract using the 55 byte EVM bytecode above, after updating it with the implementation contract address.

  • this is done with assembly in solidity

  • With assembly, we will update 0xbebebe... with the implementation address, load the entire bytes string into memory and execute it with the create opcode

Implementation with initialization

  • We may want to have different initialization for clones.

  • For example, if we were cloning an ERC20 token, every clone would have the same totalSupply, which might not be desirable.

  • The initializer pattern allows us to deploy the clone as if it has a constructor that takes arguments

Process:

  1. Create an implementation contract

  2. Clone the contract with the EIP-1167 standard

  3. Deploy the clone and call the initialization function, which can only be called once

circle-info

This restriction to only call once is necessary, or someone might alter the critical parameter we set after deployment, such as changing the total supply.

MinimalProxyFactory

  • array of addresses, proxies, is optional. Serves to keep a list of clones deployed.

Last updated