CALL with ret_offset larger than memory size and ret_size zero Then do an
MSTORE in that offset to see if memory was expanded in CALL.
This is for bug in a faulty EVM implementation where memory is expanded
when it shouldn't.
Source code in tests/frontier/opcodes/test_call.py
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 | @pytest.mark.valid_from("Berlin")
def test_call_large_offset_mstore(
state_test: StateTestFiller,
pre: Alloc,
fork: Fork,
) -> None:
"""
CALL with ret_offset larger than memory size and ret_size zero Then do an
MSTORE in that offset to see if memory was expanded in CALL.
This is for bug in a faulty EVM implementation where memory is expanded
when it shouldn't.
"""
sender = pre.fund_eoa()
mem_offset = 128 # arbitrary number
# Cost of pushing args onto the stack (each PUSH costs G_VERY_LOW)
call_push_cost = (Op.PUSH1(0) * len(Op.CALL.kwargs)).gas_cost(fork)
mstore_push_cost = (Op.PUSH1(0) * len(Op.MSTORE.kwargs)).gas_cost(fork)
call_measure = CodeGasMeasure(
code=Op.CALL(gas=0, ret_offset=mem_offset, ret_size=0),
overhead_cost=call_push_cost,
extra_stack_items=1, # Because CALL pushes 1 item to the stack
sstore_key=0,
stop=False, # Because it's the first CodeGasMeasure
)
mstore_measure = CodeGasMeasure(
code=Op.MSTORE(offset=mem_offset, value=1),
overhead_cost=mstore_push_cost,
extra_stack_items=0,
sstore_key=1,
)
contract = pre.deploy_contract(call_measure + mstore_measure)
tx = Transaction(
gas_limit=500_000,
to=contract,
value=0,
sender=sender,
)
# this call cost is just the address_access_cost
call_cost = Op.CALL(address_warm=False).gas_cost(fork)
# mstore cost: base cost + expansion cost
mstore_cost = Op.MSTORE(new_memory_size=mem_offset + 32).gas_cost(fork)
state_test(
env=Environment(),
pre=pre,
tx=tx,
post={
contract: Account(
storage={
0: call_cost,
1: mstore_cost,
},
)
},
)
|