# Understanding Gas Limits in Contract-to-Contract Calls

## Gas Considerations: Transaction Limit vs. Call Specification&#x20;

Let's say we have two contracts: ***Caller*** and ***Callee***.

```solidity
contract Caller {
    Callee public callee;

    function setCallee(address _callee) external {
        callee = Callee(_callee);
    }

    function executeCall(bytes calldata data, uint256 gasLimit) external {
        (bool success, bytes memory returnedData) = address(callee).call.gas(gasLimit)(data);
        // Handle the result of the call
    }
}

contract Callee {
    function performTask() external {
        // Perform some task
    }
}
```

In this example, the ***Caller*** contract has a function `executeCall` that executes a call to the ***Callee*** contract. It takes two parameters: the `data` to be passed to the ***Callee*** contract and the `gasLimit` to restrict the gas usage of the Caller contract during the call.

Now, let's assume the ***Caller*** contract calls `executeCall` with a gas limit of 100,000 gas units. The expectation might be that the ***Callee*** contract will receive exactly 100,000 gas units for execution. However, in the current EVM implementation, this is not guaranteed.

The gas limit of 100,000 in the `executeCall` function acts as a protection for the ***Caller*** contract, ensuring it does not exceed that gas limit during the call. But the actual amount of gas received by the ***Callee*** contract may be less than 100,000. The exact amount will depend on the gas usage of the operations executed within the ***Callee*** contract and the remaining gas available at that point.

Therefore, it's important to understand that the gas parameter in the call does not guarantee the precise allocation of gas to the called contract. It only limits the gas expenditure of the calling contract.\
\
There are two different gas limits to consider: the gas limit set for a transaction and the gas specified in a call between contracts.

1. Gas Limit in a Transaction: When a transaction is sent on the Ethereum network, the sender specifies a gas limit for that transaction. This gas limit represents the maximum amount of gas that can be consumed during the execution of the transaction. The transaction is guaranteed to receive at least that amount of gas, regardless of what happens during its execution.
2. Gas Specified in a Call: In a contract-to-contract call, the ***caller*** can specify the amount of gas to be provided for the execution of the called contract. However, unlike the transaction gas limit, ***this gas specification acts as a protection for the caller, ensuring it does not exceed the specified gas usage. It does not guarantee that the callee will receive that exact amount of gas.***

## Gas Protection Mechanism: The Vital Role of the 63/64 Rule

Now, let's address the specific scenario mentioned:

If the ***callee*** contract runs out of gas during its execution, one might assume that the ***caller*** would also throw an exception since there would be no more gas left for it to continue its execution. However, this is where the **63/64 rule** comes into play.

The **63/64 rule** states that the ***caller*** contract must always keep at least 1/64th (around 1.56%) of the available gas for itself. This means that even if the ***callee*** fails due to insufficient gas, the caller would still have a portion of the gas left to continue its execution. Therefore, the ***caller*** may carry on assuming that the ***callee*** failed for a reason other than running out of gas.

To put it into perspective, let's consider an example: If the inner call requires 6,400,000 gas, and the ***caller*** initially had 10,000,000 gas, the ***caller*** would still have around 100,000 gas left after the callee's call fails. This remaining gas allows the ***caller*** to continue its execution and handle the situation accordingly.

So, while the gas specified in a call is not necessarily the exact amount received by the ***callee***, the ***caller*** is protected by the 1/64 of the available gas to ensure it has enough gas to handle the callee's failure and continue its own execution.

## EIP-150 and Gas Provision

In previous implementations, when making a call to another contract using the `CALL` opcodes, the gas provided was a strict value. If the available gas at the time of the call was less than the specified gas value, the call would revert and fail. This ensured that the ***caller*** had control over the maximum amount of gas that could be used by the callee contract.

However, with the introduction of [EIP-150](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md), the behavior of gas provided in the `CALL` opcodes changed. Now, if approximately 63/64 (or \~98.4%) of the available gas is less than the specified gas value, the call will still proceed but with less gas than initially requested. In other words, the gas value provided is treated as a maximum rather than a strict requirement.

The reasoning behind this change, proposed initially in EIP-90, was to eliminate the need for the ***caller*** to calculate the exact gas required by a call. Instead, it aimed to protect the ***caller*** by preventing the ***callee*** from using all the gas available (\~63/64 of it). There were discussions and proposals to have an option for "give all available gas," but ultimately, the decision was made to have the gas value act as a maximum.

This change introduces a possibility where a call can proceed with less gas than expected, which may not be the natural expectation for developers. As we will see in the next section.

## Gas Mismatch: EIP-150's Impact on Caller-Contract Interaction

Suppose we have a ***caller*** contract that wants to make a call to a ***callee*** contract and specifies a gas value of 15,000 for the call. However, at the time of the call, there are only 10,000 gas units available.

In the previous implementation, the call would fail and revert because the available gas (10,000) is less than the specified gas value (15,000). The caller would not proceed with the call.

However, with the change introduced by [EIP-150](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md), if approximately 63/64 (or \~98.4%) of the available gas is less than the specified gas value, the call will still proceed but with less gas than requested. In this case, 63/64 of 10,000 is approximately 9,844.

So, even though the ***caller*** specified 10,000 gas for the call, the ***callee*** contract will only receive approximately 9,844 gas units. The ***caller*** will still continue with the call, but with less gas than expected.

This change in behavior can have implications for contract execution. For example, if the ***callee*** contract requires more gas than what it actually receives, it may not be able to complete its intended operations successfully. This can lead to unexpected outcomes and potential vulnerabilities in the contract's functionality.

In summary, the change in gas behavior introduced by [EIP-150](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md) allows calls to proceed with less gas than specified, acting as a maximum value rather than a strict requirement. This change aimed to simplify gas calculations for ***callers*** and protect them from excessive gas usage by ***callees***. However, it can have implications for contract safety and requires careful consideration by developers.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mau-eth.gitbook.io/mau/gas-griefing/understanding-gas-limits-in-contract-to-contract-calls.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
