@morpho-org/consumer-sdk 0.3.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 (82) hide show
  1. package/README.md +301 -41
  2. package/lib/actions/index.d.ts +2 -0
  3. package/lib/actions/index.js +2 -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/getRequirements.js +3 -0
  25. package/lib/actions/requirements/getRequirementsAction.d.ts +2 -2
  26. package/lib/actions/requirements/getRequirementsAction.js +7 -7
  27. package/lib/actions/requirements/index.d.ts +1 -0
  28. package/lib/actions/requirements/index.js +1 -0
  29. package/lib/actions/vaultV1/deposit.d.ts +41 -0
  30. package/lib/actions/vaultV1/deposit.js +116 -0
  31. package/lib/actions/vaultV1/index.d.ts +3 -0
  32. package/lib/actions/vaultV1/index.js +19 -0
  33. package/lib/actions/vaultV1/redeem.d.ts +29 -0
  34. package/lib/actions/vaultV1/redeem.js +48 -0
  35. package/lib/actions/vaultV1/withdraw.d.ts +29 -0
  36. package/lib/actions/vaultV1/withdraw.js +48 -0
  37. package/lib/actions/vaultV2/deposit.d.ts +20 -25
  38. package/lib/actions/vaultV2/deposit.js +78 -40
  39. package/lib/actions/vaultV2/forceRedeem.js +2 -2
  40. package/lib/actions/vaultV2/forceWithdraw.d.ts +2 -2
  41. package/lib/actions/vaultV2/forceWithdraw.js +12 -8
  42. package/lib/actions/vaultV2/redeem.js +2 -2
  43. package/lib/actions/vaultV2/withdraw.d.ts +3 -3
  44. package/lib/actions/vaultV2/withdraw.js +6 -6
  45. package/lib/client/morphoClient.d.ts +4 -1
  46. package/lib/client/morphoClient.js +6 -0
  47. package/lib/client/morphoViemExtension.d.ts +12 -9
  48. package/lib/client/morphoViemExtension.js +12 -9
  49. package/lib/entities/index.d.ts +2 -0
  50. package/lib/entities/index.js +2 -0
  51. package/lib/entities/marketV1/index.d.ts +1 -0
  52. package/lib/entities/marketV1/index.js +17 -0
  53. package/lib/entities/marketV1/marketV1.d.ts +290 -0
  54. package/lib/entities/marketV1/marketV1.js +528 -0
  55. package/lib/entities/vaultV1/index.d.ts +1 -0
  56. package/lib/entities/vaultV1/index.js +17 -0
  57. package/lib/entities/vaultV1/vaultV1.d.ts +95 -0
  58. package/lib/entities/vaultV1/vaultV1.js +129 -0
  59. package/lib/entities/vaultV2/vaultV2.d.ts +24 -21
  60. package/lib/entities/vaultV2/vaultV2.js +43 -16
  61. package/lib/helpers/computeReallocations.d.ts +23 -0
  62. package/lib/helpers/computeReallocations.js +98 -0
  63. package/lib/helpers/constant.d.ts +5 -0
  64. package/lib/helpers/constant.js +6 -1
  65. package/lib/helpers/encodeDeallocation.js +3 -3
  66. package/lib/helpers/index.d.ts +3 -0
  67. package/lib/helpers/index.js +18 -1
  68. package/lib/helpers/slippage.d.ts +46 -0
  69. package/lib/helpers/slippage.js +73 -0
  70. package/lib/helpers/validate.d.ts +150 -0
  71. package/lib/helpers/validate.js +279 -0
  72. package/lib/types/action.d.ts +113 -6
  73. package/lib/types/action.js +12 -1
  74. package/lib/types/client.d.ts +4 -1
  75. package/lib/types/deallocation.d.ts +1 -1
  76. package/lib/types/error.d.ts +127 -4
  77. package/lib/types/error.js +210 -12
  78. package/lib/types/index.d.ts +1 -0
  79. package/lib/types/index.js +1 -0
  80. package/lib/types/sharedLiquidity.d.ts +41 -0
  81. package/lib/types/sharedLiquidity.js +2 -0
  82. package/package.json +1 -1
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MorphoVaultV1 = void 0;
4
+ const blue_sdk_1 = require("@morpho-org/blue-sdk");
5
+ const blue_sdk_viem_1 = require("@morpho-org/blue-sdk-viem");
6
+ const viem_1 = require("viem");
7
+ const actions_1 = require("../../actions");
8
+ const constant_1 = require("../../helpers/constant");
9
+ const types_1 = require("../../types");
10
+ class MorphoVaultV1 {
11
+ client;
12
+ vault;
13
+ chainId;
14
+ constructor(client, vault, chainId) {
15
+ this.client = client;
16
+ this.vault = vault;
17
+ this.chainId = chainId;
18
+ }
19
+ async getData(parameters) {
20
+ if (this.client.viemClient.chain?.id &&
21
+ this.client.viemClient.chain?.id !== this.chainId) {
22
+ throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
23
+ }
24
+ return (0, blue_sdk_viem_1.fetchAccrualVault)(this.vault, this.client.viemClient, {
25
+ ...parameters,
26
+ chainId: this.chainId,
27
+ deployless: this.client.options.supportDeployless,
28
+ });
29
+ }
30
+ deposit({ amount = 0n, userAddress, accrualVault, slippageTolerance = blue_sdk_1.DEFAULT_SLIPPAGE_TOLERANCE, nativeAmount, }) {
31
+ if (this.client.viemClient.chain?.id !== this.chainId) {
32
+ throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
33
+ }
34
+ if (!(0, viem_1.isAddressEqual)(accrualVault.address, this.vault)) {
35
+ throw new types_1.VaultAddressMismatchError(this.vault, accrualVault.address);
36
+ }
37
+ if (amount < 0n) {
38
+ throw new types_1.NonPositiveAssetAmountError(this.vault);
39
+ }
40
+ if (nativeAmount && nativeAmount < 0n) {
41
+ throw new types_1.NegativeNativeAmountError(nativeAmount);
42
+ }
43
+ let wNative;
44
+ if (nativeAmount) {
45
+ ({ wNative } = (0, blue_sdk_1.getChainAddresses)(this.chainId));
46
+ if (!wNative) {
47
+ throw new types_1.ChainWNativeMissingError(this.chainId);
48
+ }
49
+ }
50
+ if (slippageTolerance < 0n) {
51
+ throw new types_1.NegativeSlippageToleranceError(slippageTolerance);
52
+ }
53
+ if (slippageTolerance > constant_1.MAX_SLIPPAGE_TOLERANCE) {
54
+ throw new types_1.ExcessiveSlippageToleranceError(slippageTolerance);
55
+ }
56
+ if (nativeAmount && wNative) {
57
+ if (!(0, viem_1.isAddressEqual)(accrualVault.asset, wNative)) {
58
+ throw new types_1.NativeAmountOnNonWNativeVaultError(accrualVault.asset, wNative);
59
+ }
60
+ }
61
+ const totalAssets = amount + (nativeAmount ?? 0n);
62
+ const shares = accrualVault.toShares(totalAssets);
63
+ if (shares <= 0n) {
64
+ throw new types_1.NonPositiveSharesAmountError(this.vault);
65
+ }
66
+ const maxSharePrice = blue_sdk_1.MathLib.min(blue_sdk_1.MathLib.mulDivUp(totalAssets, blue_sdk_1.MathLib.wToRay(blue_sdk_1.MathLib.WAD + slippageTolerance), shares), blue_sdk_1.MathLib.RAY * 100n);
67
+ return {
68
+ getRequirements: async (params) => await (0, actions_1.getRequirements)(this.client.viemClient, {
69
+ address: accrualVault.asset,
70
+ chainId: this.chainId,
71
+ supportSignature: this.client.options.supportSignature,
72
+ supportDeployless: this.client.options.supportDeployless,
73
+ useSimplePermit: params?.useSimplePermit,
74
+ args: {
75
+ amount,
76
+ from: userAddress,
77
+ },
78
+ }),
79
+ buildTx: (requirementSignature) => (0, actions_1.vaultV1Deposit)({
80
+ vault: {
81
+ chainId: this.chainId,
82
+ address: this.vault,
83
+ asset: accrualVault.asset,
84
+ },
85
+ args: {
86
+ amount,
87
+ maxSharePrice,
88
+ recipient: userAddress,
89
+ requirementSignature,
90
+ nativeAmount,
91
+ },
92
+ metadata: this.client.options.metadata,
93
+ }),
94
+ };
95
+ }
96
+ withdraw({ amount, userAddress }) {
97
+ if (this.client.viemClient.chain?.id !== this.chainId) {
98
+ throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
99
+ }
100
+ return {
101
+ buildTx: () => (0, actions_1.vaultV1Withdraw)({
102
+ vault: { address: this.vault },
103
+ args: {
104
+ amount,
105
+ recipient: userAddress,
106
+ onBehalf: userAddress,
107
+ },
108
+ metadata: this.client.options.metadata,
109
+ }),
110
+ };
111
+ }
112
+ redeem({ shares, userAddress }) {
113
+ if (this.client.viemClient.chain?.id !== this.chainId) {
114
+ throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
115
+ }
116
+ return {
117
+ buildTx: () => (0, actions_1.vaultV1Redeem)({
118
+ vault: { address: this.vault },
119
+ args: {
120
+ shares,
121
+ recipient: userAddress,
122
+ onBehalf: userAddress,
123
+ },
124
+ metadata: this.client.options.metadata,
125
+ }),
126
+ };
127
+ }
128
+ }
129
+ exports.MorphoVaultV1 = MorphoVaultV1;
@@ -1,6 +1,7 @@
1
+ import { type AccrualVaultV2 } from "@morpho-org/blue-sdk";
1
2
  import { fetchAccrualVaultV2 } from "@morpho-org/blue-sdk-viem";
