OffchainLabs / arbitrum-tutorials

Get started developing on Arbitrum
455 stars 280 forks source link

gas-estimation for smart contract not working #108

Closed fewcatltd closed 1 year ago

fewcatltd commented 1 year ago

Hello Im trying to estimate gas for transaction using

https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/gas-estimation

It works fine when I estimate simple transaction like sending ETH between 2 addresses without any additional data. But when I pass the smart contract data like this: 0x1114cd2a000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000409d44c6998bbdaa982f14b1cf2f12958b70abd800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000003b9ac9ff000000000000000000000000000000000000000000000000000000003b02337f0000000000000000000000000000000000000000000000000000000000000014409d44c6998bbdaa982f14b1cf2f12958b70abd8000000000000000000000000

Script always return an error.

Error: call revert exception; VM Exception while processing transaction: reverted with reason string "Stargate: msg.value must be > _amountLD" [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="gasEstimateComponents(address,bool,bytes)", data="0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002753746172676174653a206d73672e76616c7565206d757374206265203e205f616d6f756e744c4400000000000000000000000000000000000000000000000000", errorArgs=["Stargate: msg.value must be > _amountLD"], errorName="Error", errorSignature="Error(string)", reason="Stargate: msg.value must be > _amountLD", code=CALL_EXCEPTION, version=abi/5.7.0) at Logger.makeError (C:\Users\97158\Documents\GitHub\layerZero\node_modules\@ethersproject\logger\src.ts\index.ts:269:28) at Logger.throwError (C:\Users\97158\Documents\GitHub\layerZero\node_modules\@ethersproject\logger\src.ts\index.ts:281:20) errorSignature: 'Error(string)', address: '0x00000000000000000000000000000000000000C8', args: [ '0xbf22f0f184bccbea268df387a49ff5238dd23e40', false, '0x1114cd2a000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000409d44c6998bbdaa982f14b1cf2f12958b70abd800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000003b9ac9ff000000000000000000000000000000000000000000000000000000003b02337f0000000000000000000000000000000000000000000000000000000000000014409d44c6998bbdaa982f14b1cf2f12958b70abd8000000000000000000000000' ], transaction: { data: '0xc94e6eeb000000000000000000000000bf22f0f184bccbea268df387a49ff5238dd23e400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e41114cd2a000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000409d44c6998bbdaa982f14b1cf2f12958b70abd800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000003b9ac9ff000000000000000000000000000000000000000000000000000000003b02337f0000000000000000000000000000000000000000000000000000000000000014409d44c6998bbdaa982f14b1cf2f12958b70abd800000000000000000000000000000000000000000000000000000000000000000000000000000000', to: '0x00000000000000000000000000000000000000C8'

And this error looks like nodeInterface.callStatic.gasEstimateComponents trying to execute transaction instead of estimate it.

transaction details. 0xbf22f0f184bccbea268df387a49ff5238dd23e40 - smart contract swapETH - method

contract.methods
      .swapETH(
        destinationChainId, //111
        request.senderAccount.address, //my address
        request.senderAccount.address, //my address
        request.amount, //0.04 eth (in wei)
        minAmount  //0.04 eth * 0.99 (in wei)
      )
      .encodeABI();

const baseL2Provider = new providers.StaticJsonRpcProvider(
      "https://arb1.arbitrum.io/rpc"
    );

    addDefaultLocalNetwork();

    const destinationAddress =contractAddress;
    const nodeInterface = NodeInterface__factory.connect(
      NODE_INTERFACE_ADDRESS,
      baseL2Provider
    );

//THROWING HERE
    const gasEstimateComponents =
      await nodeInterface.callStatic.gasEstimateComponents(
        destinationAddress,
        false,
        data,
        {
          blockTag: "latest",
        }
      );

    const l1GasEstimated = gasEstimateComponents.gasEstimateForL1;
    const l2GasUsed = gasEstimateComponents.gasEstimate.sub(
      gasEstimateComponents.gasEstimateForL1
    );
    const l2EstimatedPrice = gasEstimateComponents.baseFee;
    const l1EstimatedPrice = gasEstimateComponents.l1BaseFeeEstimate.mul(16);

    const l1Cost = l1GasEstimated.mul(l2EstimatedPrice);
    const l1Size = l1Cost.div(l1EstimatedPrice);

    const P = l2EstimatedPrice;
    const L2G = l2GasUsed;
    const L1P = l1EstimatedPrice;
    const L1S = l1Size;

    // L1C (L1 Cost) = L1P * L1S
    const L1C = L1P.mul(L1S);

    // B (Extra Buffer) = L1C / P
    const B = L1C.div(P);

    // G (Gas Limit) = L2G + B
    const G = L2G.add(B);

    // TXFEES (Transaction fees) = P * G
    const TXFEES = P.mul(G);

    return {
      fullGas: G.toNumber(),
      transactionFee: TXFEES.toNumber(),
    };