Skip to content

Ethers still tries to estimate gas even when passing manual gasLimit #2603

Closed

Description

@ricmoo

Describe the bug
I'm trying to call a contract method with an unpredictable gas limit, however if I try to call it and pass the gasLimit manually I get get a "Error: cannot estimate gas; transaction may fail or may require manual gas limit" error.

Maybe I'm missing something but shouldn't ethers skip estimating gas if it's passed manually?

Reproduction steps
You can test with the following contract in rinkeby:

const CONTRACT = "0x10539a06b047259f247f8c622430c22803821A00";
const ABI = [
  'function stakeOf(address _owner) public view returns (uint256[] memory)'
];

// using JsonRpcProvider as an example, but I've tried with metamask as well and same issue
const provider =new ethers.providers.JsonRpcProvider(
    "provider URL"
);
const signer = provider.getSigner();
const contract = new ethers.Contract(CONTRACT, ABI, signer);

contract.stakeOf("0x73257cE508dBB94Ff78C27381FddD42FB7266Ba4", {
  gasLimit: '50000000',
}),

Result

Error: cannot estimate gas; transaction may fail or may require manual gas limit (error={"name":"ProviderError","code":3,"_isProviderError":true,"data":"0x4e487b710000000000000000000000000000000000000000000000000000000000000032"}, method="call", transaction={"from":"0x73257cE508dBB94Ff78C27381FddD42FB7266Ba4","gasLimit":{"type":"BigNumber","hex":"0x02faf080"},"to":"0x10539a06b047259f247f8c622430c22803821A00","data":"0x4262336000000000000000000000000073257ce508dbb94ff78c27381fddd42fb7266ba4","accessList":null}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.5.1)
    //...
  method: 'call',
  transaction: {
    from: '0x73257cE508dBB94Ff78C27381FddD42FB7266Ba4',
    gasLimit: BigNumber { value: "50000000" },
    to: '0x10539a06b047259f247f8c622430c22803821A00',
    data: '0x4262336000000000000000000000000073257ce508dbb94ff78c27381fddd42fb7266ba4',
    accessList: null
  }
}

Environment:
Node: v14.17.4

This happens in both node and browser environments.

Search Terms
gas limit, estimate gas

Activity

  1. ricmoo commented on Jan 26, 2022

    @ricmoo
    MemberAuthor

    The automatic gasLimit population is only performed for send transactions, and your method is a call (as it is a view).

    That error means the call is reverting, although I agree, it’s weird it would mention unpredictable gas.

  2. added
    enhancementNew feature or improvement.
    on-deckThis Enhancement or Bug is currently being worked on.
    and removed
    investigateUnder investigation and may be a bug.
    on Mar 25, 2022
  3. added
    fixed/completeThis Bug is fixed or Enhancement is complete and published.
    and removed
    on-deckThis Enhancement or Bug is currently being worked on.
    on Mar 26, 2022
  4. ricmoo commented on Mar 26, 2022

    @ricmoo
    MemberAuthor

    This should be fixed now, as the error checking spelunks through the object looking for the component that has both a message with the word "reverted" somewhere within it and has a data that is valid hex data.

  5. nataouze commented on Mar 26, 2022

    @nataouze

    This breaks my test code for catching call exceptions, which was working with [email protected]. Example output:

    AssertionError: Expected transaction to be reverted with EXCEPTION_MESSAGE, but other exception was thrown: Error: missing revert data in call exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (error={"stackTrace": [...]
    
  6. ricmoo commented on Mar 26, 2022

    @ricmoo
    MemberAuthor

    @nataouze That was a bug; a call should never through a call exception (in ethers v5; in v6 it comes back as a CALL_EXCEPTION Error with a data property); it is always supposed to return the data the node sent back, but due to changes in the error format some backends were breaking that. But against Geth that should not have happened, for example.

    To detect an error was thrown by a contract, the canonical way is to check the length of the bytes returned; if it is congruent to 0 mod 32 then it is not an error and if it is congruent to 4 mod 32 then it is an error, with the first 4 bytes as the selector.

    Your tests should have received a lot of false negatives in the previous version of ethers?

    Does that make sense?

  7. nataouze commented on Mar 26, 2022

    @nataouze

    @ricmoo I am not totally clear on what you describe. I didn't get false negatives in the past.

    For context, I am using hardhat evm ([email protected]). My tests are using waffle, in this case the matcher revertedWith.
    The issue arises when updating from [email protected] to [email protected]

  8. ricmoo commented on Mar 30, 2022

    @ricmoo
    MemberAuthor

    @nataouze I've added context to discussion #2849 to help explain what is going on and will be keeping that up to date if you want to hop over there. :)

  9. nedgar commented on Sep 18, 2022

    @nedgar

    Thanks for the fix @ricmoo. I've (finally) verified it -- see NomicFoundation/hardhat#2248 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or improvement.fixed/completeThis Bug is fixed or Enhancement is complete and published.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions