@gearbox-protocol/sdk 3.0.0-next.189 → 3.0.0-next.190
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.
|
@@ -17,6 +17,13 @@ export interface CalcOverallAPYProps {
|
|
|
17
17
|
baseRateWithFee: number;
|
|
18
18
|
underlyingToken: string;
|
|
19
19
|
}
|
|
20
|
+
export interface CalcMaxLendingDebtProps {
|
|
21
|
+
assets: Array<Asset>;
|
|
22
|
+
prices: Record<string, bigint>;
|
|
23
|
+
liquidationThresholds: Record<string, bigint>;
|
|
24
|
+
underlyingToken: string;
|
|
25
|
+
targetHF?: bigint;
|
|
26
|
+
}
|
|
20
27
|
export interface CalcHealthFactorProps {
|
|
21
28
|
assets: Array<Asset>;
|
|
22
29
|
quotas: Record<string, Asset>;
|
|
@@ -115,6 +122,7 @@ export declare class CreditAccountData {
|
|
|
115
122
|
isQuoted(token: string): boolean;
|
|
116
123
|
isTokenEnabled(token: string): boolean;
|
|
117
124
|
static calcMaxDebtIncrease(healthFactor: number, debt: bigint, underlyingLT: number, minHf?: number): bigint;
|
|
125
|
+
static calcMaxLendingDebt({ assets, liquidationThresholds, underlyingToken, prices, targetHF, }: CalcMaxLendingDebtProps): bigint;
|
|
118
126
|
static calcOverallAPY({ caAssets, lpAPY, prices, quotas, quotaRates, feeInterest, totalValue, debt, baseRateWithFee, underlyingToken, }: CalcOverallAPYProps): bigint | undefined;
|
|
119
127
|
hash(): string;
|
|
120
128
|
static hash(creditManager: string, borrower: string): string;
|
|
@@ -155,9 +155,33 @@ class CreditAccountData {
|
|
|
155
155
|
return this.allBalances[token].isEnabled;
|
|
156
156
|
}
|
|
157
157
|
static calcMaxDebtIncrease(healthFactor, debt, underlyingLT, minHf = Number(sdk_gov_1.PERCENTAGE_FACTOR)) {
|
|
158
|
+
// HF = (TWV + d*lt) / (D + d) => d = (HF*D - TWV) / (l - HF)
|
|
159
|
+
// hf = TWV / D
|
|
160
|
+
// HF = (TVW * D / D + d*lt) / (D + d) = (hf*D + d*lt) / (d + D) => d = D * (hf-HF) / (HF - lt)
|
|
158
161
|
const result = (debt * BigInt(healthFactor - minHf)) / BigInt(minHf - underlyingLT);
|
|
159
162
|
return math_1.BigIntMath.max(0n, result);
|
|
160
163
|
}
|
|
164
|
+
static calcMaxLendingDebt({ assets, liquidationThresholds, underlyingToken, prices, targetHF = sdk_gov_1.PERCENTAGE_FACTOR, }) {
|
|
165
|
+
const assetsLTMoney = assets.reduce((acc, { token: tokenAddress, balance: amount }) => {
|
|
166
|
+
const [, tokenDecimals] = (0, sdk_gov_1.extractTokenData)(tokenAddress);
|
|
167
|
+
const lt = liquidationThresholds[tokenAddress] || 0n;
|
|
168
|
+
const price = prices[tokenAddress] || 0n;
|
|
169
|
+
const tokenMoney = price_1.PriceUtils.calcTotalPrice(price, amount, tokenDecimals);
|
|
170
|
+
const tokenLtMoney = tokenMoney * lt;
|
|
171
|
+
return acc + tokenLtMoney;
|
|
172
|
+
}, 0n);
|
|
173
|
+
const underlyingPrice = prices[underlyingToken] || 0n;
|
|
174
|
+
const [, underlyingDecimals = 18] = (0, sdk_gov_1.extractTokenData)(underlyingToken);
|
|
175
|
+
// HF = TWV / D => D = TWV / HF; D = amount * price
|
|
176
|
+
// Debt_max = sum(LT_i * Asset_i * price_i) / (price_underlying * HF)
|
|
177
|
+
const max = underlyingPrice > 0
|
|
178
|
+
? (assetsLTMoney * 10n ** BigInt(underlyingDecimals)) /
|
|
179
|
+
underlyingPrice /
|
|
180
|
+
targetHF /
|
|
181
|
+
10n ** BigInt(sdk_gov_1.WAD_DECIMALS_POW - sdk_gov_1.PRICE_DECIMALS_POW)
|
|
182
|
+
: 0n;
|
|
183
|
+
return max;
|
|
184
|
+
}
|
|
161
185
|
static calcOverallAPY({ caAssets, lpAPY, prices, quotas, quotaRates, feeInterest, totalValue, debt, baseRateWithFee, underlyingToken, }) {
|
|
162
186
|
if (!lpAPY ||
|
|
163
187
|
!totalValue ||
|
|
@@ -171,10 +195,9 @@ class CreditAccountData {
|
|
|
171
195
|
const underlyingPrice = prices[underlyingTokenAddressLC];
|
|
172
196
|
const assetAPYMoney = caAssets.reduce((acc, { token: tokenAddress, balance: amount }) => {
|
|
173
197
|
const tokenAddressLC = tokenAddress.toLowerCase();
|
|
174
|
-
const symbol = sdk_gov_1.
|
|
198
|
+
const [symbol = "", tokenDecimals] = (0, sdk_gov_1.extractTokenData)(tokenAddressLC);
|
|
175
199
|
const apy = lpAPY[symbol] || 0;
|
|
176
200
|
const price = prices[tokenAddressLC] || 0n;
|
|
177
|
-
const tokenDecimals = sdk_gov_1.decimals[symbol];
|
|
178
201
|
const money = price_1.PriceUtils.calcTotalPrice(price, amount, tokenDecimals);
|
|
179
202
|
const apyMoney = money * BigInt(apy);
|
|
180
203
|
const { rate: quotaAPY = 0n, isActive = false } = quotaRates?.[tokenAddressLC] || {};
|
|
@@ -9,6 +9,7 @@ const creditAccount_1 = require("./creditAccount");
|
|
|
9
9
|
const prices = {
|
|
10
10
|
[sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase()]: (0, formatter_1.toBN)("1738.11830000", sdk_gov_1.PRICE_DECIMALS_POW),
|
|
11
11
|
[sdk_gov_1.tokenDataByNetwork.Mainnet.DAI.toLowerCase()]: (0, formatter_1.toBN)("0.99941103", sdk_gov_1.PRICE_DECIMALS_POW),
|
|
12
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.USDC.toLowerCase()]: (0, formatter_1.toBN)("0.999", sdk_gov_1.PRICE_DECIMALS_POW),
|
|
12
13
|
[sdk_gov_1.tokenDataByNetwork.Mainnet.STETH.toLowerCase()]: (0, formatter_1.toBN)("1703.87588096", sdk_gov_1.PRICE_DECIMALS_POW),
|
|
13
14
|
};
|
|
14
15
|
const lpAPY = { STETH: 38434 };
|
|
@@ -195,7 +196,7 @@ describe("CreditAccount CreditAccountData.calcOverallAPY test", () => {
|
|
|
195
196
|
(0, chai_1.expect)(result).to.be.eq(144919n);
|
|
196
197
|
});
|
|
197
198
|
});
|
|
198
|
-
describe("CreditAccount
|
|
199
|
+
describe("CreditAccount calcMaxDebtIncrease test", () => {
|
|
199
200
|
it("health max increase borrow is zero if hf < 1", () => {
|
|
200
201
|
const result = creditAccount_1.CreditAccountData.calcMaxDebtIncrease(9999, BigInt("156522834253690396032546"), 9300);
|
|
201
202
|
(0, chai_1.expect)(result.toString()).to.be.eq("0");
|
|
@@ -211,9 +212,121 @@ describe("CreditAccount calcMaxIncreaseBorrow test", () => {
|
|
|
211
212
|
});
|
|
212
213
|
});
|
|
213
214
|
const liquidationThresholds = {
|
|
215
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.USDC.toLowerCase()]: 9800n,
|
|
214
216
|
[sdk_gov_1.tokenDataByNetwork.Mainnet.DAI.toLowerCase()]: 9300n,
|
|
215
217
|
[sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase()]: 8500n,
|
|
218
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.STETH.toLowerCase()]: 8000n,
|
|
216
219
|
};
|
|
220
|
+
describe("CreditAccount calcMaxLendingDebt test", () => {
|
|
221
|
+
it("calcMaxLendingDebt for several collaterals with zero lt", () => {
|
|
222
|
+
const result = creditAccount_1.CreditAccountData.calcMaxLendingDebt({
|
|
223
|
+
assets: [
|
|
224
|
+
{
|
|
225
|
+
token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI.toLowerCase(),
|
|
226
|
+
balance: (0, formatter_1.toBN)("1000", sdk_gov_1.decimals.DAI),
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase(),
|
|
230
|
+
balance: (0, formatter_1.toBN)("1", sdk_gov_1.decimals.WETH),
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
liquidationThresholds: {
|
|
234
|
+
...liquidationThresholds,
|
|
235
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.DAI.toLowerCase()]: 0n,
|
|
236
|
+
},
|
|
237
|
+
underlyingToken: sdk_gov_1.tokenDataByNetwork.Mainnet.USDC.toLowerCase(),
|
|
238
|
+
prices: {
|
|
239
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.DAI.toLowerCase()]: 1n,
|
|
240
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.USDC.toLowerCase()]: 1n,
|
|
241
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase()]: 1000n,
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
(0, chai_1.expect)(result).to.be.eq((0, formatter_1.toBN)("850", sdk_gov_1.decimals.USDC));
|
|
245
|
+
});
|
|
246
|
+
it("calcMaxLendingDebt for several collaterals with zero underlying price", () => {
|
|
247
|
+
const result = creditAccount_1.CreditAccountData.calcMaxLendingDebt({
|
|
248
|
+
assets: [
|
|
249
|
+
{
|
|
250
|
+
token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI.toLowerCase(),
|
|
251
|
+
balance: (0, formatter_1.toBN)("1000", sdk_gov_1.decimals.DAI),
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase(),
|
|
255
|
+
balance: (0, formatter_1.toBN)("1", sdk_gov_1.decimals.WETH),
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
liquidationThresholds: liquidationThresholds,
|
|
259
|
+
underlyingToken: sdk_gov_1.tokenDataByNetwork.Mainnet.USDC.toLowerCase(),
|
|
260
|
+
prices: {
|
|
261
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.DAI.toLowerCase()]: 1n,
|
|
262
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase()]: 1000n,
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
(0, chai_1.expect)(result).to.be.eq(0n);
|
|
266
|
+
});
|
|
267
|
+
it("calcMaxLendingDebt for simplest case", () => {
|
|
268
|
+
const result = creditAccount_1.CreditAccountData.calcMaxLendingDebt({
|
|
269
|
+
assets: [
|
|
270
|
+
{
|
|
271
|
+
token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI.toLowerCase(),
|
|
272
|
+
balance: (0, formatter_1.toBN)("1000", sdk_gov_1.decimals.DAI),
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
liquidationThresholds,
|
|
276
|
+
underlyingToken: sdk_gov_1.tokenDataByNetwork.Mainnet.USDC.toLowerCase(),
|
|
277
|
+
prices: {
|
|
278
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.DAI.toLowerCase()]: 1n,
|
|
279
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.USDC.toLowerCase()]: 1n,
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
(0, chai_1.expect)(result).to.be.eq((0, formatter_1.toBN)("930", sdk_gov_1.decimals.USDC));
|
|
283
|
+
});
|
|
284
|
+
it("calcMaxLendingDebt for several collaterals", () => {
|
|
285
|
+
const result = creditAccount_1.CreditAccountData.calcMaxLendingDebt({
|
|
286
|
+
assets: [
|
|
287
|
+
{
|
|
288
|
+
token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI.toLowerCase(),
|
|
289
|
+
balance: (0, formatter_1.toBN)("1000", sdk_gov_1.decimals.DAI),
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase(),
|
|
293
|
+
balance: (0, formatter_1.toBN)("1", sdk_gov_1.decimals.WETH),
|
|
294
|
+
},
|
|
295
|
+
],
|
|
296
|
+
liquidationThresholds,
|
|
297
|
+
underlyingToken: sdk_gov_1.tokenDataByNetwork.Mainnet.USDC.toLowerCase(),
|
|
298
|
+
prices: {
|
|
299
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.DAI.toLowerCase()]: 1n,
|
|
300
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.USDC.toLowerCase()]: 1n,
|
|
301
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase()]: 1000n,
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
(0, chai_1.expect)(result).to.be.eq((0, formatter_1.toBN)("1780", sdk_gov_1.decimals.USDC));
|
|
305
|
+
});
|
|
306
|
+
it("calcMaxLendingDebt for several collaterals with target HF", () => {
|
|
307
|
+
const result = creditAccount_1.CreditAccountData.calcMaxLendingDebt({
|
|
308
|
+
assets: [
|
|
309
|
+
{
|
|
310
|
+
token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI.toLowerCase(),
|
|
311
|
+
balance: (0, formatter_1.toBN)("1000", sdk_gov_1.decimals.DAI),
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase(),
|
|
315
|
+
balance: (0, formatter_1.toBN)("1", sdk_gov_1.decimals.WETH),
|
|
316
|
+
},
|
|
317
|
+
],
|
|
318
|
+
liquidationThresholds,
|
|
319
|
+
underlyingToken: sdk_gov_1.tokenDataByNetwork.Mainnet.USDC.toLowerCase(),
|
|
320
|
+
prices: {
|
|
321
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.DAI.toLowerCase()]: 1n,
|
|
322
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.USDC.toLowerCase()]: 1n,
|
|
323
|
+
[sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase()]: 1000n,
|
|
324
|
+
},
|
|
325
|
+
targetHF: 12500n,
|
|
326
|
+
});
|
|
327
|
+
(0, chai_1.expect)(result).to.be.eq((0, formatter_1.toBN)("1424", sdk_gov_1.decimals.USDC));
|
|
328
|
+
});
|
|
329
|
+
});
|
|
217
330
|
const defaultCA = {
|
|
218
331
|
assets: [
|
|
219
332
|
{
|