Skip to content

test_endofcode_behavior()

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

Generate fixtures for these test cases for Amsterdam with:

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

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
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
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 1 fork.