-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new(tests): EIP-7069: Different RETURNDATACOPY oob
- Loading branch information
Showing
4 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
3 changes: 3 additions & 0 deletions
3
tests/prague/eip7692_eof_v1/eip7069_returndatacopy/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
""" | ||
EOF tests for EIP-7069 RETURNDATACOPY changes | ||
""" |
11 changes: 11 additions & 0 deletions
11
tests/prague/eip7692_eof_v1/eip7069_returndatacopy/spec.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
""" | ||
EOF V1 Constants used throughout all tests | ||
""" | ||
|
||
EOF_FORK_NAME = "CancunEIP7692" | ||
|
||
CALL_FAILURE = 0 | ||
CALL_SUCCESS = 1 | ||
EXTCALL_SUCCESS = 0 | ||
EXTCALL_REVERT = 1 | ||
EXTCALL_FAILED = 2 |
141 changes: 141 additions & 0 deletions
141
tests/prague/eip7692_eof_v1/eip7069_returndatacopy/test_returndatacopy_execution.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
""" | ||
RETURNDATACOPY tests covering changes in behavior in EOF. | ||
""" | ||
import itertools | ||
|
||
import pytest | ||
|
||
from ethereum_test_tools import Account, StateTestFiller | ||
from ethereum_test_tools.common.base_types import Address | ||
from ethereum_test_tools.common.constants import TestAddress | ||
from ethereum_test_tools.common.types import Environment, Transaction | ||
from ethereum_test_tools.eof.v1 import Container, Section | ||
from ethereum_test_tools.vm.opcode import Opcodes as Op | ||
|
||
from .. import EOF_FORK_NAME | ||
from .spec import CALL_FAILURE, CALL_SUCCESS, EXTCALL_FAILED, EXTCALL_SUCCESS | ||
|
||
REFERENCE_SPEC_GIT_PATH = "EIPS/eip-7069.md" | ||
REFERENCE_SPEC_VERSION = "73f68e76dd92486d13e27375cbb468a2be445a9f" | ||
|
||
pytestmark = pytest.mark.valid_from(EOF_FORK_NAME) | ||
|
||
_slot = itertools.count(1) | ||
slot_eof_target_call_status = next(_slot) | ||
slot_legacy_target_call_status = next(_slot) | ||
slot_eof_target_returndata = next(_slot) | ||
slot_eof_target_returndatasize = next(_slot) | ||
slot_legacy_target_returndatasize = next(_slot) | ||
|
||
_address_allocation = itertools.count(0x10000) | ||
address_entry_point = Address(next(_address_allocation)) | ||
address_callee_eof = Address(next(_address_allocation)) | ||
address_callee_legacy = Address(next(_address_allocation)) | ||
|
||
pre_storage = { | ||
slot_eof_target_call_status: "0xdd", | ||
slot_eof_target_returndata: "0xdd", | ||
slot_eof_target_returndatasize: "0xdd", | ||
slot_legacy_target_call_status: "0xdd", | ||
slot_legacy_target_returndatasize: "0xdd", | ||
} | ||
|
||
# Both codes below make an OOB (out-of-bounds) RETURNDATACOPY of one byte, | ||
# which they then attempt to return (Legacy should exceptionally halt on RETURNDATACOPY). | ||
code_eof_oob_returndatacopy = Container( | ||
sections=[ | ||
Section.Code( | ||
code=Op.RETURNDATACOPY(0, 0, 1) + Op.RETURN(0, 1), | ||
max_stack_height=3, | ||
) | ||
] | ||
) | ||
code_legacy_oob_returndatacopy = Op.RETURNDATACOPY(0, 0, 1) + Op.RETURN(0, 1) | ||
|
||
|
||
@pytest.mark.parametrize("top_level", ("LegacyContract", "EOFContract"), ids=lambda x: x) | ||
def test_returndatacopy_oob( | ||
state_test: StateTestFiller, | ||
top_level: str, | ||
): | ||
"""Test RETURNDATACOPY correct oob behavior""" | ||
env = Environment() | ||
|
||
address_entry_point = Address(0x100) | ||
address_callee_eof = Address(0x200) | ||
address_callee_legacy = Address(0x300) | ||
|
||
pre = { | ||
address_entry_point: Account( | ||
code=Op.SSTORE( | ||
slot_eof_target_call_status, Op.CALL(Op.GAS, address_callee_eof, 0, 0, 0, 0, 0) | ||
) | ||
+ Op.SSTORE(slot_eof_target_returndatasize, Op.RETURNDATASIZE) | ||
+ Op.SSTORE(slot_eof_target_returndata, Op.RETURNDATACOPY(0, 0, 1) + Op.MLOAD(0)) | ||
+ Op.SSTORE( | ||
slot_legacy_target_call_status, | ||
Op.CALL(Op.GAS, Address(address_callee_legacy), 0, 0, 0, 0, 0), | ||
) | ||
+ Op.SSTORE(slot_legacy_target_returndatasize, Op.RETURNDATASIZE) | ||
if top_level == "LegacyContract" | ||
else Container( | ||
sections=[ | ||
Section.Code( | ||
code=Op.SSTORE( | ||
slot_eof_target_call_status, Op.EXTCALL(address_callee_eof, 0, 0, 0) | ||
) | ||
+ Op.SSTORE(slot_eof_target_returndatasize, Op.RETURNDATASIZE) | ||
+ Op.SSTORE( | ||
slot_eof_target_returndata, Op.RETURNDATACOPY(0, 0, 1) + Op.MLOAD(0) | ||
) | ||
+ Op.SSTORE( | ||
slot_legacy_target_call_status, | ||
Op.EXTCALL(Address(address_callee_legacy), 0, 0, 0), | ||
) | ||
+ Op.SSTORE(slot_legacy_target_returndatasize, Op.RETURNDATASIZE) | ||
+ Op.STOP, | ||
max_stack_height=4, | ||
), | ||
], | ||
), | ||
storage=pre_storage, | ||
), | ||
address_callee_eof: Account(code=code_eof_oob_returndatacopy), | ||
address_callee_legacy: Account(code=code_legacy_oob_returndatacopy), | ||
TestAddress: Account(balance=1_000_000_000_000_000_000_000, nonce=0), | ||
} | ||
|
||
tx = Transaction( | ||
to=address_entry_point, | ||
gas_limit=50000000, | ||
gas_price=10, | ||
protected=False, | ||
data="", | ||
) | ||
|
||
post = { | ||
Address(address_entry_point): Account( | ||
storage={ | ||
slot_eof_target_call_status: CALL_SUCCESS, | ||
slot_eof_target_returndata: "0x00", | ||
slot_eof_target_returndatasize: "0x01", | ||
slot_legacy_target_call_status: CALL_FAILURE, | ||
slot_legacy_target_returndatasize: "0x00", | ||
} | ||
if top_level == "LegacyContract" | ||
else { | ||
slot_eof_target_call_status: EXTCALL_SUCCESS, | ||
slot_eof_target_returndata: "0x00", | ||
slot_eof_target_returndatasize: "0x01", | ||
slot_legacy_target_call_status: EXTCALL_FAILED, | ||
slot_legacy_target_returndatasize: "0x00", | ||
} | ||
) | ||
} | ||
|
||
state_test( | ||
env=env, | ||
pre=pre, | ||
post=post, | ||
tx=tx, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -242,6 +242,7 @@ num | |
number | ||
ommer | ||
ommers | ||
oob | ||
opc | ||
oprypin | ||
origin | ||
|