Skip to content

test_tx_installs_delegation_on_funded_recipient()

Documentation for tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_value_moving_with_tx_delegation.py::test_tx_installs_delegation_on_funded_recipient@87aba1a3.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_value_moving_with_tx_delegation.py::test_tx_installs_delegation_on_funded_recipient --fork Amsterdam

Scenario 1: tx.to is a funded EOA with no prior delegation. The type-4 transaction's authorization installs delegation on tx.to.

The authority (tx.to) already exists, so it pays no NEW_ACCOUNT; it has no prior code, so writing the delegation indicator pays AUTH_BASE. Whether it pays ACCOUNT_WRITE depends on the value transfer: with zero_value the delegation write is the transaction's first write to tx.to and ACCOUNT_WRITE is charged; with non-zero_value the transaction already pays to write tx.to when it transfers value to it, so no ACCOUNT_WRITE accrues. The top-frame COLD_ACCOUNT_ACCESS charge for the now-delegated recipient (its fresh delegation target is cold) still fires.

Source code in tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_value_moving_with_tx_delegation.py
 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
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
@pytest.mark.parametrize(
    "value",
    [
        pytest.param(0, id="zero_value"),
        pytest.param(1, id="non-zero_value"),
    ],
)
def test_tx_installs_delegation_on_funded_recipient(
    fork: Fork,
    pre: Alloc,
    state_test: StateTestFiller,
    value: int,
) -> None:
    """
    Scenario 1: ``tx.to`` is a funded EOA with no prior delegation.
    The type-4 transaction's authorization installs delegation on
    ``tx.to``.

    The authority (``tx.to``) already exists, so it pays no
    ``NEW_ACCOUNT``; it has no prior code, so writing the delegation
    indicator pays ``AUTH_BASE``. Whether it pays ``ACCOUNT_WRITE``
    depends on the value transfer: with ``zero_value`` the delegation
    write is the transaction's first write to ``tx.to`` and
    ``ACCOUNT_WRITE`` is charged; with ``non-zero_value`` the
    transaction already pays to write ``tx.to`` when it transfers value
    to it, so no ``ACCOUNT_WRITE`` accrues. The top-frame
    ``COLD_ACCOUNT_ACCESS`` charge for the now-delegated recipient (its
    fresh delegation target is cold) still fires.
    """
    sender_initial_balance = 10**18
    sender = pre.fund_eoa(sender_initial_balance)

    target_initial_balance = 100
    target = pre.fund_eoa(amount=target_initial_balance)
    delegated_to = pre.deploy_contract(code=Op.STOP)

    auth = AuthorizationTuple(
        address=delegated_to,
        nonce=0,
        signer=target,
        # Funded authority already exists, so no NEW_ACCOUNT.
        creates_account=False,
        first_write=not bool(value),
    )
    authorization_list = [auth]

    # Intrinsic sees the recipient in its pre-tx form (funded EOA); the
    # delegation only surfaces at the top-frame check.
    intrinsic_gas = fork.transaction_intrinsic_cost_calculator()(
        sends_value=bool(value),
        recipient_type=RecipientType.EOA,
        authorization_list_or_count=authorization_list,
        return_cost_deducted_prior_execution=True,
    )
    top_frame_regular = fork.transaction_top_frame_gas_calculator()(
        sends_value=bool(value),
        recipient_type=RecipientType.DELEGATION_7702,
        delegation_warm=False,
        authorizations=authorization_list,
    )
    top_frame_state = fork.transaction_top_frame_state_gas(
        sends_value=bool(value),
        recipient_type=RecipientType.DELEGATION_7702,
        authorizations=authorization_list,
    )

    # Costs are charged exactly (no refund); under the default zero
    # state-gas reservoir the state gas spills into regular gas.
    total_gas_cost = intrinsic_gas + top_frame_regular + top_frame_state
    tx_gas_limit = total_gas_cost + 1000
    gas_price = 1_000_000_000

    tx = Transaction(
        sender=sender,
        to=target,
        value=value,
        authorization_list=authorization_list,
        gas_limit=tx_gas_limit,
        max_fee_per_gas=gas_price,
        max_priority_fee_per_gas=gas_price,
    )

    sender_final_balance = (
        sender_initial_balance - value - (total_gas_cost * gas_price)
    )

    post = {
        sender: Account(nonce=1, balance=sender_final_balance),
        target: Account(
            nonce=1,
            balance=target_initial_balance + value,
            code=Spec7702.delegation_designation(delegated_to),
        ),
    }

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

Parametrized Test Cases

This test generates 2 parametrized test cases across 1 fork.