@morpho-org/consumer-sdk 0.4.0 → 0.5.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 (56) hide show
  1. package/README.md +136 -10
  2. package/lib/actions/index.d.ts +1 -0
  3. package/lib/actions/index.js +1 -0
  4. package/lib/actions/marketV1/borrow.d.ts +34 -0
  5. package/lib/actions/marketV1/borrow.js +62 -0
  6. package/lib/actions/marketV1/buildReallocationActions.d.ts +17 -0
  7. package/lib/actions/marketV1/buildReallocationActions.js +36 -0
  8. package/lib/actions/marketV1/index.d.ts +6 -0
  9. package/lib/actions/marketV1/index.js +22 -0
  10. package/lib/actions/marketV1/repay.d.ts +44 -0
  11. package/lib/actions/marketV1/repay.js +93 -0
  12. package/lib/actions/marketV1/repayWithdrawCollateral.d.ts +51 -0
  13. package/lib/actions/marketV1/repayWithdrawCollateral.js +108 -0
  14. package/lib/actions/marketV1/supplyCollateral.d.ts +28 -0
  15. package/lib/actions/marketV1/supplyCollateral.js +85 -0
  16. package/lib/actions/marketV1/supplyCollateralBorrow.d.ts +37 -0
  17. package/lib/actions/marketV1/supplyCollateralBorrow.js +109 -0
  18. package/lib/actions/marketV1/withdrawCollateral.d.ts +28 -0
  19. package/lib/actions/marketV1/withdrawCollateral.js +51 -0
  20. package/lib/actions/requirements/encode/encodeErc20Permit.js +4 -1
  21. package/lib/actions/requirements/encode/encodeErc20Permit2.js +4 -1
  22. package/lib/actions/requirements/getMorphoAuthorizationRequirement.d.ts +21 -0
  23. package/lib/actions/requirements/getMorphoAuthorizationRequirement.js +55 -0
  24. package/lib/actions/requirements/index.d.ts +1 -0
  25. package/lib/actions/requirements/index.js +1 -0
  26. package/lib/actions/vaultV2/forceWithdraw.js +5 -1
  27. package/lib/client/morphoClient.d.ts +3 -1
  28. package/lib/client/morphoClient.js +3 -0
  29. package/lib/entities/index.d.ts +1 -0
  30. package/lib/entities/index.js +1 -0
  31. package/lib/entities/marketV1/index.d.ts +1 -0
  32. package/lib/entities/marketV1/index.js +17 -0
  33. package/lib/entities/marketV1/marketV1.d.ts +290 -0
  34. package/lib/entities/marketV1/marketV1.js +528 -0
  35. package/lib/entities/vaultV1/vaultV1.js +4 -0
  36. package/lib/entities/vaultV2/vaultV2.js +4 -0
  37. package/lib/helpers/computeReallocations.d.ts +23 -0
  38. package/lib/helpers/computeReallocations.js +98 -0
  39. package/lib/helpers/constant.d.ts +5 -0
  40. package/lib/helpers/constant.js +6 -1
  41. package/lib/helpers/index.d.ts +3 -0
  42. package/lib/helpers/index.js +18 -1
  43. package/lib/helpers/slippage.d.ts +46 -0
  44. package/lib/helpers/slippage.js +73 -0
  45. package/lib/helpers/validate.d.ts +150 -0
  46. package/lib/helpers/validate.js +279 -0
  47. package/lib/types/action.d.ts +75 -3
  48. package/lib/types/action.js +12 -1
  49. package/lib/types/client.d.ts +3 -1
  50. package/lib/types/error.d.ts +106 -1
  51. package/lib/types/error.js +165 -3
  52. package/lib/types/index.d.ts +1 -0
  53. package/lib/types/index.js +1 -0
  54. package/lib/types/sharedLiquidity.d.ts +41 -0
  55. package/lib/types/sharedLiquidity.js +2 -0
  56. package/package.json +1 -1
package/README.md CHANGED
@@ -8,16 +8,19 @@
8
8
 
9
9
  ## Entities & Actions
10
10
 
