ethers.js: Gas estimation failure gives a misleading error message
Launching a transaction to the Goerli network, I have been getting this error:
{
"reason":"cannot estimate gas; transaction may fail or may require manual gas limit",
"code":"UNPREDICTABLE_GAS_LIMIT",
"error":{
"reason":"processing response error","code":"SERVER_ERROR",
"body":"{\"jsonrpc\":\"2.0\",\"id\":69,\"error\":{\"code\":-32000,\"message\":\"gas required exceeds allowance (0)\"}}","error":{"code":-32000},"requestBody":"{\"method\":\"eth_estimateGas\",\"params\":[{\"gasPrice\":\"0xb2d05e00\",\"from\":\"0xe101391adf348cd80bb71b97306f3cddd5d34586\",\"to\":\"0x1a72d4949936bda05e187706daf0db6fb96603b6\",\"data\":....}
The transaction is launched like:
const contract = new Contract(addr, abi, wallet)
const tx = await contract.myTransaction(...)
At first I checked https://github.com/ethers-io/ethers.js/issues/484 as a potential duplicate. However, the real error is that the account sending the transaction holds no ether. Nothing related to failing transactions or similar.
In such cases, it would be nice to detect the insufficient or null balance and warn about this instead of the unpredictable gas limit message alone. BTW, thank you for such a great library!
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 8
- Comments: 18 (2 by maintainers)
I’ve done further debugging in regards to this issue. I think the main problem is that Ethers includes a
gasPrice
parameter when estimating gas. I’ve added some of the Eth JSON RPC requests done via both Ethers.js and Web3.js as examples.For Ethers.js, when estimating the gas for a contract method:
Even though the from account has plenty of funds (testing account) the UNPREDICTABLE GAS LIMIT happened. For the same transaction using the web3.js library the
gasPrice
is not included (andfrom
is not included as well) and so it works:Hope this helps. Probably simplifying the
eth_estimateGas
method to not includegasPrice
should solve this.@zemse As I was saying, the transaction and the contract were both correct. Submitting the very same parameters with Remix (from the right wallet) worked flawlessly. And also, submitting the very same transaction with the right wallet from Ethers.js also worked flawlessly, then.
So:
It may be a vicious circle, because you can’t know if you have enough ether for a transaction until you have estimated it. And you can’t estimate as estimation fails because you have insufficient funds.
But at least, if the balance is exactly 0, we do know for sure that the failure to estimate is due to this.
Thank you!
We do get an insufficient funds error if enough ETH is not present. Did you try using correct wallet in your code, did that work?
But as you say you get
cannot estimate gas
error instead ofinsufficient funds
error. I think I have an explanation for this.When you run
contract.myTransaction(...)
, ethers js does 2 rpcalls to node internally:cannot estimate gas
that you are getting. (I don’t think a gas estimate requires to have enough eth at an address)insufficient funds
Which means that your tx is probably reverting for that different address even if it had some ETH. Though you can confirm this to be sure.
Yes I believe gas estimation will fail if a gas price is given and the
from
address doesn’t have enough ether to execute the tx at the given gas priceIf gas price isn’t provided for gas estimation, this isn’t taken into consideration and the gas estimation will ignore funds (unless the tx causes the funds to be moved)
It seems that your contract is reverting when you call
myTransaction
function. Can you confirm if any obvious require statements might be failing? Just to mention, there is a recently popular tool to debug on-chain contracts called tenderly. That might help you to confirm if there is any problem occurring in the contract or not.