EVM:EIP-684-prevent-create-collision
Context
Ethereum does not allow for creation of contracts to a non-empty address, which can happen with eg CREATE2 instruction. This behaviour is specified in EIP-684. When a contract creation targets an address which contains code or has non-zero nonce.
This should be a very simple feature to implement but the wording of evm behaviour in case of a collision is quite ambiguous in EIP-684 (Revert creation in case of collision).
I wasn't sure whether revert
refers to the behaviour of the REVERT
opcode which would return all the remaining gas for the call. Therefore, I tested the bahaviour on the Sepolia testnet using the contract below.
pragma solidity ^0.8.18;
contract Contract {
}
contract Create2 {
function create2() public {
new Contract{salt: "0"}();
}
}
Details of relevant transactions can be found in:
- https://sepolia.etherscan.io/tx/0xc530895d2c6a6a8399acafb7ec909f4abe35393c789fc320c39d77ab5c18be17 (creating the contract)
- https://sepolia.etherscan.io/tx/0x2610219fcab0ddb596c1ed4ba547fb001b76fdcf1f77bafb63731023f1251e27 (1st call of create2())
- https://sepolia.etherscan.io/tx/0x307afff6bb5f9e5c0086a603b352e69abbe2a44be6d63a85dce36ca27ffdde1a (2nd call of create2(), failed because target address already contains a smart contract deployed by the previous call)
The failing transaction consumes 2954002 out of the 3000000 gas limit (which does not seem to suggest that the CREATE2
returns remaining gas)
The transaction can be inspected more closely using the debugger in remix. And when running the transaction opcode by opcode(click the step into
button), we would be able to see that the CREATE2
opcode consumes more than 290000 gas. It clearly shows that the revert
in the specification just means undo the changes rather than REVERT
opcode which also returns remaining gas.
As a side note, the reason why not all gas_limit is used is due to EIP-150, which limits gas for nested call/create to 63/64 of remaining. Therefore a small amount of gas is not passed to the CREATE2
For integration test: Eth-cli would wrap receipt of failed transaction in its own error message.Since we currently don't parse error message from eth-cli,we cannot fetch the tx_hash in this case and would get an empty string as tx_hash for failed transaction. After handling of failed transcation is correctly implemented, the following check would need to be replaced with let* () = check_tx_failed ~tx:tx2 ~endpoint in
Manually testing the MR
Run unit test with make -C etherlink/kernel_evm
or integration test with dune exec tezt/tests/main.exe -- --file evm_rollup.ml
Checklist
-
Document the interface of any function added or modified (see the coding guidelines) -
Document any change to the user interface, including configuration parameters (see node configuration) -
Provide automatic testing (see the testing guide). -
For new features and bug fixes, add an item in the appropriate changelog ( docs/protocols/alpha.rst
for the protocol and the environment,CHANGES.rst
at the root of the repository for everything else). -
Select suitable reviewers using the Reviewers
field below. -
Select as Assignee
the next person who should take action on that MR