Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
ricmoo opened this issue Jan 26, 2022 Discussed in #2602 · 7 comments
Closed

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

ricmoo opened this issue Jan 26, 2022 Discussed in #2602 · 7 comments
Labels
enhancement New feature or improvement. fixed/complete This Bug is fixed or Enhancement is complete and published.

Comments

@ricmoo
Copy link
Member

ricmoo commented Jan 26, 2022

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

@ricmoo
Copy link
Member Author

ricmoo commented Jan 26, 2022

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.

@ricmoo ricmoo added the investigate Under investigation and may be a bug. label Jan 26, 2022
@ricmoo ricmoo added enhancement New feature or improvement. on-deck This Enhancement or Bug is currently being worked on. and removed investigate Under investigation and may be a bug. labels Mar 25, 2022
@ricmoo ricmoo added fixed/complete This Bug is fixed or Enhancement is complete and published. and removed on-deck This Enhancement or Bug is currently being worked on. labels Mar 26, 2022
@ricmoo
Copy link
Member Author

ricmoo commented Mar 26, 2022

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.

@ricmoo ricmoo closed this as completed Mar 26, 2022
@nataouze
Copy link

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": [...]

@ricmoo
Copy link
Member Author

ricmoo commented Mar 26, 2022

@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?

@nataouze
Copy link

@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]

@ricmoo
Copy link
Member Author

ricmoo commented Mar 30, 2022

@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. :)

@nedgar
Copy link

nedgar commented Sep 18, 2022

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
Labels
enhancement New feature or improvement. fixed/complete This Bug is fixed or Enhancement is complete and published.
Projects
None yet
Development

No branches or pull requests

3 participants