Skip to content

Commit 9c2aa6a

Browse files
pdobaczpacrob
authored andcommitted
fix(tests): EIP-7620 - make CREATE/CREATE2 restrictions specific (ethereum#1475)
1 parent e290743 commit 9c2aa6a

File tree

2 files changed

+111
-18
lines changed

2 files changed

+111
-18
lines changed

tests/osaka/eip7692_eof_v1/eip7620_eof_create/helpers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
slot_call_or_create = next(_slot)
2020
slot_counter = next(_slot)
2121
slot_data_load = next(_slot)
22+
slot_all_subcall_gas_gone = next(_slot)
2223

2324
slot_last_slot = next(_slot)
2425

tests/osaka/eip7692_eof_v1/eip7620_eof_create/test_legacy_eof_creates.py

Lines changed: 110 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import pytest
44

5+
from ethereum_test_base_types.base_types import Address, Bytes
56
from ethereum_test_tools import (
67
Account,
78
Alloc,
@@ -13,9 +14,12 @@
1314
from ethereum_test_tools.vm.opcode import Opcodes
1415
from ethereum_test_tools.vm.opcode import Opcodes as Op
1516
from ethereum_test_types.eof.v1 import Container
17+
from ethereum_test_types.helpers import compute_create_address
18+
from tests.prague.eip7702_set_code_tx.spec import Spec
1619

1720
from .. import EOF_FORK_NAME
1821
from .helpers import (
22+
slot_all_subcall_gas_gone,
1923
slot_code_worked,
2024
slot_create_address,
2125
smallest_initcode_subcontainer,
@@ -38,46 +42,128 @@
3842
],
3943
)
4044
@pytest.mark.parametrize(
41-
"deploy_code",
45+
"initcode",
4246
[
47+
Bytes("0xEF00"),
48+
Bytes("0xEF0001"),
4349
pytest.param(smallest_initcode_subcontainer, id="deploy_eof_initcontainer"),
4450
pytest.param(smallest_runtime_subcontainer, id="deploy_eof_container"),
4551
],
4652
)
47-
def test_cross_version_creates_fail(
53+
def test_cross_version_creates_fail_light(
4854
state_test: StateTestFiller,
4955
pre: Alloc,
5056
legacy_create_opcode: Opcodes,
51-
deploy_code: Container,
57+
initcode: Bytes | Container,
5258
):
53-
"""Verifies that CREATE and CREATE2 cannot create EOF contracts."""
59+
"""Verifies that CREATE and CREATE2 cannot run EOF initcodes and fail early on attempt."""
5460
env = Environment()
55-
salt_param = [0] if legacy_create_opcode == Op.CREATE2 else []
61+
5662
sender = pre.fund_eoa()
63+
64+
tx_gas_limit = 10_000_000
65+
5766
contract_address = pre.deploy_contract(
5867
code=Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE)
59-
+ Op.SSTORE(slot_create_address, legacy_create_opcode(0, 0, Op.CALLDATASIZE, *salt_param))
68+
+ Op.SSTORE(slot_create_address, legacy_create_opcode(size=Op.CALLDATASIZE))
69+
# Aproximates whether code until here consumed the 63/64th gas given to subcall
70+
+ Op.SSTORE(slot_all_subcall_gas_gone, Op.LT(Op.GAS, tx_gas_limit // 64))
6071
+ Op.SSTORE(slot_code_worked, value_code_worked)
6172
+ Op.STOP
6273
)
6374

64-
# Storage in 0 should be empty as the create/create2 should fail,
65-
# and 1 in 1 to show execution continued and did not halt
6675
post = {
6776
contract_address: Account(
6877
storage={
6978
slot_create_address: EOFCREATE_FAILURE,
7079
slot_code_worked: value_code_worked,
71-
}
72-
)
80+
slot_all_subcall_gas_gone: 0,
81+
},
82+
nonce=1,
83+
),
84+
# Double check no accounts were created
85+
compute_create_address(address=contract_address, nonce=1): Account.NONEXISTENT,
86+
compute_create_address(
87+
address=contract_address, initcode=initcode, salt=0, opcode=Op.CREATE2
88+
): Account.NONEXISTENT,
7389
}
7490
tx = Transaction(
7591
to=contract_address,
76-
gas_limit=10_000_000,
77-
gas_price=10,
78-
protected=False,
92+
gas_limit=tx_gas_limit,
7993
sender=sender,
80-
data=deploy_code,
94+
data=initcode,
95+
)
96+
97+
state_test(
98+
env=env,
99+
pre=pre,
100+
post=post,
101+
tx=tx,
102+
)
103+
104+
105+
@pytest.mark.parametrize(
106+
"legacy_create_opcode",
107+
[
108+
pytest.param(Op.CREATE, id="CREATE"),
109+
pytest.param(Op.CREATE2, id="CREATE2"),
110+
],
111+
)
112+
@pytest.mark.parametrize(
113+
"initcode",
114+
[
115+
Bytes("0xEF"),
116+
Bytes("0xEF01"),
117+
Bytes("0xEF0101"),
118+
Spec.delegation_designation(Address(0xAA)),
119+
Bytes("0xEF02"),
120+
],
121+
)
122+
def test_cross_version_creates_fail_hard(
123+
state_test: StateTestFiller,
124+
pre: Alloc,
125+
legacy_create_opcode: Opcodes,
126+
initcode: Bytes,
127+
):
128+
"""
129+
Verifies that CREATE and CREATE2 fail hard on attempt to run initcode starting with `EF` but
130+
not `EF00`.
131+
"""
132+
env = Environment()
133+
134+
sender = pre.fund_eoa()
135+
136+
tx_gas_limit = 10_000_000
137+
138+
contract_address = pre.deploy_contract(
139+
code=Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE)
140+
+ Op.SSTORE(slot_create_address, legacy_create_opcode(size=Op.CALLDATASIZE))
141+
# Aproximates whether code until here consumed the 63/64th gas given to subcall
142+
+ Op.SSTORE(slot_all_subcall_gas_gone, Op.LT(Op.GAS, tx_gas_limit // 64))
143+
+ Op.SSTORE(slot_code_worked, value_code_worked)
144+
+ Op.STOP
145+
)
146+
147+
post = {
148+
contract_address: Account(
149+
storage={
150+
slot_create_address: EOFCREATE_FAILURE,
151+
slot_code_worked: value_code_worked,
152+
slot_all_subcall_gas_gone: 1,
153+
},
154+
nonce=2,
155+
),
156+
# Double check no accounts were created
157+
compute_create_address(address=contract_address, nonce=1): Account.NONEXISTENT,
158+
compute_create_address(
159+
address=contract_address, initcode=initcode, salt=0, opcode=Op.CREATE2
160+
): Account.NONEXISTENT,
161+
}
162+
tx = Transaction(
163+
to=contract_address,
164+
gas_limit=tx_gas_limit,
165+
sender=sender,
166+
data=initcode,
81167
)
82168

83169
state_test(
@@ -98,6 +184,10 @@ def test_cross_version_creates_fail(
98184
@pytest.mark.parametrize(
99185
"deploy_code",
100186
[
187+
Bytes("0xEF"),
188+
Bytes("0xEF00"),
189+
Bytes("0xEF0001"),
190+
Bytes("0xEF01"),
101191
pytest.param(smallest_initcode_subcontainer, id="deploy_eof_initcontainer"),
102192
pytest.param(smallest_runtime_subcontainer, id="deploy_eof_container"),
103193
],
@@ -106,9 +196,13 @@ def test_legacy_initcode_eof_contract_fails(
106196
state_test: StateTestFiller,
107197
pre: Alloc,
108198
legacy_create_opcode: Opcodes,
109-
deploy_code: Container,
199+
deploy_code: Bytes | Container,
110200
):
111-
"""Verifies that legacy initcode cannot create EOF."""
201+
"""
202+
Verifies that legacy initcode cannot create EOF.
203+
204+
This tests only ensures EIP-3541 behavior is kept, not altered by EIP-7620.
205+
"""
112206
env = Environment()
113207
init_code = LegacyInitcode(deploy_code=deploy_code)
114208
salt_param = [0] if legacy_create_opcode == Op.CREATE2 else []
@@ -131,8 +225,6 @@ def test_legacy_initcode_eof_contract_fails(
131225
tx = Transaction(
132226
to=contract_address,
133227
gas_limit=10_000_000,
134-
gas_price=10,
135-
protected=False,
136228
data=init_code,
137229
sender=sender,
138230
)

0 commit comments

Comments
 (0)