I would like to use the OpenZeppelin’s Clones library to cheaply deploy contracts that are also compatible with meta-transactions via ERC2771.
The ERC2771Context.sol contract sets the immutable address trustedForwarder in the constructor.
Clones do not use constructors to initialize state variables; they use a separate function to do so. With this pattern, it seems impossible to set the trustedForwarder, which is necessary for the contract to receive meta-tx.
Am I correct in my assessment? Is there a way around this to deploy clones that are compatible with meta-tx?
Wouldn’t the cloned contract have to inherit ERC2771Context and set trustedForward through the derived base constructor? e.g:
contract MyClone is ERC2771Context {
constructor(address _trustedForwarder) is ERC2771Context(_trustedForwarder)
My understanding of clones is that the constructor is only called when deploying the “master” copy of the contract, and when deploying each clone the state variables are empty. Clones use initialize instead. However, in ERC2771Context the trustedForwarder is immutable, and thus can only be set in the constructor. Wouldn’t this set the trustedForwader to the zero address in the cloned contract, and make it impossible to change it?
Yes, with clones you will use initialize, but you can also have a constructor on the master copy and if the value is shared an immutable variable works.
I forgot to mention though, that for Clones you will want to use OpenZeppelin Upgradeable Contracts, where you will see that ERC2771Context is modified so that it doesn’t use an immutable variable.