Skip to content

test_endofcode_behavior()

Documentation for tests/amsterdam/eip8024_dupn_swapn_exchange/test_dupn.py::test_endofcode_behavior@b314d18e.

Generate fixtures for these test cases for Amsterdam with:

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

Test DUPN 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 DUPN duplicates the 145th stack item.

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

Source code in tests/amsterdam/eip8024_dupn_swapn_exchange/test_dupn.py
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
def test_endofcode_behavior(
    pre: Alloc,
    state_test: StateTestFiller,
) -> None:
    """
    Test DUPN 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
    DUPN duplicates the 145th stack item.

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

    # decode_single(0) = 145, which duplicates the 145th item from top
    # We need 145 items on the stack for this to succeed
    stack_height = 145
    marker_value = 0x42

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

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

    # Add just the DUPN opcode without immediate byte
    # After DUPN, pc += 2 goes beyond code, causing implicit STOP
    code += Op.DUPN  # 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.