Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 111 additions & 32 deletions tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""test calls across EOF and Legacy."""

import itertools
from enum import Enum, auto, unique

import pytest

Expand Down Expand Up @@ -57,12 +58,67 @@
)


@unique
class TargetAccountType(Enum):
"""Kinds of target accounts for calls."""

EMPTY = auto()
EOA = auto()
LEGACY_CONTRACT = auto()
EOF_CONTRACT = auto()
LEGACY_CONTRACT_INVALID = auto()
EOF_CONTRACT_INVALID = auto()
LEGACY_CONTRACT_REVERT = auto()
EOF_CONTRACT_REVERT = auto()
IDENTITY_PRECOMPILE = auto()

def __str__(self) -> str:
"""Return string representation of the enum."""
return f"{self.name}"


@pytest.fixture
def sender(pre: Alloc) -> EOA:
"""Sender of the transaction."""
return pre.fund_eoa()


@pytest.fixture
def target_address(pre: Alloc, target_account_type: TargetAccountType) -> Address:
"""Target address of the call depending on required type of account."""
match target_account_type:
case TargetAccountType.EMPTY:
return Address(b"\x78" * 20)
case TargetAccountType.EOA:
return pre.fund_eoa()
case TargetAccountType.LEGACY_CONTRACT:
return pre.deploy_contract(
code=Op.STOP,
)
case TargetAccountType.EOF_CONTRACT:
return pre.deploy_contract(
code=Container.Code(Op.STOP),
)
case TargetAccountType.LEGACY_CONTRACT_INVALID:
return pre.deploy_contract(
code=Op.INVALID,
)
case TargetAccountType.EOF_CONTRACT_INVALID:
return pre.deploy_contract(
code=Container.Code(Op.INVALID),
)
case TargetAccountType.LEGACY_CONTRACT_REVERT:
return pre.deploy_contract(
code=Op.REVERT(0, 0),
)
case TargetAccountType.EOF_CONTRACT_REVERT:
return pre.deploy_contract(
code=Container.Code(Op.REVERT(0, 0)),
)
case TargetAccountType.IDENTITY_PRECOMPILE:
return identity


@pytest.mark.parametrize(
"opcode",
[
Expand Down Expand Up @@ -722,23 +778,15 @@ def test_eof_calls_eof_then_fails(
)
@pytest.mark.parametrize(
"target_account_type",
(
"empty",
"EOA",
"LegacyContract",
"EOFContract",
"LegacyContractInvalid",
"EOFContractInvalid",
),
ids=lambda x: x,
TargetAccountType,
)
@pytest.mark.parametrize("value", [0, 1])
def test_eof_calls_clear_return_buffer(
state_test: StateTestFiller,
pre: Alloc,
sender: EOA,
opcode: Op,
target_account_type: str,
target_address: Address,
value: int,
):
"""Test EOF contracts calling clears returndata buffer."""
Expand All @@ -748,28 +796,6 @@ def test_eof_calls_clear_return_buffer(
)
filling_callee_address = pre.deploy_contract(filling_contract_code)

match target_account_type:
case "empty":
target_address = b"\x78" * 20
case "EOA":
target_address = pre.fund_eoa()
case "LegacyContract":
target_address = pre.deploy_contract(
code=Op.STOP,
)
case "EOFContract":
target_address = pre.deploy_contract(
code=Container.Code(Op.STOP),
)
case "LegacyContractInvalid":
target_address = pre.deploy_contract(
code=Op.INVALID,
)
case "EOFContractInvalid":
target_address = pre.deploy_contract(
code=Container.Code(Op.INVALID),
)

caller_contract = Container.Code(
# First fill the return buffer and sanity check
Op.EXTCALL(filling_callee_address, 0, 0, 0)
Expand Down Expand Up @@ -1104,3 +1130,56 @@ def test_eof_calls_msg_depth(
post=post,
tx=tx,
)


@pytest.mark.parametrize("target_account_type", TargetAccountType)
@pytest.mark.parametrize("delegate", [True, False])
def test_extdelegate_call_targets(
state_test: StateTestFiller,
pre: Alloc,
target_account_type: TargetAccountType,
target_address: Address,
delegate: bool,
):
"""
Test EOF contracts extdelegatecalling various targets, especially resolved via 7702
delegation.
"""
env = Environment()

if delegate:
target_address = pre.fund_eoa(0, delegation=target_address)

caller_contract = Container.Code(
Op.SSTORE(slot_code_worked, value_code_worked)
+ Op.SSTORE(slot_call_result, Op.EXTDELEGATECALL(address=target_address))
+ Op.STOP,
)

calling_contract_address = pre.deploy_contract(caller_contract)

tx = Transaction(
sender=pre.fund_eoa(),
to=Address(calling_contract_address),
gas_limit=2_000_000,
)

calling_storage = {
slot_code_worked: value_code_worked,
slot_call_result: EXTCALL_SUCCESS
if target_account_type == TargetAccountType.EOF_CONTRACT
else EXTCALL_FAILURE
if target_account_type == TargetAccountType.EOF_CONTRACT_INVALID
else EXTCALL_REVERT,
}

post = {
calling_contract_address: Account(storage=calling_storage),
}

state_test(
env=env,
pre=pre,
post=post,
tx=tx,
)
13 changes: 7 additions & 6 deletions tests/osaka/eip7692_eof_v1/eof_tracker.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,6 @@
- [x] Legacy executing EXTCODESIZE of EOF contract ([`tests/osaka/eip7692_eof_v1/eip3540_eof_v1/test_extcode.py::test_legacy_calls_eof_sstore`](./eip3540_eof_v1/test_extcode/test_legacy_calls_eof_sstore.md))
- [x] Legacy executing EXTCODEHASH of EOF contract ([`tests/osaka/eip7692_eof_v1/eip3540_eof_v1/test_extcode.py::test_legacy_calls_eof_sstore`](./eip3540_eof_v1/test_extcode/test_legacy_calls_eof_sstore.md))
- [x] Legacy executing EXTCODECOPY of EOF contract ([`tests/osaka/eip7692_eof_v1/eip3540_eof_v1/test_extcode.py::test_legacy_calls_eof_sstore`](./eip3540_eof_v1/test_extcode/test_legacy_calls_eof_sstore.md))
- [ ] `*CALLs` from legacy contracts to EOF contracts (ethereum/tests: src/EIPTestsFiller/StateTests/stEOF/stEIP3540/EOF1_CallsFiller.yml)
- [ ] `EXT*CALLs` from EOF to legacy contracts (ethereum/tests: src/EIPTestsFiller/StateTests/stEOF/stEIP3540/EOF1_CallsFiller.yml)
- [ ] EXTDELEGATECALL from EOF to EOF contract (ethereum/tests: src/EIPTestsFiller/StateTests/stEOF/stEIP3540/EOF1_CallsFiller.yml)
- [ ] EXTDELEGATECALL from EOF to legacy contract failing (ethereum/tests: src/EIPTestsFiller/StateTests/stEOF/stEIP3540/EOF1_CallsFiller.yml)
- [ ] EXTDELEGATECALL from EOF to EOA failing
- [ ] EXTDELEGATECALL from EOF to empty account failing

## EIP-3670: EOF - Code Validation

Expand Down Expand Up @@ -420,6 +414,13 @@
- [x] EXTSTATICCALL from EOF to non-pure legacy contract failing ([`./tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py::test_eof_calls_legacy_sstore`](./eip7069_extcall/test_calls/test_eof_calls_legacy_sstore.md))
- [x] EXTSTATICCALL from EOF to pure EOF contract ([`./tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py::test_eof_calls_legacy_mstore`](./eip7069_extcall/test_calls/test_eof_calls_legacy_mstore.md))
- [x] EXTSTATICCALL from EOF to non-pure EOF contract failing ([`./tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py::test_eof_calls_eof_sstore`](./eip7069_extcall/test_calls/test_eof_calls_eof_sstore.md))
- [x] `*CALLs` from legacy contracts to EOF contracts (ethereum/tests: ([`./tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py::test_legacy_calls_eof_sstore`](./eip7069_extcall/test_calls/test_eof_calls_eof_sstore.md))
- [x] `EXT*CALLs` from EOF to legacy contracts ([`./tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py::test_eof_calls_legacy_sstore`](./eip7069_extcall/test_calls/test_eof_calls_eof_sstore.md))
- [x] EXTDELEGATECALL from EOF to EOF contract ([`./tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py::test_eof_calls_eof_sstore`](./eip7069_extcall/test_calls/test_eof_calls_eof_sstore.md))
- [x] EXTDELEGATECALL from EOF to legacy contract failing ([`./tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py::test_extdelegate_call_targets`](./eip7069_extcall/test_calls/test_extdelegate_call_targets.md))
- [x] EXTDELEGATECALL from EOF to EOA failing ([`./tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py::test_extdelegate_call_targets`](./eip7069_extcall/test_calls/test_extdelegate_call_targets.md))
- [x] EXTDELEGATECALL from EOF to empty account failing ([`./tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py::test_extdelegate_call_targets`](./eip7069_extcall/test_calls/test_extdelegate_call_targets.md))
- [x] EXTDELEGATECALL to EIP-7702 delegate ([`./tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py::test_extdelegate_call_targets`](./eip7069_extcall/test_calls/test_extdelegate_call_targets.md))


## EIP-7620: EOF Contract Creation
Expand Down