Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Clones

*https://eips.ethereum.org/EIPS/eip-1167[ERC-1167] is a standard for deploying minimal proxy contracts, also known as "clones".

To simply and cheaply clone contract functionality in an immutable way, this standard specifies a minimal bytecode implementation that delegates all calls to a known, fixed address. The library includes functions to deploy a proxy using either create (traditional deployment) or create2 (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the deterministic method.*

Functions

clone

Deploys and returns the address of a clone that mimics the behavior of implementation. This function uses the create opcode, which should never revert. WARNING: This function does not check if implementation has code. A clone that points to an address without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they have no effect and leave the clone uninitialized, allowing a third party to initialize it later.

function clone(address implementation) internal returns (address instance);

clone

Same as {xref-Clones-clone-address-}[clone], but with a value parameter to send native currency to the new contract. WARNING: This function does not check if implementation has code. A clone that points to an address without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they have no effect and leave the clone uninitialized, allowing a third party to initialize it later. NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory) to always have enough balance for new deployments. Consider exposing this function under a payable method.

function clone(address implementation, uint256 value) internal returns (address instance);

cloneDeterministic

Deploys and returns the address of a clone that mimics the behavior of implementation. This function uses the create2 opcode and a salt to deterministically deploy the clone. Using the same implementation and salt multiple times will revert, since the clones cannot be deployed twice at the same address. WARNING: This function does not check if implementation has code. A clone that points to an address without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they have no effect and leave the clone uninitialized, allowing a third party to initialize it later.

function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance);

cloneDeterministic

Same as {xref-Clones-cloneDeterministic-address-bytes32-}[cloneDeterministic], but with a value parameter to send native currency to the new contract. WARNING: This function does not check if implementation has code. A clone that points to an address without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they have no effect and leave the clone uninitialized, allowing a third party to initialize it later. NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory) to always have enough balance for new deployments. Consider exposing this function under a payable method.

function cloneDeterministic(address implementation, bytes32 salt, uint256 value) internal returns (address instance);

predictDeterministicAddress

Computes the address of a clone deployed using {Clones-cloneDeterministic}.

function predictDeterministicAddress(address implementation, bytes32 salt, address deployer)
    internal
    pure
    returns (address predicted);

predictDeterministicAddress

Computes the address of a clone deployed using {Clones-cloneDeterministic}.

function predictDeterministicAddress(address implementation, bytes32 salt) internal view returns (address predicted);

cloneWithImmutableArgs

Deploys and returns the address of a clone that mimics the behavior of implementation with custom immutable arguments. These are provided through args and cannot be changed after deployment. To access the arguments within the implementation, use fetchCloneArgs. This function uses the create opcode, which should never revert. WARNING: This function does not check if implementation has code. A clone that points to an address without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they have no effect and leave the clone uninitialized, allowing a third party to initialize it later.

function cloneWithImmutableArgs(address implementation, bytes memory args) internal returns (address instance);

cloneWithImmutableArgs

Same as {xref-Clones-cloneWithImmutableArgs-address-bytes-}[cloneWithImmutableArgs], but with a value parameter to send native currency to the new contract. WARNING: This function does not check if implementation has code. A clone that points to an address without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they have no effect and leave the clone uninitialized, allowing a third party to initialize it later. NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory) to always have enough balance for new deployments. Consider exposing this function under a payable method.

function cloneWithImmutableArgs(address implementation, bytes memory args, uint256 value)
    internal
    returns (address instance);

cloneDeterministicWithImmutableArgs

Deploys and returns the address of a clone that mimics the behavior of implementation with custom immutable arguments. These are provided through args and cannot be changed after deployment. To access the arguments within the implementation, use fetchCloneArgs. This function uses the create2 opcode and a salt to deterministically deploy the clone. Using the same implementation, args and salt multiple times will revert, since the clones cannot be deployed twice at the same address. WARNING: This function does not check if implementation has code. A clone that points to an address without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they have no effect and leave the clone uninitialized, allowing a third party to initialize it later.

function cloneDeterministicWithImmutableArgs(address implementation, bytes memory args, bytes32 salt)
    internal
    returns (address instance);

cloneDeterministicWithImmutableArgs

Same as {xref-Clones-cloneDeterministicWithImmutableArgs-address-bytes-bytes32-}[cloneDeterministicWithImmutableArgs], but with a value parameter to send native currency to the new contract. WARNING: This function does not check if implementation has code. A clone that points to an address without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they have no effect and leave the clone uninitialized, allowing a third party to initialize it later. NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory) to always have enough balance for new deployments. Consider exposing this function under a payable method.

function cloneDeterministicWithImmutableArgs(address implementation, bytes memory args, bytes32 salt, uint256 value)
    internal
    returns (address instance);

predictDeterministicAddressWithImmutableArgs

Computes the address of a clone deployed using {Clones-cloneDeterministicWithImmutableArgs}.

function predictDeterministicAddressWithImmutableArgs(
    address implementation,
    bytes memory args,
    bytes32 salt,
    address deployer
) internal pure returns (address predicted);

predictDeterministicAddressWithImmutableArgs

Computes the address of a clone deployed using {Clones-cloneDeterministicWithImmutableArgs}.

function predictDeterministicAddressWithImmutableArgs(address implementation, bytes memory args, bytes32 salt)
    internal
    view
    returns (address predicted);

fetchCloneArgs

*Get the immutable args attached to a clone.

  • If instance is a clone that was deployed using clone or cloneDeterministic, this function will return an empty array.
  • If instance is a clone that was deployed using cloneWithImmutableArgs or cloneDeterministicWithImmutableArgs, this function will return the args array used at creation.
  • If instance is NOT a clone deployed using this library, the behavior is undefined. This function should only be used to check addresses that are known to be clones.*
function fetchCloneArgs(address instance) internal view returns (bytes memory);

_cloneCodeWithImmutableArgs

Helper that prepares the initcode of the proxy with immutable args. An assembly variant of this function requires copying the args array, which can be efficiently done using mcopy. Unfortunately, that opcode is not available before cancun. A pure solidity implementation using abi.encodePacked is more expensive but also more portable and easier to review. NOTE: https://eips.ethereum.org/EIPS/eip-170[EIP-170] limits the length of the contract code to 24576 bytes. With the proxy code taking 45 bytes, that limits the length of the immutable args to 24531 bytes.

function _cloneCodeWithImmutableArgs(address implementation, bytes memory args) private pure returns (bytes memory);

Errors

CloneArgumentsTooLong

error CloneArgumentsTooLong();