Skip to content

test_top_frame_charges_delegation_is_recipient()

Documentation for tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_warmth_invariants.py::test_top_frame_charges_delegation_is_recipient@5c024cbb.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_warmth_invariants.py::test_top_frame_charges_delegation_is_recipient --fork Amsterdam

Recipient holds a pre-existing EIP-7702 delegation pointing back at itself. The delegation target is the recipient, which is warm, so the top-frame charges WARM_ACCESS, and then the dispatched EVM frame runs the recipient's code -- which is the delegation prefix 0xef 01 00 <addr>. The leading 0xef decodes as the INVALID opcode, consuming the remaining EVM budget. The intrinsic and top-frame gas remain paid; the value transfer is rolled back.

Source code in tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_warmth_invariants.py
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
@pytest.mark.parametrize(
    "value",
    [
        pytest.param(0, id="zero_value"),
        pytest.param(1, id="non-zero_value"),
    ],
)
def test_top_frame_charges_delegation_is_recipient(
    fork: Fork,
    pre: Alloc,
    state_test: StateTestFiller,
    value: int,
) -> None:
    """
    Recipient holds a pre-existing EIP-7702 delegation pointing back
    at itself. The delegation target is the recipient, which is warm,
    so the top-frame charges ``WARM_ACCESS``, and then the dispatched
    EVM frame runs the recipient's code -- which *is* the delegation
    prefix ``0xef 01 00 <addr>``. The leading ``0xef`` decodes as the
    ``INVALID`` opcode, consuming the remaining EVM budget. The
    intrinsic and top-frame gas remain paid; the value transfer is
    rolled back.
    """
    sender_initial_balance = 10**18
    sender = pre.fund_eoa(sender_initial_balance)

    # Pre-allocate an EOA that delegates to itself. The 1-wei balance
    # keeps the account alive at top-frame check time so the
    # ``NEW_ACCOUNT`` charge does not fire.
    target = pre.fund_eoa(amount=1, delegation="Self")
    target_code = Spec7702.delegation_designation(target)

    intrinsic_gas = fork.transaction_intrinsic_cost_calculator()(
        sends_value=bool(value),
        recipient_type=RecipientType.DELEGATION_7702,
        return_cost_deducted_prior_execution=True,
    )
    top_frame_gas = fork.transaction_top_frame_gas_calculator()(
        sends_value=bool(value),
        recipient_type=RecipientType.DELEGATION_7702,
        delegation_warm=True,
    )

    # The dispatched frame burns the entire EVM budget on the
    # ``INVALID`` opcode and the value transfer is rolled back, so the
    # sender pays the full ``gas_limit``.
    gas_price = 1_000_000_000
    gas_limit = intrinsic_gas + top_frame_gas + 50_000

    tx = Transaction(
        sender=sender,
        to=target,
        value=value,
        gas_limit=gas_limit,
        gas_price=gas_price,
    )

    sender_final_balance = sender_initial_balance - gas_limit * gas_price

    post = {
        sender: Account(nonce=1, balance=sender_final_balance),
        # Value transfer rolled back by the ``INVALID``; the pre-tx
        # 1-wei balance is preserved.
        target: Account(balance=1, code=target_code),
    }

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

Parametrized Test Cases

This test generates 2 parametrized test cases across 1 fork.