I'm using hardhat/ethers.js to deploy and test a smart contract that uses Chainlink VRF and Automation, and while testing some of the functions that interact with the Chainlink contracts on the Goerli testnet, the transactions sometimes fail with a generic revert reason like:
Error: cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (reason="execution reverted", method="estimateGas" ...
Likewise when attempting to execute the function manually from Etherscan using the "Write Contract" tab, Metamask shows:
We were not able to estimate gas. There might be an error in the contract and this transaction may fail.
If I proceed anyways, it does fail and the transaction details on Etherscan only show:
Warning! Error encountered during contract execution [execution reverted]
But there's no indication of where the error is or why the revert occurred. I recently discovered the "Internal Txns" tab on the Etherscan transaction page, which helped me narrow down my most recent error when attempting to fund my automation with LINK, as it showed me the chain of external contract calls leading up to the revert. After seeing the last contract in the chain was the LINK token contract and digging into it, I realized I forgot to have my contract approve the transfer of LINK to the Automation Registry, which was the source of the error.
It appears the LINK token's implementation of the ERC20 transferFrom function has poor error reporting, as it doesn't raise an explicit error when the approval balance is too low, but instead relies on a SafeMath subtraction failing, with no error message provided.
I know hardhat can help you debug locally with console.log
statements in your solidity, but this isn't easy to do with functions that interact with external contracts that are only live on testnets and mainnet. So for deployed contracts is there an easy way to see the exact line of code/stack trace where the error occurred in the verified source code?