Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ethereum/forks/amsterdam/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ def process_transaction(
Log(
address=vm.SYSTEM_ADDRESS,
topics=(
vm.SELFDESTRUCT_TOPIC,
vm.BURN_TOPIC,
Hash32(padded_address),
),
data=balance.to_be_bytes32(),
Expand Down
12 changes: 6 additions & 6 deletions src/ethereum/forks/amsterdam/vm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

__all__ = ("Environment", "Evm", "Message")
TRANSFER_TOPIC = keccak256(b"Transfer(address,address,uint256)")
SELFDESTRUCT_TOPIC = keccak256(b"Selfdestruct(address,uint256)")
BURN_TOPIC = keccak256(b"Burn(address,uint256)")
SYSTEM_ADDRESS = Address(
bytes.fromhex("fffffffffffffffffffffffffffffffffffffffe")
)
Expand Down Expand Up @@ -244,22 +244,22 @@ def emit_transfer_log(
evm.logs = evm.logs + (log_entry,)


def emit_selfdestruct_log(
def emit_burn_log(
evm: Evm,
account: Address,
amount: U256,
) -> None:
"""
Emit a LOG2 for self-destruct to self (balance burn) per EIP-7708.
Emit a LOG2 for ETH burn per EIP-7708.

Parameters
----------
evm :
The state of the ethereum virtual machine
account :
The account address being selfdestructed
The account address whose ETH is being burned
amount :
The amount of ETH being destroyed
The amount of ETH being burned

"""
if amount == 0:
Expand All @@ -269,7 +269,7 @@ def emit_selfdestruct_log(
log_entry = Log(
address=SYSTEM_ADDRESS,
topics=(
SELFDESTRUCT_TOPIC,
BURN_TOPIC,
Hash32(padded_account),
),
data=amount.to_be_bytes32(),
Expand Down
4 changes: 2 additions & 2 deletions src/ethereum/forks/amsterdam/vm/instructions/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
CALL_SUCCESS,
Evm,
Message,
emit_selfdestruct_log,
emit_burn_log,
emit_transfer_log,
incorporate_child_on_error,
incorporate_child_on_success,
Expand Down Expand Up @@ -622,7 +622,7 @@ def selfdestruct(evm: Evm) -> None:
# or transferred to a different account
if originator in tx_state.created_accounts and beneficiary == originator:
# Self-destruct to self in same tx burns the balance
emit_selfdestruct_log(evm, originator, originator_balance)
emit_burn_log(evm, originator, originator_balance)
elif beneficiary != originator:
# Transfer to different beneficiary
emit_transfer_log(evm, originator, beneficiary, originator_balance)
Expand Down
10 changes: 4 additions & 6 deletions tests/amsterdam/eip7708_eth_transfer_logs/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ class Spec:
TRANSFER_TOPIC: Hash = Hash(
keccak256(b"Transfer(address,address,uint256)")
)
SELFDESTRUCT_TOPIC: Hash = Hash(
keccak256(b"Selfdestruct(address,uint256)")
)
BURN_TOPIC: Hash = Hash(keccak256(b"Burn(address,uint256)"))


def transfer_log(
Expand All @@ -51,12 +49,12 @@ def transfer_log(
)


def selfdestruct_log(contract_address: Address, amount: int) -> TransactionLog:
"""Create an expected Selfdestruct log for EIP-7708."""
def burn_log(contract_address: Address, amount: int) -> TransactionLog:
"""Create an expected Burn log for EIP-7708."""
return TransactionLog(
address=Spec.SYSTEM_ADDRESS,
topics=[
Spec.SELFDESTRUCT_TOPIC,
Spec.BURN_TOPIC,
Hash(bytes(contract_address).rjust(32, b"\x00")),
],
data=Bytes(amount.to_bytes(32, "big")),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Tests for EIP-7708 Selfdestruct logs.
Tests for EIP-7708 Burn logs.

Tests for the Selfdestruct(address,uint256) log emitted when:
Tests for the Burn(address,uint256) log emitted when:
- SELFDESTRUCT to self with nonzero balance
- Account created and destroyed in the same transaction
"""
Expand Down Expand Up @@ -30,7 +30,7 @@
Macros as Om,
)

from .spec import ref_spec_7708, selfdestruct_log, transfer_log
from .spec import burn_log, ref_spec_7708, transfer_log

REFERENCE_SPEC_GIT_PATH = ref_spec_7708.git_path
REFERENCE_SPEC_VERSION = ref_spec_7708.version
Expand All @@ -47,7 +47,7 @@ def test_selfdestruct_to_self_pre_existing_no_log(
"""
Test that selfdestruct-to-self emits NO log for pre-existing contracts.

Selfdestruct log only emitted when created and destroyed in same tx.
Burn log only emitted when created and destroyed in same tx.
"""
contract_balance = 2000

Expand Down Expand Up @@ -90,7 +90,7 @@ def test_selfdestruct_to_self_same_tx(
"""
Test selfdestruct-to-self for same-tx created contracts.

- With balance, SELFDESTRUCT log emitted (burns ETH).
- With balance, Burn log emitted (burns ETH).
- No balance, no logs expected.
"""
initcode = Op.SELFDESTRUCT(Op.ADDRESS)
Expand All @@ -116,7 +116,7 @@ def test_selfdestruct_to_self_same_tx(
expected_logs = [
transfer_log(sender, factory, contract_balance),
transfer_log(factory, created_address, contract_balance),
selfdestruct_log(created_address, contract_balance),
burn_log(created_address, contract_balance),
]
else:
expected_logs = []
Expand Down Expand Up @@ -277,12 +277,12 @@ def test_selfdestruct_same_tx_via_call(
if to_self:
expected_logs = [
transfer_log(factory, created_address, contract_balance),
selfdestruct_log(created_address, contract_balance),
burn_log(created_address, contract_balance),
]
if call_twice and second_call_value > 0:
expected_logs += [
transfer_log(factory, created_address, second_call_value),
selfdestruct_log(created_address, second_call_value),
burn_log(created_address, second_call_value),
]
post = {}
else:
Expand Down Expand Up @@ -346,7 +346,7 @@ def test_selfdestruct_same_tx_via_call(
pytest.param(True, id="to_self"),
],
)
def test_finalization_selfdestruct_logs(
def test_finalization_burn_logs(
state_test: StateTestFiller,
env: Environment,
pre: Alloc,
Expand All @@ -356,10 +356,10 @@ def test_finalization_selfdestruct_logs(
to_self: bool,
) -> None:
"""
Test Selfdestruct logs at finalization for post-selfdestruct balance.
Test Burn logs at finalization for post-selfdestruct balance.

X contracts (x1, x2, x3) selfdestruct, then receive ETH via payer contracts
(p1, p2, p3). At finalization, X contracts emit SELFDESTRUCT logs for their
(p1, p2, p3). At finalization, X contracts emit Burn logs for their
in lexicographical address order (only if they received ETH).

When to_self=True, X contracts SELFDESTRUCT to themselves (burning ETH
Expand Down Expand Up @@ -446,12 +446,12 @@ def test_finalization_selfdestruct_logs(
]

if to_self:
# SELFDESTRUCT to self burns ETH → LOG2 Selfdestruct
# SELFDESTRUCT to self burns ETH → LOG2 Burn
execution_logs.extend(
[
selfdestruct_log(x1, 1000),
selfdestruct_log(x2, 2000),
selfdestruct_log(x3, 3000),
burn_log(x1, 1000),
burn_log(x2, 2000),
burn_log(x3, 3000),
]
)
beneficiary_balance = 0
Expand Down Expand Up @@ -489,7 +489,7 @@ def test_finalization_selfdestruct_logs(
)
# Finalization logs emitted in SORTED address order (not call order)
finalization_logs = [
selfdestruct_log(addr, amounts[addr]) for addr in sorted_addrs
burn_log(addr, amounts[addr]) for addr in sorted_addrs
]
post = {
x1: Account.NONEXISTENT,
Expand Down Expand Up @@ -622,7 +622,7 @@ def test_selfdestruct_finalization_after_priority_fee(

expected_logs = [
transfer_log(factory_address, created_address, contract_balance),
selfdestruct_log(created_address, contract_balance),
burn_log(created_address, contract_balance),
]

# if funded after selfdestruct, expect transfer log from payer
Expand All @@ -632,10 +632,8 @@ def test_selfdestruct_finalization_after_priority_fee(
transfer_log(payer, created_address, funding_amount)
)

# finalization selfdestruct log
expected_logs.append(
selfdestruct_log(created_address, finalization_balance)
)
# finalization burn log
expected_logs.append(burn_log(created_address, finalization_balance))

tx = Transaction(
sender=sender,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
compute_create_address,
)

from .spec import ref_spec_7708, selfdestruct_log, transfer_log
from .spec import burn_log, ref_spec_7708, transfer_log

REFERENCE_SPEC_GIT_PATH = ref_spec_7708.git_path
REFERENCE_SPEC_VERSION = ref_spec_7708.version
Expand All @@ -32,17 +32,17 @@
],
)
@pytest.mark.valid_at_transition_to("Amsterdam")
def test_selfdestruct_log_at_fork_transition(
def test_burn_log_at_fork_transition(
blockchain_test: BlockchainTestFiller,
pre: Alloc,
same_tx: bool,
to_self: bool,
) -> None:
"""
Test selfdestruct log emission across the Amsterdam fork transition.
Test burn log emission across the Amsterdam fork transition.

same_tx_to_self: Factory CREATEs and selfdestructs to self in one tx.
At/after Amsterdam emits a CREATE transfer log + Selfdestruct log.
At/after Amsterdam emits a CREATE transfer log + Burn log.

pre_existing_to_self: Pre-existing contract selfdestructs to self.
No logs at any fork — SELFDESTRUCT to same account emits nothing.
Expand Down Expand Up @@ -77,11 +77,11 @@ def test_selfdestruct_log_at_fork_transition(
[],
[
transfer_log(factory, created[1], contract_balance),
selfdestruct_log(created[1], contract_balance),
burn_log(created[1], contract_balance),
],
[
transfer_log(factory, created[2], contract_balance),
selfdestruct_log(created[2], contract_balance),
burn_log(created[2], contract_balance),
],
]
post: dict = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1208,7 +1208,7 @@ def test_selfdestruct_to_self_cross_tx_no_log(
Test that selfdestruct-to-self in a cross-tx context emits no log.

A contract created in Tx1 is not in created_accounts during Tx2.
Selfdestruct-to-self in Tx2 emits no log per EIP-7708: no Selfdestruct
Selfdestruct-to-self in Tx2 emits no log per EIP-7708: no Burn
log (not same-tx) and no Transfer log (not a different account).

Tx1: Contract creation tx (to=None) deploying SELFDESTRUCT(ADDRESS),
Expand Down
Loading