Skip to content

Commit a73376d

Browse files
committed
feat: Add BAL tests for accessing delegated address via call opcodes
1 parent 2344675 commit a73376d

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7702.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,3 +528,58 @@ def test_bal_7702_invalid_chain_id_authorization(
528528
blocks=[block],
529529
post=post,
530530
)
531+
532+
533+
@pytest.mark.with_all_call_opcodes
534+
def test_bal_7702_delegated_via_call_opcode(
535+
pre: Alloc,
536+
blockchain_test: BlockchainTestFiller,
537+
call_opcode: Op,
538+
):
539+
"""
540+
Ensure BAL captures delegation target when a contract uses *CALL
541+
opcodes to call a delegated account.
542+
"""
543+
# `oracle` contract that just returns successfully
544+
oracle = pre.deploy_contract(code=Op.STOP)
545+
546+
# `alice` is a delegated account pointing to oracle
547+
alice = pre.deploy_contract(
548+
nonce=1,
549+
code=Spec7702.delegation_designation(oracle),
550+
balance=0,
551+
)
552+
553+
# caller contract that uses `call_opcode` to call `alice`
554+
caller = pre.deploy_contract(code=(call_opcode(address=alice) + Op.STOP))
555+
556+
bob = pre.fund_eoa()
557+
tx = Transaction(
558+
sender=bob,
559+
to=caller, # `bob` calls caller contract
560+
gas_limit=10_000_000,
561+
gas_price=0xA,
562+
)
563+
564+
block = Block(
565+
txs=[tx],
566+
expected_block_access_list=BlockAccessListExpectation(
567+
account_expectations={
568+
bob: BalAccountExpectation(
569+
nonce_changes=[BalNonceChange(tx_index=1, post_nonce=1)],
570+
),
571+
caller: BalAccountExpectation.empty(),
572+
# `alice` is accessed due to being the call target
573+
alice: BalAccountExpectation.empty(),
574+
# `oracle` appears in BAL due to delegation target access
575+
oracle: BalAccountExpectation.empty(),
576+
}
577+
),
578+
)
579+
580+
post = {bob: Account(nonce=1)}
581+
blockchain_test(
582+
pre=pre,
583+
blocks=[block],
584+
post=post,
585+
)

