@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.
- package/README.md +136 -10
- package/lib/actions/index.d.ts +1 -0
- package/lib/actions/index.js +1 -0
- package/lib/actions/marketV1/borrow.d.ts +34 -0
- package/lib/actions/marketV1/borrow.js +62 -0
- package/lib/actions/marketV1/buildReallocationActions.d.ts +17 -0
- package/lib/actions/marketV1/buildReallocationActions.js +36 -0
- package/lib/actions/marketV1/index.d.ts +6 -0
- package/lib/actions/marketV1/index.js +22 -0
- package/lib/actions/marketV1/repay.d.ts +44 -0
- package/lib/actions/marketV1/repay.js +93 -0
- package/lib/actions/marketV1/repayWithdrawCollateral.d.ts +51 -0
- package/lib/actions/marketV1/repayWithdrawCollateral.js +108 -0
- package/lib/actions/marketV1/supplyCollateral.d.ts +28 -0
- package/lib/actions/marketV1/supplyCollateral.js +85 -0
- package/lib/actions/marketV1/supplyCollateralBorrow.d.ts +37 -0
- package/lib/actions/marketV1/supplyCollateralBorrow.js +109 -0
- package/lib/actions/marketV1/withdrawCollateral.d.ts +28 -0
- package/lib/actions/marketV1/withdrawCollateral.js +51 -0
- package/lib/actions/requirements/encode/encodeErc20Permit.js +4 -1
- package/lib/actions/requirements/encode/encodeErc20Permit2.js +4 -1
- package/lib/actions/requirements/getMorphoAuthorizationRequirement.d.ts +21 -0
- package/lib/actions/requirements/getMorphoAuthorizationRequirement.js +55 -0
- package/lib/actions/requirements/index.d.ts +1 -0
- package/lib/actions/requirements/index.js +1 -0
- package/lib/actions/vaultV2/forceWithdraw.js +5 -1
- package/lib/client/morphoClient.d.ts +3 -1
- package/lib/client/morphoClient.js +3 -0
- package/lib/entities/index.d.ts +1 -0
- package/lib/entities/index.js +1 -0
- package/lib/entities/marketV1/index.d.ts +1 -0
- package/lib/entities/marketV1/index.js +17 -0
- package/lib/entities/marketV1/marketV1.d.ts +290 -0
- package/lib/entities/marketV1/marketV1.js +528 -0
- package/lib/entities/vaultV1/vaultV1.js +4 -0
- package/lib/entities/vaultV2/vaultV2.js +4 -0
- package/lib/helpers/computeReallocations.d.ts +23 -0
- package/lib/helpers/computeReallocations.js +98 -0
- package/lib/helpers/constant.d.ts +5 -0
- package/lib/helpers/constant.js +6 -1
- package/lib/helpers/index.d.ts +3 -0
- package/lib/helpers/index.js +18 -1
- package/lib/helpers/slippage.d.ts +46 -0
- package/lib/helpers/slippage.js +73 -0
- package/lib/helpers/validate.d.ts +150 -0
- package/lib/helpers/validate.js +279 -0
- package/lib/types/action.d.ts +75 -3
- package/lib/types/action.js +12 -1
- package/lib/types/client.d.ts +3 -1
- package/lib/types/error.d.ts +106 -1
- package/lib/types/error.js +165 -3
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +1 -0
- package/lib/types/sharedLiquidity.d.ts +41 -0
- package/lib/types/sharedLiquidity.js +2 -0
- package/package.json +1 -1
package/lib/helpers/constant.js
CHANGED
|
@@ -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;
|
package/lib/helpers/index.d.ts
CHANGED
|
@@ -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";
|
package/lib/helpers/index.js
CHANGED
|
@@ -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;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computeMinBorrowSharePrice = computeMinBorrowSharePrice;
|
|
4
|
+
exports.computeMaxRepaySharePrice = computeMaxRepaySharePrice;
|
|
5
|
+
const blue_sdk_1 = require("@morpho-org/blue-sdk");
|
|
6
|
+
const types_1 = require("../types");
|
|
7
|
+
const constant_1 = require("./constant");
|
|
8
|
+
/**
|
|
9
|
+
* Computes the minimum borrow share price (in RAY, 1e27) for slippage protection.
|
|
10
|
+
*
|
|
11
|
+
* Mirrors the on-chain check in GeneralAdapter1's `morphoBorrow`:
|
|
12
|
+
* ```solidity
|
|
13
|
+
* require(borrowedAssets.rDivDown(borrowedShares) >= minSharePriceE27)
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @param params - Computation parameters.
|
|
17
|
+
* @param params.borrowAmount - The amount of assets to borrow.
|
|
18
|
+
* @param params.market - The market to compute the minimum borrow share price for.
|
|
19
|
+
* @param params.slippageTolerance - Slippage tolerance in WAD (e.g. 0.003e18 = 0.3%).
|
|
20
|
+
* @returns minSharePriceE27 in RAY scale (1e27).
|
|
21
|
+
*/
|
|
22
|
+
function computeMinBorrowSharePrice(params) {
|
|
23
|
+
const { borrowAmount, market, slippageTolerance } = params;
|
|
24
|
+
if (slippageTolerance >= blue_sdk_1.MathLib.WAD) {
|
|
25
|
+
throw new types_1.ExcessiveSlippageToleranceError(slippageTolerance);
|
|
26
|
+
}
|
|
27
|
+
const expectedShares = market.toBorrowShares(borrowAmount, "Up");
|
|
28
|
+
if (expectedShares === 0n) {
|
|
29
|
+
throw new types_1.ShareDivideByZeroError(market.params.id);
|
|
30
|
+
}
|
|
31
|
+
return blue_sdk_1.MathLib.mulDivDown(borrowAmount, blue_sdk_1.MathLib.wToRay(blue_sdk_1.MathLib.WAD - slippageTolerance), expectedShares);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Computes the maximum repay share price (in RAY, 1e27) for slippage protection.
|
|
35
|
+
*
|
|
36
|
+
* Supports both repay-by-assets and repay-by-shares paths:
|
|
37
|
+
* - By assets: derives expected shares from the repay amount via `toBorrowShares("Down")`.
|
|
38
|
+
* - By shares: derives expected assets from the shares via `toBorrowAssets("Up")`.
|
|
39
|
+
*
|
|
40
|
+
* Direction is opposite of borrow's `minSharePrice`:
|
|
41
|
+
* - Borrow uses `(WAD - slippage)` → lower bound (protects borrower from getting fewer assets per share).
|
|
42
|
+
* - Repay uses `(WAD + slippage)` → upper bound (protects repayer from paying too many assets per share).
|
|
43
|
+
*
|
|
44
|
+
* Capped at {@link MAX_ABSOLUTE_SHARE_PRICE} to prevent absurd values.
|
|
45
|
+
*
|
|
46
|
+
* @param params - Computation parameters.
|
|
47
|
+
* @param params.repayAssets - The amount of assets to repay (0n when repaying by shares).
|
|
48
|
+
* @param params.repayShares - The amount of shares to repay (0n when repaying by assets).
|
|
49
|
+
* @param params.market - The market to compute the maximum repay share price for.
|
|
50
|
+
* @param params.slippageTolerance - Slippage tolerance in WAD (e.g. 0.003e18 = 0.3%).
|
|
51
|
+
* @returns maxSharePriceE27 in RAY scale (1e27).
|
|
52
|
+
*/
|
|
53
|
+
function computeMaxRepaySharePrice(params) {
|
|
54
|
+
const { repayAssets, repayShares, market, slippageTolerance } = params;
|
|
55
|
+
if (slippageTolerance >= blue_sdk_1.MathLib.WAD) {
|
|
56
|
+
throw new types_1.ExcessiveSlippageToleranceError(slippageTolerance);
|
|
57
|
+
}
|
|
58
|
+
let assets;
|
|
59
|
+
let shares;
|
|
60
|
+
if (repayShares > 0n) {
|
|
61
|
+
assets = market.toBorrowAssets(repayShares, "Up");
|
|
62
|
+
shares = repayShares;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
assets = repayAssets;
|
|
66
|
+
shares = market.toBorrowShares(repayAssets, "Down");
|
|
67
|
+
}
|
|
68
|
+
if (shares === 0n) {
|
|
69
|
+
throw new types_1.ShareDivideByZeroError(market.params.id);
|
|
70
|
+
}
|
|
71
|
+
const maxSharePrice = blue_sdk_1.MathLib.mulDivUp(assets, blue_sdk_1.MathLib.wToRay(blue_sdk_1.MathLib.WAD + slippageTolerance), shares);
|
|
72
|
+
return blue_sdk_1.MathLib.min(maxSharePrice, constant_1.MAX_ABSOLUTE_SHARE_PRICE);
|
|
73
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { type AccrualPosition, type MarketId } from "@morpho-org/blue-sdk";
|
|
2
|
+
import { type Address } from "viem";
|
|
3
|
+
import { type VaultReallocation } from "../types";
|
|
4
|
+
/**
|
|
5
|
+
* Validates that the provided user address matches the client's connected account.
|
|
6
|
+
* Only enforced when the client has an account — skips validation for public clients
|
|
7
|
+
* (e.g., when building transactions to be signed externally).
|
|
8
|
+
*
|
|
9
|
+
* Throws {@link AddressMismatchError} if the client account is present
|
|
10
|
+
* and does not match `userAddress`.
|
|
11
|
+
*
|
|
12
|
+
* @param clientAccountAddress - The client's account address (may be undefined).
|
|
13
|
+
* @param userAddress - The user address provided by the caller.
|
|
14
|
+
*/
|
|
15
|
+
export declare const validateUserAddress: (clientAccountAddress: Address | undefined, userAddress: Address) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Validates that the accrual position belongs to the expected market and user.
|
|
18
|
+
* Throws {@link MarketIdMismatchError} if the position's market ID
|
|
19
|
+
* does not match the expected market.
|
|
20
|
+
* Throws {@link AccrualPositionUserMismatchError} if the position's user
|
|
21
|
+
* does not match the expected user.
|
|
22
|
+
*
|
|
23
|
+
* @param params - Validation parameters.
|
|
24
|
+
* @param params.positionData - The accrual position to validate.
|
|
25
|
+
* @param params.expectedMarketId - The market ID the position must belong to.
|
|
26
|
+
* @param params.expectedUser - The user address the position must belong to.
|
|
27
|
+
*/
|
|
28
|
+
export declare const validateAccrualPosition: (params: {
|
|
29
|
+
positionData: AccrualPosition;
|
|
30
|
+
expectedMarketId: MarketId;
|
|
31
|
+
expectedUser: Address;
|
|
32
|
+
}) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Validates that the resulting position stays within the safe LTV threshold
|
|
35
|
+
* (LLTV minus buffer) after supplying additional collateral and borrowing.
|
|
36
|
+
*
|
|
37
|
+
* @param params - Validation parameters.
|
|
38
|
+
* @param params.positionData - The current accrual position with market data.
|
|
39
|
+
* @param params.additionalCollateral - Amount of collateral being added.
|
|
40
|
+
* @param params.borrowAmount - Amount being borrowed.
|
|
41
|
+
* @param params.marketId - The market identifier (for error messages).
|
|
42
|
+
* @param params.lltv - The market's liquidation LTV.
|
|
43
|
+
*/
|
|
44
|
+
export declare const validatePositionHealth: (params: {
|
|
45
|
+
positionData: AccrualPosition;
|
|
46
|
+
additionalCollateral: bigint;
|
|
47
|
+
borrowAmount: bigint;
|
|
48
|
+
marketId: MarketId;
|
|
49
|
+
lltv: bigint;
|
|
50
|
+
}) => void;
|
|
51
|
+
/**
|
|
52
|
+
* Validates that the viem client chain ID matches the expected chain ID.
|
|
53
|
+
* Throws {@link ChainIdMismatchError} if they differ.
|
|
54
|
+
*
|
|
55
|
+
* @param clientChainId - Chain ID reported by the viem client (may be undefined).
|
|
56
|
+
* @param expectedChainId - Chain ID expected by the entity or action.
|
|
57
|
+
*/
|
|
58
|
+
export declare const validateChainId: (clientChainId: number | undefined, expectedChainId: number) => void;
|
|
59
|
+
/**
|
|
60
|
+
* Validates that the given collateral token is the chain's wrapped native token.
|
|
61
|
+
* Throws {@link ChainWNativeMissingError} if wNative is not configured for the chain.
|
|
62
|
+
* Throws {@link NativeAmountOnNonWNativeCollateralError} if collateral is not wNative.
|
|
63
|
+
*
|
|
64
|
+
* @param chainId - The chain to look up wNative on.
|
|
65
|
+
* @param collateralToken - The market's collateral token address.
|
|
66
|
+
*/
|
|
67
|
+
export declare const validateNativeCollateral: (chainId: number, collateralToken: Address) => void;
|
|
68
|
+
/**
|
|
69
|
+
* Validates that the resulting position stays within the safe LTV threshold
|
|
70
|
+
* (LLTV minus buffer) after withdrawing collateral.
|
|
71
|
+
*
|
|
72
|
+
* @param params - Validation parameters.
|
|
73
|
+
* @param params.positionData - The current accrual position with market data.
|
|
74
|
+
* @param params.withdrawAmount - Amount of collateral being withdrawn.
|
|
75
|
+
* @param params.lltv - The market's liquidation LTV.
|
|
76
|
+
* @param params.marketId - The market identifier (for error messages).
|
|
77
|
+
*/
|
|
78
|
+
export declare const validatePositionHealthAfterWithdraw: (params: {
|
|
79
|
+
positionData: AccrualPosition;
|
|
80
|
+
withdrawAmount: bigint;
|
|
81
|
+
lltv: bigint;
|
|
82
|
+
marketId: MarketId;
|
|
83
|
+
}) => void;
|
|
84
|
+
/**
|
|
85
|
+
* Validates that the repay amount assets does not exceed the outstanding debt.
|
|
86
|
+
*
|
|
87
|
+
* @param params - Validation parameters.
|
|
88
|
+
* @param params.positionData - The current accrual position.
|
|
89
|
+
* @param params.repayAssets - The amount of assets to repay.
|
|
90
|
+
* @param params.marketId - The market identifier (for error messages).
|
|
91
|
+
*/
|
|
92
|
+
export declare const validateRepayAmount: (params: {
|
|
93
|
+
positionData: AccrualPosition;
|
|
94
|
+
repayAssets: bigint;
|
|
95
|
+
marketId: MarketId;
|
|
96
|
+
}) => void;
|
|
97
|
+
/**
|
|
98
|
+
* Validates that the repay shares do not exceed the outstanding borrow shares.
|
|
99
|
+
*
|
|
100
|
+
* @param params - Validation parameters.
|
|
101
|
+
* @param params.positionData - The current accrual position.
|
|
102
|
+
* @param params.repayShares - The amount of shares to repay.
|
|
103
|
+
* @param params.marketId - The market identifier (for error messages).
|
|
104
|
+
*/
|
|
105
|
+
export declare const validateRepayShares: (params: {
|
|
106
|
+
positionData: AccrualPosition;
|
|
107
|
+
repayShares: bigint;
|
|
108
|
+
marketId: MarketId;
|
|
109
|
+
}) => void;
|
|
110
|
+
/**
|
|
111
|
+
* Validates the common repay input parameters shared by `marketV1Repay`
|
|
112
|
+
* and `marketV1RepayWithdrawCollateral`.
|
|
113
|
+
*
|
|
114
|
+
* @param params - Validation parameters.
|
|
115
|
+
* @param params.assets - Repay assets amount (0n when repaying by shares).
|
|
116
|
+
* @param params.shares - Repay shares amount (0n when repaying by assets).
|
|
117
|
+
* @param params.transferAmount - ERC20 amount to transfer to GeneralAdapter1.
|
|
118
|
+
* @param params.maxSharePrice - Maximum repay share price (in ray). Must be positive.
|
|
119
|
+
* @param params.marketId - The market identifier (for error messages).
|
|
120
|
+
*/
|
|
121
|
+
export declare const validateRepayParams: (params: {
|
|
122
|
+
assets: bigint;
|
|
123
|
+
shares: bigint;
|
|
124
|
+
transferAmount: bigint;
|
|
125
|
+
maxSharePrice: bigint;
|
|
126
|
+
marketId: MarketId;
|
|
127
|
+
}) => void;
|
|
128
|
+
/**
|
|
129
|
+
* Validates that vault reallocations are well-formed.
|
|
130
|
+
*
|
|
131
|
+
* Enforces the following invariants for each {@link VaultReallocation}:
|
|
132
|
+
* - `fee` must be non-negative.
|
|
133
|
+
* - `withdrawals` must be non-empty.
|
|
134
|
+
* - Every withdrawal `amount` must be strictly positive.
|
|
135
|
+
* - No withdrawal may target `targetMarketId` (the borrow market).
|
|
136
|
+
* - Withdrawal market IDs must be strictly ascending (required by `PublicAllocator.reallocateTo`).
|
|
137
|
+
*
|
|
138
|
+
* @param reallocations - The reallocations to validate.
|
|
139
|
+
* @param targetMarketId - The ID of the market being borrowed from. No withdrawal may reference this market.
|
|
140
|
+
*/
|
|
141
|
+
export declare const validateReallocations: (reallocations: readonly VaultReallocation[], targetMarketId: MarketId) => void;
|
|
142
|
+
/**
|
|
143
|
+
* Validates that a slippage tolerance is within an acceptable range.
|
|
144
|
+
*
|
|
145
|
+
* Throws {@link NegativeSlippageToleranceError} if negative.
|
|
146
|
+
* Throws {@link ExcessiveSlippageToleranceError} if greater than {@link MAX_SLIPPAGE_TOLERANCE}.
|
|
147
|
+
*
|
|
148
|
+
* @param slippageTolerance - The slippage tolerance in WAD.
|
|
149
|
+
*/
|
|
150
|
+
export declare const validateSlippageTolerance: (slippageTolerance: bigint) => void;
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateSlippageTolerance = exports.validateReallocations = exports.validateRepayParams = exports.validateRepayShares = exports.validateRepayAmount = exports.validatePositionHealthAfterWithdraw = exports.validateNativeCollateral = exports.validateChainId = exports.validatePositionHealth = exports.validateAccrualPosition = exports.validateUserAddress = void 0;
|
|
4
|
+
const blue_sdk_1 = require("@morpho-org/blue-sdk");
|
|
5
|
+
const morpho_ts_1 = require("@morpho-org/morpho-ts");
|
|
6
|
+
const viem_1 = require("viem");
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
const constant_1 = require("./constant");
|
|
9
|
+
/**
|
|
10
|
+
* Validates that the provided user address matches the client's connected account.
|
|
11
|
+
* Only enforced when the client has an account — skips validation for public clients
|
|
12
|
+
* (e.g., when building transactions to be signed externally).
|
|
13
|
+
*
|
|
14
|
+
* Throws {@link AddressMismatchError} if the client account is present
|
|
15
|
+
* and does not match `userAddress`.
|
|
16
|
+
*
|
|
17
|
+
* @param clientAccountAddress - The client's account address (may be undefined).
|
|
18
|
+
* @param userAddress - The user address provided by the caller.
|
|
19
|
+
*/
|
|
20
|
+
const validateUserAddress = (clientAccountAddress, userAddress) => {
|
|
21
|
+
if (clientAccountAddress !== undefined &&
|
|
22
|
+
!(0, viem_1.isAddressEqual)(clientAccountAddress, userAddress)) {
|
|
23
|
+
throw new types_1.AddressMismatchError(clientAccountAddress, userAddress);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
exports.validateUserAddress = validateUserAddress;
|
|
27
|
+
/**
|
|
28
|
+
* Validates that the accrual position belongs to the expected market and user.
|
|
29
|
+
* Throws {@link MarketIdMismatchError} if the position's market ID
|
|
30
|
+
* does not match the expected market.
|
|
31
|
+
* Throws {@link AccrualPositionUserMismatchError} if the position's user
|
|
32
|
+
* does not match the expected user.
|
|
33
|
+
*
|
|
34
|
+
* @param params - Validation parameters.
|
|
35
|
+
* @param params.positionData - The accrual position to validate.
|
|
36
|
+
* @param params.expectedMarketId - The market ID the position must belong to.
|
|
37
|
+
* @param params.expectedUser - The user address the position must belong to.
|
|
38
|
+
*/
|
|
39
|
+
const validateAccrualPosition = (params) => {
|
|
40
|
+
const { positionData, expectedMarketId, expectedUser } = params;
|
|
41
|
+
if (positionData.marketId !== expectedMarketId) {
|
|
42
|
+
throw new types_1.MarketIdMismatchError(positionData.marketId, expectedMarketId);
|
|
43
|
+
}
|
|
44
|
+
if (!(0, viem_1.isAddressEqual)(positionData.user, expectedUser)) {
|
|
45
|
+
throw new types_1.AccrualPositionUserMismatchError(positionData.user, expectedUser);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.validateAccrualPosition = validateAccrualPosition;
|
|
49
|
+
/**
|
|
50
|
+
* Validates that the resulting position stays within the safe LTV threshold
|
|
51
|
+
* (LLTV minus buffer) after supplying additional collateral and borrowing.
|
|
52
|
+
*
|
|
53
|
+
* @param params - Validation parameters.
|
|
54
|
+
* @param params.positionData - The current accrual position with market data.
|
|
55
|
+
* @param params.additionalCollateral - Amount of collateral being added.
|
|
56
|
+
* @param params.borrowAmount - Amount being borrowed.
|
|
57
|
+
* @param params.marketId - The market identifier (for error messages).
|
|
58
|
+
* @param params.lltv - The market's liquidation LTV.
|
|
59
|
+
*/
|
|
60
|
+
const validatePositionHealth = (params) => {
|
|
61
|
+
const { positionData, additionalCollateral, borrowAmount, marketId, lltv } = params;
|
|
62
|
+
const { price } = positionData.market;
|
|
63
|
+
if (!price) {
|
|
64
|
+
throw new types_1.MissingMarketPriceError(marketId);
|
|
65
|
+
}
|
|
66
|
+
const totalCollateralAfter = positionData.collateral + additionalCollateral;
|
|
67
|
+
const collateralValueAfter = blue_sdk_1.MathLib.mulDivDown(totalCollateralAfter, price, blue_sdk_1.ORACLE_PRICE_SCALE);
|
|
68
|
+
const effectiveLltv = lltv > constant_1.DEFAULT_LLTV_BUFFER ? lltv - constant_1.DEFAULT_LLTV_BUFFER : 0n;
|
|
69
|
+
const maxSafeBorrowAfter = blue_sdk_1.MathLib.wMulDown(collateralValueAfter, effectiveLltv);
|
|
70
|
+
const totalBorrowAfter = positionData.borrowAssets + borrowAmount + 1n; // +1 to account for share-to-asset rounding (happens when the borrow amount doesn't divide evenly into shares)
|
|
71
|
+
if (totalBorrowAfter > maxSafeBorrowAfter) {
|
|
72
|
+
const maxSafeAdditionalBorrow = blue_sdk_1.MathLib.zeroFloorSub(maxSafeBorrowAfter, positionData.borrowAssets);
|
|
73
|
+
throw new types_1.BorrowExceedsSafeLtvError(borrowAmount, maxSafeAdditionalBorrow);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
exports.validatePositionHealth = validatePositionHealth;
|
|
77
|
+
/**
|
|
78
|
+
* Validates that the viem client chain ID matches the expected chain ID.
|
|
79
|
+
* Throws {@link ChainIdMismatchError} if they differ.
|
|
80
|
+
*
|
|
81
|
+
* @param clientChainId - Chain ID reported by the viem client (may be undefined).
|
|
82
|
+
* @param expectedChainId - Chain ID expected by the entity or action.
|
|
83
|
+
*/
|
|
84
|
+
const validateChainId = (clientChainId, expectedChainId) => {
|
|
85
|
+
if (clientChainId !== expectedChainId) {
|
|
86
|
+
throw new types_1.ChainIdMismatchError(clientChainId, expectedChainId);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
exports.validateChainId = validateChainId;
|
|
90
|
+
/**
|
|
91
|
+
* Validates that the given collateral token is the chain's wrapped native token.
|
|
92
|
+
* Throws {@link ChainWNativeMissingError} if wNative is not configured for the chain.
|
|
93
|
+
* Throws {@link NativeAmountOnNonWNativeCollateralError} if collateral is not wNative.
|
|
94
|
+
*
|
|
95
|
+
* @param chainId - The chain to look up wNative on.
|
|
96
|
+
* @param collateralToken - The market's collateral token address.
|
|
97
|
+
*/
|
|
98
|
+
const validateNativeCollateral = (chainId, collateralToken) => {
|
|
99
|
+
const { wNative } = (0, blue_sdk_1.getChainAddresses)(chainId);
|
|
100
|
+
if (!(0, morpho_ts_1.isDefined)(wNative)) {
|
|
101
|
+
throw new types_1.ChainWNativeMissingError(chainId);
|
|
102
|
+
}
|
|
103
|
+
if (!(0, viem_1.isAddressEqual)(collateralToken, wNative)) {
|
|
104
|
+
throw new types_1.NativeAmountOnNonWNativeCollateralError(collateralToken, wNative);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
exports.validateNativeCollateral = validateNativeCollateral;
|
|
108
|
+
/**
|
|
109
|
+
* Validates that the resulting position stays within the safe LTV threshold
|
|
110
|
+
* (LLTV minus buffer) after withdrawing collateral.
|
|
111
|
+
*
|
|
112
|
+
* @param params - Validation parameters.
|
|
113
|
+
* @param params.positionData - The current accrual position with market data.
|
|
114
|
+
* @param params.withdrawAmount - Amount of collateral being withdrawn.
|
|
115
|
+
* @param params.lltv - The market's liquidation LTV.
|
|
116
|
+
* @param params.marketId - The market identifier (for error messages).
|
|
117
|
+
*/
|
|
118
|
+
const validatePositionHealthAfterWithdraw = (params) => {
|
|
119
|
+
const { positionData, withdrawAmount, lltv, marketId } = params;
|
|
120
|
+
if (positionData.marketId !== marketId) {
|
|
121
|
+
throw new types_1.MarketIdMismatchError(positionData.marketId, marketId);
|
|
122
|
+
}
|
|
123
|
+
if (withdrawAmount > positionData.collateral) {
|
|
124
|
+
throw new types_1.WithdrawExceedsCollateralError({
|
|
125
|
+
withdrawAmount,
|
|
126
|
+
available: positionData.collateral,
|
|
127
|
+
market: marketId,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
// No debt means position is always healthy — oracle price not needed.
|
|
131
|
+
if (positionData.borrowAssets === 0n) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const { price } = positionData.market;
|
|
135
|
+
if (!price) {
|
|
136
|
+
throw new types_1.MissingMarketPriceError(positionData.marketId);
|
|
137
|
+
}
|
|
138
|
+
const collateralAfter = positionData.collateral - withdrawAmount;
|
|
139
|
+
const collateralValueAfter = blue_sdk_1.MathLib.mulDivDown(collateralAfter, price, blue_sdk_1.ORACLE_PRICE_SCALE);
|
|
140
|
+
const effectiveLltv = lltv > constant_1.DEFAULT_LLTV_BUFFER ? lltv - constant_1.DEFAULT_LLTV_BUFFER : 0n;
|
|
141
|
+
const maxSafeBorrowAfter = blue_sdk_1.MathLib.wMulDown(collateralValueAfter, effectiveLltv);
|
|
142
|
+
if (positionData.borrowAssets > maxSafeBorrowAfter) {
|
|
143
|
+
throw new types_1.WithdrawMakesPositionUnhealthyError({
|
|
144
|
+
withdrawAmount,
|
|
145
|
+
borrowAssets: positionData.borrowAssets,
|
|
146
|
+
maxSafeBorrow: maxSafeBorrowAfter,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
exports.validatePositionHealthAfterWithdraw = validatePositionHealthAfterWithdraw;
|
|
151
|
+
/**
|
|
152
|
+
* Validates that the repay amount assets does not exceed the outstanding debt.
|
|
153
|
+
*
|
|
154
|
+
* @param params - Validation parameters.
|
|
155
|
+
* @param params.positionData - The current accrual position.
|
|
156
|
+
* @param params.repayAssets - The amount of assets to repay.
|
|
157
|
+
* @param params.marketId - The market identifier (for error messages).
|
|
158
|
+
*/
|
|
159
|
+
const validateRepayAmount = (params) => {
|
|
160
|
+
const { positionData, repayAssets, marketId } = params;
|
|
161
|
+
if (repayAssets > positionData.borrowAssets) {
|
|
162
|
+
throw new types_1.RepayExceedsDebtError({
|
|
163
|
+
repayAmount: repayAssets,
|
|
164
|
+
debt: positionData.borrowAssets,
|
|
165
|
+
market: marketId,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
exports.validateRepayAmount = validateRepayAmount;
|
|
170
|
+
/**
|
|
171
|
+
* Validates that the repay shares do not exceed the outstanding borrow shares.
|
|
172
|
+
*
|
|
173
|
+
* @param params - Validation parameters.
|
|
174
|
+
* @param params.positionData - The current accrual position.
|
|
175
|
+
* @param params.repayShares - The amount of shares to repay.
|
|
176
|
+
* @param params.marketId - The market identifier (for error messages).
|
|
177
|
+
*/
|
|
178
|
+
const validateRepayShares = (params) => {
|
|
179
|
+
const { positionData, repayShares, marketId } = params;
|
|
180
|
+
if (repayShares > positionData.borrowShares) {
|
|
181
|
+
throw new types_1.RepaySharesExceedDebtError({
|
|
182
|
+
repayShares,
|
|
183
|
+
borrowShares: positionData.borrowShares,
|
|
184
|
+
market: marketId,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
exports.validateRepayShares = validateRepayShares;
|
|
189
|
+
/**
|
|
190
|
+
* Validates the common repay input parameters shared by `marketV1Repay`
|
|
191
|
+
* and `marketV1RepayWithdrawCollateral`.
|
|
192
|
+
*
|
|
193
|
+
* @param params - Validation parameters.
|
|
194
|
+
* @param params.assets - Repay assets amount (0n when repaying by shares).
|
|
195
|
+
* @param params.shares - Repay shares amount (0n when repaying by assets).
|
|
196
|
+
* @param params.transferAmount - ERC20 amount to transfer to GeneralAdapter1.
|
|
197
|
+
* @param params.maxSharePrice - Maximum repay share price (in ray). Must be positive.
|
|
198
|
+
* @param params.marketId - The market identifier (for error messages).
|
|
199
|
+
*/
|
|
200
|
+
const validateRepayParams = (params) => {
|
|
201
|
+
const { assets, shares, transferAmount, maxSharePrice, marketId } = params;
|
|
202
|
+
if (maxSharePrice <= 0n) {
|
|
203
|
+
throw new types_1.NonPositiveRepayMaxSharePriceError(marketId);
|
|
204
|
+
}
|
|
205
|
+
if (assets < 0n || shares < 0n) {
|
|
206
|
+
throw new types_1.NonPositiveRepayAmountError(marketId);
|
|
207
|
+
}
|
|
208
|
+
if (assets > 0n && shares > 0n) {
|
|
209
|
+
throw new types_1.MutuallyExclusiveRepayAmountsError(marketId);
|
|
210
|
+
}
|
|
211
|
+
if (assets === 0n && shares === 0n) {
|
|
212
|
+
throw new types_1.NonPositiveRepayAmountError(marketId);
|
|
213
|
+
}
|
|
214
|
+
if (transferAmount <= 0n) {
|
|
215
|
+
throw new types_1.NonPositiveTransferAmountError(marketId);
|
|
216
|
+
}
|
|
217
|
+
if (assets > 0n && transferAmount !== assets) {
|
|
218
|
+
throw new types_1.TransferAmountNotEqualToAssetsError({
|
|
219
|
+
transferAmount,
|
|
220
|
+
assets,
|
|
221
|
+
market: marketId,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
exports.validateRepayParams = validateRepayParams;
|
|
226
|
+
/**
|
|
227
|
+
* Validates that vault reallocations are well-formed.
|
|
228
|
+
*
|
|
229
|
+
* Enforces the following invariants for each {@link VaultReallocation}:
|
|
230
|
+
* - `fee` must be non-negative.
|
|
231
|
+
* - `withdrawals` must be non-empty.
|
|
232
|
+
* - Every withdrawal `amount` must be strictly positive.
|
|
233
|
+
* - No withdrawal may target `targetMarketId` (the borrow market).
|
|
234
|
+
* - Withdrawal market IDs must be strictly ascending (required by `PublicAllocator.reallocateTo`).
|
|
235
|
+
*
|
|
236
|
+
* @param reallocations - The reallocations to validate.
|
|
237
|
+
* @param targetMarketId - The ID of the market being borrowed from. No withdrawal may reference this market.
|
|
238
|
+
*/
|
|
239
|
+
const validateReallocations = (reallocations, targetMarketId) => {
|
|
240
|
+
for (const r of reallocations) {
|
|
241
|
+
if (r.fee < 0n) {
|
|
242
|
+
throw new types_1.NegativeReallocationFeeError(r.vault);
|
|
243
|
+
}
|
|
244
|
+
if (r.withdrawals.length === 0) {
|
|
245
|
+
throw new types_1.EmptyReallocationWithdrawalsError(r.vault);
|
|
246
|
+
}
|
|
247
|
+
let prevId;
|
|
248
|
+
for (const w of r.withdrawals) {
|
|
249
|
+
if (w.amount <= 0n) {
|
|
250
|
+
throw new types_1.NonPositiveReallocationAmountError(r.vault, w.marketParams.id);
|
|
251
|
+
}
|
|
252
|
+
if (w.marketParams.id === targetMarketId) {
|
|
253
|
+
throw new types_1.ReallocationWithdrawalOnTargetMarketError(r.vault, w.marketParams.id);
|
|
254
|
+
}
|
|
255
|
+
if (prevId !== undefined && w.marketParams.id <= prevId) {
|
|
256
|
+
throw new types_1.UnsortedReallocationWithdrawalsError(r.vault, w.marketParams.id);
|
|
257
|
+
}
|
|
258
|
+
prevId = w.marketParams.id;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
exports.validateReallocations = validateReallocations;
|
|
263
|
+
/**
|
|
264
|
+
* Validates that a slippage tolerance is within an acceptable range.
|
|
265
|
+
*
|
|
266
|
+
* Throws {@link NegativeSlippageToleranceError} if negative.
|
|
267
|
+
* Throws {@link ExcessiveSlippageToleranceError} if greater than {@link MAX_SLIPPAGE_TOLERANCE}.
|
|
268
|
+
*
|
|
269
|
+
* @param slippageTolerance - The slippage tolerance in WAD.
|
|
270
|
+
*/
|
|
271
|
+
const validateSlippageTolerance = (slippageTolerance) => {
|
|
272
|
+
if (slippageTolerance < 0n) {
|
|
273
|
+
throw new types_1.NegativeSlippageToleranceError(slippageTolerance);
|
|
274
|
+
}
|
|
275
|
+
if (slippageTolerance > constant_1.MAX_SLIPPAGE_TOLERANCE) {
|
|
276
|
+
throw new types_1.ExcessiveSlippageToleranceError(slippageTolerance);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
exports.validateSlippageTolerance = validateSlippageTolerance;
|