Skip to content

test_endofcode_behavior()

Documentation for tests/amsterdam/eip8024_dupn_swapn_exchange/test_swapn.py::test_endofcode_behavior@ffe48572.

Generate fixtures for these test cases for Bogota with:

fill -v tests/amsterdam/eip8024_dupn_swapn_exchange/test_swapn.py::test_endofcode_behavior --fork Bogota

Test SWAPN when the immediate byte is beyond the end of code.

Per EIP-8024, code[pc + 1] evaluates to 0 if beyond the end of the code, matching PUSH behavior. With immediate = 0, decode_single(0) = 145, so SWAPN swaps position 1 with position 146.

This test verifies the transaction succeeds (doesn't revert) when SWAPN is the last byte of the code with no immediate byte following it.

Source code in tests/amsterdam/eip8024_dupn_swapn_exchange/test_swapn.py
def test_endofcode_behavior(
    pre: Alloc,
    state_test: StateTestFiller,
) -> None:
    """
    Test SWAPN when the immediate byte is beyond the end of code.

    Per EIP-8024, code[pc + 1] evaluates to 0 if beyond the end of the code,
    matching PUSH behavior. With immediate = 0, decode_single(0) = 145, so
    SWAPN swaps position 1 with position 146.

    This test verifies the transaction succeeds (doesn't revert) when SWAPN
    is the last byte of the code with no immediate byte following it.
    """
    sender = pre.fund_eoa()

    # decode_single(0) = 145, which swaps position 1 with position 146
    # We need 146 items on the stack for this to succeed
    stack_height = 146
    marker_value = 0x42

    # Build code: store marker, push enough items, then SWAPN (no immediate)
    code = Bytecode()
    code += Op.PUSH1(marker_value) + Op.PUSH1(0) + Op.SSTORE  # Store marker

    # Push 146 items to stack so SWAPN with implicit imm=0 succeeds
    for i in range(stack_height):
        code += Op.PUSH1(i % 256)

    # Add just the SWAPN opcode without immediate byte
    # After SWAPN, pc += 2 goes beyond code, causing implicit STOP
    code += Op.SWAPN  # no immediate

    contract_address = pre.deploy_contract(code=code)

    tx = Transaction(to=contract_address, sender=sender)

    # If tx succeeds, storage[0] = marker_value
    # Bad implementation would revert and have empty storage
    post = {contract_address: Account(storage={0: marker_value})}

    state_test(pre=pre, post=post, tx=tx)

Parametrized Test Cases

This test generates 1 parametrized test case across 2 forks.