Markdown Content
Below is the verbatim markdown content from tests/amsterdam/eip7954_increase_max_contract_size/test_cases.md@02aafd78.
EIP-7954 Increase Maximum Contract Size Test Cases¶
| Function Name | Goal | Setup | Expectation | Status |
|---|---|---|---|---|
test_max_code_size |
Enforce new MAX_CODE_SIZE boundary for contract creation transactions |
Alice deploys contracts with runtime code one byte over the previous max, one byte under the new max, at the new max and one byte over the new max. | All sizes through the new max deploy; one byte over the new max fails, burning the execution allowance so the receipt shows the transaction gas limit cap. | ✅ Completed |
test_max_code_size_via_create |
Enforce new MAX_CODE_SIZE boundary via CREATE/CREATE2 opcodes |
Same as above but deployment is done through a factory contract using CREATE and CREATE2, with a sentinel pre-set in the factory's storage slot. | All sizes through the new max deploy. One byte over makes the create opcode push zero and the child does not exist. | ✅ Completed |
test_max_initcode_size |
Enforce new MAX_INITCODE_SIZE boundary for contract creation transactions |
Alice sends creation transactions with initcode one byte over the previous max, one byte under the new max, at the new max and one byte over the new max. | All sizes through the new max are accepted; one byte over the new max is rejected. | ✅ Completed |
test_max_initcode_size_via_create |
Enforce new MAX_INITCODE_SIZE boundary via CREATE/CREATE2 opcodes |
Same as above but initcode is passed through a factory contract using CREATE and CREATE2, with a sentinel pre-set in the factory's storage slot. | All sizes through the new max create the child. One byte over aborts the factory frame before a child frame runs, preserving the sentinel and burning the whole gas allowance. | ✅ Completed |
test_max_initcode_size_calldata_floor |
Enforce the calldata floor a max-size initcode creation transaction must cover, and pin that the floor is also what it pays | Alice sends a creation transaction with max-size initcode, with the gas limit one gas below the calldata floor, exactly at it, and with slack above it. | Below: transaction rejected for missing the floor. At and above: contract deployed, and the receipt shows the floor charged, rather than the gas limit or the much smaller amount the deployment spends. | ✅ Completed |
test_max_code_size_deposit_gas |
Verify code deposit gas, and the initcode word cost, are charged correctly at the new maxima | Alice deploys a contract with exactly MAX_CODE_SIZE bytes, from minimal initcode and from initcode padded to MAX_INITCODE_SIZE. Gas set to the exact intrinsic, execution and deposit cost, then one short. |
Exact gas: contract deployed. One short: deployment fails (out of gas during code deposit). | ✅ Completed |
test_max_code_size_external_opcodes |
Verify external code opcodes work with max-size contracts | Deterministically pre-deploy a max-size self-checking contract. Call it to run EXTCODESIZE, EXTCODEHASH, and EXTCODECOPY on itself via ADDRESS. | Each opcode returns the correct value for the max-size contract. | ✅ Completed |
test_max_code_size_external_code_bounds |
Verify external code opcodes address a max-size contract from another account across its whole range | A checker contract reads EXTCODESIZE and EXTCODEHASH of a MAX_CODE_SIZE target, copies the full code, then copies the last 32 bytes and 32 bytes starting at the code size. |
Size, hash and full-copy hash match the target. The last-word copy returns the final code bytes; the read starting at the code size zero-fills. | ✅ Completed |
test_max_code_size_self_opcodes |
Verify self code opcodes work with max-size contracts | Pre-deploy a max-size contract with CODESIZE and CODECOPY checker logic. Call via DELEGATECALL so opcodes operate on the large contract's own code. | CODESIZE returns the correct length, CODECOPY produces the correct hash. | ✅ Completed |
test_max_code_size_via_delegation |
Run a max-size contract through an EIP-7702 delegation | An EOA delegates to a MAX_CODE_SIZE contract that stores CODESIZE, the hash of its CODECOPY output and EXTCODESIZE of ADDRESS; call the EOA. |
CODESIZE and the copy hash match the full target code; EXTCODESIZE returns the length of the delegation designation. | ✅ Completed |
test_max_code_size_linear_execution |
Execute a max-size contract end to end without a jump | Deploy MAX_CODE_SIZE JUMPDESTs and call it at the transaction gas limit cap. |
The call halts at the end of the code and the receipt charges one gas per byte over the intrinsic cost. | ✅ Completed |
test_max_code_size_high_jumpdest |
Enforce JUMP destination validity and code execution past the old size limits | Deploy a MAX_CODE_SIZE contract that stores a flag and jumps to its last byte (far beyond the old 24 KiB code and 48 KiB initcode limits), a real JUMPDEST or a bare STOP, or to MAX_CODE_SIZE itself, one past the end; call it via a caller that records the call result. |
Valid JUMPDEST: jump succeeds and the prefix store survives. Non-JUMPDEST byte or one past the end: jump is rejected, call fails, nothing is stored. |
✅ Completed |
test_max_code_size_jumpdest_in_immediate |
Verify jumpdest analysis classifies a 0x5B immediate byte at max code size |
Place a 0x5B as the last byte of a MAX_CODE_SIZE contract, right after a PUSH1/DUPN/SWAPN/EXCHANGE, or after a PUSH2 that has no second immediate byte, and jump to it. |
PUSH1 and truncated PUSH2: 0x5B is data, skipped, jump rejected. DUPN/SWAPN/EXCHANGE: per EIP-8024 0x5B is an invalid immediate, kept as a JUMPDEST, jump accepted. |
✅ Completed |
test_max_code_size_with_max_initcode |
Deploy max-size code when initcode is also at max size | Alice deploys a contract with MAX_CODE_SIZE bytes of runtime code using initcode padded to MAX_INITCODE_SIZE. |
Contract deployed with the full max-size runtime code. | ✅ Completed |
test_max_code_size_with_max_initcode_via_create |
Deploy max-size code from max-size initcode via CREATE/CREATE2 opcodes | A factory stores a RETURN of MAX_CODE_SIZE zeroed memory bytes and runs CREATE/CREATE2 over MAX_INITCODE_SIZE bytes of memory. |
Child contract deployed with MAX_CODE_SIZE bytes of runtime code. |
✅ Completed |
test_max_initcode_size_code_opcodes |
Verify self code opcodes see a max-size initcode in full while it runs | A factory runs CREATE over MAX_INITCODE_SIZE bytes of memory; the initcode stores its own CODESIZE and the hash of its CODECOPY output. |
CODESIZE returns MAX_INITCODE_SIZE and the hash matches the whole initcode. |
✅ Completed |
test_max_initcode_size_linear_execution |
Execute a max-size initcode end to end without a jump | A factory assembles MAX_INITCODE_SIZE bytes from two EXTCODECOPYs of a MAX_CODE_SIZE JUMPDEST contract, writes a store and RETURN into the last word, and runs CREATE over it. |
The child exists with its store set, which only the tail past every JUMPDEST can write. | ✅ Completed |
test_max_initcode_size_high_jumpdest |
Enforce JUMP destination validity inside a max-size initcode | A factory runs CREATE over MAX_INITCODE_SIZE bytes of memory; the initcode jumps to its last bytes, either a real JUMPDEST or a zero byte, or to MAX_INITCODE_SIZE itself, one past the end. |
Valid JUMPDEST: the initcode runs at the high offset and the child contract keeps its store. Zero byte or one past the end: the jump is rejected and the child contract does not exist. |
✅ Completed |
test_warm_after_failed_create_over_max_code_size |
A failed CREATE/CREATE2 over max code size leaves the would-be address warm | A creator runs CREATE/CREATE2 whose initcode returns MAX_CODE_SIZE + 1 bytes; a checker then measures the gas of a BALANCE on that address. |
The address is warm: the post-RETURN size-check rejection still leaves it in the access list. | ✅ Completed |
test_max_code_size_fork_transition |
Each block is held to the MAX_CODE_SIZE active in it |
Before and after the fork, send a creation transaction whose short initcode returns runtime code at the parent fork's max, one byte over it, at the new max, and one byte over the new max. | A block deploys the contract only when the size fits the limit active in that block; otherwise the code deposit fails, nothing is deployed and the block records the transaction gas limit cap. | ✅ Completed |
test_max_code_size_via_create_fork_transition |
Each block is held to the active MAX_CODE_SIZE via CREATE/CREATE2 opcodes |
The same four boundaries as the transaction path, deployed through a factory with a sentinel pre-set in its storage slot. | Sizes within the limit active in that block: child contract created. Oversized: the create opcode pushes zero over the sentinel and the child contract does not exist. | ✅ Completed |
test_max_initcode_size_fork_transition |
Each block validates creation transactions against the MAX_INITCODE_SIZE active in it |
Before and after the fork, send a creation transaction with initcode at the parent fork's max, one byte over it, at the new max, and one byte over the new max. | A block is accepted only when the initcode fits the limit active in that block; otherwise the transaction is rejected and the block is invalid. | ✅ Completed |
test_max_initcode_size_via_create_fork_transition |
Each block is held to the active MAX_INITCODE_SIZE via CREATE/CREATE2 opcodes |
The same four boundaries as the transaction path, with the initcode built from zeroed factory memory and a sentinel pre-set in the factory's storage slot. | Sizes within the limit active in that block: child contract created. Oversized: the create opcode aborts the factory frame before any child frame runs, leaving the sentinel in place and burning the whole gas allowance. | ✅ Completed |
test_max_code_size_with_max_initcode_fork_transition |
Both new limits activate together at the fork boundary | Before the fork, deploy max code with max initcode. After the fork, attempt the same deployment. | Pre-fork: block rejected (initcode exceeds old limit). Post-fork: contract deployed with max-size runtime code. | ✅ Completed |
test_max_code_size_with_max_initcode_via_create_fork_transition |
Both new limits activate together at the fork boundary via CREATE/CREATE2 opcodes | Before and after the fork, a factory runs CREATE/CREATE2 over MAX_INITCODE_SIZE bytes of memory whose initcode returns MAX_CODE_SIZE bytes. |
Pre-fork: the initcode limit binds first, so the create opcode aborts the factory frame and the sentinel survives. Post-fork: child contract deployed with MAX_CODE_SIZE bytes of runtime code. |
✅ Completed |
test_over_max_code_size_mainnet |
Deploying above the new limit fails on mainnet | Alice deploys a contract with MAX_CODE_SIZE + 1 bytes of runtime code. |
Contract does not exist (deployment fails during code deposit). | ✅ Completed |
test_over_max_initcode_size_mainnet |
Oversized initcode creation is rejected on mainnet | Alice sends a creation transaction with MAX_INITCODE_SIZE + 1 bytes of initcode. |
Transaction rejected. No contract deployed. | ✅ Completed |
test_max_code_size_with_max_initcode_mainnet |
Verify opcodes on a max-size contract on mainnet | Call the deterministic max-size self-checking contract. It queries EXTCODESIZE, EXTCODEHASH, and EXTCODECOPY on itself via ADDRESS. | Each opcode returns the correct value for the max-size contract. | ✅ Completed |