Conversation
Replaces the imported AaveFlashLoanType with a local FlashLoanFlow enum. The upstream one in @cowprotocol/sdk-flash-loans has only CollateralSwap, DebtSwap and RepayCollateral, so a Leverage adapter could not be named at all. The string values match theirs, and the one place that widening happens is toSdkFlashLoanType, so the SDK's per-type helpers keep working; those helpers select the adapter from hookAdapterPerType[type][chainId] and so will drive Leverage unchanged once it has an address. Adds SwapType.Leverage and fills the four exhaustive maps the type checker flagged: CoW gas limit 0 (flash-loan flows take gas from the hook limits), Paraswap 0 (it cannot route leverage), an app code, and OrderKind.BUY, matching the V4 backend, since leverage targets a collateral amount to acquire and finances it by selling the flash-loaned debt. The Leverage adapter addresses are left empty on purpose. The suite is not on mainnet yet, and an empty entry makes the flow unavailable rather than encoding against the zero address.
The V3 adapters gained `_enforceUsingAsCollateral(_buyToken, owner)`, which reverts the postHook with `BuyTokenNotUsingAsCollateral`. Only the collateral swap and leverage adapters call it, so those are the two flows guarded here; debt swap and repay with collateral never run the check. Without this the order is accepted and fails at settlement, which the user sees as a swap that silently never executes. A reserve the user has never supplied is deliberately not blocked: it has no user configuration yet, and supplying through the flow sets it as collateral. Only an explicit "enabled: false" blocks. Also registers Leverage in ProtocolSwapState and isProtocolSwapState, since leverage carries source and destination reserves like the other protocol flows.
Adds the Leverage modal, its entry point on supplied positions, and the CoW encoding the flow needs, so the groundwork from the previous commits becomes a reachable flow. The order is inverted like DebtSwap: the first input is the collateral to acquire, the swap sells the flash-loaned debt that finances it, and the post-hook supplies the collateral before drawing the debt. That reuses the proven BUY-side path rather than the untested non-inverted BUY branch. `@cowprotocol/sdk-flash-loans` cannot encode this post-hook: each of its encoders passes a single tuple, while `leverageWithFlashLoan` takes an ERC20 permit and a credit delegation. Everything else in `getOrderPostingSettings` is type-agnostic, so a subclass overrides only the post-hook calldata and the dapp id, and the adapter address arrives through the existing `hookAdapterPerType` config. Health factor needed a new projection: leverage raises collateral and debt together, which no `fromAssetType`/`toAssetType` pair in `calculateHFAfterSwap` expresses, since every combination there withdraws or repays one side. Limit orders are off for now, and the adapter address stays empty until the mainnet deployment, so the flow renders and quotes but cannot post an order yet.
Three buttons overflow the supplied position row: ListButtonsColumn has a fixed min and max width, so Withdraw was clipped. Desktop now follows the Assets to Supply pattern, a "..." button opening a menu, which also leaves room for whatever action comes next. Mobile keeps a plain button on its own line, where there is vertical space for it.
Matches the Assets to Supply row: a single primary button plus a "..." menu.
Withdraw joins Leverage in the menu, which keeps the row inside the fixed width
of ListButtonsColumn however many actions we add later.
The menu renders in a portal, so the row-scoped `button:contains("Withdraw")`
the e2e withdraw steps relied on no longer matches. Both call sites now open the
menu and click the item by data-cy.
Adds the multiplier the flow is actually about: the preview shows position leverage before and after, and a picker sets the collateral amount from a target multiple instead of a token amount. Buying t USD of collateral with t USD of new debt leaves equity untouched, so a target solves in closed form as t = target * equity - collateral. `Max` instead solves for the safe health factor, making that factor the only ceiling, the same rule the backend quote applies. Net apy was a bare difference of the two reserve rates, which ignored how much is being supplied against how much is borrowed. It is now weighted by the supplied and borrowed amounts of the quote. Limit orders are enabled, matching the other CoW adapter flows.
cow-sdk 9 derives hook sell/buy amounts from the signed order and takes a single flashLoanAmount, matching how the collateral swap now posts. The SDK also dropped Lens and added Solana to SupportedChainId, so the leverage adapter map follows. The uplift removed the secondary14 typography variant and the Warning primitive; the leverage details and blocking error use h5 and a small Alert like the surrounding swap UI.
The zero-LTV guard treated the flash-loaned debt asset as a withdrawal and blocked leverage for anyone holding an LTV-0 collateral. Leverage withdraws nothing, so it is exempt like the debt swap. The supply cap guard now also covers the collateral leverage supplies, the adapter approval notice shows for the leverage instance, and the asset inputs label supply and borrow APY on their respective sides. Adds unit tests for the leverage sizing math and regenerates the catalogs.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
📦 Next.js Bundle Analysis for aave-uiThis analysis was generated by the Next.js Bundle Analysis action. 🤖
|
| Page | Size (compressed) |
|---|---|
global |
1.34 MB (🟡 +1.42 KB) |
Details
The 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 <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
Seven Pages Changed Size
The following pages changed size from the code in this PR compared to its base branch:
| Page | Size (compressed) | First Load |
|---|---|---|
/ |
92.18 KB (🟡 +370 B) |
1.43 MB |
/dashboard |
82.1 KB (🟡 +370 B) |
1.42 MB |
/history |
32.57 KB (🟡 +6 B) |
1.37 MB |
/reserve-overview |
38.85 KB (🟡 +6 B) |
1.38 MB |
/safety-module |
55.18 KB (🟡 +4 B) |
1.39 MB |
/sgho |
92.25 KB (🟡 +4 B) |
1.43 MB |
/staking |
31.51 KB (🟡 +2 B) |
1.37 MB |
Details
Only 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 next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
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.
Adds a Leverage flow to the v3 dashboard. From a supplied position's overflow menu the user picks how much more of that collateral to acquire (or a 1.5x / 2x / 3x / Max multiplier). A CoW order flash-loans a borrowable asset, sells it for the collateral, and the post-hook supplies the collateral and draws the debt on the user's behalf through credit delegation. The order is inverted relative to the other position swaps: the first input is the collateral acquired, the second is the debt that finances it.
What changed
FlashLoanFlowenum owned by the interface, mirroring the SDK'sAaveFlashLoanTypeplus a Leverage variant.toSdkFlashLoanTypeis the single widening point.AaveLeverageFlashLoanSdkextends the CoW flash-loan SDK to encode the two-tupleleverageWithFlashLoanpost-hook and stamp a leverage dapp id.LeverageModal/LeverageModalContent/LeverageDetails/LeverageMultiplierSelector/LeverageActionsViaCoW.calculateHFAfterLeverageinhfUtils: collateral and debt both grow, which no existing from/to pair expresses. Collateral that cannot count for the user (zero effective LTV, isolation) is left out so the projection does not flatter the position.helpers/shared/leverage.helpers.ts, with unit tests.BuyTokenNotUsingAsCollateral.Rebased onto main
Adapted to cow-sdk 9 (
flashLoanAmountreplacessellAmount/buyAmountin the posting settings, Lens dropped and Solana added toSupportedChainId) and the v3 uplift (secondary14typography and theWarningprimitive are gone, overflow buttons useDotsHorizontalIconon a tertiary button).Not done in this PR
HOOK_ADAPTER_PER_TYPE[FlashLoanFlow.Leverage]is empty on every chain. Until the leverage adapter is deployed, the menu entry is visible wherever swaps are enabled but the modal blocks on a missing adapter address. Decide before undrafting whether to gate the entry on a configured address or ship the config together with the deployment.ActionNamefor leverage. Settled leverage orders fall back to the plain Swap label.Checks
tsc --noEmit,pnpm lint,pnpm build, and the i18n check (pnpm i18nleaves the tree clean) all pass.jest --cihas 4 failing suites, identical on current main (ESM parse error and a missingweightedAverageAPYexport), plus the newleverage.helpers.spec.tspassing 12/12. Cypress e2e runs in CI.