[Ethereum] Ethers js estimateGas() without needing ETH in account

ethers.jsgasgas-estimatejavascriptuniswap

I am trying to estimate the gas used for a uniswap transaction. I am able to perform this on the Kovan testnet however when I try and run the same script on the mainnet it raises an error, "Error: insufficient funds for intrinsic transaction cost". I know the issue is that I do not have enough eth in my account to run the transaction but I don't want to actually send any eth. My code is:

const {ChainId, Fetcher, WETH, Route, Trade, TokenAmount, TradeType, Percent} = require('@uniswap/sdk');
const {ethers} = require("ethers");
let Web3 = require('web3');

let web3 = new Web3(new Web3.providers.HttpProvider("INFURA_ADDRESS"));
const provider = new ethers.providers.EtherscanProvider('homestead', 'API_KEY');

function toHex(Amount) {
    return `0x${Amount.raw.toString(16)}`;
}

const chainId = ChainId.MAINNET; 
const tokenAddress = '0x6b175474e89094c44da98b954eedeac495271d0f'; 

const init = async () => {
    const gas = await web3.eth.getGasPrice();
    const token = await Fetcher.fetchTokenData(chainId, tokenAddress, provider);

    const weth = WETH[token.chainId];
    const pair = await Fetcher.fetchPairData(token, weth, provider);
    const amountIn = '1200000000000000';
    const route = new Route([pair], weth);

    const trade = new Trade(route, new TokenAmount(weth, amountIn), TradeType.EXACT_INPUT);
   
    const slippageTolerance = new Percent('1', '100');
    const amountOutMin = toHex(trade.minimumAmountOut(slippageTolerance));
    const path = [weth.address, token.address];
    const to = 'PUBLIC_ADDRESS';
    const deadline = Math.floor(Date.now()/1000) + 60*20;
    const value = toHex(trade.inputAmount);

    const signer = new ethers.Wallet('PRIVATE_KEY'); 
    const account = signer.connect(provider);
    const uniswap = new ethers.Contract(
        '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
        ['function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts)'],
        account
    );

    const gasCost = await uniswap.estimateGas.swapExactETHForTokens(
        amountOutMin,
        path,
        to,
        deadline,
        {value, gasPrice: gas}
    );     
    console.log(parseInt(gasCost, 10));

}

init();

It works when run on an account that has sufficient eth (like in the testnet). Is there any way to have it estimate the gas without needing eth to be in the account? Or, is there another method entirely to calculate the gas that doesn't need eth in the account? I am rather new to this so any help would be greatly appreciated! Thanks in advance!

Best Answer

In your estimate gas query, the gas price mostly doesn't play a role, unless the smart contract you're interacting with is using 0x3A (`` opcode) for some logic.

The logic of swapExactETHForTokens doesn't use GASPRICE, so even if you pass gasPrice as 0, it wouldn't effect the estimation. And hence, you can get the estimation even if you have no ETH in your account.

Related Topic