2
- import type { Address } from "viem";
3
- import { type Deallocation, type ERC20ApprovalAction, type MorphoClientType, type Requirement, type RequirementSignature, type Transaction, type VaultV2DepositAction, type VaultV2ForceRedeemAction, type VaultV2ForceWithdrawAction, type VaultV2RedeemAction, type VaultV2WithdrawAction } from "../../types";
3
+ import { type Address } from "viem";
4
+ import { type Deallocation, type DepositAmountArgs, type ERC20ApprovalAction, type MorphoClientType, type Requirement, type RequirementSignature, type Transaction, type VaultV2DepositAction, type VaultV2ForceRedeemAction, type VaultV2ForceWithdrawAction, type VaultV2RedeemAction, type VaultV2WithdrawAction } from "../../types";
4
5
  import type { FetchParameters } from "../../types/data";
5
6
  export interface VaultV2Actions {
6
7
  /**
@@ -16,41 +17,43 @@ export interface VaultV2Actions {
16
17
  * Prepares a deposit transaction for the VaultV2 contract.
17
18
  *
18
19
  * This function constructs the transaction data required to deposit a specified amount of assets into the vault.
19
- * The function asynchronously fetches the latest vault data to ensure accurate calculations for slippage and asset address,
20
+ * Uses pre-fetched accrual vault data for accurate calculations of slippage and asset address,
20
21
  * then returns the prepared deposit transaction and a function for retrieving all required approval transactions.
21
22
  * Bundler Integration: This flow uses the bundler to atomically execute the user's asset transfer and vault deposit in a single transaction for slippage protection.
22
23
  *
23
24
  * @param {Object} params - The deposit parameters.
24
- * @param {bigint} params.assets - The amount of assets to deposit.
25
- * @param {Address} [params.userAddress] - Optional user address initiating the deposit. Default is the client's user address is used.
25
+ * @param {bigint} [params.amount=0n] - Amount of ERC-20 assets to deposit. At least one of amount or nativeAmount must be provided.
26
+ * @param {Address} params.userAddress - User address initiating the deposit.
27
+ * @param {AccrualVaultV2} params.accrualVault - Pre-fetched vault data with asset address and share conversion.
26
28
  * @param {bigint} [params.slippageTolerance=DEFAULT_SLIPPAGE_TOLERANCE] - Optional slippage tolerance value. Default is 0.03%. Slippage tolerance must be less than 10%.
29
+ * @param {bigint} [params.nativeAmount] - Amount of native token to wrap into wNative. Vault asset must be wNative.
27
30
  * @returns {Object} The result object.
28
31
  * @returns {Readonly<Transaction<VaultV2DepositAction>>} returns.tx The prepared deposit transaction.
29
- * @returns {Promise<Readonly<Transaction<ERC20ApprovalAction>[]>>} returns.getRequirements The function for retrieving all required approval transactions.
32
+ * @returns {Promise<(Readonly<Transaction<ERC20ApprovalAction>> | Requirement)[]>} returns.getRequirements The function for retrieving all required approval transactions.
30
33
  */
31
34
  deposit: (params: {
32
- assets: bigint;
33
35
  userAddress: Address;
36
+ accrualVault: AccrualVaultV2;
34
37
  slippageTolerance?: bigint;
35
- }) => Promise<{
38
+ } & DepositAmountArgs) => {
36
39
  buildTx: (requirementSignature?: RequirementSignature) => Readonly<Transaction<VaultV2DepositAction>>;
37
40
  getRequirements: (params?: {
38
41
  useSimplePermit?: boolean;
39
42
  }) => Promise<(Readonly<Transaction<ERC20ApprovalAction>> | Requirement)[]>;
40
- }>;
43
+ };
41
44
  /**
42
45
  * Prepares a withdraw transaction for the VaultV2 contract.
43
46
  *
44
47
  * This function constructs the transaction data required to withdraw a specified amount of assets from the vault.
45
48
  *
46
49
  * @param {Object} params - The withdraw parameters.
47
- * @param {bigint} params.assets - The amount of assets to withdraw.
50
+ * @param {bigint} params.amount - The amount of assets to withdraw.
48
51
  * @param {Address} params.userAddress - User address initiating the withdraw.
49
52
  * @returns {Object} The result object.
50
53
  * @returns {Readonly<Transaction<VaultV2WithdrawAction>>} returns.tx The prepared withdraw transaction.
51
54
  */
