@lifi/composer-sdk 0.2.0-staging.5 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +103 -2
  2. package/dist/client.cjs +46 -8
  3. package/dist/client.cjs.map +1 -1
  4. package/dist/client.d.cts +27 -3
  5. package/dist/client.d.ts +27 -3
  6. package/dist/client.js +49 -8
  7. package/dist/client.js.map +1 -1
  8. package/dist/errors.cjs +4 -1
  9. package/dist/errors.cjs.map +1 -1
  10. package/dist/errors.js +6 -1
  11. package/dist/errors.js.map +1 -1
  12. package/dist/generated/config.generated.cjs.map +1 -1
  13. package/dist/generated/config.generated.d.cts +80 -20
  14. package/dist/generated/config.generated.d.ts +80 -20
  15. package/dist/generated/materialisers.generated.cjs +2 -8
  16. package/dist/generated/materialisers.generated.cjs.map +1 -1
  17. package/dist/generated/materialisers.generated.d.cts +1 -1
  18. package/dist/generated/materialisers.generated.d.ts +1 -1
  19. package/dist/generated/materialisers.generated.js +1 -6
  20. package/dist/generated/materialisers.generated.js.map +1 -1
  21. package/dist/generated/operations.generated.cjs +1 -30
  22. package/dist/generated/operations.generated.cjs.map +1 -1
  23. package/dist/generated/operations.generated.d.cts +2 -94
  24. package/dist/generated/operations.generated.d.ts +2 -94
  25. package/dist/generated/operations.generated.js +1 -30
  26. package/dist/generated/operations.generated.js.map +1 -1
  27. package/dist/index.cjs +8 -0
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +4 -3
  30. package/dist/index.d.ts +4 -3
  31. package/dist/index.js +8 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/{materialisers.generated-BfWJ-g7t.d.ts → materialisers.generated-BMkBQgWZ.d.ts} +3 -8
  34. package/dist/{materialisers.generated-DaJRwiRe.d.cts → materialisers.generated-BWq5oePO.d.cts} +3 -8
  35. package/dist/responseSchemas.cjs +110 -0
  36. package/dist/responseSchemas.cjs.map +1 -0
  37. package/dist/responseSchemas.d.cts +36 -0
  38. package/dist/responseSchemas.d.ts +36 -0
  39. package/dist/responseSchemas.js +74 -0
  40. package/dist/responseSchemas.js.map +1 -0
  41. package/dist/run/simulate.cjs +41 -0
  42. package/dist/run/simulate.cjs.map +1 -0
  43. package/dist/run/simulate.d.cts +59 -0
  44. package/dist/run/simulate.d.ts +59 -0
  45. package/dist/run/simulate.js +17 -0
  46. package/dist/run/simulate.js.map +1 -0
  47. package/dist/sdk.cjs +6 -1
  48. package/dist/sdk.cjs.map +1 -1
  49. package/dist/sdk.d.cts +18 -6
  50. package/dist/sdk.d.ts +18 -6
  51. package/dist/sdk.js +6 -1
  52. package/dist/sdk.js.map +1 -1
  53. package/package.json +8 -6
  54. package/src/client.ts +96 -16
  55. package/src/errors.ts +8 -10
  56. package/src/examples/aaveClaimRewards.ts +2 -2
  57. package/src/examples/aaveRepay.ts +2 -2
  58. package/src/examples/aaveRepayWithATokens.ts +2 -2
  59. package/src/examples/aaveSetEMode.ts +2 -2
  60. package/src/examples/approveAndDeposit.ts +2 -2
  61. package/src/examples/callContract.ts +4 -4
  62. package/src/examples/config.ts +4 -1
  63. package/src/examples/consolidateToEth.ts +2 -2
  64. package/src/examples/consolidateToUsdc.ts +2 -2
  65. package/src/examples/depositFromProxy.ts +2 -2
  66. package/src/examples/dustSweep.ts +2 -2
  67. package/src/examples/emitCustomEvent.ts +2 -2
  68. package/src/examples/invariantChecks.ts +2 -2
  69. package/src/examples/lifiSwap.ts +2 -2
  70. package/src/examples/lifiZap.ts +2 -2
  71. package/src/examples/rawCallWithArithmetic.ts +2 -2
  72. package/src/examples/readContractState.ts +2 -2
  73. package/src/examples/simulateCompiledSwap.ts +76 -0
  74. package/src/examples/simulateRawTransaction.ts +39 -0
  75. package/src/examples/splitAndZap.ts +2 -2
  76. package/src/examples/splitWithArithmetic.ts +2 -2
  77. package/src/examples/swapAndZap.ts +2 -2
  78. package/src/examples/swapToRecipient.ts +2 -2
  79. package/src/examples/swapWithAllowRevert.ts +3 -3
  80. package/src/examples/swapWithBalanceCheck.ts +2 -2
  81. package/src/examples/swapWithFee.ts +2 -2
  82. package/src/examples/swapWithOutputValidation.ts +2 -2
  83. package/src/examples/transferTokens.ts +3 -3
  84. package/src/examples/untypedOpWithTypedRef.ts +2 -2
  85. package/src/generated/config.generated.ts +221 -20
  86. package/src/generated/materialisers.generated.ts +0 -12
  87. package/src/generated/operations.generated.ts +0 -177
  88. package/src/index.ts +25 -0
  89. package/src/responseSchemas.ts +143 -0
  90. package/src/run/simulate.ts +78 -0
  91. package/src/sdk.ts +25 -6
  92. package/src/examples/staged/aaveBorrow.ts +0 -128
  93. package/src/examples/staged/aaveDebtRebalanceExactOut.ts +0 -301
  94. package/src/examples/staged/aaveHealthFactorExplode.ts +0 -70
  95. package/src/examples/staged/aaveToMorphoDebtMigration.ts +0 -200
  96. package/src/examples/staged/aaveToMorphoDebtMigrationWithSwap.ts +0 -231
  97. package/src/examples/staged/aaveToMorphoDebtMigrationWithSwapExactOut.ts +0 -307
  98. package/src/examples/staged/flashloanRepay.ts +0 -142
  99. package/src/examples/staged/morphoBlueBorrow.ts +0 -93
  100. package/src/examples/staged/morphoBlueRepay.ts +0 -132
  101. package/src/examples/staged/registry.ts +0 -80
