@gearbox-protocol/sdk 3.0.0-next.93 → 3.0.0-next.95

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.
@@ -3,7 +3,8 @@ export declare const stEthPoolWrapper: Record<NetworkType, string>;
3
3
  type MainnetCreditManagersV1 = "DAI_V1" | "USDC_V1" | "WETH_V1" | "WBTC_V1";
4
4
  type MainnetCreditManagersV2 = "DAI_V2" | "USDC_V2" | "WETH_V2" | "WSTETH_V2" | "WBTC_V2" | "FRAX_V2";
5
5
  type MainnetCreditManagersV2_1 = "WETH_V2_1";
6
- export type MainnetCreditManagers = MainnetCreditManagersV1 | MainnetCreditManagersV2 | MainnetCreditManagersV2_1;
6
+ type MainnetCreditManagersV3 = "USDC_V3_TRADE_TIER_1" | "USDC_V3_TRADE_TIER_2" | "USDC_V3_TRADE_TIER_3" | "WBTC_V3_TRADE_TIER_1" | "WBTC_V3_TRADE_TIER_2" | "WBTC_V3_TRADE_TIER_3" | "WETH_V3_TRADE_TIER_1" | "WETH_V3_TRADE_TIER_2" | "WETH_V3_TRADE_TIER_3";
7
+ export type MainnetCreditManagers = MainnetCreditManagersV1 | MainnetCreditManagersV2 | MainnetCreditManagersV2_1 | MainnetCreditManagersV3;
7
8
  export type ArbitrumCreditManagers = never;
