Skip to content

test_exchange_jump_to_immediate_byte()

Documentation for tests/amsterdam/eip8024_dupn_swapn_exchange/test_exchange.py::test_exchange_jump_to_immediate_byte@a9abd46e.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip8024_dupn_swapn_exchange/test_exchange.py::test_exchange_jump_to_immediate_byte --fork Amsterdam

Test jumping to EXCHANGE immediate byte position.

Valid immediates are skipped (can't jump to them). Invalid immediates are not skipped - only 0x5B (JUMPDEST) allows jumping.

Source code in tests/amsterdam/eip8024_dupn_swapn_exchange/test_exchange.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
386
387
388
389
390
391
392
393
394
395
396
397
@pytest.mark.parametrize(
    "immediate",
    [
        # valid immediates (0-81 / 128-255): skipped during JUMPDEST
        # analysis, not reachable as jump targets
        0x00,
        0x4F,  # 79
        0x50,  # 80 — POP (valid for EXCHANGE)
        0x51,  # 81 — MLOAD (valid for EXCHANGE)
        # invalid immediates (82-127): not skipped during JUMPDEST
        # analysis, only 0x5B (91) is a JUMPDEST
        0x52,  # 82 — MSTORE (first invalid immediate)
        0x5A,  # 90 — GAS (invalid immediate)
        0x5B,  # 91 — JUMPDEST, only case where jump succeeds
        0x5C,  # 92 — TLOAD (invalid immediate)
        0x60,  # 96 — PUSH1 (invalid immediate)
        0x7F,  # 127 — PUSH32 (last invalid immediate)
        # valid immediates again (128-255)
        0x80,  # 128
        0xFF,  # 255
    ],
    ids=lambda x: f"imm_0x{x:02x}",
)
def test_exchange_jump_to_immediate_byte(
    immediate: int,
    pre: Alloc,
    state_test: StateTestFiller,
) -> None:
    """
    Test jumping to EXCHANGE immediate byte position.

    Valid immediates are skipped (can't jump to them).
    Invalid immediates are not skipped - only 0x5B (JUMPDEST) allows jumping.
    """
    sender = pre.fund_eoa()

    # Bytecode: PUSH1(4) JUMP EXCHANGE[imm] - position 4 is the immediate byte
    code = Bytecode()
    code += Op.PUSH1(4)
    code += Op.JUMP
    code += Op.EXCHANGE[immediate.to_bytes(1, "big")]

    code += Op.PUSH1(0x42) + Op.PUSH1(0) + Op.SSTORE
    code += Op.STOP

    contract_address = pre.deploy_contract(code=code)
    tx = Transaction(to=contract_address, sender=sender)

    if immediate == 0x5B:  # JUMPDEST - only case where jump succeeds
        post = {contract_address: Account(storage={0: 0x42})}
    else:
        post = {contract_address: Account(storage={})}

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

Parametrized Test Cases

This test generates 12 parametrized test cases across 1 fork.