Skip to content

Test SELFDESTRUCT Gas

Documentation for tests/amsterdam/eip8038_state_access_gas_cost_increase/test_selfdestruct_gas.py@49633827.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip8038_state_access_gas_cost_increase/test_selfdestruct_gas.py --fork Amsterdam

Tests for the EIP-8038 State Access Gas Cost Increase SELFDESTRUCT execution-gas dimension.

Under EIP-8038 SELFDESTRUCT is charged, in its execution gas dimension:

  • OPCODE_SELFDESTRUCT_BASE;
  • a COLD_ACCOUNT_ACCESS surcharge when the beneficiary is cold (a warm beneficiary adds nothing — SELFDESTRUCT has no WARM_ACCESS surcharge);
  • a net-new ACCOUNT_WRITE when a positive balance is sent to an empty (or non-existent) beneficiary, replacing the legacy combined execution account-creation cost.

So execution = OPCODE_SELFDESTRUCT_BASE + (COLD_ACCOUNT_ACCESS if cold) + (ACCOUNT_WRITE if creating).

The beneficiary account-creation charge GAS_NEW_ACCOUNT is the EIP-8037 state dimension (charge_state_gas in the spec), covered in eip8037_state_creation_gas_cost_increase/test_state_gas_selfdestruct.py.

SELFDESTRUCT halts the frame, so it is driven via a wrapping CALL and verified through block gas_used accounting and balances. Per EIP-6780, a contract not created in the same transaction is not deleted, but its balance is still transferred and the beneficiary creation charge still applies.

The framework opcode-gas model splits the two dimensions for SELFDESTRUCT exactly as the spec does: ACCOUNT_WRITE is charged as execution gas and GAS_NEW_ACCOUNT as state gas, so Op.SELFDESTRUCT(account_new=True).execution_cost(fork) is the execution charge and .state_cost(fork) is GAS_NEW_ACCOUNT. These tests assert the execution dimension and verify account-creation via balances; the state dimension is owned by eip8037_state_creation_gas_cost_increase/test_state_gas_selfdestruct.py.

Test Functions Overview

Name Type Cases (Amsterdam) Description
test_same_tx_created_selfdestruct_self_burn state_test 1 EIP-6780: a same-tx-created contract SELFDESTRUCTs to itself, charged
test_same_tx_created_selfdestruct_to_fresh_beneficiary state_test 1 EIP-6780: a same-tx-created contract sends value to a fresh
test_selfdestruct_alive_beneficiary_no_account_write state_test 2 SELFDESTRUCT to an already-alive beneficiary charges no ACCOUNT_WRITE.
test_selfdestruct_codebearing_zero_balance_beneficiary_no_account_write state_test 2 SELFDESTRUCT to a code-bearing zero-balance beneficiary: no
test_selfdestruct_new_beneficiary_execution_gas state_test 2 SELFDESTRUCT to an empty beneficiary with balance charges
test_selfdestruct_oog_boundary state_test 2 Drive a cold SELFDESTRUCT that funds a new account at its exact total
test_selfdestruct_self_or_precompile_beneficiary state_test 2 SELFDESTRUCT to self or a precompile is warm and charges no
test_selfdestruct_zero_balance_no_account_write state_test 2 SELFDESTRUCT with a zero-balance destructor charges no ACCOUNT_WRITE.