Skip to content

Commit f2e0bd7

Browse files
committed
feat(spec-specs, tests): EIP-8037 - CREATE failure refunds state gas to reservoir (#2704)
1 parent 2a7ae3e commit f2e0bd7

4 files changed

Lines changed: 458 additions & 80 deletions

File tree

src/ethereum/forks/amsterdam/vm/instructions/system.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,15 @@ def generic_create(
8686
if memory_size > U256(MAX_INIT_CODE_SIZE):
8787
raise OutOfGasError
8888

89-
# Charge state gas for account creation after initcode validation
89+
# Charge state gas for account creation (pay-before-execute).
90+
# Refunded to the reservoir on any failure path below.
9091
cost_per_state_byte = state_gas_per_byte(
9192
evm.message.block_env.block_gas_limit
9293
)
93-
charge_state_gas(evm, STATE_BYTES_PER_NEW_ACCOUNT * cost_per_state_byte)
94+
create_account_state_gas = (
95+
STATE_BYTES_PER_NEW_ACCOUNT * cost_per_state_byte
96+
)
97+
charge_state_gas(evm, create_account_state_gas)
9498

9599
tx_state = evm.message.tx_env.state
96100

@@ -117,6 +121,9 @@ def generic_create(
117121
):
118122
evm.gas_left += create_message_gas
119123
evm.state_gas_left += create_message_state_gas_reservoir
124+
# No account created — refund state gas to reservoir.
125+
evm.state_gas_left += create_account_state_gas
126+
evm.state_gas_used -= create_account_state_gas
120127
push(evm.stack, U256(0))
121128
return
122129

@@ -128,6 +135,9 @@ def generic_create(
128135
increment_nonce(tx_state, evm.message.current_target)
129136
evm.regular_gas_used += create_message_gas
130137
evm.state_gas_left += create_message_state_gas_reservoir
138+
# Address collision — no account created, refund state gas.
139+
evm.state_gas_left += create_account_state_gas
140+
evm.state_gas_used -= create_account_state_gas
131141
push(evm.stack, U256(0))
132142
return
133143

@@ -157,6 +167,9 @@ def generic_create(
157167

158168
if child_evm.error:
159169
incorporate_child_on_error(evm, child_evm)
170+
# No account created, refund parent's CREATE state gas.
171+
evm.state_gas_left += create_account_state_gas
172+
evm.state_gas_used -= create_account_state_gas
160173
evm.return_data = child_evm.output
161174
push(evm.stack, U256(0))
162175
else:

tests/amsterdam/eip8037_state_creation_gas_cost_increase/spec.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
from dataclasses import dataclass
44

5+
from execution_testing.vm import Bytecode, Op
6+
7+
8+
def init_code_at_high_bytes(
9+
init_code: Op | Bytecode | bytes,
10+
) -> tuple[int, int]:
11+
"""Return (mstore_value, size) to place init_code at memory[0:size]."""
12+
code_bytes = bytes(init_code)
13+
size = len(code_bytes)
14+
return int.from_bytes(code_bytes, "big") << (256 - 8 * size), size
15+
516

617
@dataclass(frozen=True)
718
class ReferenceSpec:

0 commit comments

Comments
 (0)