Skip to content

test_exchange_basic()

Documentation for tests/amsterdam/eip8024_dupn_swapn_exchange/test_exchange.py::test_exchange_basic@b314d18e.

Generate fixtures for these test cases for Amsterdam with:

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

Test EXCHANGE with various n and m values.

Source code in tests/amsterdam/eip8024_dupn_swapn_exchange/test_exchange.py
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
@pytest.mark.parametrize(
    "n,m",
    [
        (1, 2),  # Swap positions 2 and 3
        (1, 16),  # Swap positions 2 and 17
        (1, 29),  # Swap positions 2 and 30 (n + m = 30)
        (5, 10),  # Swap positions 6 and 11
        (13, 17),  # Swap positions 14 and 18 (n + m = 30)
        (14, 16),  # Swap positions 15 and 17 (n + m = 30)
    ],
    ids=lambda x: f"{x}",
)
def test_exchange_basic(
    n: int,
    m: int,
    pre: Alloc,
    fork: Fork,
    state_test: StateTestFiller,
) -> None:
    """Test EXCHANGE with various n and m values."""
    sender = pre.fund_eoa()

    # EXCHANGE with decoded (n, m) swaps position (n+1) with position (m+1)
    stack_height = m + 1  # Need at least m+1 items
    value_at_n_plus_1 = 0xAAAA
    value_at_m_plus_1 = 0xBBBB

    # Build stack with known values at swap positions (n+1) and (m+1)
    code = Bytecode()
    for i in range(stack_height):
        # Stack position is 1-indexed from top, so i=0 is bottom
        stack_pos = stack_height - i  # Position from top (1-indexed)
        if stack_pos == n + 1:
            code += Op.PUSH2(value_at_n_plus_1)
        elif stack_pos == m + 1:
            code += Op.PUSH2(value_at_m_plus_1)
        else:
            code += Op.PUSH2(0x1000 + i)

    # Pass n and m directly - encoder will handle encoding
    code += Op.EXCHANGE[n, m]

    # Store all stack values to verify the swap
    for i in range(stack_height):
        code += Op.PUSH1(i) + Op.SSTORE

    code += Op.STOP

    contract_address = pre.deploy_contract(code=code)

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

    # Build expected storage
    expected_storage = {}
    for i in range(stack_height):
        stack_pos = i + 1  # Position from top (1-indexed)
        if stack_pos == n + 1:
            expected_storage[i] = value_at_m_plus_1  # Now has value from m+1
        elif stack_pos == m + 1:
            expected_storage[i] = value_at_n_plus_1  # Now has value from n+1
        else:
            # Original value at this position
            original_i = stack_height - stack_pos
            expected_storage[i] = 0x1000 + original_i

    post = {contract_address: Account(storage=expected_storage)}

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

Parametrized Test Cases

This test generates 6 parametrized test cases across 1 fork.