fix(swap): force flashloan flow for Paraswap collateral swaps#3012
fix(swap): force flashloan flow for Paraswap collateral swaps#3012mgrabina wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f12961556b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
📦 Next.js Bundle Analysis for aave-uiThis analysis was generated by the Next.js Bundle Analysis action. 🤖 🎉 Global Bundle Size Decreased
DetailsThe global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster. Any third party scripts you have added directly to your app using the If you want further insight into what is behind the changes, give @next/bundle-analyzer a try! One Page Changed SizeThe following page changed size from the code in this PR compared to its base branch:
DetailsOnly the gzipped size is provided here based on an expert tip. First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If Any third party scripts you have added directly to your app using the Next to the size is how much the size has increased or decreased compared with the base branch of this PR. If this percentage has increased by 20% or more, there will be a red status indicator applied, indicating that special attention should be given to this. |
A no-flashloan collateral swap routes through the simple SwapActionsViaParaswap path, which builds the tx on the aToken addresses. Paraswap can't price or trade aTokens: it doesn't list them and defaults unknown tokens to 18 decimals, so the priceRoute came back with srcDecimals=18 for a 6-decimal asset while buildTx sent 6, and Paraswap rejected it with "Source Decimals Mismatch". On Sonic, where CoW is unsupported and the provider falls back to Paraswap, this hit any collateral swap with a healthy health factor. Force the flashloan flow for Paraswap collateral swaps so they use the adapter (which unwraps to the underlying), matching the existing CoW repay/debt handling. This routes the dispatcher to CollateralSwapActionsViaParaswapAdapters and flips usesAddressToSwap off, so the quote runs on the underlying tokens too. Both sides then agree on real, priceable tokens.
f129615 to
e503750
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e503750296
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| (state.swapType === SwapType.RepayWithCollateral || state.swapType === SwapType.DebtSwap); | ||
| (state.provider === SwapProvider.COW_PROTOCOL && | ||
| (state.swapType === SwapType.RepayWithCollateral || state.swapType === SwapType.DebtSwap)) || | ||
| (state.provider === SwapProvider.PARASWAP && state.swapType === SwapType.CollateralSwap); |
There was a problem hiding this comment.
Force flashloan before requiring a ParaSwap quote
This new ParaSwap collateral-swap override only runs after the early guard has already required state.swapRate (line 97), but the first quote is still requested with useFlashloan === false, so useSwapQuote uses the aToken addressToSwap pair for ParaSwap. For any collateral pair where ParaSwap rejects the unlisted aToken quote instead of returning a bogus route, state.swapRate remains undefined and this line is never reached, leaving the flow stuck on the broken non-flashloan/aToken path with a quote error. The forced flow needs to be selected before the initial quote can fail, or this fix only works for aTokens that happen to get a response.
Useful? React with 👍 / 👎.
|
📦 Next.js Bundle Analysis for aave-uiThis analysis was generated by the Next.js Bundle Analysis action. 🤖 🎉 Global Bundle Size Decreased
DetailsThe global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster. Any third party scripts you have added directly to your app using the If you want further insight into what is behind the changes, give @next/bundle-analyzer a try! |
General Changes
Source Decimals Mismatch(reported on Sonic, USDC → wS).Developer Notes
Root cause. A no-flashloan collateral swap renders the generic
SwapActionsViaParaswappath (seeCollateralSwapActionsdispatcher), which builds the Paraswap tx on the aToken addresses (state.sourceToken.addressToSwap). Paraswap can't price or trade aTokens — it doesn't list them, so it ignores thesrcDecimalswe send and defaults the unknown token to 18. Reproduced against the live API on Sonic (chainId 146):The build sends
srcDecimalsfrom the quote wrapper (6) plus that priceRoute (18). Paraswap's/transactionsvalidatesbody.srcDecimals === priceRoute.srcDecimals(6 !== 18) →Source Decimals Mismatch. This also explains the$0.00input USD in the report: the route priced100000base units as an 18-decimal token (~1e-13 ≈ $0). The destination matched only by coincidence (wS is 18 and Paraswap's default for the unknown aWS was also 18), which is why the error is Source and not Destination.Even if the API had accepted it, the on-chain tx would revert — aTokens have no DEX liquidity. The non-flashloan path is fundamentally non-functional for Paraswap collateral swaps.
On Sonic, CoW is unsupported, so
getSwitchProvideralways falls back to Paraswap; with a healthy health factor,useFlowSelectorleftuseFlashloan = false, routing into that broken path.Fix. Force the flashloan flow for Paraswap collateral swaps in
useFlowSelector, alongside the existing CoW repay/debt rule. This routes the dispatcher toCollateralSwapActionsViaParaswapAdapters(which unwraps aTokens → underlying → swaps underlying via Paraswap → re-supplies) and, becauseusesAddressToSwapis gated onuseFlashloan === false, also makes the quote use the underlying tokens. Both sides then agree on real, priceable tokens.Scope:
SWAP_COLLATERAL_ADAPTER(0x78F8…) is deployed, so the flashloan path works there.