Skip to content

test_create2_failed_deposit_refunds_storage_state_gas()

Documentation for tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_create2_failed_deposit_refunds_storage_state_gas@c74f1a67.

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

Test a failed CREATE2 deposit refunds the init's storage-slot state gas.

Total gas used is independent of slots, so a client that drops the slot refund diverges for slots >= 1; slots == 0 is the negative control.

Source code in tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
@pytest.mark.parametrize("slots", [0, 1, 3])
@pytest.mark.parametrize("fail_mode", ["eip3541", "oog_deposit"])
@pytest.mark.valid_from("EIP8037")
def test_create2_failed_deposit_refunds_storage_state_gas(
    state_test: StateTestFiller,
    pre: Alloc,
    fork: Fork,
    slots: int,
    fail_mode: str,
) -> None:
    """
    Test a failed CREATE2 deposit refunds the init's storage-slot state gas.

    Total gas used is independent of `slots`, so a client that drops the
    slot refund diverges for `slots >= 1`; `slots == 0` is the negative
    control.
    """
    gas_limit_cap = fork.transaction_gas_limit_cap()
    assert gas_limit_cap is not None

    # init: write `slots` new storage slots, then trigger a deposit failure
    init_code = Bytecode()
    for i in range(slots):
        init_code += Op.SSTORE(i, i + 1)
    if fail_mode == "eip3541":
        # return 0xEF -> EIP-3541 rejects the deposited code
        init_code += Op.MSTORE8(0, 0xEF) + Op.RETURN(0, 1)
    else:
        # return max-size code: the code-deposit state gas cannot be paid
        init_code += Op.RETURN(0, fork.max_code_size())
    mstore_value, size = init_code_at_high_bytes(init_code)

    storage = Storage()
    factory = pre.deploy_contract(
        code=(
            Op.MSTORE(0, mstore_value)
            + Op.SSTORE(
                storage.store_next(0, "create2_failed"),
                Op.CREATE2(value=0, offset=0, size=size, salt=0),
            )
        ),
    )

    tx = Transaction(
        to=factory,
        gas_limit=gas_limit_cap,
        sender=pre.fund_eoa(),
    )

    state_test(
        pre=pre,
        post={factory: Account(storage=storage)},
        tx=tx,
    )

Parametrized Test Cases

This test generates 6 parametrized test cases across 1 fork.