@@ -1,200 +0,0 @@
1
- import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
2
-
3
- import { createComposeSdk, materialisers, resources } from '../../index.js';
4
- import type { Address } from '../../types.js';
5
- import {
6
- padForAaveDebtRounding,
7
- trimForAaveWithdrawalRounding,
8
- } from '../aaveRounding.js';
9
- import { BASE_URL } from '../config.js';
10
-
11
- // Base mainnet token addresses.
12
- const BASE_WETH = '0x4200000000000000000000000000000000000006';
13
- const BASE_USDC = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
14
-
15
- // Aave V3 on Base (pool + aWETH receipt + variable-debt USDC).
16
- const AAVE_V3_POOL_BASE = '0xA238Dd80C259a72e81d7e4664a9801593F98d1c5';
17
- const A_BAS_WETH = '0xD4a0e0b9149BCee3C920d2E00b5dE09138fd8bb7';
18
- const VDEBT_BAS_USDC = '0x59dca05b6c26dbd64b5381374aAaC5CD05644C28';
19
-
20
- // Morpho Blue WETH/USDC market on Base (same parameters as the
21
- // `morphoBlueBorrow` / `morphoBlueRepay` examples).
22
- const ADAPTIVE_CURVE_IRM_BASE = '0x46415998764C29aB2a25CbeA6254146D50D22687';
23
- const WETH_USDC_ORACLE = '0xFEa2D58cEfCb9fcb597723c6bAE66fFE4193aFE4';
24
- const WETH_USDC_LLTV = '860000000000000000';
25
-
26
- const MORPHO_WETH_USDC_MARKET = {
27
- loanToken: BASE_USDC,
28
- collateralToken: BASE_WETH,
29
- oracle: WETH_USDC_ORACLE,
30
- irm: ADAPTIVE_CURVE_IRM_BASE,
31
- lltv: WETH_USDC_LLTV,
32
- };
33
-
34
- export interface AaveToMorphoDebtMigrationInput {
35
- readonly owner: Address;
36
- /** WETH collateral the user posts (in smallest units). */
37
- readonly collateralAmount: `${bigint}`;
38
- /** USDC principal borrowed from Aave (in smallest units). */
39
- readonly debtAmount: `${bigint}`;
40
- /**
41
- * Aave-V3 flashloan fee on `debtAmount` — equals
42
- * `computeDefaultFee('aave-v3', debtAmount)` (5 bps of the principal).
43
- */
44
- readonly debtFlashloanFee: `${bigint}`;
45
- }
46
-
47
- /**
48
- * Atomically provision an Aave V3 borrow position on Base and migrate it to
49
- * a Morpho Blue WETH/USDC market — all in a single compose flow driven by
50
- * two concurrent flashloans.
51
- *
52
- * Phase 1 — provision the source position on Aave V3:
53
- * - User direct-deposits WETH.
54
- * - `lifi.zap` supplies the WETH to Aave (WETH → aBasWETH routing edge).
55
- * - `aave.borrow` mints USDC debt; the borrowed USDC stays on the proxy
56
- * and is swept back to the signer as the user's loan proceeds.
57
- *
58
- * Phase 2 — migrate the position to Morpho using two concurrent flashloans:
59
- * - Flashloan #1 (Aave V3, USDC) bridges the Aave debt payoff before the
60
- * Morpho borrow exists.
61
- * - Flashloan #2 (Balancer V2, WETH) bridges the Morpho collateral supply
62
- * before the Aave collateral is freed.
63
- * - `aave.repay` clears the Aave USDC debt with flashloan #1.
64
- * - `lifi.zap` withdraws the freed WETH from Aave (aBasWETH → WETH).
65
- * - `morphoBlue.supplyCollateral` deposits flashloan #2's WETH into Morpho.
66
- * - `morphoBlue.borrow` mints exactly `debtAmount + debtFlashloanFee` USDC
67
- * so the `borrowed` resource settles flashloan #1 with zero residual.
68
- * - Two `lifi.flashloanRepay` ops settle each leg: the USDC leg from the
69
- * Morpho borrow, the WETH leg from the Aave withdrawal (Balancer V2
70
- * charges no fee, so the principal alone covers it).
71
- *
72
- * After execution the signer holds `debtAmount` USDC and an open Morpho
73
- * Blue position (`collateralAmount` WETH collateral, `debtAmount +
74
- * debtFlashloanFee` USDC debt). The Aave position is closed.
75
- */
76
- export const buildAaveToMorphoDebtMigration = ({
77
- owner,
78
- collateralAmount,
79
- debtAmount,
80
- debtFlashloanFee,
81
- }: AaveToMorphoDebtMigrationInput): {
82
- flow: Flow;
83
- request: ComposeCompileRequest;
84
- } => {
85
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
86
-
87
- // Both flashloan legs absorb Aave's 1-wei scaled-balance skew: the USDC
88
- // leg funds a max-mode repay, the WETH leg is covered by a withdrawal.
89
- const debtFlashloanAmount = padForAaveDebtRounding(debtAmount);
90
- const collateralFlashloanAmount =
91
- trimForAaveWithdrawalRounding(collateralAmount);
92
-
93
- // Morpho borrow must equal principal + Aave-V3 flashloan fee so the
94
- // `borrowed` resource exactly settles the USDC flashloan leg.
95
- const morphoBorrowAmount = (
96
- BigInt(debtFlashloanAmount) + BigInt(debtFlashloanFee)
97
- ).toString() as `${bigint}`;
98
-
99
- const builder = sdk.flow(8453, {
100
- name: 'aave-to-morpho-debt-migration',
101
- inputs: {
102
- initialCollateral: resources.erc20(BASE_WETH, 8453),
103
- debtFlashloan: resources.erc20(BASE_USDC, 8453),
104
- collateralFlashloan: resources.erc20(BASE_WETH, 8453),
105
- },
106
- });
107
-
108
- // --- Phase 1: provision the Aave V3 borrow position ----------------------
109
-
110
- // WETH → aBasWETH via the aave routing edge family (Aave V3 supply).
111
- const supplyToAave = builder.lifi.zap('supply-to-aave', {
112
- bind: { amountIn: builder.inputs.initialCollateral },
113
- config: { resourceOut: resources.erc20(A_BAS_WETH, 8453) },
114
- });
115
-
116
- // Borrow USDC against the freshly supplied collateral. The `borrowed`
117
- // resource is left unbound; request-level `sweepTo` forwards it to the
118
- // signer as the user's loan proceeds.
119
- builder.aave.borrow('borrow-from-aave', {
120
- bind: {},
121
- config: {
122
- pool: AAVE_V3_POOL_BASE,
123
- asset: BASE_USDC,
124
- variableDebtToken: VDEBT_BAS_USDC,
125
- amount: debtAmount,
126
- },
127
- });
128
-
129
- // --- Phase 2: migrate to Morpho with two concurrent flashloans -----------
130
-
131
- // Settle the Aave USDC debt with flashloan #1. mode: 'max' makes Aave's
132
- // Pool clamp paybackAmount to userVariableDebt exactly, so any unspent
133
- // flashloan principal flows through the op's residual port (swept by the
134
- // request-level sweepTo).
135
- builder.aave.repay('repay-aave', {
136
- bind: {
137
- assetIn: builder.inputs.debtFlashloan,
138
- onBehalfOf: builder.context.executionAddress,
139
- },
140
- config: { pool: AAVE_V3_POOL_BASE, mode: 'max' },
141
- });
142
-
143
- // Withdraw the freed WETH from Aave (aBasWETH → WETH) via routing.
144
- const withdrawFromAave = builder.lifi.zap('withdraw-from-aave', {
145
- bind: { amountIn: supplyToAave.amountOut },
146
- config: { resourceOut: resources.erc20(BASE_WETH, 8453) },
147
- });
148
-
149
- // Open the Morpho Blue position with flashloan #2's WETH.
150
- builder.morphoBlue.supplyCollateral('supply-to-morpho', {
151
- bind: { assetIn: builder.inputs.collateralFlashloan },
152
- config: { marketParams: MORPHO_WETH_USDC_MARKET, mode: 'exact' },
153
- });
154
-
155
- // Borrow exactly principal + fee from Morpho to settle the USDC leg.
156
- const morphoBorrow = builder.morphoBlue.borrow('borrow-from-morpho', {
157
- bind: {},
158
- config: {
159
- marketParams: MORPHO_WETH_USDC_MARKET,
160
- amount: morphoBorrowAmount,
161
- },
162
- });
163
-
164
- // Settle the USDC flashloan leg with the Morpho borrow.
165
- builder.lifi.flashloanRepay('repay-debt-flashloan', {
166
- bind: { funds: morphoBorrow.borrowed },
167
- config: { leg: 'debtFlashloan' },
168
- });
169
-
170
- // Settle the WETH flashloan leg with the Aave withdrawal. Balancer V2
171
- // charges no fee, so the withdrawn principal alone covers the leg.
172
- builder.lifi.flashloanRepay('repay-collateral-flashloan', {
173
- bind: { funds: withdrawFromAave.amountOut },
174
- config: { leg: 'collateralFlashloan' },
175
- });
176
-
177
- const flow = builder.build();
178
-
179
- const request = sdk.request(flow, {
180
- signer: owner,
181
- inputs: {
182
- initialCollateral: materialisers.directDeposit({
183
- amount: collateralAmount,
184
- }),
185
- debtFlashloan: materialisers.flashloan({
186
- providerKind: 'aave-v3',
187
- amount: debtFlashloanAmount,
188
- }),
189
- collateralFlashloan: materialisers.flashloan({
190
- providerKind: 'balancer-v2',
191
- amount: collateralFlashloanAmount,
192
- }),
193
- },
194
- // Sweep the Aave borrow proceeds (and any aave.repay residual) to the
195
- // signer.
196
- sweepTo: builder.context.sender,
197
- });
198
-
199
- return { flow, request };
200
- };
@@ -1,231 +0,0 @@
1
- import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
2
-
3
- import { createComposeSdk, materialisers, resources } from '../../index.js';
4
- import type { Address } from '../../types.js';
5
- import {
6
- padForAaveDebtRounding,
7
- trimForAaveWithdrawalRounding,
8
- } from '../aaveRounding.js';
9
- import { BASE_URL } from '../config.js';
10
-
11
- // Base mainnet token addresses.
12
- const BASE_WETH = '0x4200000000000000000000000000000000000006';
13
- const BASE_USDC = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
14
- // Circle EURC on Base (6 decimals).
15
- const BASE_EURC = '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42';
16
-
17
- // Aave V3 on Base (pool + aWETH receipt + variable-debt USDC).
18
- const AAVE_V3_POOL_BASE = '0xA238Dd80C259a72e81d7e4664a9801593F98d1c5';
19
- const A_BAS_WETH = '0xD4a0e0b9149BCee3C920d2E00b5dE09138fd8bb7';
20
- const VDEBT_BAS_USDC = '0x59dca05b6c26dbd64b5381374aAaC5CD05644C28';
21
-
22
- // Morpho Blue WETH/EURC market on Base. Real listed market — borrow APY
23
- // ~1.02% at the time of writing vs ~5.30% on the WETH/USDC market, which is
24
- // what makes this migration economically interesting. Market ID:
25
- // 0xa9b5142fa687a24c275faf731f13b52faa9873252bb4e1cb6077aa1f412edb0b
26
- // (= keccak256(MarketParams) of the values below).
27
- const ADAPTIVE_CURVE_IRM_BASE = '0x46415998764C29aB2a25CbeA6254146D50D22687';
28
- const WETH_EURC_ORACLE = '0xE1bb8E5b4930eC9FeC7f7943FCF6227649F14B37';
29
- const WETH_EURC_LLTV = '860000000000000000';
30
-
31
- const MORPHO_WETH_EURC_MARKET = {
32
- loanToken: BASE_EURC,
33
- collateralToken: BASE_WETH,
34
- oracle: WETH_EURC_ORACLE,
35
- irm: ADAPTIVE_CURVE_IRM_BASE,
36
- lltv: WETH_EURC_LLTV,
37
- };
38
-
39
- // Slippage budget on the EURC → USDC swap. The caller must size
40
- // `morphoBorrowAmount` such that the swap's slippage-adjusted minimum covers
41
- // `debtAmount + computeDefaultFee('aave-v3', debtAmount)`.
42
- const SWAP_SLIPPAGE = 0.03;
43
-
44
- export interface AaveToMorphoDebtMigrationWithSwapInput {
45
- readonly owner: Address;
46
- /** WETH collateral the user posts (in smallest units, 18 decimals). */
47
- readonly collateralAmount: `${bigint}`;
48
- /** USDC principal borrowed from Aave (6 decimals). */
49
- readonly debtAmount: `${bigint}`;
50
- /**
51
- * EURC to borrow from Morpho (6 decimals). Must be large enough that, after
52
- * the EURC → USDC swap at `SWAP_SLIPPAGE`, the swap's minimum output covers
53
- * `debtAmount + computeDefaultFee('aave-v3', debtAmount)`. Caller sizes this
54
- * off-chain from a live LI.FI quote, e.g.
55
- * morphoBorrowAmount =
56
- * ceil((debtAmount + aaveV3Fee) * eurcPerUsdc / (1 - slippage))
57
- * Note: EUR/USD is not 1:1 — the example fixture assumes ~1.075 USD/EUR.
58
- */
59
- readonly morphoBorrowAmount: `${bigint}`;
60
- }
61
-
62
- /**
63
- * Atomically migrate an Aave V3 USDC borrow on Base into the Morpho Blue
64
- * WETH/EURC market — same WETH collateral, different stablecoin debt. At the
65
- * time of writing Morpho's WETH/EURC borrow APY is ~1.02% vs ~5.30% on
66
- * USDC-denominated WETH-collateral markets, so a long-running borrow position
67
- * can be made materially cheaper by migrating the debt asset.
68
- *
69
- * Topology mirrors `aaveToMorphoDebtMigration`, with one extra step: after
70
- * Morpho mints EURC debt, the borrow proceeds are swapped to USDC via
71
- * `lifi.swap`, and the swap's `amountOut` (which carries the slippage-adjusted
72
- * minimum) settles the USDC flashloan leg.
73
- *
74
- * Phase 1 — provision the source position on Aave V3:
75
- * - User direct-deposits WETH.
76
- * - `lifi.zap` supplies the WETH to Aave (WETH → aBasWETH routing edge).
77
- * - `aave.borrow` mints USDC debt; the borrowed USDC is swept back to the
78
- * signer as the user's loan proceeds.
79
- *
80
- * Phase 2 — migrate to Morpho using two concurrent flashloans:
81
- * - Flashloan #1 (Aave V3, USDC) bridges the Aave debt payoff before the
82
- * Morpho borrow + swap exists.
83
- * - Flashloan #2 (Balancer V2, WETH) bridges the Morpho collateral supply
84
- * before the Aave collateral is freed.
85
- * - `aave.repay` clears the Aave USDC debt with flashloan #1.
86
- * - `lifi.zap` withdraws the freed WETH from Aave (aBasWETH → WETH).
87
- * - `morphoBlue.supplyCollateral` deposits flashloan #2's WETH into Morpho.
88
- * - `morphoBlue.borrow` mints `morphoBorrowAmount` EURC.
89
- * - `lifi.swap` converts the borrowed EURC into USDC. `amountOut` is the
90
- * slippage-adjusted minimum that settles the USDC flashloan leg.
91
- * - Two `lifi.flashloanRepay` ops settle each leg: the USDC leg from the swap
92
- * output, the WETH leg from the Aave withdrawal (Balancer V2 charges no
93
- * fee, so the withdrawn principal alone covers it).
94
- *
95
- * After execution the signer holds a Morpho Blue position with
96
- * `collateralAmount` WETH collateral and `morphoBorrowAmount` EURC debt; the
97
- * Aave position is closed. Any EURC dust (Morpho residual above what the swap
98
- * consumed) and USDC residual from `aave.repay`'s `mode: 'max'` clamp flow
99
- * back to the signer via `sweepTo`.
100
- */
101
- export const buildAaveToMorphoDebtMigrationWithSwap = ({
102
- owner,
103
- collateralAmount,
104
- debtAmount,
105
- morphoBorrowAmount,
106
- }: AaveToMorphoDebtMigrationWithSwapInput): {
107
- flow: Flow;
108
- request: ComposeCompileRequest;
109
- } => {
110
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
111
-
112
- // Both flashloan legs absorb Aave's 1-wei scaled-balance skew: the USDC
113
- // leg funds a max-mode repay, the WETH leg is covered by a withdrawal.
114
- const debtFlashloanAmount = padForAaveDebtRounding(debtAmount);
115
- const collateralFlashloanAmount =
116
- trimForAaveWithdrawalRounding(collateralAmount);
117
-
118
- const builder = sdk.flow(8453, {
119
- name: 'aave-to-morpho-debt-migration-with-swap',
120
- inputs: {
121
- initialCollateral: resources.erc20(BASE_WETH, 8453),
122
- debtFlashloan: resources.erc20(BASE_USDC, 8453),
123
- collateralFlashloan: resources.erc20(BASE_WETH, 8453),
124
- },
125
- });
126
-
127
- // --- Phase 1: provision the Aave V3 borrow position ----------------------
128
-
129
- // WETH → aBasWETH via the aave routing edge family (Aave V3 supply).
130
- const supplyToAave = builder.lifi.zap('supply-to-aave', {
131
- bind: { amountIn: builder.inputs.initialCollateral },
132
- config: { resourceOut: resources.erc20(A_BAS_WETH, 8453) },
133
- });
134
-
135
- // Borrow USDC against the freshly supplied collateral. The `borrowed`
136
- // resource is left unbound; request-level `sweepTo` forwards it to the
137
- // signer as the user's loan proceeds.
138
- builder.aave.borrow('borrow-from-aave', {
139
- bind: {},
140
- config: {
141
- pool: AAVE_V3_POOL_BASE,
142
- asset: BASE_USDC,
143
- variableDebtToken: VDEBT_BAS_USDC,
144
- amount: debtAmount,
145
- },
146
- });
147
-
148
- // --- Phase 2: migrate to Morpho with two concurrent flashloans -----------
149
-
150
- // Settle the Aave USDC debt with flashloan #1. mode: 'max' makes Aave's
151
- // Pool clamp paybackAmount to userVariableDebt exactly, so any unspent
152
- // flashloan principal flows through the op's residual port (swept by
153
- // request-level sweepTo).
154
- builder.aave.repay('repay-aave', {
155
- bind: {
156
- assetIn: builder.inputs.debtFlashloan,
157
- onBehalfOf: builder.context.executionAddress,
158
- },
159
- config: { pool: AAVE_V3_POOL_BASE, mode: 'max' },
160
- });
161
-
162
- // Withdraw the freed WETH from Aave (aBasWETH → WETH) via routing.
163
- const withdrawFromAave = builder.lifi.zap('withdraw-from-aave', {
164
- bind: { amountIn: supplyToAave.amountOut },
165
- config: { resourceOut: resources.erc20(BASE_WETH, 8453) },
166
- });
167
-
168
- // Open the Morpho Blue position with flashloan #2's WETH.
169
- builder.morphoBlue.supplyCollateral('supply-to-morpho', {
170
- bind: { assetIn: builder.inputs.collateralFlashloan },
171
- config: { marketParams: MORPHO_WETH_EURC_MARKET, mode: 'exact' },
172
- });
173
-
174
- // Borrow EURC at the destination's (cheaper) APR.
175
- const morphoBorrow = builder.morphoBlue.borrow('borrow-from-morpho', {
176
- bind: {},
177
- config: {
178
- marketParams: MORPHO_WETH_EURC_MARKET,
179
- amount: morphoBorrowAmount,
180
- },
181
- });
182
-
183
- // Swap EURC → USDC so the borrow proceeds can settle the USDC flashloan
184
- // leg. `amountOut` carries `providesMinimum: true`; the caller is
185
- // responsible for sizing `morphoBorrowAmount` so the slippage-adjusted
186
- // minimum covers `debtAmount + aaveV3Fee(debtAmount)`.
187
- const swapDebt = builder.lifi.swap('swap-borrow-to-usdc', {
188
- bind: { amountIn: morphoBorrow.borrowed },
189
- config: {
190
- resourceOut: resources.erc20(BASE_USDC, 8453),
191
- slippage: SWAP_SLIPPAGE,
192
- },
193
- });
194
-
195
- // Settle the USDC flashloan leg with the swap output.
196
- builder.lifi.flashloanRepay('repay-debt-flashloan', {
197
- bind: { funds: swapDebt.amountOut },
198
- config: { leg: 'debtFlashloan' },
199
- });
200
-
201
- // Settle the WETH flashloan leg with the Aave withdrawal. Balancer V2
202
- // charges no fee, so the withdrawn principal alone covers the leg.
203
- builder.lifi.flashloanRepay('repay-collateral-flashloan', {
204
- bind: { funds: withdrawFromAave.amountOut },
205
- config: { leg: 'collateralFlashloan' },
206
- });
207
-
208
- const flow = builder.build();
209
-
210
- const request = sdk.request(flow, {
211
- signer: owner,
212
- inputs: {
213
- initialCollateral: materialisers.directDeposit({
214
- amount: collateralAmount,
215
- }),
216
- debtFlashloan: materialisers.flashloan({
217
- providerKind: 'aave-v3',
218
- amount: debtFlashloanAmount,
219
- }),
220
- collateralFlashloan: materialisers.flashloan({
221
- providerKind: 'balancer-v2',
222
- amount: collateralFlashloanAmount,
223
- }),
224
- },
225
- // Sweep Aave borrow proceeds, aave.repay's residual, and any EURC / USDC
226
- // dust left after the swap back to the signer.
227
- sweepTo: builder.context.sender,
228
- });
229
-
230
- return { flow, request };
231
- };