Skip to content

test_eof_calls_min_callee_gas()

Documentation for tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py::test_eof_calls_min_callee_gas@21fb11c8.

Generate fixtures for these test cases for Osaka with:

fill -v tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py::test_eof_calls_min_callee_gas --fork Osaka

Test EOF contracts calls do light failure when retained/callee gas is not enough.

Premise of the test is that there exists a range of gas_limit values, which are enough for all instructions to execute, but call's returned value is 1, meaning not enough for gas allowances (MIN_RETAINED_GAS and MIN_CALLEE_GAS) - ones marked with reverts==False.

Once we provide both allowances, the RJUMPI condition is no longer met and reverts==True.

Source code in tests/osaka/eip7692_eof_v1/eip7069_extcall/test_calls.py
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
@pytest.mark.parametrize(
    ["opcode", "extra_gas_value_transfer", "value"],
    [
        [Op.EXTCALL, 0, 0],
        [Op.EXTCALL, 9_000, 1],
        [Op.EXTSTATICCALL, 0, 0],
        [Op.EXTDELEGATECALL, 0, 0],
    ],
    ids=["extcall_without_value", "extcall_with_value", "extstaticcall", "extdelegatecall"],
)
@pytest.mark.parametrize(
    ["extra_gas_limit", "reverts"],
    [
        [0, False],
        [min_retained_gas, False],
        [min_callee_gas, False],
        [min_retained_gas + min_callee_gas, True],
    ],
    ids=["no_allowances", "only_retained", "only_callee", "both_allowances"],
)
def test_eof_calls_min_callee_gas(
    state_test: StateTestFiller,
    pre: Alloc,
    sender: EOA,
    opcode: Op,
    extra_gas_value_transfer: int,
    value: int,
    extra_gas_limit: int,
    reverts: bool,
):
    """
    Test EOF contracts calls do light failure when retained/callee gas is not enough.

    Premise of the test is that there exists a range of `gas_limit` values, which are enough
    for all instructions to execute, but call's returned value is 1, meaning not enough for gas
    allowances (MIN_RETAINED_GAS and MIN_CALLEE_GAS) - ones marked with `reverts==False`.

    Once we provide both allowances, the RJUMPI condition is no longer met and `reverts==True`.
    """
    env = Environment()

    noop_callee_address = pre.deploy_contract(Container.Code(Op.STOP))

    revert_block = Op.REVERT(0, 0)
    calling_contract_address = pre.deploy_contract(
        Container.Code(
            Op.SSTORE(slot_code_worked, value_code_worked)
            + Op.EQ(opcode(address=noop_callee_address, value=value), EXTCALL_REVERT)
            # If the return code isn't 1, it means gas was enough to cover the allowances.
            + Op.RJUMPI[len(revert_block)]
            + revert_block
            + Op.STOP
        ),
        balance=value,
    )

    # `no_oog_gas` is minimum amount of gas_limit which makes the transaction not go oog.
    push_operations = 3 + len(opcode.kwargs)  # type: ignore
    no_oog_gas = (
        21_000
        + 20_000  # SSTORE
        + 2_100  # SSTORE COLD_SLOAD_COST
        + push_operations * 3  # PUSH operations
        + 100  # WARM_STORAGE_READ_COST
        + 2500  # COLD_ACCOUNT_ACCESS - WARM_STORAGE_READ_COST
        + extra_gas_value_transfer
        + 4  # RJUMPI
        + 3  # EQ
    )

    tx = Transaction(
        sender=sender,
        to=Address(calling_contract_address),
        gas_limit=no_oog_gas + extra_gas_limit,
    )

    calling_storage = {
        slot_code_worked: 0 if reverts else value_code_worked,
    }

    post = {
        calling_contract_address: Account(storage=calling_storage),
    }

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

Parametrized Test Cases

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

