@morpho-org/blue-sdk 2.0.0-next.1 → 2.0.0-next.11
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/LICENSE +21 -0
- package/README.md +16 -15
- package/lib/addresses.d.ts +117 -0
- package/lib/addresses.js +156 -0
- package/lib/chain.d.ts +29 -0
- package/lib/chain.js +286 -0
- package/lib/constants.d.ts +29 -0
- package/lib/constants.js +30 -0
- package/lib/errors.d.ts +52 -0
- package/lib/errors.js +97 -0
- package/lib/holding/AssetBalances.d.ts +48 -0
- package/lib/holding/AssetBalances.js +38 -0
- package/lib/holding/Holding.d.ts +64 -0
- package/lib/holding/Holding.js +65 -0
- package/lib/holding/index.d.ts +2 -0
- package/lib/holding/index.js +2 -0
- package/lib/index.js +12 -0
- package/lib/market/Market.d.ts +332 -0
- package/lib/market/Market.js +459 -0
- package/lib/market/MarketParams.d.ts +52 -0
- package/lib/market/MarketParams.js +71 -0
- package/lib/market/MarketUtils.d.ts +233 -0
- package/lib/market/MarketUtils.js +257 -0
- package/lib/market/index.d.ts +3 -0
- package/lib/market/index.js +3 -0
- package/lib/math/AdaptiveCurveIrmLib.d.ts +39 -0
- package/lib/math/AdaptiveCurveIrmLib.js +131 -0
- package/lib/math/MathLib.d.ts +111 -0
- package/lib/math/MathLib.js +185 -0
- package/lib/math/SharesMath.d.ts +12 -0
- package/lib/math/SharesMath.js +18 -0
- package/lib/math/index.d.ts +3 -0
- package/lib/math/index.js +3 -0
- package/lib/position/Position.d.ts +127 -0
- package/lib/position/Position.js +199 -0
- package/lib/position/index.d.ts +1 -0
- package/lib/position/index.js +1 -0
- package/lib/token/ConstantWrappedToken.d.ts +17 -0
- package/lib/token/ConstantWrappedToken.js +30 -0
- package/lib/token/ExchangeRateWrappedToken.d.ts +11 -0
- package/lib/token/ExchangeRateWrappedToken.js +17 -0
- package/lib/token/Token.d.ts +46 -0
- package/lib/token/Token.js +59 -0
- package/lib/token/VaultToken.d.ts +23 -0
- package/lib/token/VaultToken.js +27 -0
- package/lib/token/WrappedToken.d.ts +17 -0
- package/lib/token/WrappedToken.js +29 -0
- package/lib/token/index.d.ts +5 -0
- package/lib/token/index.js +5 -0
- package/lib/types.d.ts +27 -0
- package/lib/types.js +17 -0
- package/lib/user/User.d.ts +20 -0
- package/lib/user/User.js +19 -0
- package/lib/user/index.d.ts +1 -0
- package/lib/user/index.js +1 -0
- package/lib/vault/Vault.d.ts +152 -0
- package/lib/vault/Vault.js +221 -0
- package/lib/vault/VaultConfig.d.ts +22 -0
- package/lib/vault/VaultConfig.js +28 -0
- package/lib/vault/VaultMarketAllocation.d.ts +20 -0
- package/lib/vault/VaultMarketAllocation.js +26 -0
- package/lib/vault/VaultMarketConfig.d.ts +43 -0
- package/lib/vault/VaultMarketConfig.js +39 -0
- package/lib/vault/VaultMarketPublicAllocatorConfig.d.ts +29 -0
- package/lib/vault/VaultMarketPublicAllocatorConfig.js +24 -0
- package/lib/vault/VaultUser.d.ts +26 -0
- package/lib/vault/VaultUser.js +24 -0
- package/lib/vault/VaultUtils.d.ts +16 -0
- package/lib/vault/VaultUtils.js +17 -0
- package/lib/vault/index.d.ts +7 -0
- package/lib/vault/index.js +7 -0
- package/package.json +32 -36
- /package/{src/index.ts → lib/index.d.ts} +0 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { type RoundingDirection } from "../math/index.js";
|
|
2
|
+
import type { BigIntish, MarketId } from "../types.js";
|
|
3
|
+
import type { InputMarketParams } from "./MarketParams.js";
|
|
4
|
+
/**
|
|
5
|
+
* Namespace of utility functions to ease market-related calculations.
|
|
6
|
+
*/
|
|
7
|
+
export declare namespace MarketUtils {
|
|
8
|
+
/**
|
|
9
|
+
* Returns the id of a market based on its params.
|
|
10
|
+
* @param market The market params.
|
|
11
|
+
*/
|
|
12
|
+
function getMarketId(market: InputMarketParams): MarketId;
|
|
13
|
+
/**
|
|
14
|
+
* Returns the liquidation incentive factor for a given market params.
|
|
15
|
+
* @param config The market params.
|
|
16
|
+
*/
|
|
17
|
+
function getLiquidationIncentiveFactor({ lltv }: {
|
|
18
|
+
lltv: BigIntish;
|
|
19
|
+
}): bigint;
|
|
20
|
+
/**
|
|
21
|
+
* Returns the market's utilization rate (scaled by WAD).
|
|
22
|
+
* @param market The market state.
|
|
23
|
+
*/
|
|
24
|
+
function getUtilization({ totalSupplyAssets, totalBorrowAssets, }: {
|
|
25
|
+
totalSupplyAssets: BigIntish;
|
|
26
|
+
totalBorrowAssets: BigIntish;
|
|
27
|
+
}): bigint;
|
|
28
|
+
/**
|
|
29
|
+
* Returns the rate at which interest accrued on average for suppliers on the corresponding market,
|
|
30
|
+
* since the last time the market was updated (scaled by WAD).
|
|
31
|
+
* @param borrowRate The average borrow rate since the last market update (scaled by WAD).
|
|
32
|
+
* @param market The market state.
|
|
33
|
+
*/
|
|
34
|
+
function getSupplyRate(borrowRate: BigIntish, { utilization, fee }: {
|
|
35
|
+
utilization: BigIntish;
|
|
36
|
+
fee: BigIntish;
|
|
37
|
+
}): bigint;
|
|
38
|
+
/**
|
|
39
|
+
* Returns the Annual Percentage Yield (APY) from an average rate, as calculated in Morpho Blue.
|
|
40
|
+
* @param rate The average rate to convert to APY (scaled by WAD).
|
|
41
|
+
*/
|
|
42
|
+
function getApy(rate: BigIntish): bigint;
|
|
43
|
+
/**
|
|
44
|
+
* Returns the interest accrued on both sides of the given market
|
|
45
|
+
* as well as the supply shares minted to the fee recipient.
|
|
46
|
+
* @param borrowRate The average borrow rate since the last market update (scaled by WAD).
|
|
47
|
+
* @param market The market state.
|
|
48
|
+
* @param elapsed The time elapsed since the last market update (in seconds).
|
|
49
|
+
*/
|
|
50
|
+
function getAccruedInterest(borrowRate: BigIntish, { totalSupplyAssets, totalBorrowAssets, totalSupplyShares, fee, }: {
|
|
51
|
+
totalSupplyAssets: BigIntish;
|
|
52
|
+
totalBorrowAssets: BigIntish;
|
|
53
|
+
totalSupplyShares: BigIntish;
|
|
54
|
+
fee: BigIntish;
|
|
55
|
+
}, elapsed?: bigint): {
|
|
56
|
+
interest: bigint;
|
|
57
|
+
feeShares: bigint;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Returns the smallest volume to supply until the market gets the closest to the given utilization rate.
|
|
61
|
+
* @param market The market state.
|
|
62
|
+
* @param utilization The target utilization rate (scaled by WAD).
|
|
63
|
+
*/
|
|
64
|
+
function getSupplyToUtilization(market: {
|
|
65
|
+
totalSupplyAssets: BigIntish;
|
|
66
|
+
totalBorrowAssets: BigIntish;
|
|
67
|
+
}, utilization: BigIntish): bigint;
|
|
68
|
+
/**
|
|
69
|
+
* Returns the liquidity available to withdraw until the market gets the closest to the given utilization rate.
|
|
70
|
+
* @param market The market state.
|
|
71
|
+
* @param utilization The target utilization rate (scaled by WAD).
|
|
72
|
+
*/
|
|
73
|
+
function getWithdrawToUtilization({ totalSupplyAssets, totalBorrowAssets, }: {
|
|
74
|
+
totalSupplyAssets: BigIntish;
|
|
75
|
+
totalBorrowAssets: BigIntish;
|
|
76
|
+
}, utilization: BigIntish): bigint;
|
|
77
|
+
/**
|
|
78
|
+
* Returns the liquidity available to borrow until the market gets the closest to the given utilization rate.
|
|
79
|
+
* @param market The market state.
|
|
80
|
+
* @param utilization The target utilization rate (scaled by WAD).
|
|
81
|
+
*/
|
|
82
|
+
function getBorrowToUtilization({ totalSupplyAssets, totalBorrowAssets, }: {
|
|
83
|
+
totalSupplyAssets: BigIntish;
|
|
84
|
+
totalBorrowAssets: BigIntish;
|
|
85
|
+
}, utilization: BigIntish): bigint;
|
|
86
|
+
/**
|
|
87
|
+
* Returns the smallest volume to repay until the market gets the closest to the given utilization rate.
|
|
88
|
+
* @param market The market state.
|
|
89
|
+
* @param utilization The target utilization rate (scaled by WAD).
|
|
90
|
+
*/
|
|
91
|
+
function getRepayToUtilization({ totalSupplyAssets, totalBorrowAssets, }: {
|
|
92
|
+
totalSupplyAssets: BigIntish;
|
|
93
|
+
totalBorrowAssets: BigIntish;
|
|
94
|
+
}, utilization: BigIntish): bigint;
|
|
95
|
+
function getCollateralPower(collateral: BigIntish, { lltv }: {
|
|
96
|
+
lltv: BigIntish;
|
|
97
|
+
}): bigint;
|
|
98
|
+
function getCollateralValue(collateral: BigIntish, { price }: {
|
|
99
|
+
price: BigIntish;
|
|
100
|
+
}): bigint;
|
|
101
|
+
function getMaxBorrowAssets(collateral: BigIntish, market: {
|
|
102
|
+
price: BigIntish;
|
|
103
|
+
}, { lltv }: {
|
|
104
|
+
lltv: BigIntish;
|
|
105
|
+
}): bigint;
|
|
106
|
+
function getMaxBorrowableAssets({ collateral, borrowShares, }: {
|
|
107
|
+
collateral: BigIntish;
|
|
108
|
+
borrowShares: BigIntish;
|
|
109
|
+
}, market: {
|
|
110
|
+
totalBorrowAssets: BigIntish;
|
|
111
|
+
totalBorrowShares: BigIntish;
|
|
112
|
+
price: BigIntish;
|
|
113
|
+
}, marketParams: {
|
|
114
|
+
lltv: BigIntish;
|
|
115
|
+
}): bigint;
|
|
116
|
+
function getLiquidationSeizedAssets(repaidShares: BigIntish, market: {
|
|
117
|
+
totalBorrowAssets: BigIntish;
|
|
118
|
+
totalBorrowShares: BigIntish;
|
|
119
|
+
price: BigIntish;
|
|
120
|
+
}, config: {
|
|
121
|
+
lltv: BigIntish;
|
|
122
|
+
}): bigint;
|
|
123
|
+
function getLiquidationRepaidShares(seizedAssets: BigIntish, market: {
|
|
124
|
+
totalBorrowAssets: BigIntish;
|
|
125
|
+
totalBorrowShares: BigIntish;
|
|
126
|
+
price: BigIntish;
|
|
127
|
+
}, config: {
|
|
128
|
+
lltv: BigIntish;
|
|
129
|
+
}): bigint;
|
|
130
|
+
function getSeizableCollateral(position: {
|
|
131
|
+
collateral: BigIntish;
|
|
132
|
+
borrowShares: BigIntish;
|
|
133
|
+
}, market: {
|
|
134
|
+
totalBorrowAssets: BigIntish;
|
|
135
|
+
totalBorrowShares: BigIntish;
|
|
136
|
+
price: BigIntish;
|
|
137
|
+
}, config: {
|
|
138
|
+
lltv: BigIntish;
|
|
139
|
+
}): bigint;
|
|
140
|
+
function getWithdrawableCollateral({ collateral, borrowShares, }: {
|
|
141
|
+
collateral: BigIntish;
|
|
142
|
+
borrowShares: BigIntish;
|
|
143
|
+
}, market: {
|
|
144
|
+
totalBorrowAssets: BigIntish;
|
|
145
|
+
totalBorrowShares: BigIntish;
|
|
146
|
+
price: BigIntish;
|
|
147
|
+
}, { lltv }: {
|
|
148
|
+
lltv: BigIntish;
|
|
149
|
+
}): bigint;
|
|
150
|
+
function isHealthy({ collateral, borrowShares, }: {
|
|
151
|
+
collateral: BigIntish;
|
|
152
|
+
borrowShares: BigIntish;
|
|
153
|
+
}, market: {
|
|
154
|
+
totalBorrowAssets: BigIntish;
|
|
155
|
+
totalBorrowShares: BigIntish;
|
|
156
|
+
price: BigIntish;
|
|
157
|
+
}, marketParams: {
|
|
158
|
+
lltv: BigIntish;
|
|
159
|
+
}): boolean;
|
|
160
|
+
/**
|
|
161
|
+
* Returns the price of the collateral quoted in the loan token (e.g. ETH/DAI)
|
|
162
|
+
* that set the user's position to be liquidatable.
|
|
163
|
+
* Returns null if the position is not a borrow.
|
|
164
|
+
*/
|
|
165
|
+
function getLiquidationPrice({ collateral, borrowShares, }: {
|
|
166
|
+
collateral: BigIntish;
|
|
167
|
+
borrowShares: BigIntish;
|
|
168
|
+
}, market: {
|
|
169
|
+
totalBorrowAssets: BigIntish;
|
|
170
|
+
totalBorrowShares: BigIntish;
|
|
171
|
+
}, marketParams: {
|
|
172
|
+
lltv: BigIntish;
|
|
173
|
+
}): bigint | null;
|
|
174
|
+
/**
|
|
175
|
+
* Returns the price variation required for the given position to reach its liquidation threshold (scaled by WAD).
|
|
176
|
+
* Negative when healthy (the price needs to drop x%), positive when unhealthy (the price needs to soar x%).
|
|
177
|
+
* Returns null if the position is not a borrow.
|
|
178
|
+
*/
|
|
179
|
+
function getPriceVariationToLiquidationPrice(position: {
|
|
180
|
+
collateral: BigIntish;
|
|
181
|
+
borrowShares: BigIntish;
|
|
182
|
+
}, market: {
|
|
183
|
+
totalBorrowAssets: BigIntish;
|
|
184
|
+
totalBorrowShares: BigIntish;
|
|
185
|
+
price: BigIntish;
|
|
186
|
+
}, marketParams: {
|
|
187
|
+
lltv: BigIntish;
|
|
188
|
+
}): bigint | null;
|
|
189
|
+
function getHealthFactor({ collateral, borrowShares, }: {
|
|
190
|
+
collateral: BigIntish;
|
|
191
|
+
borrowShares: BigIntish;
|
|
192
|
+
}, market: {
|
|
193
|
+
totalBorrowAssets: BigIntish;
|
|
194
|
+
totalBorrowShares: BigIntish;
|
|
195
|
+
price: BigIntish;
|
|
196
|
+
}, marketParams: {
|
|
197
|
+
lltv: BigIntish;
|
|
198
|
+
}): bigint | null;
|
|
199
|
+
function getLtv({ collateral, borrowShares, }: {
|
|
200
|
+
collateral: BigIntish;
|
|
201
|
+
borrowShares: BigIntish;
|
|
202
|
+
}, market: {
|
|
203
|
+
totalBorrowAssets: BigIntish;
|
|
204
|
+
totalBorrowShares: BigIntish;
|
|
205
|
+
price: BigIntish;
|
|
206
|
+
}): bigint | null;
|
|
207
|
+
function getBorrowCapacityUsage(position: {
|
|
208
|
+
collateral: BigIntish;
|
|
209
|
+
borrowShares: BigIntish;
|
|
210
|
+
}, market: {
|
|
211
|
+
totalBorrowAssets: BigIntish;
|
|
212
|
+
totalBorrowShares: BigIntish;
|
|
213
|
+
price: BigIntish;
|
|
214
|
+
}, marketParams: {
|
|
215
|
+
lltv: BigIntish;
|
|
216
|
+
}): bigint | null;
|
|
217
|
+
function toSupplyAssets(shares: BigIntish, market: {
|
|
218
|
+
totalSupplyAssets: BigIntish;
|
|
219
|
+
totalSupplyShares: BigIntish;
|
|
220
|
+
}, rounding?: RoundingDirection): bigint;
|
|
221
|
+
function toSupplyShares(assets: BigIntish, market: {
|
|
222
|
+
totalSupplyAssets: BigIntish;
|
|
223
|
+
totalSupplyShares: BigIntish;
|
|
224
|
+
}, rounding?: RoundingDirection): bigint;
|
|
225
|
+
function toBorrowAssets(shares: BigIntish, market: {
|
|
226
|
+
totalBorrowAssets: BigIntish;
|
|
227
|
+
totalBorrowShares: BigIntish;
|
|
228
|
+
}, rounding?: RoundingDirection): bigint;
|
|
229
|
+
function toBorrowShares(assets: BigIntish, market: {
|
|
230
|
+
totalBorrowAssets: BigIntish;
|
|
231
|
+
totalBorrowShares: BigIntish;
|
|
232
|
+
}, rounding?: RoundingDirection): bigint;
|
|
233
|
+
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import keccak256 from "keccak256";
|
|
2
|
+
import { LIQUIDATION_CURSOR, MAX_LIQUIDATION_INCENTIVE_FACTOR, ORACLE_PRICE_SCALE, SECONDS_PER_YEAR, } from "../constants.js";
|
|
3
|
+
import { MathLib, SharesMath } from "../math/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* Namespace of utility functions to ease market-related calculations.
|
|
6
|
+
*/
|
|
7
|
+
export var MarketUtils;
|
|
8
|
+
(function (MarketUtils) {
|
|
9
|
+
/**
|
|
10
|
+
* Returns the id of a market based on its params.
|
|
11
|
+
* @param market The market params.
|
|
12
|
+
*/
|
|
13
|
+
function getMarketId(market) {
|
|
14
|
+
return `0x${keccak256(`0x${market.loanToken.substring(2).toLowerCase().padStart(64, "0") +
|
|
15
|
+
market.collateralToken.substring(2).toLowerCase().padStart(64, "0") +
|
|
16
|
+
market.oracle.substring(2).padStart(64, "0") +
|
|
17
|
+
market.irm.substring(2).toLowerCase().padStart(64, "0") +
|
|
18
|
+
BigInt(market.lltv).toString(16).padStart(64, "0")}`).toString("hex")}`;
|
|
19
|
+
}
|
|
20
|
+
MarketUtils.getMarketId = getMarketId;
|
|
21
|
+
/**
|
|
22
|
+
* Returns the liquidation incentive factor for a given market params.
|
|
23
|
+
* @param config The market params.
|
|
24
|
+
*/
|
|
25
|
+
function getLiquidationIncentiveFactor({ lltv }) {
|
|
26
|
+
return MathLib.min(MAX_LIQUIDATION_INCENTIVE_FACTOR, MathLib.wDivDown(MathLib.WAD, MathLib.WAD -
|
|
27
|
+
MathLib.wMulDown(LIQUIDATION_CURSOR, MathLib.WAD - BigInt(lltv))));
|
|
28
|
+
}
|
|
29
|
+
MarketUtils.getLiquidationIncentiveFactor = getLiquidationIncentiveFactor;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the market's utilization rate (scaled by WAD).
|
|
32
|
+
* @param market The market state.
|
|
33
|
+
*/
|
|
34
|
+
function getUtilization({ totalSupplyAssets, totalBorrowAssets, }) {
|
|
35
|
+
totalSupplyAssets = BigInt(totalSupplyAssets);
|
|
36
|
+
totalBorrowAssets = BigInt(totalBorrowAssets);
|
|
37
|
+
if (totalSupplyAssets === 0n) {
|
|
38
|
+
if (totalBorrowAssets > 0n)
|
|
39
|
+
return MathLib.MAX_UINT_256;
|
|
40
|
+
return 0n;
|
|
41
|
+
}
|
|
42
|
+
return MathLib.wDivDown(totalBorrowAssets, totalSupplyAssets);
|
|
43
|
+
}
|
|
44
|
+
MarketUtils.getUtilization = getUtilization;
|
|
45
|
+
/**
|
|
46
|
+
* Returns the rate at which interest accrued on average for suppliers on the corresponding market,
|
|
47
|
+
* since the last time the market was updated (scaled by WAD).
|
|
48
|
+
* @param borrowRate The average borrow rate since the last market update (scaled by WAD).
|
|
49
|
+
* @param market The market state.
|
|
50
|
+
*/
|
|
51
|
+
function getSupplyRate(borrowRate, { utilization, fee }) {
|
|
52
|
+
const borrowRateWithoutFees = MathLib.wMulUp(borrowRate, utilization);
|
|
53
|
+
return MathLib.wMulUp(borrowRateWithoutFees, MathLib.WAD - BigInt(fee));
|
|
54
|
+
}
|
|
55
|
+
MarketUtils.getSupplyRate = getSupplyRate;
|
|
56
|
+
/**
|
|
57
|
+
* Returns the Annual Percentage Yield (APY) from an average rate, as calculated in Morpho Blue.
|
|
58
|
+
* @param rate The average rate to convert to APY (scaled by WAD).
|
|
59
|
+
*/
|
|
60
|
+
function getApy(rate) {
|
|
61
|
+
return MathLib.wTaylorCompounded(rate, SECONDS_PER_YEAR);
|
|
62
|
+
}
|
|
63
|
+
MarketUtils.getApy = getApy;
|
|
64
|
+
/**
|
|
65
|
+
* Returns the interest accrued on both sides of the given market
|
|
66
|
+
* as well as the supply shares minted to the fee recipient.
|
|
67
|
+
* @param borrowRate The average borrow rate since the last market update (scaled by WAD).
|
|
68
|
+
* @param market The market state.
|
|
69
|
+
* @param elapsed The time elapsed since the last market update (in seconds).
|
|
70
|
+
*/
|
|
71
|
+
function getAccruedInterest(borrowRate, { totalSupplyAssets, totalBorrowAssets, totalSupplyShares, fee, }, elapsed = 0n) {
|
|
72
|
+
const interest = MathLib.wMulDown(totalBorrowAssets, MathLib.wTaylorCompounded(borrowRate, elapsed));
|
|
73
|
+
const feeAmount = MathLib.wMulDown(interest, fee);
|
|
74
|
+
const feeShares = toSupplyShares(feeAmount, {
|
|
75
|
+
totalSupplyAssets: BigInt(totalSupplyAssets) - feeAmount,
|
|
76
|
+
totalSupplyShares,
|
|
77
|
+
}, "Down");
|
|
78
|
+
return { interest, feeShares };
|
|
79
|
+
}
|
|
80
|
+
MarketUtils.getAccruedInterest = getAccruedInterest;
|
|
81
|
+
/**
|
|
82
|
+
* Returns the smallest volume to supply until the market gets the closest to the given utilization rate.
|
|
83
|
+
* @param market The market state.
|
|
84
|
+
* @param utilization The target utilization rate (scaled by WAD).
|
|
85
|
+
*/
|
|
86
|
+
function getSupplyToUtilization(market, utilization) {
|
|
87
|
+
utilization = BigInt(utilization);
|
|
88
|
+
if (utilization === 0n) {
|
|
89
|
+
if (getUtilization(market) === 0n)
|
|
90
|
+
return 0n;
|
|
91
|
+
return MathLib.MAX_UINT_256;
|
|
92
|
+
}
|
|
93
|
+
return MathLib.zeroFloorSub(MathLib.wDivUp(market.totalBorrowAssets, utilization), market.totalSupplyAssets);
|
|
94
|
+
}
|
|
95
|
+
MarketUtils.getSupplyToUtilization = getSupplyToUtilization;
|
|
96
|
+
/**
|
|
97
|
+
* Returns the liquidity available to withdraw until the market gets the closest to the given utilization rate.
|
|
98
|
+
* @param market The market state.
|
|
99
|
+
* @param utilization The target utilization rate (scaled by WAD).
|
|
100
|
+
*/
|
|
101
|
+
function getWithdrawToUtilization({ totalSupplyAssets, totalBorrowAssets, }, utilization) {
|
|
102
|
+
utilization = BigInt(utilization);
|
|
103
|
+
totalSupplyAssets = BigInt(totalSupplyAssets);
|
|
104
|
+
totalBorrowAssets = BigInt(totalBorrowAssets);
|
|
105
|
+
if (utilization === 0n) {
|
|
106
|
+
if (totalBorrowAssets === 0n)
|
|
107
|
+
return totalSupplyAssets;
|
|
108
|
+
return 0n;
|
|
109
|
+
}
|
|
110
|
+
return MathLib.zeroFloorSub(totalSupplyAssets, MathLib.wDivUp(totalBorrowAssets, utilization));
|
|
111
|
+
}
|
|
112
|
+
MarketUtils.getWithdrawToUtilization = getWithdrawToUtilization;
|
|
113
|
+
/**
|
|
114
|
+
* Returns the liquidity available to borrow until the market gets the closest to the given utilization rate.
|
|
115
|
+
* @param market The market state.
|
|
116
|
+
* @param utilization The target utilization rate (scaled by WAD).
|
|
117
|
+
*/
|
|
118
|
+
function getBorrowToUtilization({ totalSupplyAssets, totalBorrowAssets, }, utilization) {
|
|
119
|
+
return MathLib.zeroFloorSub(MathLib.wMulDown(totalSupplyAssets, utilization), totalBorrowAssets);
|
|
120
|
+
}
|
|
121
|
+
MarketUtils.getBorrowToUtilization = getBorrowToUtilization;
|
|
122
|
+
/**
|
|
123
|
+
* Returns the smallest volume to repay until the market gets the closest to the given utilization rate.
|
|
124
|
+
* @param market The market state.
|
|
125
|
+
* @param utilization The target utilization rate (scaled by WAD).
|
|
126
|
+
*/
|
|
127
|
+
function getRepayToUtilization({ totalSupplyAssets, totalBorrowAssets, }, utilization) {
|
|
128
|
+
return MathLib.zeroFloorSub(totalBorrowAssets, MathLib.wMulDown(totalSupplyAssets, utilization));
|
|
129
|
+
}
|
|
130
|
+
MarketUtils.getRepayToUtilization = getRepayToUtilization;
|
|
131
|
+
function getCollateralPower(collateral, { lltv }) {
|
|
132
|
+
return MathLib.wMulDown(collateral, lltv);
|
|
133
|
+
}
|
|
134
|
+
MarketUtils.getCollateralPower = getCollateralPower;
|
|
135
|
+
function getCollateralValue(collateral, { price }) {
|
|
136
|
+
return MathLib.mulDivDown(collateral, price, ORACLE_PRICE_SCALE);
|
|
137
|
+
}
|
|
138
|
+
MarketUtils.getCollateralValue = getCollateralValue;
|
|
139
|
+
function getMaxBorrowAssets(collateral, market, { lltv }) {
|
|
140
|
+
return MathLib.wMulDown(getCollateralValue(collateral, market), lltv);
|
|
141
|
+
}
|
|
142
|
+
MarketUtils.getMaxBorrowAssets = getMaxBorrowAssets;
|
|
143
|
+
function getMaxBorrowableAssets({ collateral, borrowShares, }, market, marketParams) {
|
|
144
|
+
return MathLib.zeroFloorSub(getMaxBorrowAssets(collateral, market, marketParams), toBorrowAssets(borrowShares, market));
|
|
145
|
+
}
|
|
146
|
+
MarketUtils.getMaxBorrowableAssets = getMaxBorrowableAssets;
|
|
147
|
+
function getLiquidationSeizedAssets(repaidShares, market, config) {
|
|
148
|
+
market.price = BigInt(market.price);
|
|
149
|
+
if (market.price === 0n)
|
|
150
|
+
return 0n;
|
|
151
|
+
return MathLib.mulDivDown(MathLib.wMulDown(toBorrowAssets(repaidShares, market, "Down"), getLiquidationIncentiveFactor(config)), ORACLE_PRICE_SCALE, market.price);
|
|
152
|
+
}
|
|
153
|
+
MarketUtils.getLiquidationSeizedAssets = getLiquidationSeizedAssets;
|
|
154
|
+
function getLiquidationRepaidShares(seizedAssets, market, config) {
|
|
155
|
+
return toBorrowShares(MathLib.wDivUp(MathLib.mulDivUp(seizedAssets, market.price, ORACLE_PRICE_SCALE), getLiquidationIncentiveFactor(config)), market, "Up");
|
|
156
|
+
}
|
|
157
|
+
MarketUtils.getLiquidationRepaidShares = getLiquidationRepaidShares;
|
|
158
|
+
function getSeizableCollateral(position, market, config) {
|
|
159
|
+
market.price = BigInt(market.price);
|
|
160
|
+
if (market.price === 0n || isHealthy(position, market, config))
|
|
161
|
+
return 0n;
|
|
162
|
+
return MathLib.min(position.collateral, getLiquidationSeizedAssets(position.borrowShares, market, config));
|
|
163
|
+
}
|
|
164
|
+
MarketUtils.getSeizableCollateral = getSeizableCollateral;
|
|
165
|
+
function getWithdrawableCollateral({ collateral, borrowShares, }, market, { lltv }) {
|
|
166
|
+
market.price = BigInt(market.price);
|
|
167
|
+
if (market.price === 0n)
|
|
168
|
+
return 0n;
|
|
169
|
+
return MathLib.zeroFloorSub(collateral, MathLib.wDivUp(MathLib.mulDivUp(toBorrowAssets(borrowShares, market), ORACLE_PRICE_SCALE, market.price), lltv));
|
|
170
|
+
}
|
|
171
|
+
MarketUtils.getWithdrawableCollateral = getWithdrawableCollateral;
|
|
172
|
+
function isHealthy({ collateral, borrowShares, }, market, marketParams) {
|
|
173
|
+
return (getMaxBorrowAssets(collateral, market, marketParams) >=
|
|
174
|
+
toBorrowAssets(borrowShares, market));
|
|
175
|
+
}
|
|
176
|
+
MarketUtils.isHealthy = isHealthy;
|
|
177
|
+
/**
|
|
178
|
+
* Returns the price of the collateral quoted in the loan token (e.g. ETH/DAI)
|
|
179
|
+
* that set the user's position to be liquidatable.
|
|
180
|
+
* Returns null if the position is not a borrow.
|
|
181
|
+
*/
|
|
182
|
+
function getLiquidationPrice({ collateral, borrowShares, }, market, marketParams) {
|
|
183
|
+
borrowShares = BigInt(borrowShares);
|
|
184
|
+
market.totalBorrowShares = BigInt(market.totalBorrowShares);
|
|
185
|
+
if (borrowShares === 0n || market.totalBorrowShares === 0n)
|
|
186
|
+
return null;
|
|
187
|
+
const collateralPower = getCollateralPower(collateral, marketParams);
|
|
188
|
+
if (collateralPower === 0n)
|
|
189
|
+
return MathLib.MAX_UINT_256;
|
|
190
|
+
const borrowAssets = toBorrowAssets(borrowShares, market);
|
|
191
|
+
return MathLib.mulDivUp(borrowAssets, ORACLE_PRICE_SCALE, collateralPower);
|
|
192
|
+
}
|
|
193
|
+
MarketUtils.getLiquidationPrice = getLiquidationPrice;
|
|
194
|
+
/**
|
|
195
|
+
* Returns the price variation required for the given position to reach its liquidation threshold (scaled by WAD).
|
|
196
|
+
* Negative when healthy (the price needs to drop x%), positive when unhealthy (the price needs to soar x%).
|
|
197
|
+
* Returns null if the position is not a borrow.
|
|
198
|
+
*/
|
|
199
|
+
function getPriceVariationToLiquidationPrice(position, market, marketParams) {
|
|
200
|
+
market.price = BigInt(market.price);
|
|
201
|
+
if (market.price === 0n)
|
|
202
|
+
return null;
|
|
203
|
+
const liquidationPrice = getLiquidationPrice(position, market, marketParams);
|
|
204
|
+
if (liquidationPrice == null)
|
|
205
|
+
return null;
|
|
206
|
+
return MathLib.wDivUp(liquidationPrice, market.price) - MathLib.WAD;
|
|
207
|
+
}
|
|
208
|
+
MarketUtils.getPriceVariationToLiquidationPrice = getPriceVariationToLiquidationPrice;
|
|
209
|
+
function getHealthFactor({ collateral, borrowShares, }, market, marketParams) {
|
|
210
|
+
borrowShares = BigInt(borrowShares);
|
|
211
|
+
market.totalBorrowShares = BigInt(market.totalBorrowShares);
|
|
212
|
+
if (borrowShares === 0n || market.totalBorrowShares === 0n)
|
|
213
|
+
return null;
|
|
214
|
+
const borrowAssets = toBorrowAssets(borrowShares, market);
|
|
215
|
+
if (borrowAssets === 0n)
|
|
216
|
+
return MathLib.MAX_UINT_256;
|
|
217
|
+
const maxBorrowAssets = getMaxBorrowAssets(collateral, market, marketParams);
|
|
218
|
+
return MathLib.wDivDown(maxBorrowAssets, borrowAssets);
|
|
219
|
+
}
|
|
220
|
+
MarketUtils.getHealthFactor = getHealthFactor;
|
|
221
|
+
function getLtv({ collateral, borrowShares, }, market) {
|
|
222
|
+
borrowShares = BigInt(borrowShares);
|
|
223
|
+
market.totalBorrowShares = BigInt(market.totalBorrowShares);
|
|
224
|
+
if (borrowShares === 0n || market.totalBorrowShares === 0n)
|
|
225
|
+
return null;
|
|
226
|
+
const collateralValue = getCollateralValue(collateral, market);
|
|
227
|
+
if (collateralValue === 0n)
|
|
228
|
+
return MathLib.MAX_UINT_256;
|
|
229
|
+
return MathLib.wDivUp(toBorrowAssets(borrowShares, market), collateralValue);
|
|
230
|
+
}
|
|
231
|
+
MarketUtils.getLtv = getLtv;
|
|
232
|
+
function getBorrowCapacityUsage(position, market, marketParams) {
|
|
233
|
+
const hf = getHealthFactor(position, market, marketParams);
|
|
234
|
+
if (hf === null)
|
|
235
|
+
return null;
|
|
236
|
+
if (hf === 0n)
|
|
237
|
+
return MathLib.MAX_UINT_256;
|
|
238
|
+
return MathLib.wDivUp(MathLib.WAD, hf);
|
|
239
|
+
}
|
|
240
|
+
MarketUtils.getBorrowCapacityUsage = getBorrowCapacityUsage;
|
|
241
|
+
function toSupplyAssets(shares, market, rounding = "Down") {
|
|
242
|
+
return SharesMath.toAssets(shares, market.totalSupplyAssets, market.totalSupplyShares, rounding);
|
|
243
|
+
}
|
|
244
|
+
MarketUtils.toSupplyAssets = toSupplyAssets;
|
|
245
|
+
function toSupplyShares(assets, market, rounding = "Up") {
|
|
246
|
+
return SharesMath.toShares(assets, market.totalSupplyAssets, market.totalSupplyShares, rounding);
|
|
247
|
+
}
|
|
248
|
+
MarketUtils.toSupplyShares = toSupplyShares;
|
|
249
|
+
function toBorrowAssets(shares, market, rounding = "Up") {
|
|
250
|
+
return SharesMath.toAssets(shares, market.totalBorrowAssets, market.totalBorrowShares, rounding);
|
|
251
|
+
}
|
|
252
|
+
MarketUtils.toBorrowAssets = toBorrowAssets;
|
|
253
|
+
function toBorrowShares(assets, market, rounding = "Down") {
|
|
254
|
+
return SharesMath.toShares(assets, market.totalBorrowAssets, market.totalBorrowShares, rounding);
|
|
255
|
+
}
|
|
256
|
+
MarketUtils.toBorrowShares = toBorrowShares;
|
|
257
|
+
})(MarketUtils || (MarketUtils = {}));
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { BigIntish } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* JS implementation of {@link https://github.com/morpho-org/morpho-blue-irm/blob/main/src/libraries/adaptive-curve/ExpLib.sol ExpLib} used by the Adaptive Curve IRM.
|
|
4
|
+
*/
|
|
5
|
+
export declare namespace AdaptiveCurveIrmLib {
|
|
6
|
+
const CURVE_STEEPNESS = 4000000000000000000n;
|
|
7
|
+
const TARGET_UTILIZATION = 900000000000000000n;
|
|
8
|
+
const INITIAL_RATE_AT_TARGET: bigint;
|
|
9
|
+
const ADJUSTMENT_SPEED: bigint;
|
|
10
|
+
const MIN_RATE_AT_TARGET: bigint;
|
|
11
|
+
const MAX_RATE_AT_TARGET: bigint;
|
|
12
|
+
/**
|
|
13
|
+
* ln(2), scaled by WAD.
|
|
14
|
+
*/
|
|
15
|
+
const LN_2_INT = 693147180559945309n;
|
|
16
|
+
/**
|
|
17
|
+
* ln(1e-18), scaled by WAD.
|
|
18
|
+
*/
|
|
19
|
+
const LN_WEI_INT = -41446531673892822312n;
|
|
20
|
+
/**
|
|
21
|
+
* Above this bound, `wExp` is clipped to avoid overflowing when multiplied with 1 ether.
|
|
22
|
+
* This upper bound corresponds to: ln(type(int256).max / 1e36) (scaled by WAD, floored).
|
|
23
|
+
*/
|
|
24
|
+
const WEXP_UPPER_BOUND = 93859467695000404319n;
|
|
25
|
+
/**
|
|
26
|
+
* The value of wExp(`WEXP_UPPER_BOUND`).
|
|
27
|
+
*/
|
|
28
|
+
const WEXP_UPPER_VALUE = 57716089161558943949701069502944508345128422502756744429568n;
|
|
29
|
+
/**
|
|
30
|
+
* Returns an approximation of exp(x) used by the Adaptive Curve IRM.
|
|
31
|
+
* @param x
|
|
32
|
+
*/
|
|
33
|
+
function wExp(x: BigIntish): bigint;
|
|
34
|
+
function getBorrowRate(startUtilization: BigIntish, startRateAtTarget: BigIntish, elapsed: BigIntish): {
|
|
35
|
+
avgBorrowRate: bigint;
|
|
36
|
+
endRateAtTarget: bigint;
|
|
37
|
+
};
|
|
38
|
+
function getUtilizationAtBorrowRate(borrowRate: BigIntish, rateAtTarget: BigIntish): bigint;
|
|
39
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { SECONDS_PER_YEAR } from "../constants.js";
|
|
2
|
+
import { MathLib } from "./MathLib.js";
|
|
3
|
+
/**
|
|
4
|
+
* JS implementation of {@link https://github.com/morpho-org/morpho-blue-irm/blob/main/src/libraries/adaptive-curve/ExpLib.sol ExpLib} used by the Adaptive Curve IRM.
|
|
5
|
+
*/
|
|
6
|
+
export var AdaptiveCurveIrmLib;
|
|
7
|
+
(function (AdaptiveCurveIrmLib) {
|
|
8
|
+
AdaptiveCurveIrmLib.CURVE_STEEPNESS = 4000000000000000000n;
|
|
9
|
+
AdaptiveCurveIrmLib.TARGET_UTILIZATION = 900000000000000000n;
|
|
10
|
+
AdaptiveCurveIrmLib.INITIAL_RATE_AT_TARGET = 40000000000000000n / SECONDS_PER_YEAR;
|
|
11
|
+
AdaptiveCurveIrmLib.ADJUSTMENT_SPEED = 50000000000000000000n / SECONDS_PER_YEAR;
|
|
12
|
+
AdaptiveCurveIrmLib.MIN_RATE_AT_TARGET = 1000000000000000n / SECONDS_PER_YEAR;
|
|
13
|
+
AdaptiveCurveIrmLib.MAX_RATE_AT_TARGET = 2000000000000000000n / SECONDS_PER_YEAR;
|
|
14
|
+
/**
|
|
15
|
+
* ln(2), scaled by WAD.
|
|
16
|
+
*/
|
|
17
|
+
AdaptiveCurveIrmLib.LN_2_INT = 693147180559945309n;
|
|
18
|
+
/**
|
|
19
|
+
* ln(1e-18), scaled by WAD.
|
|
20
|
+
*/
|
|
21
|
+
AdaptiveCurveIrmLib.LN_WEI_INT = -41446531673892822312n;
|
|
22
|
+
/**
|
|
23
|
+
* Above this bound, `wExp` is clipped to avoid overflowing when multiplied with 1 ether.
|
|
24
|
+
* This upper bound corresponds to: ln(type(int256).max / 1e36) (scaled by WAD, floored).
|
|
25
|
+
*/
|
|
26
|
+
AdaptiveCurveIrmLib.WEXP_UPPER_BOUND = 93859467695000404319n;
|
|
27
|
+
/**
|
|
28
|
+
* The value of wExp(`WEXP_UPPER_BOUND`).
|
|
29
|
+
*/
|
|
30
|
+
AdaptiveCurveIrmLib.WEXP_UPPER_VALUE = 57716089161558943949701069502944508345128422502756744429568n;
|
|
31
|
+
/**
|
|
32
|
+
* Returns an approximation of exp(x) used by the Adaptive Curve IRM.
|
|
33
|
+
* @param x
|
|
34
|
+
*/
|
|
35
|
+
function wExp(x) {
|
|
36
|
+
x = BigInt(x);
|
|
37
|
+
// If x < ln(1e-18) then exp(x) < 1e-18 so it is rounded to zero.
|
|
38
|
+
if (x < AdaptiveCurveIrmLib.LN_WEI_INT)
|
|
39
|
+
return 0n;
|
|
40
|
+
// `wExp` is clipped to avoid overflowing when multiplied with 1 ether.
|
|
41
|
+
if (x >= AdaptiveCurveIrmLib.WEXP_UPPER_BOUND)
|
|
42
|
+
return AdaptiveCurveIrmLib.WEXP_UPPER_VALUE;
|
|
43
|
+
// Decompose x as x = q * ln(2) + r with q an integer and -ln(2)/2 <= r <= ln(2)/2.
|
|
44
|
+
// q = x / ln(2) rounded half toward zero.
|
|
45
|
+
const roundingAdjustment = x < 0n ? -(AdaptiveCurveIrmLib.LN_2_INT / 2n) : AdaptiveCurveIrmLib.LN_2_INT / 2n;
|
|
46
|
+
const q = (x + roundingAdjustment) / AdaptiveCurveIrmLib.LN_2_INT;
|
|
47
|
+
const r = x - q * AdaptiveCurveIrmLib.LN_2_INT;
|
|
48
|
+
// Compute e^r with a 2nd-order Taylor polynomial.
|
|
49
|
+
const expR = MathLib.WAD + r + (r * r) / MathLib.WAD / 2n;
|
|
50
|
+
// Return e^x = 2^q * e^r.
|
|
51
|
+
if (q === 0n)
|
|
52
|
+
return expR << q;
|
|
53
|
+
return expR >> -q;
|
|
54
|
+
}
|
|
55
|
+
AdaptiveCurveIrmLib.wExp = wExp;
|
|
56
|
+
function getBorrowRate(startUtilization, startRateAtTarget, elapsed) {
|
|
57
|
+
startUtilization = BigInt(startUtilization);
|
|
58
|
+
startRateAtTarget = BigInt(startRateAtTarget);
|
|
59
|
+
elapsed = BigInt(elapsed);
|
|
60
|
+
const errNormFactor = startUtilization > AdaptiveCurveIrmLib.TARGET_UTILIZATION
|
|
61
|
+
? MathLib.WAD - AdaptiveCurveIrmLib.TARGET_UTILIZATION
|
|
62
|
+
: AdaptiveCurveIrmLib.TARGET_UTILIZATION;
|
|
63
|
+
const err = MathLib.wDivDown(startUtilization - AdaptiveCurveIrmLib.TARGET_UTILIZATION, errNormFactor);
|
|
64
|
+
let avgRateAtTarget;
|
|
65
|
+
let endRateAtTarget;
|
|
66
|
+
if (startRateAtTarget === 0n) {
|
|
67
|
+
// First interaction.
|
|
68
|
+
avgRateAtTarget = AdaptiveCurveIrmLib.INITIAL_RATE_AT_TARGET;
|
|
69
|
+
endRateAtTarget = AdaptiveCurveIrmLib.INITIAL_RATE_AT_TARGET;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// The speed is assumed constant between two updates, but it is in fact not constant because of interest.
|
|
73
|
+
// So the rate is always underestimated.
|
|
74
|
+
const speed = MathLib.wMulDown(AdaptiveCurveIrmLib.ADJUSTMENT_SPEED, err);
|
|
75
|
+
const linearAdaptation = speed * elapsed;
|
|
76
|
+
if (linearAdaptation === 0n) {
|
|
77
|
+
// If linearAdaptation == 0, avgRateAtTarget = endRateAtTarget = startRateAtTarget;
|
|
78
|
+
avgRateAtTarget = startRateAtTarget;
|
|
79
|
+
endRateAtTarget = startRateAtTarget;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// Non negative because MIN_RATE_AT_TARGET > 0.
|
|
83
|
+
const _newRateAtTarget = (linearAdaptation) => MathLib.min(MathLib.max(MathLib.wMulDown(startRateAtTarget, wExp(linearAdaptation)), AdaptiveCurveIrmLib.MIN_RATE_AT_TARGET), AdaptiveCurveIrmLib.MAX_RATE_AT_TARGET);
|
|
84
|
+
// Formula of the average rate that should be returned to Morpho Blue:
|
|
85
|
+
// avg = 1/T * ∫_0^T curve(startRateAtTarget*exp(speed*x), err) dx
|
|
86
|
+
// The integral is approximated with the trapezoidal rule:
|
|
87
|
+
// avg ~= 1/T * Σ_i=1^N [curve(f((i-1) * T/N), err) + curve(f(i * T/N), err)] / 2 * T/N
|
|
88
|
+
// Where f(x) = startRateAtTarget*exp(speed*x)
|
|
89
|
+
// avg ~= Σ_i=1^N [curve(f((i-1) * T/N), err) + curve(f(i * T/N), err)] / (2 * N)
|
|
90
|
+
// As curve is linear in its first argument:
|
|
91
|
+
// avg ~= curve([Σ_i=1^N [f((i-1) * T/N) + f(i * T/N)] / (2 * N), err)
|
|
92
|
+
// avg ~= curve([(f(0) + f(T))/2 + Σ_i=1^(N-1) f(i * T/N)] / N, err)
|
|
93
|
+
// avg ~= curve([(startRateAtTarget + endRateAtTarget)/2 + Σ_i=1^(N-1) f(i * T/N)] / N, err)
|
|
94
|
+
// With N = 2:
|
|
95
|
+
// avg ~= curve([(startRateAtTarget + endRateAtTarget)/2 + startRateAtTarget*exp(speed*T/2)] / 2, err)
|
|
96
|
+
// avg ~= curve([startRateAtTarget + endRateAtTarget + 2*startRateAtTarget*exp(speed*T/2)] / 4, err)
|
|
97
|
+
endRateAtTarget = _newRateAtTarget(linearAdaptation);
|
|
98
|
+
avgRateAtTarget =
|
|
99
|
+
(startRateAtTarget +
|
|
100
|
+
endRateAtTarget +
|
|
101
|
+
2n * _newRateAtTarget(linearAdaptation / 2n)) /
|
|
102
|
+
4n;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Non negative because 1 - 1/C >= 0, C - 1 >= 0.
|
|
106
|
+
const coeff = err < 0
|
|
107
|
+
? MathLib.WAD - MathLib.wDivDown(MathLib.WAD, AdaptiveCurveIrmLib.CURVE_STEEPNESS)
|
|
108
|
+
: AdaptiveCurveIrmLib.CURVE_STEEPNESS - MathLib.WAD;
|
|
109
|
+
// Non negative if avgRateAtTarget >= 0 because if err < 0, coeff <= 1.
|
|
110
|
+
return {
|
|
111
|
+
avgBorrowRate: MathLib.wMulDown(MathLib.wMulDown(coeff, err) + MathLib.WAD, avgRateAtTarget),
|
|
112
|
+
endRateAtTarget,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
AdaptiveCurveIrmLib.getBorrowRate = getBorrowRate;
|
|
116
|
+
function getUtilizationAtBorrowRate(borrowRate, rateAtTarget) {
|
|
117
|
+
borrowRate = BigInt(borrowRate);
|
|
118
|
+
rateAtTarget = BigInt(rateAtTarget);
|
|
119
|
+
if (borrowRate >= rateAtTarget) {
|
|
120
|
+
const maxBorrowRate = MathLib.wMulDown(rateAtTarget, AdaptiveCurveIrmLib.CURVE_STEEPNESS);
|
|
121
|
+
const diffToMaxBorrowRate = maxBorrowRate - rateAtTarget;
|
|
122
|
+
if (diffToMaxBorrowRate === 0n)
|
|
123
|
+
return MathLib.WAD;
|
|
124
|
+
return MathLib.min(MathLib.WAD, AdaptiveCurveIrmLib.TARGET_UTILIZATION +
|
|
125
|
+
MathLib.mulDivDown(MathLib.WAD - AdaptiveCurveIrmLib.TARGET_UTILIZATION, borrowRate - rateAtTarget, diffToMaxBorrowRate));
|
|
126
|
+
}
|
|
127
|
+
const minBorrowRate = MathLib.wDivDown(rateAtTarget, AdaptiveCurveIrmLib.CURVE_STEEPNESS);
|
|
128
|
+
return MathLib.max(0n, MathLib.mulDivDown(AdaptiveCurveIrmLib.TARGET_UTILIZATION, borrowRate - minBorrowRate, rateAtTarget - minBorrowRate));
|
|
129
|
+
}
|
|
130
|
+
AdaptiveCurveIrmLib.getUtilizationAtBorrowRate = getUtilizationAtBorrowRate;
|
|
131
|
+
})(AdaptiveCurveIrmLib || (AdaptiveCurveIrmLib = {}));
|