These contracts are for test purposes and should not be used in production environments.
- Metamorphic Smart Contracts: Is EVM Code Truly Immutable? (MixBytes Blog)
- 0xOwenThurm Twitter Thread
foundry.tomldoes not affect contracts deployed to Anvil.- EVM Version: Shanghai should be selected. Otherwise,
selfdestructonly sends ether and contracts are not destroyed. This must be specified in Anvil:
anvil --hardfork shanghai - A new contract (
MetaDeployer) is deployed withCREATE. This contract has aCREATE2function to create a factory contract (MutDeployer). - The
MutDeployercontract has 3 functions:- Deploys a V1 version of an implementation contract.
- Deploys a V2 version of an implementation contract.
- Destroys (selfdestructs) itself.
- The two implementation contracts each have arbitrary functions and variables, but both must have a
destroy(selfdestruct) function.
- The
MetaDeployercontract is deployed at address A.
It has a function to deployMutDeployerusingCREATE2. MetaDeployerdeploys theMutDeployercontract usingCREATE2at address B.
CREATE2is used so that the same contract can be redeployed to the same address afterMutDeployeris destroyed. This is necessary becauseMutDeployerwill deploy V2 of the implementation contract, and to deploy V2 to the same address as V1, the nonce ofMutDeployermust be reset. Once reset,MutDeployercan deploy V2 to the same address as the destroyed V1 implementation contract.MutDeployerdeploys the V1 implementation contract at address C.- V1 implementation contract is destroyed.
There is no contract at address C at this point. MutDeployeris destroyed.
There is no contract at address B at this point.MetaDeployerdeploys the sameMutDeployercontract usingCREATE2at address B again.
The nonce is now reset.- V2 implementation contract is deployed at the same address where V1 was deployed (address C).
- This process ensures that the V2 implementation contract is deployed at the same address as the V1 implementation contract, maintaining consistency in contract addresses.
The reason for having a two-part script is to complete the destroy process. selfdestruct is completed at the end of a block.
The addresses deployed in the first part of the script are saved to a directory called vmreadwritefile.
Scripts need to be run separately:
anvil --hardfork shanghai
forge script MetaDeployerScript --broadcast --rpc-url localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --sig "run1()" -vvvvv
forge script MetaDeployerScript --broadcast --rpc-url localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --sig "run2()" -vvvvvTest file is not complete nad outputs collision error. I couldn't find a way to complete the selfdestruct transaction yet.