Skip to content

test_transfer_gas_is_cleared()

Documentation for tests/osaka/eip7692_eof_v1/eip7069_extcall/test_gas.py::test_transfer_gas_is_cleared@21fb11c8.

Generate fixtures for these test cases for Osaka with:

fill -v tests/osaka/eip7692_eof_v1/eip7069_extcall/test_gas.py::test_transfer_gas_is_cleared --fork Osaka

Test that EXT*CALL call doesn't charge for value transfer, even if the outer call transfered value.

NOTE: This is particularly possible for EXTDELEGATECALL, which carries over the value sent in the outer call, however, we extend the test to all 3 EXT*CALL opcodes for good measure.

Source code in tests/osaka/eip7692_eof_v1/eip7069_extcall/test_gas.py
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
@pytest.mark.parametrize("opcode", [Op.EXTCALL, Op.EXTDELEGATECALL, Op.EXTSTATICCALL])
@pytest.mark.parametrize("value", [0, 1])
def test_transfer_gas_is_cleared(
    state_test: StateTestFiller,
    pre: Alloc,
    state_env: Environment,
    opcode: Op,
    value: int,
):
    """
    Test that EXT*CALL call doesn't charge for value transfer, even if the outer call
    transfered value.

    NOTE: This is particularly possible for EXTDELEGATECALL, which carries over the value sent
    in the outer call, however, we extend the test to all 3 EXT*CALL opcodes for good measure.
    """
    noop_callee_address = pre.deploy_contract(Container.Code(Op.STOP))

    extdelegatecall_contract_address = pre.deploy_contract(
        Container.Code(opcode(address=noop_callee_address) + Op.STOP)
    )

    push_gas = (4 if opcode == Op.EXTCALL else 3) * 3

    gas_test(
        state_test,
        state_env,
        pre,
        setup_code=Op.PUSH1(value) + Op.PUSH0 * 2 + Op.PUSH20(extdelegatecall_contract_address),
        subject_code=Op.EXTCALL,
        subject_balance=5 * value,
        tear_down_code=Op.STOP,
        # NOTE: CALL_WITH_VALUE_GAS is charged only once on the outer EXTCALL, while the base
        # call gas - twice.
        cold_gas=2 * COLD_ACCOUNT_ACCESS_GAS
        + (CALL_WITH_VALUE_GAS if value > 0 else 0)
        + push_gas,
        warm_gas=2 * WARM_ACCOUNT_ACCESS_GAS
        + (CALL_WITH_VALUE_GAS if value > 0 else 0)
        + push_gas,
        out_of_gas_testing=False,
    )

Parametrized Test Cases

The interactive table below is also available as a standalone page.

Test ID (Abbreviated) value opcode
...fork_Osaka-state_test-value_0-opcode_EXTCALL 0 EXTCALL
...fork_Osaka-state_test-value_0-opcode_EXTDELEGATECALL 0 EXTDELEGATECALL
...fork_Osaka-state_test-value_0-opcode_EXTSTATICCALL 0 EXTSTATICCALL
...fork_Osaka-state_test-value_1-opcode_EXTCALL 1 EXTCALL
...fork_Osaka-state_test-value_1-opcode_EXTDELEGATECALL 1 EXTDELEGATECALL
...fork_Osaka-state_test-value_1-opcode_EXTSTATICCALL 1 EXTSTATICCALL
...fork_Osaka-blockchain_test_from_state_test-value_0-opcode_EXTCALL 0 EXTCALL
...fork_Osaka-blockchain_test_from_state_test-value_0-opcode_EXTDELEGATECALL 0 EXTDELEGATECALL
...fork_Osaka-blockchain_test_from_state_test-value_0-opcode_EXTSTATICCALL 0 EXTSTATICCALL
...fork_Osaka-blockchain_test_from_state_test-value_1-opcode_EXTCALL 1 EXTCALL
...fork_Osaka-blockchain_test_from_state_test-value_1-opcode_EXTDELEGATECALL 1 EXTDELEGATECALL
...fork_Osaka-blockchain_test_from_state_test-value_1-opcode_EXTSTATICCALL 1 EXTSTATICCALL