ethers.js icon indicating copy to clipboard operation
ethers.js copied to clipboard

Add `estimateGasExtra` override

Open zemse opened this issue 2 years ago • 1 comments

Describe the Feature

Currently, if an explicit gasLimit override is not provided then ethers uses eth_estimateGas to fill the gasLimit option.

However, if between user's gas estimate and the transaction confirmation, there are any state changes due to transactions or even change in env, e.g. if some contract depends on timestamp, the actual gas needed can be slightly more or less. Many recent smart contract applications are composed of other applications, which increase these cases.

Hardcoding value might not be always great, because lets say usually tx takes 200k to 300k, but due to some situation, it is needing 310K right now.

await contract.method({
  gasLimit: 300_000 // this could fail
})

Passing a huge value does not work, since ETH is necessary to be present in the wallet.

// can throw "insufficient balance" error for many application users
await contract.method({
  gasLimit: 30_000_000
})

So a reasonable solution could be:

const gasEstimated = await contract.estimateGas.method();
await contract.estimateGas.method({
  gasLimit: gasEstimated + 10000 // extra 10k to account for sudden changes in state or env
})

It can be very useful if ethers can help with doing the above. There some tools that support similar feature.

Code Example

await contract.method({ extraGas: 10000 })
// or
await contract.method({ extraGasLimit: 10000 })
// or
await contract.method({ estimateGasExtra: 10000 })

zemse avatar Aug 05 '22 09:08 zemse

Describe the Feature

Currently, if an explicit gasLimit override is not provided then ethers uses eth_estimateGas to fill the gasLimit option.

However, if between user's gas estimate and the transaction confirmation, there are any state changes due to transactions or even change in env, e.g. if some contract depends on timestamp, the actual gas needed can be slightly more or less. Many recent smart contract applications are composed of other applications, which increase these cases.

Hardcoding value might not be always great, because lets say usually tx takes 200k to 300k, but due to some situation, it is needing 310K right now.

await contract.method({
  gasLimit: 300_000 // this could fail
})

Passing a huge value does not work, since ETH is necessary to be present in the wallet.

// can throw "insufficient balance" error for many application users
await contract.method({
  gasLimit: 30_000_000
})

So a reasonable solution could be:

const gasEstimated = await contract.estimateGas.method();
await contract.estimateGas.method({
  gasLimit: gasEstimated + 10000 // extra 10k to account for sudden changes in state or env
})

It can be very useful if ethers can help with doing the above. There some tools that support similar feature.

Code Example

await contract.method({ extraGas: 10000 })
// or
await contract.method({ extraGasLimit: 10000 })
// or
await contract.method({ estimateGasExtra: 10000 })

Wdyt about this being used in the case of conditional swap output orders? Are you still interested in this? Looks nice 👍

sambacha avatar Sep 13 '22 22:09 sambacha

conditional swap output orders

Does that mean swaps that would fail if output amount does not match? or can you please explain the situation?

Are you still interested in this?

Yeah I think it could be helpful. For e.g. Uni v3 swaps maybe they can cross more ticks or something due to which they might fail with out of gas. Also given that apps can have logic based on things like prevrandao, the estimated gas and actual gas can defer (it can be more or less) if tx doesn't get mind in next block. It makes sense to pass more gas, but for answering how much more, it depends on use case anyway.

zemse avatar Oct 02 '22 06:10 zemse