Skip to content

Commit

Permalink
Merge pull request #756 from shemnon/eof/fuzzing-1
Browse files Browse the repository at this point in the history
new(tests): EOF - Tests from Fuzzing
  • Loading branch information
shemnon committed Aug 29, 2024
2 parents bc820c6 + f53700c commit 681f3a3
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 158 deletions.
101 changes: 5 additions & 96 deletions tests/prague/eip7692_eof_v1/eip3540_eof_v1/test_code_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,111 +2,20 @@
EOF V1 Code Validation tests
"""

from typing import Dict, List

import pytest

from ethereum_test_tools import (
EOA,
Account,
Address,
Alloc,
Environment,
EOFTestFiller,
Transaction,
compute_eofcreate_address,
)
from ethereum_test_tools.eof.v1 import Container, Initcode
from ethereum_test_tools import EOFTestFiller
from ethereum_test_tools.eof.v1 import Container

from .. import EOF_FORK_NAME

# from .code_validation import INVALID as INVALID_CODE
# from .code_validation import VALID as VALID_CODE
# from .code_validation_function import INVALID as INVALID_FN
# from .code_validation_function import VALID as VALID_FN
# from .code_validation_jump import INVALID as INVALID_RJUMP
# from .code_validation_jump import VALID as VALID_RJUMP
from .container import INVALID as INVALID_CONTAINERS
from .container import VALID as VALID_CONTAINERS

# from .tests_execution_function import VALID as VALID_EXEC_FN

ALL_VALID = VALID_CONTAINERS
ALL_INVALID = INVALID_CONTAINERS
# ALL_VALID = (
# VALID_CONTAINERS + VALID_CODE + VALID_RJUMP + VALID_FN + VALID_EXEC_FN
# )
# ALL_INVALID = INVALID_CONTAINERS + INVALID_CODE + INVALID_RJUMP + INVALID_FN
from .container import INVALID, VALID

REFERENCE_SPEC_GIT_PATH = "EIPS/eip-3540.md"
REFERENCE_SPEC_VERSION = "8dcb0a8c1c0102c87224308028632cc986a61183"

pytestmark = pytest.mark.valid_from(EOF_FORK_NAME)


@pytest.fixture
def env(): # noqa: D103
return Environment()


@pytest.fixture
def sender(pre: Alloc): # noqa: D103
return pre.fund_eoa()


@pytest.fixture
def create3_init_container(container: Container) -> Initcode: # noqa: D103
return Initcode(deploy_container=container)


@pytest.fixture
def create3_opcode_contract_address( # noqa: D103
pre: Alloc,
create3_init_container: Initcode,
) -> Address:
return pre.deploy_contract(create3_init_container, address=Address(0x300))


@pytest.fixture
def txs( # noqa: D103
sender: EOA,
create3_opcode_contract_address: Address,
) -> List[Transaction]:
return [
Transaction(
to=create3_opcode_contract_address,
gas_limit=100000000,
gas_price=10,
# data=initcode,
protected=False,
sender=sender,
)
]


@pytest.fixture
def post( # noqa: D103
create3_init_container: Initcode,
container: Container,
create3_opcode_contract_address: Address,
) -> Dict[Address, Account]:
create_opcode_created_contract_address = compute_eofcreate_address(
create3_opcode_contract_address,
0,
bytes(create3_init_container.init_container),
)

new_account = Account(code=container)

# Do not expect to create account if it is invalid
if hasattr(new_account, "code") and container.validity_error != "":
return {}
else:
return {
create_opcode_created_contract_address: new_account,
}


def container_name(c: Container):
"""
Return the name of the container for use in pytest ids.
Expand All @@ -119,7 +28,7 @@ def container_name(c: Container):

