Can't estimate_gas for a USDT or DAI transaction

I’m trying to estimate gas required to transfer usdt using Infura node but always receive gas required exceeds allowance (12451164) or always failing transaction error. I have tried both using web3 and post (via axios) and both return same error.

Axios attempt:

export const estimateUsdtGas: EstimateGasType = async ({ web3 }, to, amount, wallet) => {
  const contract = new web3.eth.Contract(USDT_ABI, USDT_CONTRACT_ADDRESS)
  const gasPrice = await getGasPrice()
  const data = await contract.methods.transfer(to, '1').encodeABI()
  const body = {
    jsonrpc: '2.0',
    method: 'eth_estimateGas',
    params: [{
      value: web3.utils.numberToHex(0),
      gasPrice: web3.utils.numberToHex(gasPrice),
      to: USDT_CONTRACT_ADDRESS,
      from: wallet.address,
      data
    }],
    id: '1'
  }
  await axios.post(process.env.NODE_URL, body).then(res => {
    console.log(res.data)
    return res.data
  })
}

returns

{
 jsonrpc: '2.0',
 id: '122',
 error: {
   code: -32000,
   message: 'gas required exceeds allowance (12451164) or always failing transaction'
 }
}

web3 approach:

export const estimateUsdtGas: EstimateGasType = async ({ web3 }, to, amount) => {
  const contract = new web3.eth.Contract(USDT_ABI, USDT_CONTRACT_ADDRESS)
  return contract.methods.transfer(to, amount).estimateGas()
}

throws:

Error: Returned error: gas required exceeds allowance (12475588) or always failing transaction

USDT_ABI and contact address are correct, since if I hardcode gasLimit I am able to transfer.

Hello @Vallo - Welcome to the Infura community!
Per our docs, the gas parameter is capped at 10x the current block gas limit. I would check if this is not the issue causing the error.

Hi @Vallo - you can also check out this thread from earlier this year where someone was having a similar issue. If the capping of gas limit doesn’t seem to be the issue, I would suggest checking the contract size.

@serena I can’t understand why I need to pass the “gas” parameter, since that is the value I want to estimate. Anyway, whatever value I put on “gas” parameter gets rejected and said value appears on the message 'gas required exceeds allowance (100000) or always failing transaction'

@Leiya_Kenney I don’t think that is the problem, as the contract I’m using is USDT. Don’t know the contract size but should definitely not be exceedingly big.

https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7

Which network are you using to interact with Infura? Apologies if I’m just missing that - I don’t seem to see it in your code you posted above.

Sorry, forgot to mention: its the mainnet

If you try using the curl command from the eth_estimateGas method in our docs, does that go through successfully? The only required fields for this one are the from and to addresses.

That would be the Axios attemp from the first post, and it returns

{
 jsonrpc: '2.0',
 id: '122',
 error: {
   code: -32000,
   message: 'gas required exceeds allowance (12451164) or always failing transaction'
 }
}

I have the impression something is wrong with the “data” parameter, which comes from this line

const data = await contract.methods.transfer(to, amount).encodeABI()

Yet when signing a transaction, the dataparameter on the rawTx is obtained exactly the same way. Creating, signing and broadcasting a transaction works flawlessly: I am able to transfer USDT or Dai to another wallet. The only thing that fails is estimating the gas, which I have hardcoded as a temporary workaround.

Steps to reproduce:

eg:

curl https://mainnet.infura.io/v3/YOUR-PROJECT-ID \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","method":"eth_estimateGas","params": [{"to": "0xdac17f958d2ee523a2206206994597c13d831ec7","gas": "0x76c0","gasPrice": "0x9184e72a000", "data": "0xa9059cbb00000000000000000000000000000029801b39e37b9d7d438246f85e531e21cf0000000000000000000000000000000000000000000000000000000000000001"}],"id":1}'

returns

{"jsonrpc":"2.0","id":1,"error":{"code":-32000,"message":"gas required exceeds allowance (12493857) or always failing transaction"}}

Am I doing something wrong? does the data field needs to be encoded differently? I have tried adding or removing extra fields such as gas, gasPrice, with same result.

Thanks

Got it, and thanks for including the steps to reproduce the error! I’ve been playing around with it, and it seems to work with the address and Uint256 amounts I tried out.

Based on that, I believe the issue stems from that “gas required exceeds allowance” part of the message, as the rest of it all works fine when I try it out on my end. Are you able to increase your gas limit in your config file?

Could you provide me what address and Uint256 you tried, with resulting working curl command? Maybe I’m doing something wrong with the Uint256 value.

Thanks

I used just the example transfer from our docs, and the Uint256 value was 1,000,000. One thing I noticed, however, was that when I first started trying it out on my side, I ran into the same error message you were getting, but when I tried some lower values that gave me a response I was expecting and went back to that higher value, it then started to work.

I would suggest trying that tactic out and let us know how that works!

Try to remove gasPrice from your estimateGas parameter or deposit some eth into your account.

We (ThunderCore) met this error too. After analysis, we think it’s due to the upgrade of ethereum. If the gasPrice is given, estimateGas will check your balance and adjust the hi gas. This will lower the upper bound of gas and cause this problem. The higher gas price you give, the lower allowance will be returned.

1 Like