---
# System prepended metadata

title: Gas Calculation for sgReceive()

---

# Gas Calculation for sgReceive()

The basic strategy for determining gas for the entire function, written here in pseudo code, is:
> Total_Gas = Entry_Gas + `limit` + Exit_Gas

Going through this, part by part:
#### Total_Gas
This represents the actual gas sent to the `sgReceive()` function. As mentioned in [the previous note](https://hackmd.io/@ethzed/S1kFaOP3q), this is the value of the variable `_dstGasForCall` in the Stargate code.

To send the correct gas for `sgReceive()`, we need to correctly predict the value of Total_Gas, which means correctly predicting the values of all three of its constituent variables.

#### Entry_Gas
This is the amount of gas needed to run all of the initial code from  `sgReceive()`: 

    
    
```
        if (msg.sender != address(stargateRouter)) revert NotStargateRouter();

        (
            address to,
            uint8[] memory actions,
            uint256[] memory values,
            bytes[] memory datas,
            bytes32 srcContext
        ) = abi.decode(payload, (address, uint8[], uint256[], bytes[], bytes32));

        // 100000 -> exit gas
        uint256 limit = gasleft() - 100000;
        bool failed;
        /// @dev incase the actions fail, transfer bridge token to the to address
        try
            ISushiXSwap(payable(address(this))).cook{
```
It includes the gas price to make the external call to `ISushiXSwap.cook()`, but not the gas passed to that call.

This gas will always be required and will always be consumed. 

#### `limit`
This is the actual variable calculated dynamically within `sgreceive()`. It needs to cover the actions in this call and nothing more:

```
            ISushiXSwap(payable(address(this))).cook{gas: limit}(
                actions,
                values,
                datas
            )
```
#### Exit_Gas
This is the amount of gas needed to run all of the final code from `sgReceive()`, including the contents of both the `catch` block and the `if` block.
```
        {} catch (bytes memory) {
            IERC20(_token).safeTransfer(to, amountLD);
            failed = true;
        }

        /// @dev transfer any native token received as dust to the to address
        if (address(this).balance > 0)
            to.call{value: (address(this).balance)}("");

        emit StargateSushiXSwapDst(srcContext, failed);

```
Exit_Gas is also the value which should be subtracted from `gasleft()` to calculate `limit`:
```
        uint256 limit = gasleft() - 100000;
```
In this current code, Exit_Gas is set to 100000.

### 0xc365c128fa67b0516ee14ce1d7b5a5ab72a6c0e16c4185ade455687182aebf20
In light of this breakdown, we can see that in [this transaction](https://optimistic.etherscan.io/tx/0xc365c128fa67b0516ee14ce1d7b5a5ab72a6c0e16c4185ade455687182aebf20) the value of Exit_Gas has been set to 100000 by being hardcoded within `sgReceive()` as that value. With a Total_Gas of 100000 as well, this effectively predicts both Entry_Gas and `limit` as zero.