Skip to content

test_top_frame_regular_charge()

Documentation for tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_top_frame_charges.py::test_top_frame_regular_charge@c74f1a67.

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_regular_charge --fork Amsterdam

Recipient is an existing EIP-7702 delegation, so the top-frame fires the COLD_ACCOUNT_ACCESS regular-gas charge regardless of whether the transaction transfers value.

  • oog: gas limit is one short of covering the regular charge (plus the value-transfer charge when value > 0). The transaction OOGs at charge_gas(COLD_ACCOUNT_ACCESS) before the delegated code runs. The sender pays the full gas_limit and the recipient keeps its pre-tx state.
  • success: gas limit covers the regular charge; the delegated code is a STOP and the transaction lands the value transfer.
  • evm_reverts: the delegated code reverts immediately. The top-frame charge is consumed before dispatch and the two PUSH opcodes that feed the REVERT are paid before the revert; the value transfer is rolled back, the unused EVM budget is returned, and the intrinsic and top-frame gas remain paid.
Source code in tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/test_top_frame_charges.py
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
@pytest.mark.parametrize("outcome", ["oog", "success", "evm_reverts"])
@pytest.mark.parametrize(
    "value",
    [
        pytest.param(0, id="zero_value"),
        pytest.param(1, id="non-zero_value"),
    ],
)
def test_top_frame_regular_charge(
    fork: Fork,
    pre: Alloc,
    state_test: StateTestFiller,
    outcome: str,
    value: int,
) -> None:
    """
    Recipient is an existing EIP-7702 delegation, so the top-frame
    fires the ``COLD_ACCOUNT_ACCESS`` regular-gas charge regardless of
    whether the transaction transfers value.

    - ``oog``: gas limit is one short of covering the regular charge
      (plus the value-transfer charge when ``value > 0``). The
      transaction OOGs at ``charge_gas(COLD_ACCOUNT_ACCESS)`` before
      the delegated code runs. The sender pays the full ``gas_limit``
      and the recipient keeps its pre-tx state.
    - ``success``: gas limit covers the regular charge; the delegated
      code is a ``STOP`` and the transaction lands the value transfer.
    - ``evm_reverts``: the delegated code reverts immediately. The
      top-frame charge is consumed before dispatch and the two
      ``PUSH`` opcodes that feed the ``REVERT`` are paid before the
      revert; the value transfer is rolled back, the unused EVM
      budget is returned, and the intrinsic and top-frame gas remain
      paid.
    """
    sender_initial_balance = 10**18
    sender = pre.fund_eoa(sender_initial_balance)

    revert_code = Op.REVERT(0, 0)
    if outcome == "evm_reverts":
        delegated_to = pre.deploy_contract(code=revert_code)
    else:
        delegated_to = pre.deploy_contract(code=Op.STOP)
    target_code = Spec7702.delegation_designation(delegated_to)
    target = pre.deploy_contract(code=target_code)

    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,
    )
    assert top_frame_gas > 0, (
        "top-frame regular gas must be non-zero for this scenario"
    )

    gas_price = 1_000_000_000
    if outcome == "oog":
        gas_limit = intrinsic_gas + top_frame_gas - 1
        sender_final_balance = sender_initial_balance - gas_limit * gas_price
        target_balance = 0
    elif outcome == "success":
        total_gas_cost = intrinsic_gas + top_frame_gas
        gas_limit = total_gas_cost + 1000
        sender_final_balance = (
            sender_initial_balance - value - total_gas_cost * gas_price
        )
        target_balance = value
    else:
        # Two ``PUSH`` opcodes feed ``REVERT`` before it halts.
        revert_exec_gas = revert_code.gas_cost(fork)
        gas_used = intrinsic_gas + top_frame_gas + revert_exec_gas
        gas_limit = gas_used + 1000
        # Value transfer is rolled back, so the sender keeps the
        # would-be transferred value. The intrinsic, top-frame, and
        # pre-revert EVM gas stay paid.
        sender_final_balance = sender_initial_balance - gas_used * gas_price
        target_balance = 0

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

    post = {
        sender: Account(nonce=1, balance=sender_final_balance),
        target: Account(balance=target_balance, code=target_code),
    }

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

Parametrized Test Cases

This test generates 6 parametrized test cases across 1 fork.