-
Notifications
You must be signed in to change notification settings - Fork 391
Qu0b/add bal test cases #1812
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: eips/amsterdam/eip-7928
Are you sure you want to change the base?
Qu0b/add bal test cases #1812
Conversation
| | `test_bal_create2_collision` | Ensure BAL handles CREATE2 address collision correctly | Factory contract (nonce=1, storage slot 0=0xDEAD) executes `CREATE2(salt=0, initcode)` targeting address that already has `code=STOP, nonce=1`. Pre-deploy contract at calculated CREATE2 target address before factory deployment. | BAL **MUST** include: (1) Factory with `nonce_changes` (1→2, incremented even on failed CREATE2), `storage_changes` for slot 0 (0xDEAD→0, stores failure). (2) Collision address with empty changes (accessed during collision check, no state changes). CREATE2 returns 0. Collision address **MUST NOT** have `nonce_changes` or `code_changes`. | 🟡 Planned | | ||
| | `test_bal_create_selfdestruct_to_self_with_call` | Ensure BAL handles init code that calls external contract then selfdestructs to itself | Factory executes `CREATE2` with endowment=100. Init code: (1) `CALL(Oracle, 0)` - Oracle writes to its storage slot 0x01. (2) `SSTORE(0x01, 0x42)` - write to own storage. (3) `SELFDESTRUCT(SELF)` - selfdestruct to own address. Contract created and destroyed in same tx. Note: Uses EXTCODECOPY from template contract for init code (too long for PUSH32). | BAL **MUST** include: (1) Factory with `nonce_changes`, `balance_changes` (loses 100). (2) Oracle with `storage_changes` for slot 0x01 (external call succeeded). (3) Template contract (EXTCODECOPY source). (4) Created address with `storage_reads` for slot 0x01 (aborted write becomes read) - **MUST NOT** have `nonce_changes`, `code_changes`, `storage_changes`, or `balance_changes` (ephemeral contract, SELFDESTRUCT to self = net zero). | 🟡 Planned | | ||
| | `test_bal_selfdestruct_to_7702_delegation` | Ensure BAL correctly handles SELFDESTRUCT to a 7702 delegated account (no code execution on recipient) | Tx1: Alice authorizes delegation to Oracle (sets code to `0xef0100\|\|Oracle`). Tx2: Victim contract (balance=100) executes `SELFDESTRUCT(Alice)`. Two separate transactions in same block. Note: Alice starts with initial balance which accumulates with selfdestruct. | BAL **MUST** include: (1) Alice at tx_index=1 with `code_changes` (delegation), `nonce_changes`. (2) Alice at tx_index=2 with `balance_changes` (receives selfdestruct). (3) Victim at tx_index=2 with `balance_changes` (100→0). **Oracle MUST NOT appear in tx2** - per EVM spec, SELFDESTRUCT transfers balance without executing recipient code, so delegation target is never accessed. | 🟡 Planned | | ||
| | `test_bal_revert_insufficient_funds` | Ensure BAL handles CALL failure due to insufficient balance (not OOG) | Contract (balance=100, storage slot 0x02=0xDEAD) executes: `SLOAD(0x01), CALL(target, value=1000), SSTORE(0x02, result)`. CALL fails because 1000 > 100. Target address 0xDEAD (pre-existing with non-zero balance to avoid pruning). Note: slot 0x02 must start non-zero so SSTORE(0) is a change. | BAL **MUST** include: (1) Contract with `storage_reads` for slot 0x01, `storage_changes` for slot 0x02 (value=0, CALL returned failure). (2) Target (0xDEAD) with empty changes. Per EVM, CALL loads target address before balance check, so target **MUST** appear in BAL even though transfer failed. No `balance_changes` for target. | 🟡 Planned | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re test_bal_revert_insufficient_funds , we need to double check if the target address should be in the BAL or not. My intuition is that the BAL MUST NOT include the target if the balance of the caller is insufficient for the CALL.
Also, the sentence in the expectation ends abruptly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm yeah I know what you mean. Maybe we should add the balance check here:
before the accessed_addresses list here:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the specs are correct.
But the test definition is potentially wrong.
In L412, we're only tracing the 2929 access list, nothing re BALs.
Then at L455ff we never call generic_call such that the target would never be tracked.
Based on the specs, the target of a call with value, but with insufficient balance, is only put in the BAL in case generic_call executes and calls process_message.
jochem-brouwer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey Stefan 😄 👍 We met at Devconnect!! 🥳
Very impressive edge cases! I left a few comments on them, also some clarifications or just some notes. Thanks a lot 😄 👍
e4c7fe1 to
98c2154
Compare

🗒️ Description
Implement new BAL (Block Access List) tests with full test implementations:
test_bal_create2_collision- CREATE2 address collision handlingtest_bal_create_selfdestruct_to_self_with_call- Init code with external call then selfdestruct to selftest_bal_selfdestruct_to_7702_delegation- SELFDESTRUCT to EIP-7702 delegated accounttest_bal_revert_insufficient_funds- CALL failure due to insufficient balancetest_bal_lexicographic_address_ordering- Strict byte-wise address ordering validation with endian-trap addressestest_bal_transient_storage_not_tracked- EIP-1153 transient storage exclusiontest_bal_selfdestruct_to_precompile- SELFDESTRUCT with precompile beneficiarytest_bal_all_transaction_types- All 5 tx types (Legacy, EIP-2930, EIP-1559, Blob, EIP-7702) in single blocktest_bal_create_early_failure- CREATE failure before track_addresstest_bal_withdrawal_to_7702_delegation- Withdrawal to EIP-7702 delegated account