Skip to content

test_delegatecall_child_spill_not_double_charged()

Documentation for tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_call.py::test_delegatecall_child_spill_not_double_charged@c74f1a67.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_call.py::test_delegatecall_child_spill_not_double_charged --fork Amsterdam

Test DELEGATECALL child state gas paid from gas_left is not recharged.

With the gas limit pinned to the Amsterdam tx gas cap and no requested reservoir (state_gas_reservoir=0), the top-level frame starts with no state gas reservoir and the child pays for SSTOREs by spilling from gas_left. The parent frame must not charge the same state growth again at frame end.

Source code in tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_call.py
 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
@pytest.mark.valid_from("EIP8037")
def test_delegatecall_child_spill_not_double_charged(
    state_test: StateTestFiller,
    pre: Alloc,
) -> None:
    """
    Test DELEGATECALL child state gas paid from `gas_left` is not recharged.

    With the gas limit pinned to the Amsterdam tx gas cap and no requested
    reservoir (`state_gas_reservoir=0`), the top-level frame starts with no
    state gas reservoir and the child pays for SSTOREs by spilling from
    `gas_left`. The parent frame must not charge the same state growth again
    at frame end.
    """
    child_code = sum(Op.SSTORE(i, i + 1) for i in range(6)) + Op.STOP
    child = pre.deploy_contract(code=child_code)

    caller = pre.deploy_contract(
        code=Op.POP(
            Op.DELEGATECALL(
                gas=Op.GAS,
                address=child,
                args_offset=0,
                args_size=0,
                ret_offset=0,
                ret_size=0,
            )
        )
    )

    tx = Transaction(
        to=caller,
        state_gas_reservoir=0,
        sender=pre.fund_eoa(),
    )

    post = {
        caller: Account(storage={i: i + 1 for i in range(6)}),
    }
    state_test(pre=pre, post=post, tx=tx)

Parametrized Test Cases

This test generates 1 parametrized test case across 1 fork.