fix: Support gasless withdraw even with no gas fee tokens in EOA#8146
fix: Support gasless withdraw even with no gas fee tokens in EOA#8146
Conversation
packages/transaction-pay-controller/src/strategy/relay/relay-quotes.ts
Outdated
Show resolved
Hide resolved
packages/transaction-pay-controller/src/strategy/relay/relay-quotes.ts
Outdated
Show resolved
Hide resolved
Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
packages/transaction-pay-controller/src/strategy/relay/relay-quotes.ts
Outdated
Show resolved
Hide resolved
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>
Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
…balance-only 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>
Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
There was a problem hiding this comment.
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.
packages/transaction-pay-controller/src/strategy/relay/relay-quotes.ts
Outdated
Show resolved
Hide resolved
Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
| * @param transaction - Transaction metadata. | ||
| * @returns `true` when the transaction is a Predict withdrawal. | ||
| */ | ||
| export function isPredictWithdrawTransaction( |
There was a problem hiding this comment.
Won't this transaction type always be top level?
| fullRequest, | ||
| ); | ||
|
|
||
| if ( |
There was a problem hiding this comment.
To clarify, won't it always be the inverse in this scenario?
We don't have gas station to begin with, then we get it after we fix the quote?
Should we early return to skip all this if the user can already do gas station using token balance from their EOA?
| messenger, | ||
| request.isPostQuote ? transaction : undefined, | ||
| ); | ||
| request.isPostQuote && transaction.txParams.to |
There was a problem hiding this comment.
Why do we check to is present here?
| : undefined; | ||
|
|
||
| if (paramGasLimit) { | ||
| if (paramGasLimit && !fromOverride) { |
There was a problem hiding this comment.
Makes sense, since we know param value in this gas is the 2.5M.
| ...singleParams, | ||
| gas: singleParams.gas ? toHex(singleParams.gas) : undefined, | ||
| gas: | ||
| !fromOverride && singleParams.gas |
There was a problem hiding this comment.
Also makes sense, since we want to force a estimation and not use the param value.
| sourceChainId, | ||
| sourceTokenAddress, | ||
| }, | ||
| totalGasEstimate: relayOnlyGas.totalGasEstimate, |
There was a problem hiding this comment.
Why are we only extrapolating to cover the total Relay gas limit, what about our original withdraw transaction gas that we added in totalGasEstimate?
| totalGasEstimate: relayOnlyGas.totalGasEstimate, | ||
| // Simulation estimates gas for one relay step; force totalItemCount >= 2 | ||
| // so normalization scales the cost to cover all relay gas. | ||
| totalItemCount: Math.max( |
There was a problem hiding this comment.
For predict withdraw, won't this always be relayParams.length + 1?
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
Note
Medium Risk
Changes quote computation and gas-fee-token eligibility logic for Relay post-quote flows and alters submit-time balance validation, which could affect fee calculations and transaction batching behavior in edge cases.
Overview
Fixes gasless withdraw for post-quote flows (notably Predict Withdraw) by introducing two-phase Relay quoting: fetch a phase-1 quote to compute source-network gas cost in the gas fee token, then re-fetch a phase-2 quote with
sourceTokenAmountreduced by that cost (with fallbacks to phase 1 if the adjusted amount is non-positive, phase 2 fails, or phase 2 loses gas-fee-token eligibility).For Predict Withdraw specifically, gas estimation and gas-station simulation now use
refundTo(proxy/Safe) as the effectivefrom, including clearing any Relay-providedgasvalues when overridingfromto force re-estimation. Relay submit additionally skips source token balance validation for post-quote flows since funds become available only after the original transaction executes in the batch. AddsisPredictWithdrawTransactionhelper and updates the package changelog with the fix.Written by Cursor Bugbot for commit c0550af. This will update automatically on new commits. Configure here.