tests/amsterdam/eip7928_block_level_access_lists/test_cases.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
| `test_bal_2930_slot_listed_but_untouched` | Ensure BAL excludes listed but untouched storage slots | Alice sends tx with EIP-2930 access list including `(PureCalculator, slot=0x01)`; PureCalculator executes pure arithmetic (adding two numbers) without touching slot `0x01` | BAL MUST NOT include any entry for PureCalculator's slot `0x01` because it doesn't access state | ✅ Completed |
1919
| `test_bal_2930_slot_listed_and_unlisted_writes` | Ensure BAL includes storage writes regardless of access list presence | Alice sends tx with EIP-2930 access list including `(StorageWriter, slot=0x01)`; StorageWriter executes `SSTORE` to slots `0x01` and `0x02` | BAL MUST include `storage_changes` for StorageWriter's slots `0x01` and `0x02` | ✅ Completed |
2020
| `test_bal_2930_slot_listed_and_unlisted_reads` | Ensure BAL includes storage reads regardless of access list presence | Alice sends tx with EIP-2930 access list including `(StorageReader, slot=0x01)`; StorageReader executes `SLOAD` from slots `0x01` and `0x02` | BAL MUST include `storage_reads` for StorageReader's slots `0x01` and `0x02` | ✅ Completed |
21-
| `test_bal_7702_delegated_create` | BAL tracks EIP-7702 delegation indicator write and contract creation | Alice sends a type-4 (7702) tx authorizing herself to delegate to `Deployer` code which executes `CREATE` | BAL MUST include for **Alice**: `code_changes` (delegation indicator), `nonce_changes` (increment from 7702 processing), and `balance_changes` (post-gas). For **Child**: `code_changes` (runtime bytecode) and `nonce_changes = 1`. | 🟡 Planned |
2221
| `test_bal_self_transfer` | BAL handles self-transfers correctly | Alice sends `100 wei` to Alice | BAL **MUST** include one entry for Alice with `balance_changes` reflecting gas cost only (value cancels out) and nonce change. | ✅ Completed |
2322
| `test_bal_zero_value_transfer` | BAL handles zero-value transfers correctly | Alice sends `0 wei` to Bob | BAL **MUST** include Alice with `balance_changes` (gas cost only) and nonce change, and Bob in `account_changes` with empty `balance_changes`. | ✅ Completed |
2423
| `test_bal_system_contracts_2935_4788` | BAL includes pre-exec system writes for parent hash & beacon root | Build a block with `N` normal txs; 2935 & 4788 active | BAL MUST include `HISTORY_STORAGE_ADDRESS` (EIP-2935) and `BEACON_ROOTS_ADDRESS` (EIP-4788) with `storage_changes` to ring-buffer slots; each write uses `tx_index = N` (system op). | 🟡 Planned |
@@ -32,11 +31,13 @@
3231
| `test_bal_precompile_funded_then_called` | BAL records precompile with balance change (fund) and access (call) | **Tx0**: Alice sends `1 ETH` to `ecrecover` (0x01). **Tx1**: Alice (or Bob) calls `ecrecover` with valid input and `0 ETH`. | BAL **MUST** include address `0x01` with `balance_changes` (from Tx0). No `storage_changes` or `code_changes`. | 🟡 Planned |
3332
| `test_bal_precompile_call_only` | BAL records precompile when called with no balance change | Alice calls `ecrecover` (0x01) with a valid input, sending **0 ETH**. | BAL **MUST** include address `0x01` in access list, with **no** `balance_changes`, `storage_changes`, or `code_changes`. | 🟡 Planned |
3433
| `test_bal_fully_unmutated_account` | Ensure BAL captures account that has zero net mutations | Alice sends 0 wei to `Oracle` which writes same pre-existing value to storage | BAL MUST include Alice with `nonce_changes` and balance changes (gas), `Oracle` with `storage_reads` for accessed slot but empty `storage_changes`. | ✅ Completed |
34+
| `test_bal_7702_delegated_create` | BAL tracks EIP-7702 delegation indicator write and contract creation | Alice sends a type-4 (7702) tx authorizing herself to delegate to `Deployer` code which executes `CREATE` | BAL MUST include for **Alice**: `code_changes` (delegation indicator), `nonce_changes` (increment from 7702 processing), and `balance_changes` (post-gas). For **Child**: `code_changes` (runtime bytecode) and `nonce_changes = 1`. | 🟡 Planned |
3535
| `test_bal_7702_delegation_create` | Ensure BAL captures creation of EOA delegation | Alice authorizes delegation to contract `Oracle`. Transaction sends 10 wei to Bob. Two variants: (1) Self-funded: Alice sends 7702 tx herself. (2) Sponsored: `Relayer` sends 7702 tx on Alice's behalf. | BAL **MUST** include Alice: `code_changes` (delegation designation `0xef0100\|\|address(Oracle)`),`nonce_changes` (increment). Bob: `balance_changes` (receives 10 wei). For sponsored variant, BAL **MUST** also include `Relayer`:`nonce_changes`.`Oracle` **MUST NOT** be present in BAL - the account is never accessed. | ✅ Completed |
3636
| `test_bal_7702_delegation_update` | Ensure BAL captures update of existing EOA delegation | Alice first delegates to `Oracle1`, then in second tx updates delegation to `Oracle2`. Each transaction sends 10 wei to Bob. Two variants: (1) Self-funded: Alice sends both 7702 txs herself. (2) Sponsored: `Relayer` sends both 7702 txs on Alice's behalf. | BAL **MUST** include Alice: first tx has `code_changes` (delegation designation `0xef0100\|\|address(Oracle1)`),`nonce_changes`. Second tx has`code_changes` (delegation designation `0xef0100\|\|address(Oracle2)`),`nonce_changes`. Bob:`balance_changes` (receives 10 wei on each tx). For sponsored variant, BAL **MUST** also include `Relayer`:`nonce_changes` for both transactions. `Oracle1` and `Oracle2` **MUST NOT** be present in BAL - accounts are never accessed. | ✅ Completed |
3737
| `test_bal_7702_delegation_clear` | Ensure BAL captures clearing of EOA delegation | Alice first delegates to `Oracle`, then in second tx clears delegation by authorizing to `0x0` address. Each transaction sends 10 wei to Bob. Two variants: (1) Self-funded: Alice sends both 7702 txs herself. (2) Sponsored: `Relayer` sends both 7702 txs on Alice's behalf. | BAL **MUST** include Alice: first tx has `code_changes` (delegation designation `0xef0100\|\|address(Oracle)`), `nonce_changes`. Second tx has `code_changes` (empty code - delegation cleared), `nonce_changes`. Bob: `balance_changes` (receives 10 wei on each tx). For sponsored variant, BAL **MUST** also include `Relayer`: `nonce_changes` for both transactions. `Oracle` and `0x0` address **MUST NOT** be present in BAL - accounts are never accessed. | ✅ Completed |
3838
| `test_bal_7702_delegated_storage_access` | Ensure BAL captures storage operations when calling a delegated EIP-7702 account | Alice has delegated her account to `Oracle`. `Oracle` contract contains code that reads from storage slot `0x01` and writes to storage slot `0x02`. Bob sends 10 wei to Alice (the delegated account), which executes `Oracle`'s code. | BAL **MUST** include Alice: `balance_changes` (receives 10 wei), `storage_changes` for slot `0x02` (write operation performed in Alice's storage), `storage_reads` for slot `0x01` (read operation from Alice's storage). Bob: `nonce_changes` (sender), `balance_changes` (loses 10 wei plus gas costs). `Oracle` (account access). | ✅ Completed |
3939
| `test_bal_7702_invalid_nonce_authorization` | Ensure BAL handles failed authorization due to wrong nonce | `Relayer` sends sponsored transaction to Bob (10 wei transfer succeeds) but Alice's authorization to delegate to `Oracle` uses incorrect nonce, causing silent authorization failure | BAL **MUST** include Alice with empty changes (account access), Bob with `balance_changes` (receives 10 wei), Relayer with `nonce_changes`. **MUST NOT** include `Oracle` (authorization failed, no delegation) | ✅ Completed |
4040
| `test_bal_7702_invalid_chain_id_authorization` | Ensure BAL handles failed authorization due to wrong chain id | `Relayer` sends sponsored transaction to Bob (10 wei transfer succeeds) but Alice's authorization to delegate to `Oracle` uses incorrect chain id, causing authorization failure before account access | BAL **MUST** include Bob with `balance_changes` (receives 10 wei), Relayer with `nonce_changes`. **MUST NOT** include Alice (authorization fails before loading account) or `Oracle` (authorization failed, no delegation) | ✅ Completed |
41+
| `test_bal_7702_delegated_via_call_opcode` | Ensure BAL captures delegation target when a contract uses *CALL opcodes to call a delegated account | Pre-deployed contract `Alice` delegated to `Oracle`. `Caller` contract uses CALL/CALLCODE/DELEGATECALL/STATICCALL to call `Alice`. Bob sends transaction to `Caller`. | BAL **MUST** include Bob: `nonce_changes`. `Caller`: empty changes (account access). `Alice`: empty changes (account access - delegated account being called). `Oracle`: empty changes (delegation target access). | ✅ Completed |
4142

4243
> ℹ️ Scope describes whether a test spans a single transaction (`tx`) or entire block (`blk`).

0 commit comments

Comments
 (0)