52
55
  withdraw: (params: {
53
- assets: bigint;
56
+ amount: bigint;
54
57
  userAddress: Address;
55
58
  }) => {
56
59
  buildTx: () => Readonly<Transaction<VaultV2WithdrawAction>>;
@@ -82,7 +85,7 @@ export interface VaultV2Actions {
82
85
  * @param {Object} params - The force withdraw parameters.
83
86
  * @param {readonly Deallocation[]} params.deallocations - The typed list of deallocations to perform.
84
87
  * @param {Object} params.withdraw - The withdraw parameters applied after deallocations.
85
- * @param {bigint} params.withdraw.assets - The amount of assets to withdraw.
88
+ * @param {bigint} params.withdraw.amount - The amount of assets to withdraw.
86
89
  * @param {Address} params.userAddress - User address (penalty source and withdraw recipient).
87
90
  * @returns {Object} The result object.
88
91
  * @returns {Readonly<Transaction<VaultV2ForceWithdrawAction>>} returns.buildTx The prepared multicall transaction.
@@ -90,7 +93,7 @@ export interface VaultV2Actions {
90
93
  forceWithdraw: (params: {
91
94
  deallocations: readonly Deallocation[];
92
95
  withdraw: {
93
- assets: bigint;
96
+ amount: bigint;
94
97
  };
95
98
  userAddress: Address;
96
99
  }) => {
@@ -133,19 +136,19 @@ export declare class MorphoVaultV2 implements VaultV2Actions {
133
136
  private readonly vault;
134
137
  private readonly chainId;
135
138
  constructor(client: MorphoClientType, vault: Address, chainId: number);
136
- getData(parameters?: FetchParameters): Promise<import("@morpho-org/blue-sdk").AccrualVaultV2>;
137
- deposit({ assets, userAddress, slippageTolerance, }: {
138
- assets: bigint;
139
+ getData(parameters?: FetchParameters): Promise<AccrualVaultV2>;
140
+ deposit({ amount, userAddress, accrualVault, slippageTolerance, nativeAmount, }: {
139
141
  userAddress: Address;
142
+ accrualVault: AccrualVaultV2;
140
143
  slippageTolerance?: bigint;
141
- }): Promise<{
144
+ } & DepositAmountArgs): {
142
145
  getRequirements: (params?: {
143
146
  useSimplePermit?: boolean;
144
147
  }) => Promise<(Requirement | Readonly<Transaction<ERC20ApprovalAction>>)[]>;
145
148
  buildTx: (requirementSignature?: RequirementSignature) => Readonly<Transaction<VaultV2DepositAction>>;
146
- }>;
147
- withdraw({ assets, userAddress }: {
148
- assets: bigint;
149
+ };
150
+ withdraw({ amount, userAddress }: {
151
+ amount: bigint;
149
152
  userAddress: Address;
150
153
  }): {
151
154
  buildTx: () => Readonly<Transaction<VaultV2WithdrawAction>>;
@@ -159,7 +162,7 @@ export declare class MorphoVaultV2 implements VaultV2Actions {
159
162
  forceWithdraw({ deallocations, withdraw, userAddress, }: {
160
163
  deallocations: readonly Deallocation[];
161
164
  withdraw: {
162
- assets: bigint;
165
+ amount: bigint;
163
166
  };
164
167
  userAddress: Address;
165
168
  }): {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MorphoVaultV2 = void 0;
4
4
  const blue_sdk_1 = require("@morpho-org/blue-sdk");
5
5
  const blue_sdk_viem_1 = require("@morpho-org/blue-sdk-viem");
6
+ const viem_1 = require("viem");
6
7
  const actions_1 = require("../../actions");
7
8
  const constant_1 = require("../../helpers/constant");
8
9
  const types_1 = require("../../types");
@@ -16,37 +17,62 @@ class MorphoVaultV2 {
16
17
  this.chainId = chainId;
17
18
  }
18
19
  async getData(parameters) {
20
+ if (this.client.viemClient.chain?.id &&
21
+ this.client.viemClient.chain?.id !== this.chainId) {
22
+ throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
23
+ }
19
24
  return (0, blue_sdk_viem_1.fetchAccrualVaultV2)(this.vault, this.client.viemClient, {
20
25
  ...parameters,
21
26
  chainId: this.chainId,
22
27
  deployless: this.client.options.supportDeployless,
23
28
  });
24
29
  }
25
- async deposit({ assets, userAddress, slippageTolerance = blue_sdk_1.DEFAULT_SLIPPAGE_TOLERANCE, }) {
30
+ deposit({ amount = 0n, userAddress, accrualVault, slippageTolerance = blue_sdk_1.DEFAULT_SLIPPAGE_TOLERANCE, nativeAmount, }) {
26
31
  if (this.client.viemClient.chain?.id !== this.chainId) {
27
32
  throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
28
33
  }
29
- const vaultData = await (0, blue_sdk_viem_1.fetchVaultV2)(this.vault, this.client.viemClient, {
30
- chainId: this.chainId,
31
- deployless: this.client.options.supportDeployless,
32
- });
34
+ if (!(0, viem_1.isAddressEqual)(accrualVault.address, this.vault)) {
35
+ throw new types_1.VaultAddressMismatchError(this.vault, accrualVault.address);
36
+ }
37
+ if (amount < 0n) {
38
+ throw new types_1.NonPositiveAssetAmountError(this.vault);
39
+ }
40
+ if (nativeAmount && nativeAmount < 0n) {
41
+ throw new types_1.NegativeNativeAmountError(nativeAmount);
42
+ }
43
+ let wNative;
44
+ if (nativeAmount) {
45
+ ({ wNative } = (0, blue_sdk_1.getChainAddresses)(this.chainId));
46
+ if (!wNative) {
47
+ throw new types_1.ChainWNativeMissingError(this.chainId);
48
+ }
49
+ }
50
+ if (slippageTolerance < 0n) {
51
+ throw new types_1.NegativeSlippageToleranceError(slippageTolerance);
52
+ }
33
53
  if (slippageTolerance > constant_1.MAX_SLIPPAGE_TOLERANCE) {
34
54
  throw new types_1.ExcessiveSlippageToleranceError(slippageTolerance);
35
55
  }
36
- const shares = vaultData.toShares(assets);
37
- if (shares === 0n) {
38
- throw new types_1.ZeroSharesAmountError(this.vault);
56
+ if (nativeAmount && wNative) {
57
+ if (!(0, viem_1.isAddressEqual)(accrualVault.asset, wNative)) {
58
+ throw new types_1.NativeAmountOnNonWNativeVaultError(accrualVault.asset, wNative);
59
+ }
60
+ }
61
+ const totalAssets = amount + (nativeAmount ?? 0n);
62
+ const shares = accrualVault.toShares(totalAssets);
63
+ if (shares <= 0n) {
64
+ throw new types_1.NonPositiveSharesAmountError(this.vault);
39
65
  }
40
- const maxSharePrice = blue_sdk_1.MathLib.min(blue_sdk_1.MathLib.mulDivUp(assets, blue_sdk_1.MathLib.wToRay(blue_sdk_1.MathLib.WAD + slippageTolerance), shares), blue_sdk_1.MathLib.RAY * 100n);
66
+ const maxSharePrice = blue_sdk_1.MathLib.min(blue_sdk_1.MathLib.mulDivUp(totalAssets, blue_sdk_1.MathLib.wToRay(blue_sdk_1.MathLib.WAD + slippageTolerance), shares), blue_sdk_1.MathLib.RAY * 100n);
41
67
  return {
42
68
  getRequirements: async (params) => await (0, actions_1.getRequirements)(this.client.viemClient, {
43
- address: vaultData.asset,
69
+ address: accrualVault.asset,
44
70
  chainId: this.chainId,
45
71
  supportSignature: this.client.options.supportSignature,
46
72
  supportDeployless: this.client.options.supportDeployless,
47
73
  useSimplePermit: params?.useSimplePermit,
48
74
  args: {
49
- amount: assets,
75
+ amount,
50
76
  from: userAddress,
51
77
  },
52
78
  }),
@@ -54,19 +80,20 @@ class MorphoVaultV2 {
54
80
  vault: {
55
81
  chainId: this.chainId,
56
82
  address: this.vault,
57
- asset: vaultData.asset,
83
+ asset: accrualVault.asset,
58
84
  },
59
85
  args: {
60
- assets,
86
+ amount,
61
87
  maxSharePrice,
62
88
  recipient: userAddress,
63
89
  requirementSignature,
90
+ nativeAmount,
64
91
  },
65
92
  metadata: this.client.options.metadata,
66
93
  }),
67
94
  };
68
95
  }
69
- withdraw({ assets, userAddress }) {
96
+ withdraw({ amount, userAddress }) {
70
97
  if (this.client.viemClient.chain?.id !== this.chainId) {
71
98
  throw new types_1.ChainIdMismatchError(this.client.viemClient.chain?.id, this.chainId);
72
99
  }
@@ -74,7 +101,7 @@ class MorphoVaultV2 {
74
101
  buildTx: () => (0, actions_1.vaultV2Withdraw)({
75
102
  vault: { address: this.vault },
76
103
  args: {
77
- assets,
104
+ amount,
78
105
  recipient: userAddress,
79
106
  onBehalf: userAddress,
80
107
  },
@@ -108,7 +135,7 @@ class MorphoVaultV2 {
108
135
  args: {
109
136
  deallocations,
110
137
  withdraw: {
111
- assets: withdraw.assets,
138
+ amount: withdraw.amount,
112
139
  recipient: userAddress,
113
140
  },
114
141
  onBehalf: userAddress,
@@ -0,0 +1,23 @@
1
+ import { type MarketId } from "@morpho-org/blue-sdk";
2
+ import type { SimulationState } from "@morpho-org/simulation-sdk";
3
+ import { type ReallocationComputeOptions, type VaultReallocation } from "../types";
4
+ /**
5
+ * Computes vault reallocations for a borrow operation on a target market.
6
+ *
7
+ * Replicates the shared liquidity algorithm from `populateSubBundle` in
8
+ * `@morpho-org/bundler-sdk-viem`. First attempts "friendly" reallocations
9
+ * respecting withdrawal utilization targets, then falls back to aggressive
10
+ * reallocations (100% withdrawal utilization) if liquidity is still insufficient.
11
+ *
12
+ * @param params.reallocationData - The simulation state containing market, vault, and position data.
13
+ * @param params.marketId - The target market to reallocate liquidity into.
14
+ * @param params.borrowAmount - The intended borrow amount (used to compute post-borrow utilization).
15
+ * @param params.options - Optional reallocation computation options.
16
+ * @returns Array of vault reallocations, sorted with withdrawals in ascending market id order.
17
+ */
18
+ export declare const computeReallocations: ({ reallocationData: data, marketId, borrowAmount, options, }: {
19
+ readonly reallocationData: SimulationState;
20
+ readonly marketId: MarketId;
21
+ readonly borrowAmount: bigint;
22
+ readonly options?: ReallocationComputeOptions;
23
+ }) => readonly VaultReallocation[];
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeReallocations = 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 types_1 = require("../types");
7
+ /**
8
+ * Computes vault reallocations for a borrow operation on a target market.
9
+ *
10
+ * Replicates the shared liquidity algorithm from `populateSubBundle` in
11
+ * `@morpho-org/bundler-sdk-viem`. First attempts "friendly" reallocations
12
+ * respecting withdrawal utilization targets, then falls back to aggressive
13
+ * reallocations (100% withdrawal utilization) if liquidity is still insufficient.
14
+ *
15
+ * @param params.reallocationData - The simulation state containing market, vault, and position data.
16
+ * @param params.marketId - The target market to reallocate liquidity into.
17
+ * @param params.borrowAmount - The intended borrow amount (used to compute post-borrow utilization).
18
+ * @param params.options - Optional reallocation computation options.
19
+ * @returns Array of vault reallocations, sorted with withdrawals in ascending market id order.
20
+ */
21
+ const computeReallocations = ({ reallocationData: data, marketId, borrowAmount, options, }) => {
22
+ if (options?.enabled === false)
23
+ return [];
24
+ const market = data.getMarket(marketId).accrueInterest(data.block.timestamp);
25
+ const newTotalBorrowAssets = market.totalBorrowAssets + borrowAmount;
26
+ const newTotalSupplyAssets = market.totalSupplyAssets;
27
+ const supplyTargetUtilization = options?.supplyTargetUtilization?.[market.params.id] ??
28
+ options?.defaultSupplyTargetUtilization ??
29
+ bundler_sdk_viem_1.DEFAULT_SUPPLY_TARGET_UTILIZATION;
30
+ if (blue_sdk_1.MarketUtils.getUtilization({
31
+ totalSupplyAssets: newTotalSupplyAssets,
32
+ totalBorrowAssets: newTotalBorrowAssets,
33
+ }) <= supplyTargetUtilization)
34
+ return [];
35
+ // Solve: newTotalBorrowAssets / (newTotalSupplyAssets + reallocatedAssets) = supplyTargetUtilization
36
+ let requiredAssets = supplyTargetUtilization === 0n
37
+ ? blue_sdk_1.MathLib.MAX_UINT_160
38
+ : blue_sdk_1.MathLib.wDivDown(newTotalBorrowAssets, supplyTargetUtilization) -
39
+ newTotalSupplyAssets;
40
+ // Phase 1: "friendly" reallocations respecting withdrawal utilization targets.
41
+ const { withdrawals: friendlyWithdrawals, data: friendlyReallocationData } = data.getMarketPublicReallocations(market.id, options);
42
+ const withdrawals = [...friendlyWithdrawals];
43
+ const friendlyReallocationMarket = friendlyReallocationData.getMarket(market.id);
44
+ if (friendlyReallocationMarket.totalBorrowAssets + borrowAmount >
45
+ friendlyReallocationMarket.totalSupplyAssets) {
46
+ // Phase 2: "aggressive" — fully withdraw from every market (100% utilization).
47
+ requiredAssets = newTotalBorrowAssets - newTotalSupplyAssets;
48
+ withdrawals.push(...friendlyReallocationData.getMarketPublicReallocations(market.id, {
49
+ ...options,
50
+ defaultMaxWithdrawalUtilization: blue_sdk_1.MathLib.WAD,
51
+ maxWithdrawalUtilization: {},
52
+ }).withdrawals);
53
+ }
54
+ if (requiredAssets <= 0n)
55
+ return [];
56
+ // Group withdrawals by vault, capping total at requiredAssets.
57
+ const reallocationsMap = {};
58
+ for (const { vault, ...withdrawal } of withdrawals) {
59
+ const vaultReallocations = (reallocationsMap[vault] ??= []);
60
+ const existing = vaultReallocations.find((item) => item.id === withdrawal.id);
61
+ const reallocatedAssets = blue_sdk_1.MathLib.min(withdrawal.assets, requiredAssets);
62
+ if (reallocatedAssets <= 0n)
63
+ continue;
64
+ if (existing != null) {
65
+ existing.assets += reallocatedAssets;
66
+ }
67
+ else {
68
+ vaultReallocations.push({
69
+ ...withdrawal,
70
+ assets: reallocatedAssets,
71
+ });
72
+ }
73
+ requiredAssets -= reallocatedAssets;
74
+ if (requiredAssets === 0n)
75
+ break;
76
+ }
77
+ // Transform into VaultReallocation[] format.
78
+ return Object.entries(reallocationsMap)
79
+ .filter(([, vaultWithdrawals]) => vaultWithdrawals.length > 0)
80
+ .map(([vault, vaultWithdrawals]) => ({
81
+ vault: vault,
82
+ fee: (() => {
83
+ const config = data.getVault(vault).publicAllocatorConfig;
84
+ if (config == null) {
85
+ throw new types_1.MissingPublicAllocatorConfigError(vault);
86
+ }
87
+ return config.fee;
88
+ })(),
89
+ withdrawals: vaultWithdrawals
90
+ // Reallocation withdrawals must be sorted by market id in ascending order.
91
+ .sort(({ id: idA }, { id: idB }) => idA > idB ? 1 : idA < idB ? -1 : 0)
92
+ .map(({ id, assets }) => ({
93
+ marketParams: data.getMarket(id).params,
94
+ amount: assets,
95
+ })),
96
+ }));
97
+ };
98
+ exports.computeReallocations = computeReallocations;
@@ -1 +1,6 @@
1
+ /** Maximum slippage tolerance: 10% */
1
2
  export declare const MAX_SLIPPAGE_TOLERANCE: bigint;
3
+ /** Default LLTV buffer: 0.5% below LLTV. Prevents instant liquidation on new positions. */
4
+ export declare const DEFAULT_LLTV_BUFFER: bigint;
5
+ /** Maximum absolute share price cap (100 RAY). Prevents absurd maxSharePrice values in repay. */
6
+ export declare const MAX_ABSOLUTE_SHARE_PRICE: bigint;
@@ -1,5 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MAX_SLIPPAGE_TOLERANCE = void 0;
3
+ exports.MAX_ABSOLUTE_SHARE_PRICE = exports.DEFAULT_LLTV_BUFFER = exports.MAX_SLIPPAGE_TOLERANCE = void 0;
4
4
  const blue_sdk_1 = require("@morpho-org/blue-sdk");
5
+ /** Maximum slippage tolerance: 10% */
5
6
  exports.MAX_SLIPPAGE_TOLERANCE = blue_sdk_1.MathLib.WAD / 10n;
7
+ /** Default LLTV buffer: 0.5% below LLTV. Prevents instant liquidation on new positions. */
8
+ exports.DEFAULT_LLTV_BUFFER = blue_sdk_1.MathLib.WAD / 200n;
9
+ /** Maximum absolute share price cap (100 RAY). Prevents absurd maxSharePrice values in repay. */
10
+ exports.MAX_ABSOLUTE_SHARE_PRICE = 100n * blue_sdk_1.MathLib.RAY;
@@ -25,13 +25,13 @@ function encodeDeallocateData(deallocation) {
25
25
  * @returns The ABI-encoded calldata for `VaultV2.forceDeallocate`.
26
26
  */
27
27
  function encodeForceDeallocateCall(deallocation, onBehalf) {
28
- if (deallocation.assets === 0n) {
29
- throw new types_1.ZeroAssetAmountError(deallocation.adapter);
28
+ if (deallocation.amount <= 0n) {
29
+ throw new types_1.NonPositiveAssetAmountError(deallocation.adapter);
30
30
  }
31
31
  const data = encodeDeallocateData(deallocation);
32
32
  return (0, viem_1.encodeFunctionData)({
33
33
  abi: blue_sdk_viem_1.vaultV2Abi,
34
34
  functionName: "forceDeallocate",
35
- args: [deallocation.adapter, data, deallocation.assets, onBehalf],
35
+ args: [deallocation.adapter, data, deallocation.amount, onBehalf],
36
36
  });
37
37
  }
@@ -1 +1,4 @@
1
+ export { computeReallocations } from "./computeReallocations";
1
2
  export { addTransactionMetadata } from "./metadata";
3
+ export { computeMaxRepaySharePrice, computeMinBorrowSharePrice, } from "./slippage";
4
+ export { validateAccrualPosition, validateChainId, validateNativeCollateral, validatePositionHealth, validatePositionHealthAfterWithdraw, validateReallocations, validateRepayAmount, validateRepayParams, validateRepayShares, validateSlippageTolerance, validateUserAddress, } from "./validate";
@@ -1,5 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.addTransactionMetadata = void 0;
3
+ exports.validateUserAddress = exports.validateSlippageTolerance = exports.validateRepayShares = exports.validateRepayParams = exports.validateRepayAmount = exports.validateReallocations = exports.validatePositionHealthAfterWithdraw = exports.validatePositionHealth = exports.validateNativeCollateral = exports.validateChainId = exports.validateAccrualPosition = exports.computeMinBorrowSharePrice = exports.computeMaxRepaySharePrice = exports.addTransactionMetadata = exports.computeReallocations = void 0;
4
+ var computeReallocations_1 = require("./computeReallocations");
5
+ Object.defineProperty(exports, "computeReallocations", { enumerable: true, get: function () { return computeReallocations_1.computeReallocations; } });
4
6
  var metadata_1 = require("./metadata");
5
7
  Object.defineProperty(exports, "addTransactionMetadata", { enumerable: true, get: function () { return metadata_1.addTransactionMetadata; } });
8
+ var slippage_1 = require("./slippage");
9
+ Object.defineProperty(exports, "computeMaxRepaySharePrice", { enumerable: true, get: function () { return slippage_1.computeMaxRepaySharePrice; } });
10
+ Object.defineProperty(exports, "computeMinBorrowSharePrice", { enumerable: true, get: function () { return slippage_1.computeMinBorrowSharePrice; } });
11
+ var validate_1 = require("./validate");
12
+ Object.defineProperty(exports, "validateAccrualPosition", { enumerable: true, get: function () { return validate_1.validateAccrualPosition; } });
13
+ Object.defineProperty(exports, "validateChainId", { enumerable: true, get: function () { return validate_1.validateChainId; } });
14
+ Object.defineProperty(exports, "validateNativeCollateral", { enumerable: true, get: function () { return validate_1.validateNativeCollateral; } });
15
+ Object.defineProperty(exports, "validatePositionHealth", { enumerable: true, get: function () { return validate_1.validatePositionHealth; } });
16
+ Object.defineProperty(exports, "validatePositionHealthAfterWithdraw", { enumerable: true, get: function () { return validate_1.validatePositionHealthAfterWithdraw; } });
17
+ Object.defineProperty(exports, "validateReallocations", { enumerable: true, get: function () { return validate_1.validateReallocations; } });
18
+ Object.defineProperty(exports, "validateRepayAmount", { enumerable: true, get: function () { return validate_1.validateRepayAmount; } });
19
+ Object.defineProperty(exports, "validateRepayParams", { enumerable: true, get: function () { return validate_1.validateRepayParams; } });
20
+ Object.defineProperty(exports, "validateRepayShares", { enumerable: true, get: function () { return validate_1.validateRepayShares; } });
21
+ Object.defineProperty(exports, "validateSlippageTolerance", { enumerable: true, get: function () { return validate_1.validateSlippageTolerance; } });
22
+ Object.defineProperty(exports, "validateUserAddress", { enumerable: true, get: function () { return validate_1.validateUserAddress; } });
@@ -0,0 +1,46 @@
1
+ import { type Market } from "@morpho-org/blue-sdk";
2
+ /**
3
+ * Computes the minimum borrow share price (in RAY, 1e27) for slippage protection.
4
+ *
5
+ * Mirrors the on-chain check in GeneralAdapter1's `morphoBorrow`:
6
+ * ```solidity
7
+ * require(borrowedAssets.rDivDown(borrowedShares) >= minSharePriceE27)
8
+ * ```
9
+ *
10
+ * @param params - Computation parameters.
11
+ * @param params.borrowAmount - The amount of assets to borrow.
12
+ * @param params.market - The market to compute the minimum borrow share price for.
13
+ * @param params.slippageTolerance - Slippage tolerance in WAD (e.g. 0.003e18 = 0.3%).
14
+ * @returns minSharePriceE27 in RAY scale (1e27).
15
+ */
16
+ export declare function computeMinBorrowSharePrice(params: {
17
+ borrowAmount: bigint;
18
+ market: Market;
19
+ slippageTolerance: bigint;
20
+ }): bigint;
21
+ /**
22
+ * Computes the maximum repay share price (in RAY, 1e27) for slippage protection.
23
+ *
24
+ * Supports both repay-by-assets and repay-by-shares paths:
25
+ * - By assets: derives expected shares from the repay amount via `toBorrowShares("Down")`.
26
+ * - By shares: derives expected assets from the shares via `toBorrowAssets("Up")`.
27
+ *
28
+ * Direction is opposite of borrow's `minSharePrice`:
29
+ * - Borrow uses `(WAD - slippage)` → lower bound (protects borrower from getting fewer assets per share).
30
+ * - Repay uses `(WAD + slippage)` → upper bound (protects repayer from paying too many assets per share).
31
+ *
32
+ * Capped at {@link MAX_ABSOLUTE_SHARE_PRICE} to prevent absurd values.
33
+ *
34
+ * @param params - Computation parameters.
35
+ * @param params.repayAssets - The amount of assets to repay (0n when repaying by shares).
36
+ * @param params.repayShares - The amount of shares to repay (0n when repaying by assets).
37
+ * @param params.market - The market to compute the maximum repay share price for.
38
+ * @param params.slippageTolerance - Slippage tolerance in WAD (e.g. 0.003e18 = 0.3%).
39
+ * @returns maxSharePriceE27 in RAY scale (1e27).
40
+ */
41
+ export declare function computeMaxRepaySharePrice(params: {
42
+ repayAssets: bigint;
43
+ repayShares: bigint;
44
+ market: Market;
45
+ slippageTolerance: bigint;
46
+ }): bigint;