@pytest.mark.parametrize(
"container",
ALL_VALID,
VALID,
ids=container_name,
)
def test_legacy_initcode_valid_eof_v1_contract(
Expand All @@ -140,7 +49,7 @@ def test_legacy_initcode_valid_eof_v1_contract(

@pytest.mark.parametrize(
"container",
ALL_INVALID,
INVALID,
ids=container_name,
)
def test_legacy_initcode_invalid_eof_v1_contract(
Expand Down
46 changes: 46 additions & 0 deletions tests/prague/eip7692_eof_v1/eip4200_relative_jumps/test_rjump.py
Original file line number Diff line number Diff line change
Expand Up @@ -696,3 +696,49 @@ def test_rjump_backwards_reference_only(
data=container,
expect_exception=EOFException.UNREACHABLE_INSTRUCTIONS,
)


def test_rjump_backwards_illegal_stack_height(
eof_test: EOFTestFiller,
):
"""
Invalid backward jump, found via fuzzing coverage
"""
eof_test(
data=Container.Code(
code=(
Op.PUSH0
+ Op.RJUMPI[3]
+ Op.RJUMP(7)
+ Op.PUSH2(0x2015)
+ Op.PUSH3(0x015500)
+ Op.RJUMP[-10]
),
max_stack_height=0x24,
),
expect_exception=EOFException.STACK_HEIGHT_MISMATCH,
)


def test_rjump_backwards_infinite_loop(
eof_test: EOFTestFiller,
):
"""
Validate that a backwards RJUMP as terminal operation is valid
"""
eof_test(
data=Container(
name="backwards_rjump_terminal",
sections=[
Section.Code(
code=Op.PUSH0
+ Op.RJUMPI[3]
+ Op.RJUMP[7]
+ Op.SSTORE(1, 0x2015)
+ Op.STOP
+ Op.RJUMP[-10]
),
Section.Data(data="0xdeadbeef"),
],
),
)
41 changes: 41 additions & 0 deletions tests/prague/eip7692_eof_v1/eip4200_relative_jumps/test_rjumpi.py
Original file line number Diff line number Diff line change
Expand Up @@ -861,3 +861,44 @@ def test_rjumpi_at_the_end(
),
expect_exception=EOFException.MISSING_STOP_OPCODE,
)


def test_tangled_rjumpi(
eof_test: EOFTestFiller,
):
"""
EOF code containing tangled RJUMPI paths
"""
container = Container.Code(
code=(
Op.PUSH0 # [0,0]
+ Op.PUSH0 # [1,1]
+ Op.RJUMPI[8] # [2,2]
+ Op.PUSH1(127) # [1,1]
+ Op.RJUMPI[7] # [2,2]
+ Op.RJUMP[5] # [1,1]
+ Op.PUSH0 # [1,1]
+ Op.RJUMP[0] # [2,1]
+ Op.LT # [1,x]
+ Op.STOP # [1,x]
)
)
eof_test(
data=container,
expect_exception=EOFException.STACK_UNDERFLOW,
)


def test_rjumpi_backwards_onto_dup(
eof_test: EOFTestFiller,
):
"""
Backwards jumpi onto a dup
"""
container = Container.Code(
code=(Op.PUSH0 + Op.DUP1 + Op.RJUMPI[-4] + Op.STOP),
max_stack_height=2,
)
eof_test(
data=container,
)
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,40 @@ def test_rjumpv_backwards(
)


def test_rjumpv_backwards_onto_dup(
eof_test: EOFTestFiller,
):
"""
Backwards jump vector onto a dup
"""
container = Container.Code(
code=(Op.PUSH0 + Op.DUP1 + Op.RJUMPV[-5] + Op.STOP),
max_stack_height=2,
)
eof_test(
data=container,
)


@pytest.mark.parametrize("len", [8, 9])
def test_rjumpv_backwards_large_table(
eof_test: EOFTestFiller,
len: int,
):
"""
Backwards jump vector with a large table
"""
jump_table = [0] * len
jump_table += [len * -2 - 6]
container = Container.Code(
code=(Op.RJUMPV[jump_table](len) + Op.STOP),
max_stack_height=1,
)
eof_test(
data=container,
)


def test_rjumpv_zero(
eof_state_test: EOFStateTestFiller,
):
Expand Down Expand Up @@ -982,7 +1016,7 @@ def test_rjumpv_into_swapn(
pytest.param(256, 255, id="t256i255"),
],
)
def test_rjump_into_exchange(
def test_rjumpv_into_exchange(
eof_test: EOFTestFiller,
table_size: int,
invalid_index: int,
Expand Down
Loading

0 comments on commit 681f3a3

Please sign in to comment.