Skip to content

fix: Support gasless withdraw even with no gas fee tokens in EOA#8146

Open
dan437 wants to merge 4 commits intomainfrom
predict-balance-only
Open

fix: Support gasless withdraw even with no gas fee tokens in EOA#8146
dan437 wants to merge 4 commits intomainfrom
predict-balance-only

Conversation

@dan437
Copy link
Contributor

@dan437 dan437 commented Mar 9, 2026

Explanation

When a user has no native POL and no USDC.e in their EOA (tokens are in a Predict Safe), gasless withdrawals to non-USDC.e tokens fail with FAILED_INSUFFICIENT_FUNDS. The gas station simulation returns no fee tokens because the EOA balance is zero at quote time.

This PR skips the simulation for post-quote flows and builds a synthetic gas fee token by taking the estimated gas cost in USD (from calculateGasCost), applying a 10% buffer, and converting to USDC.e via its USD exchange rate. It also implements two-phase quoting: the first quote determines the gas cost, then a second quote is fetched with the source amount reduced by that cost. Source balance validation is skipped for post-quote flows since tokens move from Safe to EOA during batch execution.

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Changes Relay post-quote quoting/submission logic to compute gas fee token amounts from fiat estimates and to re-quote with adjusted source amounts, which can affect fee calculation and execution paths. Fallbacks are added, but mispricing or edge-case rate availability could still impact withdrawals.

Overview
Fixes Relay post-quote flows where the EOA has no native balance (and no source token at quote time) by skipping gas-station simulation and instead building a synthetic GasFeeToken from the quote’s USD gas estimate (token info + fiat rate + token-to-native rate), with fallbacks back to native gas costing when required rates/info are missing.

Adds two-phase quoting for post-quote requests: fetch phase-1, compute gas-in-source, then re-fetch a phase-2 quote with sourceTokenAmount reduced by that gas reserve (falling back to phase-1 if subtraction underflows or phase-2 fails). Submission is updated to skip EOA source-balance validation for post-quote batches, and tests/changelog are updated accordingly.

Written by Cursor Bugbot for commit 00a00a8. This will update automatically on new commits. Configure here.

@dan437 dan437 requested a review from a team as a code owner March 9, 2026 12:59
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

}

const WEI_PER_NATIVE_UNIT = '1000000000000000000';
const rateWei = new BigNumber(tokenToNativeRate).multipliedBy(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: I believe we already have a function for this conversion, will use it here shortly.

dan437 added 3 commits March 9, 2026 14:05
Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
@dan437 dan437 requested a review from a team as a code owner March 9, 2026 13:11

### Fixed

- Support gasless withdraw for post-quote flows (e.g. Predict) when EOA has no native balance or source token by computing a synthetic gas fee token from the fiat gas estimate ([#8146](https://github.com/MetaMask/core/pull/8146))
Copy link
Member

@matthewwalsh0 matthewwalsh0 Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Support gasless withdraw for post-quote flows (e.g. Predict) when EOA has no native balance or source token by computing a synthetic gas fee token from the fiat gas estimate ([#8146](https://github.com/MetaMask/core/pull/8146))
- Support gasless withdraw for post-quote flows (e.g. Predict Withdraw) when transaction would provide sufficient token balance for gas fee token ([#8146](https://github.com/MetaMask/core/pull/8146))

* @param params.totalGasEstimate - Total gas estimate for all transactions.
* @returns A synthetic GasFeeToken, or undefined if rates are unavailable.
*/
function buildPostQuoteGasFeeToken({
Copy link
Member

@matthewwalsh0 matthewwalsh0 Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the late pivot, but have a suggestion that may avoid the estimation / emulation.

Our issue is even if we simulate just the withdraw transaction, it will fail since it's not the signed Safe transaction yet given the beforeSign hook.

So what if we instead just simulate an empty transaction and set the from to be the Proxy address since we can guarantee that has sufficient balance as that's where we are withdrawing it from? We already have the proxy address in the refundTo.

Then we can get a real gas fee token, and the existing logic should already extrapolate the amount based on our total gas limit for both real calls.

This could just be for predictWithdraw transaction type, since any other post-quote flow could just simulate the original transaction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Gasless withdraw doesn't work if a user doesn't have any gas fee token in EOA, only their Predict balance

2 participants