Skip to content

test_top_frame_new_account_skipped_for_nonce_only_recipient()

Documentation for tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_top_frame_charges.py::test_top_frame_new_account_skipped_for_nonce_only_recipient@2119b382.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_top_frame_charges.py::test_top_frame_new_account_skipped_for_nonce_only_recipient --fork Amsterdam

A recipient that is alive only by its nonce (nonce=1, zero balance, no code) is not empty per EIP-161, so a value transfer to it does not incur the top-frame NEW_ACCOUNT charge. This pins that the gate keys on is_account_alive, not balance == 0.

Such an account is reachable on-chain: any EOA that has sent a transaction (nonce bumped) and been fully drained sits at nonce>0, balance=0, no code.

The gas limit is pinned to exactly the intrinsic, leaving no room for any extra charge: an implementation that wrongly charged NEW_ACCOUNT (keying on the zero balance) would out-of-gas rather than succeed. The recipient has no code, so no EVM runs and the intrinsic is fully consumed with nothing to refund.

Source code in tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_top_frame_charges.py
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
@pytest.mark.pre_alloc_mutable
def test_top_frame_new_account_skipped_for_nonce_only_recipient(
    fork: Fork,
    pre: Alloc,
    state_test: StateTestFiller,
) -> None:
    """
    A recipient that is alive only by its nonce (``nonce=1``, zero
    balance, no code) is not empty per EIP-161, so a value transfer to
    it does *not* incur the top-frame ``NEW_ACCOUNT`` charge. This pins
    that the gate keys on ``is_account_alive``, not ``balance == 0``.

    Such an account is reachable on-chain: any EOA that has sent a
    transaction (nonce bumped) and been fully drained sits at
    ``nonce>0, balance=0, no code``.

    The gas limit is pinned to exactly the intrinsic, leaving no room
    for any extra charge: an implementation that wrongly charged
    ``NEW_ACCOUNT`` (keying on the zero balance) would out-of-gas
    rather than succeed. The recipient has no code, so no EVM runs and
    the intrinsic is fully consumed with nothing to refund.
    """
    sender_initial_balance = 10**18
    sender = pre.fund_eoa(sender_initial_balance)
    # Alive via nonce only: not empty per EIP-161 because nonce != 0.
    target = pre.fund_eoa(amount=0, nonce=1)
    value = 1

    intrinsic_gas = fork.transaction_intrinsic_cost_calculator()(
        sends_value=True,
        recipient_type=RecipientType.EOA,
        return_cost_deducted_prior_execution=True,
    )
    top_frame_state_gas = fork.transaction_top_frame_state_gas(
        sends_value=True,
        recipient_type=RecipientType.EOA,
    )
    assert top_frame_state_gas == 0, (
        "a nonce-only-alive recipient must not incur the NEW_ACCOUNT charge"
    )

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

    sender_final_balance = (
        sender_initial_balance - value - intrinsic_gas * gas_price
    )
    post = {
        sender: Account(nonce=1, balance=sender_final_balance),
        target: Account(nonce=1, balance=value),
    }

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

Parametrized Test Cases

This test generates 1 parametrized test case across 1 fork.