Skip to content

test_create_no_double_charge_new_account()

Documentation for tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_create_no_double_charge_new_account@622620d8.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_create_no_double_charge_new_account --fork Amsterdam

Verify CREATE does not double-charge new-account gas.

CREATE charges EXECUTION_GAS_CREATE as execution gas and new-account state gas separately. Provide exactly enough gas for both — if GAS_NEW_ACCOUNT were charged twice (once in execution, once in state), the CREATE would OOG.

Source code in tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
@pytest.mark.valid_from("EIP8037")
def test_create_no_double_charge_new_account(
    state_test: StateTestFiller,
    pre: Alloc,
    fork: Fork,
) -> None:
    """
    Verify CREATE does not double-charge new-account gas.

    CREATE charges EXECUTION_GAS_CREATE as execution gas and new-account
    state gas separately. Provide exactly enough gas for both — if
    GAS_NEW_ACCOUNT were charged twice (once in execution, once in
    state), the CREATE would OOG.
    """
    # Child: just does CREATE(value=0, offset=0, size=0) and stores result.
    # This creates an empty account (no code deposit).
    child_code = Op.SSTORE(0, Op.CREATE(value=0, offset=0, size=0))
    child = pre.deploy_contract(child_code)

    create_address = compute_create_address(address=child, nonce=1)

    # Caller forwards exact execution gas via CALL. State gas for
    # new account comes from the reservoir (gas_limit above the cap).
    caller_storage = Storage()
    caller = pre.deploy_contract(
        Op.SSTORE(
            caller_storage.store_next(1, "create_succeeds"),
            Op.CALL(gas=child_code.execution_cost(fork), address=child),
        )
    )

    tx = Transaction(
        sender=pre.fund_eoa(),
        to=caller,
        state_gas_reservoir=child_code.state_cost(fork),
    )

    post = {
        caller: Account(storage=caller_storage),
        child: Account(storage={0: create_address}),
        create_address: Account(nonce=1),
    }
    state_test(pre=pre, tx=tx, post=post)

Parametrized Test Cases

This test generates 1 parametrized test case across 1 fork.