test(levm): add EIP-7702 delegation gas behavior tests#6043
test(levm): add EIP-7702 delegation gas behavior tests#6043
Conversation
initial transactions to delegated accounts do NOT charge cold access costs for the delegation target. This confirms the current LEVM implementation is correct per EIP-7702 spec which specifies delegation resolution for "opcodes which get code" - initial transactions are not opcodes. Tests added: - test_initial_tx_to_delegated_account_no_cold_access_charge - test_delegated_address_is_warmed_after_resolution - test_delegation_code_format
There was a problem hiding this comment.
Pull request overview
This PR adds comprehensive tests to verify and document the correct EIP-7702 delegation gas accounting behavior in LEVM. The tests confirm that delegation resolution gas costs (cold/warm access charges) are NOT applied during initial transaction setup, but only during CALL opcodes, as specified by EIP-7702. This addresses concerns raised during an audit review (Finding #2) and serves as regression prevention.
Changes:
- Added three test functions verifying EIP-7702 delegation gas behavior
- Added necessary test dependencies (
ethrex-vm,once_cell,rustc-hash) - Added helper functions to create delegation bytecode and test environments
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| test/tests/levm/mod.rs | Added module declaration for new eip7702_tests |
| test/tests/levm/eip7702_tests.rs | New test file with three tests: verifying no cold access charge at tx setup, verifying address warming after resolution, and verifying delegation code format |
| test/Cargo.toml | Added dev-dependencies: ethrex-vm, once_cell 1.21, and rustc-hash |
| Cargo.lock | Updated to reflect new dependencies in test package |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| assert!( | ||
| gas_used < 21000 + COLD_ADDRESS_ACCESS_COST, | ||
| "Gas used ({}) suggests cold access was incorrectly charged. \ | ||
| Expected less than {} (21000 intrinsic + {} cold access)", | ||
| gas_used, | ||
| 21000 + COLD_ADDRESS_ACCESS_COST, | ||
| COLD_ADDRESS_ACCESS_COST | ||
| ); |
There was a problem hiding this comment.
The assertion checks that gas used is less than 21000 + COLD_ADDRESS_ACCESS_COST (23600), which correctly verifies that cold access wasn't charged. However, consider adding a more precise lower bound check to ensure gas is at least 21000 (the base transaction cost). This would make the test more robust by verifying the gas is in the expected range (around 21000) rather than just under the upper threshold. For example: assert!(gas_used >= 21000 && gas_used < 21000 + COLD_ADDRESS_ACCESS_COST, ...)
test/tests/levm/eip7702_tests.rs
Outdated
| /// Test: Verify delegated address is warmed after initial transaction | ||
| /// | ||
| /// After the initial transaction to a delegated account, subsequent accesses | ||
| /// to the delegated target should be warm (100 gas) not cold (2600 gas). |
There was a problem hiding this comment.
The description implies we are testing the gas cost, but we aren't.
Resolve conflicts: - test/Cargo.toml: Keep new dependencies (ethrex-vm, once_cell) - test/tests/levm/mod.rs: Keep both eip7702_tests and eip7708_tests modules
test/tests/levm/eip7702_tests.rs
Outdated
| use std::sync::Arc; | ||
|
|
||
| // EIP-7702 delegation code prefix: 0xef0100 | ||
| const DELEGATION_PREFIX: [u8; 3] = [0xef, 0x01, 0x00]; |
The description implied testing gas costs (100 vs 2600 gas) but the test only verifies the address is in accessed_addresses. Updated to accurately describe what the test checks. Addresses review feedback from iovoid.
Import the existing constant from ethrex_levm::constants instead of defining a local DELEGATION_PREFIX. Addresses review feedback from ElFantasma.
Motivation
During audit review on a potential EIP-7702 gas accounting issue, it was determined that the current LEVM implementation is correct -
_eip7702_gas_consumedis intentionally dropped at transaction setup because EIP-7702 specifies delegation resolution for "opcodes which get code" (CALL, CALLCODE, DELEGATECALL, STATICCALL, etc.), not for initial transactions.These tests document and verify this behavior to prevent future regressions and serve as documentation of the expected semantics.
Description
Add three tests to verify EIP-7702 delegation gas behavior:
test_initial_tx_to_delegated_account_no_cold_access_charge: Verifies that when a transaction is sent to a delegated account (with0xef0100 || target_addressbytecode), the cold access cost (2600 gas) for the delegation target is NOT charged at transaction setup time.test_delegated_address_is_warmed_after_resolution: Verifies that after delegation resolution, the target address IS added toaccessed_addresses(warming it for subsequent calls), even though no gas was charged.test_delegation_code_format: Verifies the delegation code format is correctly constructed (3 byte prefix + 20 byte address = 23 bytes).