Skip to content

Commit 1f3a6a6

Browse files
committed
✨ feat(tests): EIP-7928 SELFDESTRUCT Sendall
1 parent 9e3c959 commit 1f3a6a6

File tree

2 files changed

+53
-7
lines changed

2 files changed

+53
-7
lines changed

tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists.py

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,13 +287,56 @@ def test_bal_code_changes(
287287

288288

289289
@pytest.mark.valid_from("Amsterdam")
290-
def test_bal_self_destruct(pre: Alloc, blockchain_test: BlockchainTestFiller):
290+
@pytest.mark.parametrize(
291+
"self_destruct_in_same_tx",
292+
[True, False],
293+
ids=["self_destruct_in_same_tx", "self_destruct_in_a_new_tx"],
294+
)
295+
def test_bal_self_destruct(
296+
pre: Alloc,
297+
blockchain_test: BlockchainTestFiller,
298+
self_destruct_in_same_tx: bool,
299+
):
291300
"""Ensure BAL captures balance changes caused by `SELFDESTRUCT`."""
292301
alice = pre.fund_eoa()
293302
bob = pre.fund_eoa(amount=0)
294-
kaboom = pre.deploy_contract(code=Op.SELFDESTRUCT(bob), balance=100)
295303

296-
tx = Transaction(sender=alice, to=kaboom, gas_limit=1_000_000)
304+
# A template, self-destructing contract
305+
kaboom = pre.deploy_contract(code=Op.SELFDESTRUCT(bob))
306+
307+
if self_destruct_in_same_tx:
308+
# The goal is to create a self-destructing contract in the same
309+
# transaction to trigger deletion of code as per EIP-6780.
310+
# The factory contract below clones the template `kaboom`
311+
# contract and calls it in this transaction.
312+
313+
template = pre[kaboom]
314+
assert template is not None, "Template contract MUST be deployed for cloning"
315+
316+
bytecode_size = len(template.code)
317+
factory_bytecode = (
318+
# Clone template memory
319+
Op.EXTCODECOPY(kaboom, 0, 0, bytecode_size)
320+
# Fund 100 wei and deploy the clone
321+
+ Op.CREATE(100, 0, bytecode_size)
322+
# Call the clone, which self-destructs
323+
+ Op.CALL(50_000, Op.DUP6, 0, 0, 0, 0, 0)
324+
+ Op.STOP
325+
)
326+
327+
factory = pre.deploy_contract(code=factory_bytecode)
328+
kaboom_same_tx = compute_create_address(address=factory, nonce=1)
329+
330+
tx = Transaction(
331+
sender=alice,
332+
to=factory if self_destruct_in_same_tx else kaboom,
333+
value=100,
334+
gas_limit=1_000_000,
335+
)
336+
337+
# Determine which account was destructed
338+
self_destructed_account = kaboom_same_tx if self_destruct_in_same_tx else kaboom
339+
297340
block = Block(
298341
txs=[tx],
299342
expected_block_access_list=BlockAccessListExpectation(
@@ -304,8 +347,12 @@ def test_bal_self_destruct(pre: Alloc, blockchain_test: BlockchainTestFiller):
304347
bob: BalAccountExpectation(
305348
balance_changes=[BalBalanceChange(tx_index=1, post_balance=100)]
306349
),
307-
kaboom: BalAccountExpectation(
308-
balance_changes=[BalBalanceChange(tx_index=1, post_balance=0)]
350+
self_destructed_account: BalAccountExpectation(
351+
balance_changes=[BalBalanceChange(tx_index=1, post_balance=0)],
352+
# Expect code to be cleared if self-destructed in same transaction.
353+
code_changes=[BalCodeChange(tx_index=1, new_code="")]
354+
if self_destruct_in_same_tx
355+
else [],
309356
),
310357
}
311358
),
@@ -317,6 +364,5 @@ def test_bal_self_destruct(pre: Alloc, blockchain_test: BlockchainTestFiller):
317364
post={
318365
alice: Account(nonce=1),
319366
bob: Account(balance=100),
320-
kaboom: Account(balance=0),
321367
},
322368
)

tests/amsterdam/eip7928_block_level_access_lists/test_cases.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
| `test_bal_storage_writes` | Ensure BAL captures storage writes | Alice calls contract that writes to storage slot `0x01` | BAL MUST include storage changes with correct slot and value | ✅ Completed |
88
| `test_bal_storage_reads` | Ensure BAL captures storage reads | Alice calls contract that reads from storage slot `0x01` | BAL MUST include storage access for the read operation | ✅ Completed |
99
| `test_bal_code_changes` | Ensure BAL captures changes to account code | Alice deploys factory contract that creates new contract | BAL MUST include code changes for newly deployed contract | ✅ Completed |
10-
| `test_bal_self_destruct` | Ensure BAL captures balance changes caused by `SELFDESTRUCT` | Alice calls a contract (funded with 100 wei) that executes `SELFDESTRUCT` with Bob as its recipient | BAL MUST include Alice's nonce change (increment), the self-destructing contract's balance change (100 → 0), and Bob's balance change (0 → 100) | ✅ Completed |
10+
| `test_bal_self_destruct` | Ensure BAL captures balance changes caused by `SELFDESTRUCT` | Alice calls a contract (funded with 100 wei) that executes `SELFDESTRUCT` with Bob as its recipient | BAL MUST include Alice's nonce change (increment), the self-destructing contract's balance change (100 → 0), and Bob's balance change (0 → 100). If the contract is created in the same transaction, BAL MUST also include code changes (new_code = empty bytes, indicating code has been cleared) | ✅ Completed |
1111
| `test_bal_2930_slot_listed_but_untouched` | Ensure 2930 access list alone doesn't appear in BAL | Include `(KV, S=0x01)` in tx's EIP-2930 access list; tx executes code that does **no** `SLOAD`/`SSTORE` to `S` (e.g., pure arithmetic/log). | BAL **MUST NOT** contain any entry for `(KV, S)` — neither reads nor writes — because the slot wasn't touched. | 🟡 Planned |
1212
| `test_bal_2930_slot_listed_and_modified` | Ensure BAL records writes only because the slot is touched | Same access list as above, but tx executes `SSTORE` to `S`. | BAL **MUST** include `storage_changes` for `(KV, S)` (and no separate read record for that slot if implementation deduplicates). Presence in the access list is irrelevant; inclusion is due to the actual write. | 🟡 Planned |
1313
| `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 |

0 commit comments

Comments
 (0)