ethereumblockchainsoliditysmartcontractserc20

Usdc estimate gas "approve from the zero address"


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:

The 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 });
    };
}


Solution

  • 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.