zeta-chain / protocol-contracts

Protocol contracts implementing the core logic of the protocol, deployed on ZetaChain and on connected chains
MIT License
71 stars 58 forks source link

Enforce gas use limit for omnichain call hooks #424

Closed lumtis closed 1 week ago

lumtis commented 3 weeks ago

Related: https://github.com/zeta-chain/node/issues/3084

A limit for the gas usage must be set. We set a gas limit value in the call in https://github.com/zeta-chain/node/pull/3106 however this requires the next chain upgrade to fix the issue

This issue is about setting a temporary workaround at the smart contract level and upgrade the GatewayZEVM

Since no gas limit is not manually set currently, the gas limit is set with the estimated call function.

We can therefore revert automatically when the "gasleft" value is above a certain threshold https://www.rareskills.io/post/solidity-gasleft

Example: if the developer onCall is too expensive, gasleft will be set to a high value because of the gas estimated.

Example:

function execute(
        MessageContext calldata context,
        address zrc20,
        uint256 amount,
        address target,
        bytes calldata message
    )
        external
        nonReentrant
        onlyFungible
        whenNotPaused
    {
        if (zrc20 == address(0) || target == address(0)) revert ZeroAddress();

        require(gasleft() < 1000000)

        UniversalContract(target).onCall(context, zrc20, amount, message);
    }
lumtis commented 1 week ago

After experimentation this solution can't be used: it rely on using gasleft() to prevent tx with high estimated gas limit. The problem is that the check will be run when estimating the gas limit, it will create discrepancies given that gasleft() will return a different value when tx is simulated. This makes the solution unreliable because the tx simulation is different than the tx execution.