8
9
  type CreditManagersListType = {
9
10
  [key in NetworkType]: key extends "Mainnet" ? Record<MainnetCreditManagers, string> : key extends "Arbitrum" ? Record<ArbitrumCreditManagers, string> : never;
@@ -11,7 +12,9 @@ type CreditManagersListType = {
11
12
  export declare const creditManagerByNetwork: CreditManagersListType;
12
13
  export type SupportedCreditManagers = MainnetCreditManagers | ArbitrumCreditManagers;
13
14
  export declare const creditManagerByAddress: Record<string, SupportedCreditManagers>;
14
- export type MainnetPools = "DAI_V1" | "USDC_V1" | "WETH_V1" | "WBTC_V1" | "WSTETH_V1" | "FRAX_V1";
15
+ export type MainnetPoolsV1 = "DAI_V1" | "USDC_V1" | "WETH_V1" | "WBTC_V1" | "WSTETH_V1" | "FRAX_V1";
16
+ export type MainnetPoolsV3 = "USDC_V3_TRADE" | "WETH_V3_TRADE" | "WBTC_V3_TRADE";
17
+ export type MainnetPools = MainnetPoolsV1 | MainnetPoolsV3;
15
18
  export type ArbitrumPools = never;
16
19
  type PoolsListType = {
17
20
  [key in NetworkType]: key extends "Mainnet" ? Record<MainnetPools, string> : key extends "Arbitrum" ? Record<ArbitrumPools, string> : never;
@@ -19,6 +19,15 @@ exports.creditManagerByNetwork = {
19
19
  WBTC_V2: "0xc62BF8a7889AdF1c5Dc4665486c7683ae6E74e0F".toLowerCase(),
20
20
  FRAX_V2: "0xA3E1e0d58FE8dD8C9dd48204699a1178f1B274D8".toLowerCase(),
21
21
  WETH_V2_1: "0x4C6309fe2085EfE7A0Cfb426C16Ef3b41198cCE3".toLowerCase(),
22
+ USDC_V3_TRADE_TIER_1: "0x3eb95430fdb99439a86d3c6d7d01c3c561393556".toLowerCase(),
23
+ USDC_V3_TRADE_TIER_2: "0xea7c28428d3916dbe2f113b8a6e6dd0f3819c050".toLowerCase(),
24
+ USDC_V3_TRADE_TIER_3: "0x4e94cd228ef386ebc32900ec745d1865934688a3".toLowerCase(),
25
+ WBTC_V3_TRADE_TIER_1: "0xefc134755aaf89fe84476946251680bece41246e".toLowerCase(),
26
+ WBTC_V3_TRADE_TIER_2: "0xcac3e41b9bad20e2aa35e150de96eefb2d043735".toLowerCase(),
27
+ WBTC_V3_TRADE_TIER_3: "0x46709ca16b1ffea5d6c6bb6b7e77dd9e3b4908ed".toLowerCase(),
28
+ WETH_V3_TRADE_TIER_1: "0xa30099925b14b00b76ae2efe2639cd01598fe68a".toLowerCase(),
29
+ WETH_V3_TRADE_TIER_2: "0x3f11758aca3f2eb7a27828c9cbcd0b347944ac14".toLowerCase(),
30
+ WETH_V3_TRADE_TIER_3: "0x0b2486355e987586c32fc0feefe2943e396c484e".toLowerCase(),
22
31
  },
23
32
  Arbitrum: {},
24
33
  };
@@ -36,6 +45,9 @@ exports.poolByNetwork = {
36
45
  WBTC_V1: "0xB2A015c71c17bCAC6af36645DEad8c572bA08A08".toLowerCase(),
37
46
  WSTETH_V1: "0xB8cf3Ed326bB0E51454361Fb37E9E8df6DC5C286".toLowerCase(),
38
47
  FRAX_V1: "0x79012c8d491dcf3a30db20d1f449b14caf01da6c".toLowerCase(),
48
+ USDC_V3_TRADE: "0xda00000035fef4082f78def6a8903bee419fbf8e".toLowerCase(),
49
+ WBTC_V3_TRADE: "0xda00010eda646913f273e10e7a5d1f659242757d".toLowerCase(),
50
+ WETH_V3_TRADE: "0xda0002859b2d05f66a753d8241fcde8623f26f4f".toLowerCase(),
39
51
  },
40
52
  Arbitrum: {},
41
53
  };
@@ -8,10 +8,11 @@ export interface CalcOverallAPYProps {
8
8
  lpAPY: LpTokensAPY | undefined;
9
9
  quotas: Record<string, Asset>;
10
10
  quotaRates: Record<string, Pick<QuotaInfo, "isActive" | "rate">>;
11
+ feeInterest: number;
11
12
  prices: Record<string, bigint>;
12
13
  totalValue: bigint | undefined;
13
14
  debt: bigint | undefined;
14
- baseBorrowRate: number;
15
+ baseRateWithFee: number;
15
16
  underlyingToken: string;
16
17
  }
17
18
  export interface CalcHealthFactorProps {
@@ -21,7 +22,7 @@ export interface CalcHealthFactorProps {
21
22
  prices: Record<string, bigint>;
22
23
  liquidationThresholds: Record<string, bigint>;
23
24
  underlyingToken: string;
24
- borrowed: bigint;
25
+ debt: bigint;
25
26
  }
26
27
  export interface CalcQuotaUpdateProps {
27
28
  quotas: Record<string, Pick<QuotaInfo, "isActive" | "token">>;
@@ -39,7 +40,17 @@ interface CalcQuotaUpdateReturnType {
39
40
  export interface CalcQuotaBorrowRateProps {
40
41
  quotas: Record<string, Asset>;
41
42
  quotaRates: Record<string, Pick<QuotaInfo, "isActive" | "rate">>;
42
- borrowAmount: bigint;
43
+ }
44
+ export interface CalcRelativeBaseBorrowRateProps {
45
+ debt: bigint;
46
+ baseRateWithFee: number;
47
+ assetAmountInUnderlying: bigint;
48
+ totalValue: bigint;
49
+ }
50
+ export interface CalcAvgQuotaBorrowRateProps {
51
+ quotas: Record<string, Asset>;
52
+ quotaRates: Record<string, Pick<QuotaInfo, "isActive" | "rate">>;
53
+ totalValue: bigint;
43
54
  }
44
55
  export declare class CreditAccountData {
45
56
  readonly isSuccessful: boolean;
@@ -55,8 +66,8 @@ export declare class CreditAccountData {
55
66
  readonly enabledTokenMask: bigint;
56
67
  readonly healthFactor: number;
57
68
  isDeleting: boolean;
58
- readonly baseBorrowRate: number;
59
- readonly borrowRate: number;
69
+ readonly baseBorrowRateWithoutFee: number;
70
+ readonly borrowRateWithoutFee: number;
60
71
  readonly borrowedAmount: bigint;
61
72
  readonly accruedInterest: bigint;
62
73
  readonly accruedFees: bigint;
@@ -81,12 +92,13 @@ export declare class CreditAccountData {
81
92
  isForbidden(token: string): boolean;
82
93
  isQuoted(token: string): boolean;
83
94
  isTokenEnabled(token: string): boolean;
84
- static calcMaxDebtIncrease(healthFactor: number, borrowAmountPlusInterest: bigint, underlyingLT: number, minHf?: number): bigint;
85
- static calcOverallAPY({ caAssets, lpAPY, prices, quotas, quotaRates, totalValue, debt, baseBorrowRate, underlyingToken, }: CalcOverallAPYProps): bigint | undefined;
95
+ static calcMaxDebtIncrease(healthFactor: number, debt: bigint, underlyingLT: number, minHf?: number): bigint;
96
+ static calcOverallAPY({ caAssets, lpAPY, prices, quotas, quotaRates, feeInterest, totalValue, debt, baseRateWithFee, underlyingToken, }: CalcOverallAPYProps): bigint | undefined;
86
97
  hash(): string;
87
98
  static hash(creditManager: string, borrower: string): string;
88
- static calcHealthFactor({ assets, quotas, quotasInfo, liquidationThresholds, underlyingToken, borrowed, prices, }: CalcHealthFactorProps): number;
99
+ static calcHealthFactor({ assets, quotas, quotasInfo, liquidationThresholds, underlyingToken, debt, prices, }: CalcHealthFactorProps): number;
89
100
  static calcQuotaUpdate({ quotas, initialQuotas, assetsAfterUpdate, allowedToSpend, allowedToObtain, quotaReserve, }: CalcQuotaUpdateProps): CalcQuotaUpdateReturnType;
90
- static calcQuotaBorrowRate({ quotas, quotaRates, borrowAmount, }: CalcQuotaBorrowRateProps): number;
101
+ static calcQuotaBorrowRate({ quotas, quotaRates }: CalcQuotaBorrowRateProps): bigint;
102
+ static calcRelativeBaseBorrowRate({ debt, baseRateWithFee, assetAmountInUnderlying, totalValue, }: CalcRelativeBaseBorrowRateProps): bigint;
91
103
  }
92
104
  export {};
@@ -19,8 +19,8 @@ class CreditAccountData {
19
19
  enabledTokenMask;
20
20
  healthFactor;
21
21
  isDeleting;
22
- baseBorrowRate;
23
- borrowRate;
22
+ baseBorrowRateWithoutFee;
23
+ borrowRateWithoutFee;
24
24
  borrowedAmount;
25
25
  accruedInterest;
26
26
  accruedFees;
@@ -60,10 +60,10 @@ class CreditAccountData {
60
60
  this.totalValue = (0, sdk_gov_1.toBigInt)(payload.totalValue || 0n);
61
61
  this.totalValueUSD = (0, sdk_gov_1.toBigInt)(payload.totalValueUSD);
62
62
  this.twvUSD = (0, sdk_gov_1.toBigInt)(payload.twvUSD);
63
- this.baseBorrowRate = (0, formatter_1.rayToNumber)((0, sdk_gov_1.toBigInt)(payload.baseBorrowRate) *
63
+ this.baseBorrowRateWithoutFee = (0, formatter_1.rayToNumber)((0, sdk_gov_1.toBigInt)(payload.baseBorrowRate) *
64
64
  sdk_gov_1.PERCENTAGE_DECIMALS *
65
65
  sdk_gov_1.PERCENTAGE_FACTOR);
66
- this.borrowRate = (0, formatter_1.rayToNumber)((0, sdk_gov_1.toBigInt)(payload.aggregatedBorrowRate) *
66
+ this.borrowRateWithoutFee = (0, formatter_1.rayToNumber)((0, sdk_gov_1.toBigInt)(payload.aggregatedBorrowRate) *
67
67
  sdk_gov_1.PERCENTAGE_DECIMALS *
68
68
  sdk_gov_1.PERCENTAGE_FACTOR);
69
69
  this.cumulativeIndexLastUpdate = (0, sdk_gov_1.toBigInt)(payload.cumulativeIndexLastUpdate);
@@ -132,12 +132,11 @@ class CreditAccountData {
132
132
  isTokenEnabled(token) {
133
133
  return this.allBalances[token].isEnabled;
134
134
  }
135
- static calcMaxDebtIncrease(healthFactor, borrowAmountPlusInterest, underlyingLT, minHf = Number(sdk_gov_1.PERCENTAGE_FACTOR)) {
136
- const result = (borrowAmountPlusInterest * BigInt(healthFactor - minHf)) /
137
- BigInt(minHf - underlyingLT);
135
+ static calcMaxDebtIncrease(healthFactor, debt, underlyingLT, minHf = Number(sdk_gov_1.PERCENTAGE_FACTOR)) {
136
+ const result = (debt * BigInt(healthFactor - minHf)) / BigInt(minHf - underlyingLT);
138
137
  return math_1.BigIntMath.max(0n, result);
139
138
  }
140
- static calcOverallAPY({ caAssets, lpAPY, prices, quotas, quotaRates, totalValue, debt, baseBorrowRate, underlyingToken, }) {
139
+ static calcOverallAPY({ caAssets, lpAPY, prices, quotas, quotaRates, feeInterest, totalValue, debt, baseRateWithFee, underlyingToken, }) {
141
140
  if (!lpAPY ||
142
141
  !totalValue ||
143
142
  totalValue <= 0n ||
@@ -160,14 +159,16 @@ class CreditAccountData {
160
159
  const { balance: quotaBalance = 0n } = quotas[tokenAddressLC] || {};
161
160
  const quotaAmount = isActive ? quotaBalance : 0n;
162
161
  const quotaMoney = price_1.PriceUtils.calcTotalPrice(underlyingPrice || 0n, quotaAmount, underlyingTokenDecimals);
163
- const quotaAPYMoney = quotaMoney * BigInt(quotaAPY);
162
+ const quotaRate = ((0, sdk_gov_1.toBigInt)(quotaAPY) * (BigInt(feeInterest) + sdk_gov_1.PERCENTAGE_FACTOR)) /
163
+ sdk_gov_1.PERCENTAGE_FACTOR;
164
+ const quotaAPYMoney = quotaMoney * quotaRate;
164
165
  return acc + apyMoney - quotaAPYMoney;
165
166
  }, 0n);
166
167
  const assetAPYAmountInUnderlying = price_1.PriceUtils.convertByPrice(assetAPYMoney, {
167
168
  price: underlyingPrice || sdk_gov_1.PRICE_DECIMALS,
168
169
  decimals: underlyingTokenDecimals,
169
170
  });
170
- const debtAPY = debt * BigInt(baseBorrowRate);
171
+ const debtAPY = debt * BigInt(baseRateWithFee);
171
172
  const yourAssets = totalValue - debt;
172
173
  const apyInPercent = (assetAPYAmountInUnderlying - debtAPY) / yourAssets;
173
174
  return apyInPercent;
@@ -178,7 +179,7 @@ class CreditAccountData {
178
179
  static hash(creditManager, borrower) {
179
180
  return `${creditManager.toLowerCase()}:${borrower.toLowerCase()}`;
180
181
  }
181
- static calcHealthFactor({ assets, quotas, quotasInfo, liquidationThresholds, underlyingToken, borrowed, prices, }) {
182
+ static calcHealthFactor({ assets, quotas, quotasInfo, liquidationThresholds, underlyingToken, debt, prices, }) {
182
183
  const [, underlyingDecimals] = (0, sdk_gov_1.extractTokenData)(underlyingToken);
183
184
  const underlyingPrice = prices[underlyingToken] || 0n;
184
185
  const assetLTMoney = assets.reduce((acc, { token: tokenAddress, balance: amount }) => {
@@ -197,7 +198,7 @@ class CreditAccountData {
197
198
  const ltMoney = money * lt;
198
199
  return acc + ltMoney;
199
200
  }, 0n);
200
- const borrowedMoney = price_1.PriceUtils.calcTotalPrice(underlyingPrice || sdk_gov_1.PRICE_DECIMALS, borrowed, underlyingDecimals);
201
+ const borrowedMoney = price_1.PriceUtils.calcTotalPrice(underlyingPrice || sdk_gov_1.PRICE_DECIMALS, debt, underlyingDecimals);
201
202
  const hfInPercent = borrowedMoney > 0n ? assetLTMoney / borrowedMoney : 0n;
202
203
  return Number(hfInPercent);
203
204
  }
@@ -247,17 +248,19 @@ class CreditAccountData {
247
248
  }, { desiredQuota: {}, quotaIncrease: [], quotaDecrease: [] });
248
249
  return r;
249
250
  }
250
- static calcQuotaBorrowRate({ quotas, quotaRates, borrowAmount, }) {
251
- if (borrowAmount <= 0)
252
- return 0;
251
+ static calcQuotaBorrowRate({ quotas, quotaRates }) {
253
252
  const totalRateBalance = Object.values(quotas).reduce((acc, { token, balance }) => {
254
253
  const { rate = 0, isActive = false } = quotaRates?.[token] || {};
255
254
  const quotaBalance = isActive ? balance : 0n;
256
255
  const rateBalance = quotaBalance * BigInt(rate);
257
256
  return acc + rateBalance;
258
257
  }, 0n);
259
- const quotaBorrowRate = Number(totalRateBalance / borrowAmount);
260
- return quotaBorrowRate;
258
+ return totalRateBalance;
259
+ }
260
+ static calcRelativeBaseBorrowRate({ debt, baseRateWithFee, assetAmountInUnderlying, totalValue, }) {
261
+ if (totalValue === 0n)
262
+ return 0n;
263
+ return ((debt * BigInt(baseRateWithFee) * assetAmountInUnderlying) / totalValue);
261
264
  }
262
265
  }
263
266
  exports.CreditAccountData = CreditAccountData;
@@ -75,10 +75,11 @@ describe("CreditAccount CreditAccountData.calcOverallAPY test", () => {
75
75
  caAssets: caWithoutLP.assets,
76
76
  totalValue: caWithoutLP.totalValue,
77
77
  debt: caWithoutLP.debt,
78
- baseBorrowRate: caWithoutLP.borrowRate,
78
+ baseRateWithFee: caWithoutLP.borrowRate,
79
79
  underlyingToken: caWithoutLP.underlyingToken,
80
80
  quotaRates: {},
81
81
  quotas: {},
82
+ feeInterest: 0,
82
83
  lpAPY,
83
84
  prices,
84
85
  });
@@ -89,10 +90,11 @@ describe("CreditAccount CreditAccountData.calcOverallAPY test", () => {
89
90
  caAssets: caWithLP.assets,
90
91
  totalValue: caWithLP.totalValue,
91
92
  debt: caWithLP.debt,
92
- baseBorrowRate: caWithLP.borrowRate,
93
+ baseRateWithFee: caWithLP.borrowRate,
93
94
  underlyingToken: caWithLP.underlyingToken,
94
95
  quotaRates: {},
95
96
  quotas: {},
97
+ feeInterest: 0,
96
98
  lpAPY,
97
99
  prices,
98
100
  });
@@ -103,10 +105,11 @@ describe("CreditAccount CreditAccountData.calcOverallAPY test", () => {
103
105
  caAssets: caWithLP.assets,
104
106
  totalValue: caWithLP.totalValue,
105
107
  debt: caWithLP.debt,
106
- baseBorrowRate: caWithLP.borrowRate,
108
+ baseRateWithFee: caWithLP.borrowRate,
107
109
  underlyingToken: caWithLP.underlyingToken,
108
110
  quotaRates: {},
109
111
  quotas: {},
112
+ feeInterest: 0,
110
113
  lpAPY: undefined,
111
114
  prices,
112
115
  });
@@ -117,10 +120,11 @@ describe("CreditAccount CreditAccountData.calcOverallAPY test", () => {
117
120
  caAssets: caWithLP.assets,
118
121
  totalValue: undefined,
119
122
  debt: caWithLP.debt,
120
- baseBorrowRate: caWithLP.borrowRate,
123
+ baseRateWithFee: caWithLP.borrowRate,
121
124
  underlyingToken: caWithLP.underlyingToken,
122
125
  quotaRates: {},
123
126
  quotas: {},
127
+ feeInterest: 0,
124
128
  lpAPY,
125
129
  prices,
126
130
  });
@@ -131,10 +135,11 @@ describe("CreditAccount CreditAccountData.calcOverallAPY test", () => {
131
135
  caAssets: caWithLP.assets,
132
136
  totalValue: caWithLP.totalValue,
133
137
  debt: undefined,
134
- baseBorrowRate: caWithLP.borrowRate,
138
+ baseRateWithFee: caWithLP.borrowRate,
135
139
  underlyingToken: caWithLP.underlyingToken,
136
140
  quotaRates: {},
137
141
  quotas: {},
142
+ feeInterest: 0,
138
143
  lpAPY,
139
144
  prices,
140
145
  });
@@ -145,10 +150,11 @@ describe("CreditAccount CreditAccountData.calcOverallAPY test", () => {
145
150
  caAssets: caWithLP.assets,
146
151
  totalValue: 0n,
147
152
  debt: undefined,
148
- baseBorrowRate: caWithLP.borrowRate,
153
+ baseRateWithFee: caWithLP.borrowRate,
149
154
  underlyingToken: caWithLP.underlyingToken,
150
155
  quotaRates: {},
151
156
  quotas: {},
157
+ feeInterest: 0,
152
158
  lpAPY,
153
159
  prices,
154
160
  });
@@ -159,10 +165,11 @@ describe("CreditAccount CreditAccountData.calcOverallAPY test", () => {
159
165
  caAssets: caWithLP.assets,
160
166
  totalValue: caWithLP.totalValue,
161
167
  debt: caWithLP.debt,
162
- baseBorrowRate: caWithLP.borrowRate,
168
+ baseRateWithFee: caWithLP.borrowRate,
163
169
  underlyingToken: caWithLP.underlyingToken,
164
170
  quotaRates: caWithLP.rates,
165
171
  quotas: caWithLP.quotas,
172
+ feeInterest: 0,
166
173
  lpAPY,
167
174
  prices,
168
175
  });
@@ -173,7 +180,7 @@ describe("CreditAccount CreditAccountData.calcOverallAPY test", () => {
173
180
  caAssets: caWithLP.assets,
174
181
  totalValue: caWithLP.totalValue,
175
182
  debt: caWithLP.debt,
176
- baseBorrowRate: caWithLP.borrowRate,
183
+ baseRateWithFee: caWithLP.borrowRate,
177
184
  underlyingToken: caWithLP.underlyingToken,
178
185
  quotaRates: caWithLP.rates,
179
186
  quotas: {
@@ -182,6 +189,7 @@ describe("CreditAccount CreditAccountData.calcOverallAPY test", () => {
182
189
  token: sdk_gov_1.tokenDataByNetwork.Mainnet.STETH.toLowerCase(),
183
190
  },
184
191
  },
192
+ feeInterest: 0,
185
193
  lpAPY,
186
194
  prices,
187
195
  });
@@ -243,7 +251,7 @@ describe("CreditAccount calcHealthFactor test", () => {
243
251
  prices,
244
252
  liquidationThresholds,
245
253
  underlyingToken: defaultCA.underlyingToken,
246
- borrowed: defaultCA.debt,
254
+ debt: defaultCA.debt,
247
255
  });
248
256
  (0, chai_1.expect)(result).to.be.eq(defaultCA.healthFactor);
249
257
  });
@@ -255,7 +263,7 @@ describe("CreditAccount calcHealthFactor test", () => {
255
263
  prices: {},
256
264
  liquidationThresholds: {},
257
265
  underlyingToken: "",
258
- borrowed: 0n,
266
+ debt: 0n,
259
267
  });
260
268
  (0, chai_1.expect)(result).to.be.eq(0);
261
269
  });
@@ -272,7 +280,7 @@ describe("CreditAccount calcHealthFactor test", () => {
272
280
  prices,
273
281
  liquidationThresholds,
274
282
  underlyingToken: defaultCA.underlyingToken,
275
- borrowed: defaultCA.debt,
283
+ debt: defaultCA.debt,
276
284
  });
277
285
  (0, chai_1.expect)(result).to.be.eq(11188);
278
286
  });
@@ -292,7 +300,7 @@ describe("CreditAccount calcHealthFactor test", () => {
292
300
  prices,
293
301
  liquidationThresholds,
294
302
  underlyingToken: defaultCA.underlyingToken,
295
- borrowed: defaultCA.debt - amountDecrease,
303
+ debt: defaultCA.debt - amountDecrease,
296
304
  });
297
305
  (0, chai_1.expect)(result).to.be.eq(10308);
298
306
  });
@@ -312,7 +320,7 @@ describe("CreditAccount calcHealthFactor test", () => {
312
320
  prices,
313
321
  liquidationThresholds,
314
322
  underlyingToken: defaultCA.underlyingToken,
315
- borrowed: defaultCA.debt + amountIncrease,
323
+ debt: defaultCA.debt + amountIncrease,
316
324
  });
317
325
  (0, chai_1.expect)(result).to.be.eq(10137);
318
326
  });
@@ -337,7 +345,7 @@ describe("CreditAccount calcHealthFactor test", () => {
337
345
  prices,
338
346
  liquidationThresholds,
339
347
  underlyingToken: defaultCA.underlyingToken,
340
- borrowed: defaultCA.debt,
348
+ debt: defaultCA.debt,
341
349
  });
342
350
  (0, chai_1.expect)(result).to.be.eq(9444);
343
351
  });
@@ -349,7 +357,7 @@ describe("CreditAccount calcHealthFactor test", () => {
349
357
  prices,
350
358
  liquidationThresholds,
351
359
  underlyingToken: defaultCA.underlyingToken,
352
- borrowed: defaultCA.debt,
360
+ debt: defaultCA.debt,
353
361
  });
354
362
  (0, chai_1.expect)(result).to.be.eq(defaultCA.healthFactor);
355
363
  });
@@ -366,7 +374,7 @@ describe("CreditAccount calcHealthFactor test", () => {
366
374
  prices,
367
375
  liquidationThresholds,
368
376
  underlyingToken: defaultCA.underlyingToken,
369
- borrowed: defaultCA.debt,
377
+ debt: defaultCA.debt,
370
378
  });
371
379
  (0, chai_1.expect)(result).to.be.eq(9300);
372
380
  });
