I'm trying to estimate the gas for an ERC20 approve on the USDC smart contract, and while my implementation works both on Mainnet and Sepolia for any other ERC20 contract, it fails when I do so on USDC.
Does anyone have an idea what is specifically required to do so with USDC?
I'm using Ethers.js v5 and the standard ERC20 ABI.
My implementation looks like the following:
const erc20Contract = new ethers.Contract(contractAddress, ERC20_ABI, this.provider);
return erc20Contract.estimateGas.approve(address, amount);
Where:
contractAddress
is the address of the contractthis.provider
is Infuraaddress
is the destination addressamount
is a BigNumber
computed with the appropriate number of decimalsThe error I get is the following:
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: ERC20: approve from the zero address", method="estimateGas", transaction={"to":"0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238","data":"0x095ea7b3000000000000000000000000000000000000000000000000000000000000dead0000000000000000000000000000000000000000000000000de0b6b3a7640000","accessList":null}, error={"reason":"processing response error","code":"SERVER_ERROR","body":"{"jsonrpc":"2.0","id":56,"error":{"code":3,"data":"0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002445524332303a20617070726f76652066726f6d20746865207a65726f206164647265737300000000000000000000000000000000000000000000000000000000","message":"execution reverted: ERC20: approve from the zero address"}}","error":{"code":3,"data":"0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002445524332303a20617070726f76652066726f6d20746865207a65726f206164647265737300000000000000000000000000000000000000000000000000000000"},"requestBody":"{"method":"eth_estimateGas","params":[{"to":"0x1c7d4b196cb0c7b01d743fbc6116a902379c7238","data":"0x095ea7b3000000000000000000000000000000000000000000000000000000000000dead0000000000000000000000000000000000000000000000000de0b6b3a7640000"}],"id":56,"jsonrpc":"2.0"}","requestMethod":"POST","url":"https://sepolia.infura.io/v3/d5ca672c9aa246ff9df442b72d89bc4a"}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.7.2)
Given that the error mentions "approve from the zero address", I've tried, as in this example, to hardcode 0x000000000000000000000000000000000000dead
or 0x000000000000000000000000000000000000dEaD
as the destination address, but it did not help.
I'm not sure what I am missing. Any help would be appreciated.
Solution
Solution was provided by Yilmaz. The Usdc smart contract required a from
address when I called the estimation of the gas fee. I passed this information using the overrides
option of ether.js v5.
export const ERC20_ABI = [
'function approve(address _spender, uint256 _value) public returns (bool success)',
];
class InfuraProvider {
private readonly provider: InfuraProvider;
constructor(private readonly network: Networkish) {
this.provider = new InfuraProvider(this.network, API_KEY);
}
getFeeData = ({
contract: { address: contractAddress },
to,
from,
amount
}: {
contract: {address: string};
from: string;
to: string;
amount: BigNumber;
}): Promise<BigNumber> => {
const erc20Contract = new ethers.Contract(contractAddress, ERC20_ABI, this.provider);
return erc20Contract.estimateGas.approve(to, amount, { from });
};
}
cannot estimate gas; transaction may fail or may require manual gas limit
ethereum smart contract wallets has two steps to execute a smart contract function. first they simulate the transaction which checks if the function signtature is correct. If it it correct, it executes the function if not you get the above error. With that being said, you are passing wrong function arguments.
ERC20: approve from the zero address
in solidity every type has default values. defaul value for address
type is zero address. For somehow, from address
is not correctly set, defaulting to the zero address.