11
- | Entity | Action | Route | Why |
12
- | ----------- | --------------- | ------------------------- | --------------------------------------------------------------------------------------- |
13
- | **VaultV2** | `deposit` | Bundler (general adapter) | Enforces `maxSharePrice` — inflation attack prevention. Supports native token wrapping. |
14
- | | `withdraw` | Direct vault call | No attack surface, no bundler overhead needed |
15
- | | `redeem` | Direct vault call | No attack surface, no bundler overhead needed |
16
- | | `forceWithdraw` | Vault `multicall` | N `forceDeallocate` + 1 `withdraw` in a single tx |
17
- | | `forceRedeem` | Vault `multicall` | N `forceDeallocate` + 1 `redeem` in a single tx |
18
- | **VaultV1** | `deposit` | Bundler (general adapter) | Same ERC-4626 inflation attack prevention as V2. Supports native token wrapping. |
19
- | | `withdraw` | Direct vault call | No attack surface |
20
- | | `redeem` | Direct vault call | No attack surface |
11
+ | Entity | Action | Route | Why |
12
+ | ------------ | ------------------------ | ------------------------- | --------------------------------------------------------------------------------------------------- |
13
+ | **VaultV2** | `deposit` | Bundler (general adapter) | Enforces `maxSharePrice` — inflation attack prevention. Supports native token wrapping. |
14
+ | | `withdraw` | Direct vault call | No attack surface, no bundler overhead needed |
15
+ | | `redeem` | Direct vault call | No attack surface, no bundler overhead needed |
16
+ | | `forceWithdraw` | Vault `multicall` | N `forceDeallocate` + 1 `withdraw` in a single tx |
17
+ | | `forceRedeem` | Vault `multicall` | N `forceDeallocate` + 1 `redeem` in a single tx |
18
+ | **VaultV1** | `deposit` | Bundler (general adapter) | Same ERC-4626 inflation attack prevention as V2. Supports native token wrapping. |
19
+ | | `withdraw` | Direct vault call | No attack surface |
20
+ | | `redeem` | Direct vault call | No attack surface |
21
+ | **MarketV1** | `supplyCollateral` | Bundler (general adapter) | `erc20TransferFrom` + `morphoSupplyCollateral`. Supports native wrapping. |
22
+ | | `borrow` | Bundler (general adapter) | `morphoBorrow` with `minSharePrice` slippage protection. Requires GA1 auth. Supports reallocations. |
23
+ | | `supplyCollateralBorrow` | Bundler (general adapter) | Atomic supply + borrow. LLTV buffer prevents instant liquidation. Supports reallocations. |
21
24
 
22
25
  ## VaultV2
23
26
 