@@ -382,7 +390,7 @@ describe("CreditAccount calcHealthFactor test", () => {
382
390
  prices,
383
391
  liquidationThresholds,
384
392
  underlyingToken: defaultCA.underlyingToken,
385
- borrowed: defaultCA.debt,
393
+ debt: defaultCA.debt,
386
394
  });
387
395
  (0, chai_1.expect)(result).to.be.eq(9300);
388
396
  });
@@ -804,7 +812,7 @@ describe("CreditAccount calcQuotaUpdate test", () => {
804
812
  });
805
813
  });
806
814
  });
807
- describe("CreditAccount calcQuotaBorrowRate test", () => {
815
+ describe("CreditAccount calcAvgQuotaBorrowRate test", () => {
808
816
  it("should calculate quota rate (same amounts, different rates)", () => {
809
817
  const result = creditAccount_1.CreditAccountData.calcQuotaBorrowRate({
810
818
  quotas: {
@@ -835,9 +843,8 @@ describe("CreditAccount calcQuotaBorrowRate test", () => {
835
843
  isActive: true,
836
844
  },
837
845
  },
838
- borrowAmount: 30n,
839
846
  });
840
- (0, chai_1.expect)(result).to.be.eq(10);
847
+ (0, chai_1.expect)(result).to.be.eq(300n);
841
848
  });
842
849
  it("should calculate quota rate (same rates, different amounts)", () => {
843
850
  const result = creditAccount_1.CreditAccountData.calcQuotaBorrowRate({
@@ -869,11 +876,10 @@ describe("CreditAccount calcQuotaBorrowRate test", () => {
869
876
  isActive: true,
870
877
  },
871
878
  },
872
- borrowAmount: 30n,
873
879
  });
874
- (0, chai_1.expect)(result).to.be.eq(10);
880
+ (0, chai_1.expect)(result).to.be.eq(300n);
875
881
  });
876
- it("should calculate quota rate (borrow amount)", () => {
882
+ it("should calculate quota rate (disabled quota)", () => {
877
883
  const result = creditAccount_1.CreditAccountData.calcQuotaBorrowRate({
878
884
  quotas: {
879
885
  [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
@@ -896,49 +902,79 @@ describe("CreditAccount calcQuotaBorrowRate test", () => {
896
902
  },
897
903
  [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
898
904
  rate: 10,
899
- isActive: true,
905
+ isActive: false,
900
906
  },
901
907
  [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: {
902
908
  rate: 10,
903
909
  isActive: true,
904
910
  },
905
911
  },
906
- borrowAmount: 60n,
907
912
  });
908
- (0, chai_1.expect)(result).to.be.eq(5);
913
+ (0, chai_1.expect)(result).to.be.eq(200n);
909
914
  });
910
- it("should calculate quota rate (disabled quota)", () => {
915
+ });
916
+ describe("CreditAccount calcQuotaBorrowRate test", () => {
917
+ it("should calculate quota borrow rate", () => {
911
918
  const result = creditAccount_1.CreditAccountData.calcQuotaBorrowRate({
912
919
  quotas: {
913
920
  [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
914
921
  token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
915
- balance: 5n,
916
- },
917
- [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
918
- token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
919
922
  balance: 10n,
920
923
  },
921
- [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: {
922
- token: sdk_gov_1.tokenDataByNetwork.Mainnet.STETH,
923
- balance: 15n,
924
- },
925
924
  },
926
925
  quotaRates: {
927
926
  [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
928
- rate: 10,
927
+ rate: 5,
929
928
  isActive: true,
930
929
  },
931
- [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
932
- rate: 10,
933
- isActive: false,
930
+ },
931
+ });
932
+ (0, chai_1.expect)(result).to.be.eq(50n);
933
+ });
934
+ it("should calculate quota borrow rate when no balance", () => {
935
+ const result = creditAccount_1.CreditAccountData.calcQuotaBorrowRate({
936
+ quotas: {
937
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
938
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
939
+ balance: 1n,
934
940
  },
935
- [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: {
936
- rate: 10,
941
+ },
942
+ quotaRates: {
943
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
944
+ rate: 5,
937
945
  isActive: true,
938
946
  },
939
947
  },
940
- borrowAmount: 50n,
941
948
  });
942
- (0, chai_1.expect)(result).to.be.eq(4);
949
+ (0, chai_1.expect)(result).to.be.eq(5n);
950
+ });
951
+ });
952
+ describe("CreditAccount calcRelativeBaseBorrowRate test", () => {
953
+ it("should calculate relative borrow rate", () => {
954
+ const result = creditAccount_1.CreditAccountData.calcRelativeBaseBorrowRate({
955
+ debt: 200n,
956
+ baseRateWithFee: 250,
957
+ assetAmountInUnderlying: 200n,
958
+ totalValue: 400n,
959
+ });
960
+ (0, chai_1.expect)(result).to.be.eq(25000n);
961
+ });
962
+ it("should calculate relative borrow rate if position asset === 0", () => {
963
+ const result = creditAccount_1.CreditAccountData.calcRelativeBaseBorrowRate({
964
+ debt: 200n,
965
+ baseRateWithFee: 250,
966
+ assetAmountInUnderlying: 1n,
967
+ totalValue: 400n,
968
+ });
969
+ (0, chai_1.expect)(result).to.be.eq(125n);
970
+ });
971
+ it("should calculate relative borrow rate if position === 0", () => {
972
+ const result = creditAccount_1.CreditAccountData.calcRelativeBaseBorrowRate({
973
+ debt: 1n,
974
+ baseRateWithFee: 250,
975
+ assetAmountInUnderlying: 1n,
976
+ totalValue: 1n,
977
+ });
978
+ (0, chai_1.expect)(result).to.be.eq(250n);
943
979
  });
944
980
  });
@@ -12,11 +12,17 @@ export interface StrategyPayload {
12
12
  interface LiquidationPriceProps {
13
13
  prices: Record<string, bigint>;
14
14
  liquidationThresholds: Record<string, bigint>;
15
- borrowed: bigint;
15
+ debt: bigint;
16
16
  underlyingToken: string;
17
17
  targetToken: string;
18
18
  assets: Record<string, Asset>;
19
19
  }
20
+ interface CalculateMaxAPYProps {
21
+ apy: number;
22
+ leverage: number;
23
+ baseRateWithFee: number;
24
+ quotaRateWithFee: number;
25
+ }
20
26
  export declare class Strategy {
21
27
  apy: number | undefined;
22
28
  name: string;
@@ -27,8 +33,8 @@ export declare class Strategy {
27
33
  creditManagers: Array<string>;
28
34
  constructor(payload: StrategyPayload);
29
35
  static maxLeverage(lpToken: string, cms: Array<PartialCM>): number;
30
- static maxAPY(baseAPY: number, maxLeverage: number, borrowAPY: number): number;
31
- static liquidationPrice({ prices, liquidationThresholds, borrowed, underlyingToken, targetToken, assets, }: LiquidationPriceProps): bigint;
36
+ static maxAPY({ apy, leverage, baseRateWithFee, quotaRateWithFee, }: CalculateMaxAPYProps): number;
37
+ static liquidationPrice({ prices, liquidationThresholds, debt, underlyingToken, targetToken, assets, }: LiquidationPriceProps): bigint;
32
38
  protected static maxLeverageThreshold(lpToken: string, cms: Array<PartialCM>): readonly [bigint, string];
33
39
  }
34
40
  type PartialCM = Pick<CreditManagerData, "liquidationThresholds" | "address">;
@@ -27,17 +27,19 @@ class Strategy {
27
27
  (sdk_gov_1.PERCENTAGE_FACTOR - maxThreshold);
28
28
  return Number(maxLeverage - sdk_gov_1.LEVERAGE_DECIMALS);
29
29
  }
30
- static maxAPY(baseAPY, maxLeverage, borrowAPY) {
31
- return (baseAPY +
32
- ((baseAPY - borrowAPY) * (maxLeverage - Number(sdk_gov_1.LEVERAGE_DECIMALS))) /
33
- Number(sdk_gov_1.LEVERAGE_DECIMALS));
30
+ static maxAPY({ apy, leverage, baseRateWithFee, quotaRateWithFee, }) {
31
+ const collateralTerm = apy - quotaRateWithFee;
32
+ const debtTerm = ((apy - baseRateWithFee - quotaRateWithFee) *
33
+ (leverage - Number(sdk_gov_1.LEVERAGE_DECIMALS))) /
34
+ Number(sdk_gov_1.LEVERAGE_DECIMALS);
35
+ return collateralTerm + Math.floor(debtTerm);
34
36
  }
35
- static liquidationPrice({ prices, liquidationThresholds, borrowed, underlyingToken, targetToken, assets, }) {
37
+ static liquidationPrice({ prices, liquidationThresholds, debt, underlyingToken, targetToken, assets, }) {
36
38
  const underlyingTokenLC = underlyingToken.toLowerCase();
37
39
  const [, underlyingDecimals = 18] = (0, sdk_gov_1.extractTokenData)(underlyingTokenLC);
38
40
  const { balance: underlyingBalance = 0n } = assets[underlyingTokenLC] || {};
39
41
  const underlyingPrice = prices[underlyingTokenLC] || sdk_gov_1.PRICE_DECIMALS;
40
- const borrowedMoney = price_1.PriceUtils.calcTotalPrice(underlyingPrice, math_1.BigIntMath.max(0n, borrowed - underlyingBalance), underlyingDecimals);
42
+ const borrowedMoney = price_1.PriceUtils.calcTotalPrice(underlyingPrice, math_1.BigIntMath.max(0n, debt - underlyingBalance), underlyingDecimals);
41
43
  const targetTokenLC = targetToken.toLowerCase();
42
44
  const [, targetDecimals = 18] = (0, sdk_gov_1.extractTokenData)(targetTokenLC);
43
45
  const { balance: targetBalance = 0n } = assets[targetTokenLC] || {};
@@ -24,14 +24,19 @@ const liquidationThresholds = {
24
24
  };
25
25
  describe("Strategy test", () => {
26
26
  it("maxAPY calculation is correct", () => {
27
- const result = strategy_1.Strategy.maxAPY(53203, 10 * Number(sdk_gov_1.LEVERAGE_DECIMALS), pools["0x1"].borrowRate);
27
+ const result = strategy_1.Strategy.maxAPY({
28
+ apy: 53203,
29
+ leverage: 10 * Number(sdk_gov_1.LEVERAGE_DECIMALS),
30
+ baseRateWithFee: pools["0x1"].borrowRate,
31
+ quotaRateWithFee: 0,
32
+ });
28
33
  (0, chai_1.expect)(result).to.be.eq(284143);
29
34
  });
30
35
  it("liquidationPrice: calculation is correct", () => {
31
36
  const result = strategy_1.Strategy.liquidationPrice({
32
37
  liquidationThresholds,
33
38
  prices,
34
- borrowed: (0, formatter_1.toBN)("350", sdk_gov_1.decimals.WETH),
39
+ debt: (0, formatter_1.toBN)("350", sdk_gov_1.decimals.WETH),
35
40
  underlyingToken: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
36
41
  targetToken: sdk_gov_1.tokenDataByNetwork.Mainnet.STETH,
37
42
  assets: {
@@ -47,7 +52,7 @@ describe("Strategy test", () => {
47
52
  const result = strategy_1.Strategy.liquidationPrice({
48
53
  liquidationThresholds,
49
54
  prices,
50
- borrowed: (0, formatter_1.toBN)("350", sdk_gov_1.decimals.WETH),
55
+ debt: (0, formatter_1.toBN)("350", sdk_gov_1.decimals.WETH),
51
56
  underlyingToken: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
52
57
  targetToken: sdk_gov_1.tokenDataByNetwork.Mainnet.STETH,
53
58
  assets: {
@@ -67,7 +72,7 @@ describe("Strategy test", () => {
67
72
  const result = strategy_1.Strategy.liquidationPrice({
68
73
  liquidationThresholds,
69
74
  prices,
70
- borrowed: (0, formatter_1.toBN)("350", sdk_gov_1.decimals.WETH),
75
+ debt: (0, formatter_1.toBN)("350", sdk_gov_1.decimals.WETH),
71
76
  underlyingToken: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
72
77
  targetToken: sdk_gov_1.tokenDataByNetwork.Mainnet.STETH,
73
78
  assets: {
@@ -87,7 +92,7 @@ describe("Strategy test", () => {
87
92
  const result = strategy_1.Strategy.liquidationPrice({
88
93
  liquidationThresholds,
89
94
  prices,
90
- borrowed: (0, formatter_1.toBN)("450", sdk_gov_1.decimals.WETH),
95
+ debt: (0, formatter_1.toBN)("450", sdk_gov_1.decimals.WETH),
91
96
  underlyingToken: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
92
97
  targetToken: sdk_gov_1.tokenDataByNetwork.Mainnet.STETH,
93
98
  assets: {
@@ -128,7 +128,7 @@ class TXSwap extends eventOrTx_1.EVMTx {
128
128
  this.tokenFrom = opts.tokenFrom;
129
129
  this.tokenTo = opts.tokenTo;
130
130
  this.creditManager = opts.creditManager;
131
- this.creditManagerName = opts.creditManager;
131
+ this.creditManagerName = opts.creditManagerName;
132
132
  }
133
133
  toString() {
134
134
  let toPart = "";
@@ -157,7 +157,7 @@ class TxAddCollateral extends eventOrTx_1.EVMTx {
157
157
  this.amount = opts.amount;
158
158
  this.addedToken = opts.addedToken;
159
159
  this.creditManager = opts.creditManager;
160
- this.creditManagerName = opts.creditManager;
160
+ this.creditManagerName = opts.creditManagerName;
161
161
  }
162
162
  toString() {
163
163
  const [addedSymbol, addedDecimals] = (0, sdk_gov_1.extractTokenData)(this.addedToken);
@@ -181,7 +181,7 @@ class TxIncreaseBorrowAmount extends eventOrTx_1.EVMTx {
181
181
  this.amount = opts.amount;
182
182
  this.underlyingToken = opts.underlyingToken;
183
183
  this.creditManager = opts.creditManager;
184
- this.creditManagerName = opts.creditManager;
184
+ this.creditManagerName = opts.creditManagerName;
185
185
  }
186
186
  toString() {
187
187
  const [tokenSymbol, tokenDecimals] = (0, sdk_gov_1.extractTokenData)(this.underlyingToken);
@@ -205,7 +205,7 @@ class TxDecreaseBorrowAmount extends eventOrTx_1.EVMTx {
205
205
  this.amount = opts.amount;
206
206
  this.underlyingToken = opts.underlyingToken;
207
207
  this.creditManager = opts.creditManager;
208
- this.creditManagerName = opts.creditManager;
208
+ this.creditManagerName = opts.creditManagerName;
209
209
  }
210
210
  toString() {
211
211
  const [tokenSymbol, tokenDecimals] = (0, sdk_gov_1.extractTokenData)(this.underlyingToken);
@@ -231,7 +231,7 @@ class TxOpenAccount extends eventOrTx_1.EVMTx {
231
231
  this.underlyingToken = opts.underlyingToken;
232
232
  this.leverage = opts.leverage;
233
233
  this.creditManager = opts.creditManager;
234
- this.creditManagerName = opts.creditManager;
234
+ this.creditManagerName = opts.creditManagerName;
235
235
  }
236
236
  toString() {
237
237
  const [tokenSymbol, tokenDecimals] = (0, sdk_gov_1.extractTokenData)(this.underlyingToken);
@@ -259,7 +259,7 @@ class TxOpenMultitokenAccount extends eventOrTx_1.EVMTx {
259
259
  this.borrowedAmount = opts.borrowedAmount;
260
260
  this.underlyingToken = opts.underlyingToken;
261
261
  this.creditManager = opts.creditManager;
262
- this.creditManagerName = opts.creditManager;
262
+ this.creditManagerName = opts.creditManagerName;
263
263
  this.assets = opts.assets;
264
264
  }
265
265
  toString() {
@@ -339,7 +339,7 @@ class TxRepayAccount extends eventOrTx_1.EVMTx {
339
339
  constructor(opts) {
340
340
  super(opts);
341
341
  this.creditManager = opts.creditManager;
342
- this.creditManagerName = opts.creditManager;
342
+ this.creditManagerName = opts.creditManagerName;
343
343
  }
344
344
  toString() {
345
345
  return `Credit Account ${this.creditManagerName || (0, contractsRegister_1.getContractName)(this.creditManager)}: Repaying account`;
@@ -358,10 +358,10 @@ class TxCloseAccount extends eventOrTx_1.EVMTx {
358
358
  constructor(opts) {
359
359
  super(opts);
360
360
  this.creditManager = opts.creditManager;
361
- this.creditManagerName = opts.creditManager;
361
+ this.creditManagerName = opts.creditManagerName;
362
362
  }
363
363
  toString() {
364
- return `Credit Account ${this.creditManager || (0, contractsRegister_1.getContractName)(this.creditManager)}: Closing account`;
364
+ return `Credit Account ${this.creditManagerName || (0, contractsRegister_1.getContractName)(this.creditManager)}: Closing account`;
365
365
  }
366
366
  serialize() {
367
367
  return {
@@ -399,7 +399,7 @@ class TxEnableTokens extends eventOrTx_1.EVMTx {
399
399
  this.enabledTokens = opts.enabledTokens;
400
400
  this.disabledTokens = opts.disabledTokens;
401
401
  this.creditManager = opts.creditManager;
402
- this.creditManagerName = opts.creditManager;
402
+ this.creditManagerName = opts.creditManagerName;
403
403
  }
404
404
  toString() {
405
405
  const enabledSymbols = this.enabledTokens.map(address => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "3.0.0-next.93",
3
+ "version": "3.0.0-next.95",
4
4
  "description": "Gearbox SDK",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",