EIP-7610 Reject contract creation at addresses with leftover storage (Revert creation in case of non-empty storage)

Proposed for Inclusion · EVM & execution · EIP status Last Call · created 2024-02-02

Allows a contract to be created at an address only if its storage is empty, in addition to its nonce and code. Creation fails at an address where values remain in storage.

Why it is needed

Ethereum rests on the premise that a deployed contract does not change. To uphold this, EIP-684 allowed a new contract to be created only when the target address has a nonce of 0 and a code length of 0. However, these two conditions alone are not enough. Before EIP-161 took effect, the nonce of a newly deployed contract stayed at 0, so if the constructor wrote storage values, an account could end up with a nonce of 0 and a code length of 0 but with data remaining in storage. There are currently 28 such contracts on mainnet. Under EIP-684, such addresses are still in a deployable state, so how to handle them was unclear, and implementations diverged, with some clients implementing an account reset solely to pass tests. This EIP closes the gap by making creation fail whenever storage is non-empty.

What changes

Today

After EIP-7610

Who is affected

In depth

Creation failure conditions: nonce, code, and storage

Whether contract creation is attempted by a creation transaction, the CREATE opcode, the CREATE2 opcode, or for any other reason, creation MUST fail if the target address meets any of the following: the nonce is non-zero, the code length is non-zero, or the storage is non-empty. The failure is handled as if the first byte of the init code were an invalid opcode. This rule MUST apply retroactively to all existing blocks. The first two conditions were already defined by EIP-684, and what this EIP adds is the third condition, the empty storage requirement.

Why it supplements EIP-684: 28 accounts with nonce 0 but leftover storage

EIP-684 requires only two things for deployment: the target address has a nonce of 0 and a code length of 0. However, before EIP-161 took effect, the nonce of a newly deployed contract stayed at 0. So by setting a storage slot in the constructor, it was possible to create a contract with a nonce of 0 and a code length of 0 whose storage is non-empty. As of the time the source was written, 28 such contracts exist on Ethereum mainnet. Under EIP-684, these addresses are still in a redeployable state, so this EIP closes the gap by adding an empty storage condition.

No impact on EIP-7702

This EIP does not affect EIP-7702. In EIP-7702, the authority's nonce always increases after an authorization is applied. Contract deployment is possible only when the nonce is 0, so an account with an authorization applied already conflicts with the deployment conditions. Therefore, adding the empty storage condition does not change the behavior of EIP-7702.

Test status and client implementation inconsistencies

Many tests covering scenarios of deploying to a target with non-empty storage already exist in the ethereum tests repository and execution spec tests. These tests have long been regarded as a problem. Reth and EELS implemented a kind of account reset solely to pass the tests, while Py-evm declared the situation impossible and did not implement an account reset at all. The source holds that refilling the existing tests can provide sufficient test coverage for this EIP.

Security nature and how it applies

This EIP is a security upgrade that enforces the immutability of deployed code. Because it is a change to the execution layer, it requires a hard fork. However, the specification requires the creation failure rule itself to apply retroactively to all existing blocks, not from a particular block onward. If no deployment to an address with leftover storage has ever actually occurred, the execution results of past blocks do not change, and it amounts to only tidying up the definition of the rule consistently.

Progress: removed from Glamsterdam, then fully cancelled

The original document's status is Last Call (deadline 2024-11-20). The fork schedule included the following decisions. On 08.17 at ACDT #92, it was agreed to remove EIP-7610 from Glamsterdam. Geth and Reth already skip the relevant tests, so the judgment was that behavior does not change. On 08.20 at ACDC #185, it was cancelled outright rather than postponed. EIP-8253 in Hegotá removes the root cause, so the rule itself becomes unnecessary. On 09.10 at ACDE #245, it was decided that EIP-8253 would not be added late to Glamsterdam and would instead be handled in Hegotá as originally planned. On 09.14 at ACDT #96, legacy test PR #18 was merged, reverting to the handling of collisions used by the Yellow Paper and EIP-684. The collision handling for the Block Access List (BAL) is left undefined until EIP-8253 is settled.

Original EIP · ← EIPs