Test ID (Abbreviated) extra_gas_limit reverts opcode extra_gas_value_transfer value
...fork_Osaka-state_test-no_allowances-extcall_without_value 0 False EXTCALL 0 0
...fork_Osaka-state_test-no_allowances-extcall_with_value 0 False EXTCALL 9000 1
...fork_Osaka-state_test-no_allowances-extstaticcall 0 False EXTSTATICCALL 0 0
...fork_Osaka-state_test-no_allowances-extdelegatecall 0 False EXTDELEGATECALL 0 0
...fork_Osaka-state_test-only_retained-extcall_without_value 2300 False EXTCALL 0 0
...fork_Osaka-state_test-only_retained-extcall_with_value 2300 False EXTCALL 9000 1
...fork_Osaka-state_test-only_retained-extstaticcall 2300 False EXTSTATICCALL 0 0
...fork_Osaka-state_test-only_retained-extdelegatecall 2300 False EXTDELEGATECALL 0 0
...fork_Osaka-state_test-only_callee-extcall_without_value 5000 False EXTCALL 0 0
...fork_Osaka-state_test-only_callee-extcall_with_value 5000 False EXTCALL 9000 1
...fork_Osaka-state_test-only_callee-extstaticcall 5000 False EXTSTATICCALL 0 0
...fork_Osaka-state_test-only_callee-extdelegatecall 5000 False EXTDELEGATECALL 0 0
...fork_Osaka-state_test-both_allowances-extcall_without_value 7300 True EXTCALL 0 0
...fork_Osaka-state_test-both_allowances-extcall_with_value 7300 True EXTCALL 9000 1
...fork_Osaka-state_test-both_allowances-extstaticcall 7300 True EXTSTATICCALL 0 0
...fork_Osaka-state_test-both_allowances-extdelegatecall 7300 True EXTDELEGATECALL 0 0
...fork_Osaka-blockchain_test_from_state_test-no_allowances-extcall_without_value 0 False EXTCALL 0 0
...fork_Osaka-blockchain_test_from_state_test-no_allowances-extcall_with_value 0 False EXTCALL 9000 1
...fork_Osaka-blockchain_test_from_state_test-no_allowances-extstaticcall 0 False EXTSTATICCALL 0 0
...fork_Osaka-blockchain_test_from_state_test-no_allowances-extdelegatecall 0 False EXTDELEGATECALL 0 0
...fork_Osaka-blockchain_test_from_state_test-only_retained-extcall_without_value 2300 False EXTCALL 0 0
...fork_Osaka-blockchain_test_from_state_test-only_retained-extcall_with_value 2300 False EXTCALL 9000 1
...fork_Osaka-blockchain_test_from_state_test-only_retained-extstaticcall 2300 False EXTSTATICCALL 0 0
...fork_Osaka-blockchain_test_from_state_test-only_retained-extdelegatecall 2300 False EXTDELEGATECALL 0 0
...fork_Osaka-blockchain_test_from_state_test-only_callee-extcall_without_value 5000 False EXTCALL 0 0
...fork_Osaka-blockchain_test_from_state_test-only_callee-extcall_with_value 5000 False EXTCALL 9000 1
...fork_Osaka-blockchain_test_from_state_test-only_callee-extstaticcall 5000 False EXTSTATICCALL 0 0
...fork_Osaka-blockchain_test_from_state_test-only_callee-extdelegatecall 5000 False EXTDELEGATECALL 0 0
...fork_Osaka-blockchain_test_from_state_test-both_allowances-extcall_without_value 7300 True EXTCALL 0 0
...fork_Osaka-blockchain_test_from_state_test-both_allowances-extcall_with_value 7300 True EXTCALL 9000 1
...fork_Osaka-blockchain_test_from_state_test-both_allowances-extstaticcall 7300 True EXTSTATICCALL 0 0
...fork_Osaka-blockchain_test_from_state_test-both_allowances-extdelegatecall 7300 True EXTDELEGATECALL 0 0