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) orcreate2(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
instanceis a clone that was deployed usingcloneorcloneDeterministic, this function will return an empty array. - If
instanceis a clone that was deployed usingcloneWithImmutableArgsorcloneDeterministicWithImmutableArgs, this function will return the args array used at creation. - If
instanceis 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();