-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: missing gas padding on native gas token deposits #849
fix: missing gas padding on native gas token deposits #849
Conversation
ACX-1546 Missing FE gas padding on native/gas token deposits
The FE used to impose a "gas buffer", such that a user was not able to deposit the "max" amount of their native token. This recognised that some residual amount would be needed for gas. The FE currently permits the user to max-out their deposit amount, leaving 0 for gas, and produces a deposit transaction that can not be submitted. This can be seen in the screenshot below, where the dev wallet (0x9a8…) has a balance of 0.16498… ETH, and that amount is auto-filled when MAX is selected. |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
…-nativegas-token-deposits
…-nativegas-token-deposits
const gasEstimation = await contract.estimateGas[method](...args); | ||
// Factor in the padding | ||
const gasToRecommend = gasEstimation | ||
.mul(parseEther(String(gasMultiplier))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we precompute this in the constants? We could theoretically define
export const gasMultiplierPerChain: Record<string, number> = process.env
.REACT_APP_GAS_ESTIMATION_MULTIPLIER_PER_CHAIN
? JSON.parse(process.env.REACT_APP_GAS_ESTIMATION_MULTIPLIER_PER_CHAIN).map((mul) => parseEther(String(mul)))
: {};
in constants so that we only call parseEther
once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, we could. But I am not sure if this makes things more predictable or intuitive tbh. So if I import this constant somewhere, I would not expect this to be a BigNumber.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough!
) { | ||
const provider = getProvider(selectedRoute.fromChain); | ||
const spokePool = config.getSpokePool(selectedRoute.fromChain); | ||
const mockedArgs = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: should we call this mocked
? I feel like that term is usually reserved for tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, yea feel free to provide an alternative name :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe: argsForEstimation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - left a comment
const gasEstimation = await contract.estimateGas[method](...args); | ||
// Factor in the padding | ||
const gasToRecommend = gasEstimation | ||
.mul(parseEther(String(gasMultiplier))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough!
) | ||
.catch((err) => { | ||
console.error(err); | ||
return max(balance.sub(utils.parseEther("0.01")), 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we encode this somewhere as a constant? This way, we can modify 0.01
without having to grep for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! Will change
) { | ||
const provider = getProvider(selectedRoute.fromChain); | ||
const spokePool = config.getSpokePool(selectedRoute.fromChain); | ||
const mockedArgs = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe: argsForEstimation
return max(balance.sub(utils.parseEther("0.01")), 0); | ||
}); | ||
} else { | ||
maxBridgeAmount = BigNumber.from(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can save a little bit by using ethers.contracts.Zero
for this. We also export it as bnZero from the sdk: https://github.com/across-protocol/sdk-v2/blob/5a69b7ce77f0b2e75956786308156b657d7b88e2/src/utils/BigNumberUtils.ts#L12
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One high-level comment - we also have gas padding that occurs in the API for estimating the fill cost of the relayer, and there's some potential for them to be confused. The main hint here is that this new env var is prefixed with REACT_APP.
Not sure exactly what to do about it, but I just wanted to note it.
@pxrl Thanks for flagging. Yea I also noticed that. You are referring to |
…-nativegas-token-deposits
This PR does two main things:
gasMultiplier
for a single chain withgasMultiplierPerChain
which is a mappingchainId -> gasMultiplier
. This allows setting different buffers for different chains.