@@ -151,6 +154,111 @@ const { buildTx } = vault.redeem({
151
154
  const tx = buildTx();
152
155
  ```
153
156
 
157
+ ## MarketV1
158
+
159
+ ```typescript
160
+ const market = morpho.marketV1(
161
+ {
162
+ loanToken: "0xLoan...",
163
+ collateralToken: "0xCollateral...",
164
+ oracle: "0xOracle...",
165
+ irm: "0xIrm...",
166
+ lltv: 860000000000000000n,
167
+ },
168
+ 1
169
+ );
170
+ ```
171
+
172
+ ### Supply Collateral
173
+
174
+ ```typescript
175
+ const { buildTx, getRequirements } = market.supplyCollateral({
176
+ amount: 1000000000000000000n,
177
+ userAddress: "0xUser...",
178
+ });
179
+
180
+ const requirements = await getRequirements();
181
+ const tx = buildTx(requirementSignature);
182
+ ```
183
+
184
+ ### Borrow
185
+
186
+ ```typescript
187
+ const positionData = await market.getPositionData("0xUser...");
188
+
189
+ const { buildTx, getRequirements } = market.borrow({
190
+ amount: 500000000000000000n,
191
+ userAddress: "0xUser...",
192
+ positionData,
193
+ });
194
+
195
+ const requirements = await getRequirements();
196
+ const tx = buildTx();
197
+ ```
198
+
199
+ ### Supply Collateral & Borrow
200
+
201
+ ```typescript
202
+ const positionData = await market.getPositionData("0xUser...");
203
+
204
+ const { buildTx, getRequirements } = market.supplyCollateralBorrow({
205
+ amount: 1000000000000000000n,
206
+ borrowAmount: 500000000000000000n,
207
+ userAddress: "0xUser...",
208
+ positionData,
209
+ });
210
+
211
+ const requirements = await getRequirements();
212
+ const tx = buildTx(requirementSignature);
213
+ ```
214
+
215
+ ### Borrow with Shared Liquidity (Reallocations)
216
+
217
+ When a market lacks sufficient liquidity, you can reallocate liquidity from other markets managed by MetaMorpho Vaults via the **PublicAllocator** contract:
218
+
219
+ ```typescript
220
+ import type { VaultReallocation } from "@morpho-org/consumer-sdk";
221
+
222
+ const reallocations: VaultReallocation[] = [
223
+ {
224
+ vault: "0xVault...", // MetaMorpho vault to reallocate from
225
+ fee: 0n, // PublicAllocator fee in native token (can be 0)
226
+ withdrawals: [
227
+ {
228
+ marketParams: sourceMarketParams, // Source market to withdraw from
229
+ amount: 2000000000n, // Amount to withdraw
230
+ },
231
+ ],
232
+ },
233
+ ];
234
+
235
+ const positionData = await market.getPositionData("0xUser...");
236
+
237
+ // Borrow with reallocations
238
+ const { buildTx, getRequirements } = market.borrow({
239
+ amount: 500000000000000000n,
240
+ userAddress: "0xUser...",
241
+ positionData,
242
+ reallocations,
243
+ });
244
+
245
+ const requirements = await getRequirements();
246
+ const tx = buildTx();
247
+ // tx.value includes the sum of all reallocation fees
248
+ ```
249
+
250
+ Reallocations also work with `supplyCollateralBorrow`:
251
+
252
+ ```typescript
253
+ const { buildTx, getRequirements } = market.supplyCollateralBorrow({
254
+ amount: 1000000000000000000n,
255
+ borrowAmount: 500000000000000000n,
256
+ userAddress: "0xUser...",
257
+ positionData,
258
+ reallocations,
259
+ });
260
+ ```
261
+
154
262
  ## Architecture
155
263
 
156
264
  ```mermaid
@@ -159,6 +267,7 @@ graph LR
159
267
 
160
268
  MC -->|.vaultV1| MV1
161
269
  MC -->|.vaultV2| MV2
270
+ MC -->|.marketV1| MM1
162
271
 
163
272
  subgraph VaultV1 Flow
164
273
  MV1[MorphoVaultV1]
@@ -186,18 +295,35 @@ graph LR
186
295
  V2FR -->|multicall| V2C
187
296
  end
188
297
 
298
+ subgraph MarketV1 Flow
299
+ MM1[MorphoMarketV1]
300
+ MM1 --> M1SC[marketV1SupplyCollateral]
301
+ MM1 --> M1B[marketV1Borrow]
302
+ MM1 --> M1SCB[marketV1SupplyCollateralBorrow]
303
+
304
+ M1SC -->|erc20TransferFrom + morphoSupplyCollateral| B3[Bundler3]
305
+ M1B -->|reallocateTo? + morphoBorrow| B3
306
+ M1SCB -->|transfer + supplyCollateral + reallocateTo? + borrow| B3
307
+
308
+ B3 -.->|reallocateTo| PA[PublicAllocator]
309
+ end
310
+
311
+
189
312
  subgraph Shared
190
313
  REQ[getRequirements]
191
314
  end
192
315
 
193
316
  MV1 -.->|approval / permit| REQ
194
317
  MV2 -.->|approval / permit| REQ
318
+ MM1 -.->|approval / permit / authorization| REQ
195
319
 
196
320
  style B1 fill:#e8f5e9,stroke:#4caf50
197
321
  style B2 fill:#e8f5e9,stroke:#4caf50
322
+ style B3 fill:#e8f5e9,stroke:#4caf50
198
323
  style MM fill:#fff3e0,stroke:#ff9800
199
324
  style V2C fill:#e3f2fd,stroke:#2196f3
200
325
  style REQ fill:#f3e5f5,stroke:#9c27b0
326
+ style PA fill:#fff9c4,stroke:#f9a825
201
327
  ```
202
328
 
203
329
  ## Local Development
@@ -1,3 +1,4 @@
1
+ export * from "./marketV1";
1
2
  export * from "./requirements";
2
3
  export * from "./vaultV1";
3
4
  export * from "./vaultV2";
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./marketV1"), exports);
17
18
  __exportStar(require("./requirements"), exports);
18
19
  __exportStar(require("./vaultV1"), exports);
19
20
  __exportStar(require("./vaultV2"), exports);
@@ -0,0 +1,34 @@
1
+ import type { MarketParams } from "@morpho-org/blue-sdk";
2
+ import type { Address } from "viem";
3
+ import { type MarketV1BorrowAction, type Metadata, type Transaction, type VaultReallocation } from "../../types";
4
+ /** Parameters for {@link marketV1Borrow}. */
5
+ export interface MarketV1BorrowParams {
6
+ market: {
7
+ readonly chainId: number;
8
+ readonly marketParams: MarketParams;
9
+ };
10
+ args: {
11
+ amount: bigint;
12
+ receiver: Address;
13
+ /** Minimum borrow share price (in ray). Protects against share price manipulation. */
14
+ minSharePrice: bigint;
15
+ /** Vault reallocations to execute before borrowing (computed by entity). */
16
+ reallocations?: readonly VaultReallocation[];
17
+ };
18
+ metadata?: Metadata;
19
+ }
20
+ /**
21
+ * Prepares a borrow transaction for a Morpho Blue market.
22
+ *
23
+ * Routed through bundler3 via `morphoBorrow`. The bundler uses the transaction
24
+ * initiator as `onBehalf`. Uses `minSharePrice` to protect against share price
25
+ * manipulation between transaction construction and execution.
26
+ *
27
+ * When `reallocations` are provided, `reallocateTo` actions are prepended to
28
+ * the bundle, moving liquidity from other markets via the PublicAllocator
29
+ * before borrowing. The reallocation fees are set as the transaction value.
30
+ *
31
+ * @param params - Borrow parameters.
32
+ * @returns Deep-frozen transaction.
33
+ */
34
+ export declare const marketV1Borrow: ({ market: { chainId, marketParams }, args: { amount, receiver, minSharePrice, reallocations }, metadata, }: MarketV1BorrowParams) => Readonly<Transaction<MarketV1BorrowAction>>;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.marketV1Borrow = void 0;
4
+ const bundler_sdk_viem_1 = require("@morpho-org/bundler-sdk-viem");
5
+ const morpho_ts_1 = require("@morpho-org/morpho-ts");
6
+ const helpers_1 = require("../../helpers");
7
+ const types_1 = require("../../types");
8
+ const buildReallocationActions_1 = require("./buildReallocationActions");
9
+ /**
10
+ * Prepares a borrow transaction for a Morpho Blue market.
11
+ *
12
+ * Routed through bundler3 via `morphoBorrow`. The bundler uses the transaction
13
+ * initiator as `onBehalf`. Uses `minSharePrice` to protect against share price
14
+ * manipulation between transaction construction and execution.
15
+ *
16
+ * When `reallocations` are provided, `reallocateTo` actions are prepended to
17
+ * the bundle, moving liquidity from other markets via the PublicAllocator
18
+ * before borrowing. The reallocation fees are set as the transaction value.
19
+ *
20
+ * @param params - Borrow parameters.
21
+ * @returns Deep-frozen transaction.
22
+ */
23
+ const marketV1Borrow = ({ market: { chainId, marketParams }, args: { amount, receiver, minSharePrice, reallocations }, metadata, }) => {
24
+ if (amount <= 0n) {
25
+ throw new types_1.NonPositiveBorrowAmountError(marketParams.id);
26
+ }
27
+ if (minSharePrice < 0n) {
28
+ throw new types_1.NonPositiveMinBorrowSharePriceError(marketParams.id);
29
+ }
30
+ const actions = [];
31
+ let reallocationFee = 0n;
32
+ if (reallocations && reallocations.length > 0) {
33
+ const result = (0, buildReallocationActions_1.buildReallocationActions)(reallocations, marketParams);
34
+ actions.push(...result.actions);
35
+ reallocationFee = result.fee;
36
+ }
37
+ actions.push({
38
+ type: "morphoBorrow",
39
+ args: [marketParams, amount, 0n, minSharePrice, receiver, false],
40
+ });
41
+ let tx = {
42
+ ...bundler_sdk_viem_1.BundlerAction.encodeBundle(chainId, actions),
43
+ value: reallocationFee,
44
+ };
45
+ if (metadata) {
46
+ tx = (0, helpers_1.addTransactionMetadata)(tx, metadata);
47
+ }
48
+ return (0, morpho_ts_1.deepFreeze)({
49
+ ...tx,
50
+ action: {
51
+ type: "marketV1Borrow",
52
+ args: {
53
+ market: marketParams.id,
54
+ amount,
55
+ receiver,
56
+ minSharePrice,
57
+ reallocationFee,
58
+ },
59
+ },
60
+ });
61
+ };
62
+ exports.marketV1Borrow = marketV1Borrow;
@@ -0,0 +1,17 @@
1
+ import type { MarketParams } from "@morpho-org/blue-sdk";
2
+ import type { Action } from "@morpho-org/bundler-sdk-viem";
3
+ import type { VaultReallocation } from "../../types";
4
+ /**
5
+ * Builds reallocation bundler actions and computes the total fee.
6
+ *
7
+ * Validates the reallocations, then encodes each as a `reallocateTo` action.
8
+ * Caller must ensure `reallocations` is non-empty before calling.
9
+ *
10
+ * @param reallocations - The vault reallocations to encode.
11
+ * @param targetMarketParams - The target market params for the borrow.
12
+ * @returns The encoded actions and total reallocation fee.
13
+ */
14
+ export declare const buildReallocationActions: (reallocations: readonly VaultReallocation[], targetMarketParams: MarketParams) => {
15
+ readonly actions: Action[];
16
+ readonly fee: bigint;
17
+ };
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildReallocationActions = void 0;
4
+ const helpers_1 = require("../../helpers");
5
+ /**
6
+ * Builds reallocation bundler actions and computes the total fee.
7
+ *
8
+ * Validates the reallocations, then encodes each as a `reallocateTo` action.
9
+ * Caller must ensure `reallocations` is non-empty before calling.
10
+ *
11
+ * @param reallocations - The vault reallocations to encode.
12
+ * @param targetMarketParams - The target market params for the borrow.
13
+ * @returns The encoded actions and total reallocation fee.
14
+ */
15
+ const buildReallocationActions = (reallocations, targetMarketParams) => {
16
+ (0, helpers_1.validateReallocations)(reallocations, targetMarketParams.id);
17
+ const fee = reallocations.reduce((sum, r) => sum + r.fee, 0n);
18
+ const actions = [];
19
+ for (const r of reallocations) {
20
+ actions.push({
21
+ type: "reallocateTo",
22
+ args: [
23
+ r.vault,
24
+ r.fee,
25
+ r.withdrawals.map((w) => ({
26
+ marketParams: w.marketParams,
27
+ amount: w.amount,
28
+ })),
29
+ targetMarketParams,
30
+ false,
31
+ ],
32
+ });
33
+ }
34
+ return { actions, fee };
35
+ };
36
+ exports.buildReallocationActions = buildReallocationActions;
@@ -0,0 +1,6 @@
1
+ export * from "./borrow";
2
+ export * from "./repay";
3
+ export * from "./repayWithdrawCollateral";
4
+ export * from "./supplyCollateral";
5
+ export * from "./supplyCollateralBorrow";
6
+ export * from "./withdrawCollateral";
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./borrow"), exports);
18
+ __exportStar(require("./repay"), exports);
19
+ __exportStar(require("./repayWithdrawCollateral"), exports);
20
+ __exportStar(require("./supplyCollateral"), exports);
21
+ __exportStar(require("./supplyCollateralBorrow"), exports);
22
+ __exportStar(require("./withdrawCollateral"), exports);
@@ -0,0 +1,44 @@
1
+ import { type MarketParams } from "@morpho-org/blue-sdk";
2
+ import { type Address } from "viem";
3
+ import type { MarketV1RepayAction, Metadata, RequirementSignature, Transaction } from "../../types";
4
+ /** Parameters for {@link marketV1Repay}. */
5
+ export interface MarketV1RepayParams {
6
+ market: {
7
+ readonly chainId: number;
8
+ readonly marketParams: MarketParams;
9
+ };
10
+ args: {
11
+ /** Repay assets amount (0n when repaying by shares). */
12
+ assets: bigint;
13
+ /** Repay shares amount (0n when repaying by assets). */
14
+ shares: bigint;
15
+ /** ERC20 amount to transfer to GeneralAdapter1. Must be greater than or equal to the repay amount to take into account the slippage. */
16
+ transferAmount: bigint;
17
+ /** Address whose debt is being repaid. */
18
+ onBehalf: Address;
19
+ /** Receives residual loan tokens in shares mode. */
20
+ receiver: Address;
21
+ /** Maximum repay share price (in ray). Protects against share price manipulation. */
22
+ maxSharePrice: bigint;
23
+ requirementSignature?: RequirementSignature;
24
+ };
25
+ metadata?: Metadata;
26
+ }
27
+ /**
28
+ * Prepares a repay transaction for a Morpho Blue market.
29
+ *
30
+ * Routed through bundler3 via GeneralAdapter1. Supports two modes:
31
+ * - **By assets** (`assets > 0, shares = 0`): repays an exact asset amount.
32
+ * - **By shares** (`assets = 0, shares > 0`): repays exact shares (full repay).
33
+ *
34
+ * Exactly one of `assets`/`shares` must be non-zero. The `transferAmount` controls
35
+ * how many ERC20 tokens are pulled from the user (may differ from `assets` in
36
+ * shares mode where the entity computes an upper-bound estimate).
37
+ *
38
+ * Uses `maxSharePrice` to protect against share price manipulation between
39
+ * transaction construction and execution.
40
+ *
41
+ * @param params - Repay parameters.
42
+ * @returns Deep-frozen transaction.
43
+ */
44
+ export declare const marketV1Repay: ({ market: { chainId, marketParams }, args: { assets, shares, transferAmount, onBehalf, receiver, maxSharePrice, requirementSignature, }, metadata, }: MarketV1RepayParams) => Readonly<Transaction<MarketV1RepayAction>>;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.marketV1Repay = void 0;
4
+ const blue_sdk_1 = require("@morpho-org/blue-sdk");
5
+ const bundler_sdk_viem_1 = require("@morpho-org/bundler-sdk-viem");
6
+ const morpho_ts_1 = require("@morpho-org/morpho-ts");
7
+ const viem_1 = require("viem");
8
+ const helpers_1 = require("../../helpers");
9
+ const getRequirementsAction_1 = require("../requirements/getRequirementsAction");
10
+ /**
11
+ * Prepares a repay transaction for a Morpho Blue market.
12
+ *
13
+ * Routed through bundler3 via GeneralAdapter1. Supports two modes:
14
+ * - **By assets** (`assets > 0, shares = 0`): repays an exact asset amount.
15
+ * - **By shares** (`assets = 0, shares > 0`): repays exact shares (full repay).
16
+ *
17
+ * Exactly one of `assets`/`shares` must be non-zero. The `transferAmount` controls
18
+ * how many ERC20 tokens are pulled from the user (may differ from `assets` in
19
+ * shares mode where the entity computes an upper-bound estimate).
20
+ *
21
+ * Uses `maxSharePrice` to protect against share price manipulation between
22
+ * transaction construction and execution.
23
+ *
24
+ * @param params - Repay parameters.
25
+ * @returns Deep-frozen transaction.
26
+ */
27
+ const marketV1Repay = ({ market: { chainId, marketParams }, args: { assets, shares, transferAmount, onBehalf, receiver, maxSharePrice, requirementSignature, }, metadata, }) => {
28
+ (0, helpers_1.validateRepayParams)({
29
+ assets,
30
+ shares,
31
+ transferAmount,
32
+ maxSharePrice,
33
+ marketId: marketParams.id,
34
+ });
35
+ const { bundler3: { generalAdapter1 }, } = (0, blue_sdk_1.getChainAddresses)(chainId);
36
+ const actions = [];
37
+ if (requirementSignature) {
38
+ actions.push(...(0, getRequirementsAction_1.getRequirementsAction)({
39
+ chainId,
40
+ asset: marketParams.loanToken,
41
+ amount: transferAmount,
42
+ requirementSignature,
43
+ }));
44
+ }
45
+ else {
46
+ actions.push({
47
+ type: "erc20TransferFrom",
48
+ args: [marketParams.loanToken, transferAmount, generalAdapter1, false],
49
+ });
50
+ }
51
+ actions.push({
52
+ type: "morphoRepay",
53
+ args: [marketParams, assets, shares, maxSharePrice, onBehalf, [], false],
54
+ });
55
+ // Skim residual loan tokens back to the payer when repaying by shares.
56
+ // In shares mode, transferAmount is an upper-bound estimate; morphoRepay
57
+ // consumes only the exact amount needed, leaving a residual in the adapter.
58
+ if (shares > 0n) {
59
+ actions.push({
60
+ type: "erc20Transfer",
61
+ args: [
62
+ marketParams.loanToken,
63
+ receiver,
64
+ viem_1.maxUint256,
65
+ generalAdapter1,
66
+ false,
67
+ ],
68
+ });
69
+ }
70
+ let tx = {
71
+ ...bundler_sdk_viem_1.BundlerAction.encodeBundle(chainId, actions),
72
+ value: 0n,
73
+ };
74
+ if (metadata) {
75
+ tx = (0, helpers_1.addTransactionMetadata)(tx, metadata);
76
+ }
77
+ return (0, morpho_ts_1.deepFreeze)({
78
+ ...tx,
79
+ action: {
80
+ type: "marketV1Repay",
81
+ args: {
82
+ market: marketParams.id,
83
+ assets,
84
+ shares,
85
+ transferAmount,
86
+ onBehalf,
87
+ receiver,
88
+ maxSharePrice,
89
+ },
90
+ },
91
+ });
92
+ };
93
+ exports.marketV1Repay = marketV1Repay;
@@ -0,0 +1,51 @@
1
+ import { type MarketParams } from "@morpho-org/blue-sdk";
2
+ import { type Address } from "viem";
3
+ import { type MarketV1RepayWithdrawCollateralAction, type Metadata, type RequirementSignature, type Transaction } from "../../types";
4
+ /** Parameters for {@link marketV1RepayWithdrawCollateral}. */
5
+ export interface MarketV1RepayWithdrawCollateralParams {
6
+ market: {
7
+ readonly chainId: number;
8
+ readonly marketParams: MarketParams;
9
+ };
10
+ args: {
11
+ /** Repay assets amount (0n when repaying by shares). */
12
+ assets: bigint;
13
+ /** Repay shares amount (0n when repaying by assets). */
14
+ shares: bigint;
15
+ /** ERC20 amount to transfer to GeneralAdapter1 (computed by entity). */
16
+ transferAmount: bigint;
17
+ /** Amount of collateral to withdraw. */
18
+ withdrawAmount: bigint;
19
+ /** Address whose debt is being repaid. */
20
+ onBehalf: Address;
21
+ /** Receives withdrawn collateral and residual loan tokens in shares mode. */
22
+ receiver: Address;
23
+ /** Maximum repay share price (in ray). Protects against share price manipulation. */
24
+ maxSharePrice: bigint;
25
+ requirementSignature?: RequirementSignature;
26
+ };
27
+ metadata?: Metadata;
28
+ }
29
+ /**
30
+ * Prepares an atomic repay-and-withdraw-collateral transaction for a Morpho Blue market.
31
+ *
32
+ * Routed through bundler3. The bundle order is critical:
33
+ * 1. ERC20 transfer (loan token to GeneralAdapter1)
34
+ * 2. `morphoRepay` — reduces debt FIRST
35
+ * 3. `morphoWithdrawCollateral` — then withdraws collateral
36
+ *
37
+ * If the order were reversed, Morpho would revert because the position would be
38
+ * insolvent at the time of the withdraw.
39
+ *
40
+ * Supports two repay modes:
41
+ * - **By assets** (`assets > 0, shares = 0`): repays an exact asset amount.
42
+ * - **By shares** (`assets = 0, shares > 0`): repays exact shares (full repay).
43
+ *
44
+ * **Prerequisites:**
45
+ * - ERC20 approval for loan token to GeneralAdapter1 (for the repay).
46
+ * - GeneralAdapter1 must be authorized on Morpho (for the withdraw).
47
+ *
48
+ * @param params - Combined repay and withdraw collateral parameters.
49
+ * @returns Deep-frozen transaction.
50
+ */
51
+ export declare const marketV1RepayWithdrawCollateral: ({ market: { chainId, marketParams }, args: { assets, shares, transferAmount, withdrawAmount, onBehalf, receiver, maxSharePrice, requirementSignature, }, metadata, }: MarketV1RepayWithdrawCollateralParams) => Readonly<Transaction<MarketV1RepayWithdrawCollateralAction>>;