Skip to main content
Not public yet. Contact us to get early access.

Scenario

A user holds a WETH-collateralised USDC borrow on Aave V3 (Base) and wants the same position on Morpho Blue instead — to capture a better rate, say. Doing this manually means finding capital to repay Aave before you can withdraw the collateral, which is exactly the chicken-and-egg that flash loans solve. The flow borrows two flash loans concurrently and unwinds both within the same transaction:
  • Flash loan #1 (Aave V3, USDC) repays the Aave debt before the Morpho borrow exists.
  • Flash loan #2 (Balancer V2, WETH) supplies the Morpho collateral before the Aave collateral is freed.
The Morpho borrow is sized to exactly principal + Aave fee so it settles flash loan #1 with zero residual; the WETH freed from Aave settles flash loan #2 (Balancer V2 charges no fee).

What this recipe demonstrates

  • The flashloan materialiser sourcing two flow inputs from two different providers.
  • Settling each leg with lifi.flashloanRepay, keyed by leg to the input it repays.
  • Threading receipt handles across protocols: aave.repaylifi.zap withdraw → morphoBlue.supplyCollateral / morphoBlue.borrow.
  • A safe sweepTo: the Aave aToken collateral is fully unwound (withdrawn to WETH), so nothing non-transferable is left on the proxy. (Contrast with flows that keep an aToken position — see the sweepTo caveat.)

Full example

Adapted from aaveToMorphoDebtMigration.ts in the composer-sdk-examples repo. Two variants that route the destination debt through a swap — ...WithSwap and ...WithSwapExactOut — build on the same shape.

What to observe

  • Inputs. Three resource inputs: the user’s collateral (directDeposit) plus two flashloan-sourced inputs from different providers.
  • Why two providers. Aave V3 supplies the USDC to repay; Balancer V2 supplies the WETH collateral (and charges no fee, so its leg is settled by the withdrawn principal alone).
  • Sizing the Morpho borrow. principal + debtFlashloanFee so the borrowed resource settles the USDC leg with zero leftover.
  • Repayment is mandatory. Both flash loans must be repaid in-flow via lifi.flashloanRepay, or simulation reverts.
  • sweepTo is safe here because the Aave aToken is fully withdrawn to WETH — no bound collateral receipt remains on the proxy. When a flow keeps an aToken position, omit the blanket sweepTo and transfer only loose tokens (see the caveat).