@gearbox-protocol/sdk 3.0.0-next.30 → 3.0.0-next.31

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.
@@ -7,7 +7,7 @@ export interface CalcOverallAPYProps {
7
7
  caAssets: Array<Asset>;
8
8
  lpAPY: LpTokensAPY | undefined;
9
9
  quotas: Record<string, Asset>;
10
- quotaRates: Record<string, Pick<QuotaInfo, "rate">>;
10
+ quotaRates: Record<string, Pick<QuotaInfo, "isActive" | "rate">>;
11
11
  prices: Record<string, bigint>;
12
12
  totalValue: bigint | undefined;
13
13
  debt: bigint | undefined;
@@ -17,6 +17,7 @@ export interface CalcOverallAPYProps {
17
17
  export interface CalcHealthFactorProps {
18
18
  assets: Array<Asset>;
19
19
  quotas: Record<string, Asset>;
20
+ quotasInfo: Record<string, Pick<QuotaInfo, "isActive">>;
20
21
  prices: Record<string, bigint>;
21
22
  liquidationThresholds: Record<string, bigint>;
22
23
  underlyingToken: string;
@@ -36,7 +37,7 @@ interface CalcQuotaUpdateReturnType {
36
37
  }
37
38
  export interface CalcQuotaBorrowRateProps {
38
39
  quotas: Record<string, Asset>;
39
- quotaRates: Record<string, Pick<QuotaInfo, "rate">>;
40
+ quotaRates: Record<string, Pick<QuotaInfo, "isActive" | "rate">>;
40
41
  borrowAmount: bigint;
41
42
  }
42
43
  export declare class CreditAccountData {
@@ -87,7 +88,7 @@ export declare class CreditAccountData {
87
88
  static calcOverallAPY({ caAssets, lpAPY, prices, quotas, quotaRates, totalValue, debt, baseBorrowRate, underlyingToken, }: CalcOverallAPYProps): bigint | undefined;
88
89
  hash(): string;
89
90
  static hash(creditManager: string, borrower: string): string;
90
- static calcHealthFactor({ assets, quotas, liquidationThresholds, underlyingToken, borrowed, prices, }: CalcHealthFactorProps): number;
91
+ static calcHealthFactor({ assets, quotas, quotasInfo, liquidationThresholds, underlyingToken, borrowed, prices, }: CalcHealthFactorProps): number;
91
92
  static calcQuotaUpdate({ quotas, initialQuotas, assetsAfterUpdate, allowedToSpend, allowedToObtain, }: CalcQuotaUpdateProps): CalcQuotaUpdateReturnType;
92
93
  static calcQuotaBorrowRate({ quotas, quotaRates, borrowAmount, }: CalcQuotaBorrowRateProps): number;
93
94
  }
@@ -170,9 +170,10 @@ class CreditAccountData {
170
170
  const tokenDecimals = sdk_gov_1.decimals[symbol];
171
171
  const money = price_1.PriceUtils.calcTotalPrice(price, amount, tokenDecimals);
172
172
  const apyMoney = money * BigInt(apy);
173
- const { balance: quotaAmount = 0n } = quotas[tokenAddressLC] || {};
173
+ const { rate: quotaAPY = 0, isActive = false } = quotaRates?.[tokenAddressLC] || {};
174
+ const { balance: quotaBalance = 0n } = quotas[tokenAddressLC] || {};
175
+ const quotaAmount = isActive ? quotaBalance : 0n;
174
176
  const quotaMoney = price_1.PriceUtils.calcTotalPrice(underlyingPrice || 0n, quotaAmount, underlyingTokenDecimals);
175
- const { rate: quotaAPY = 0 } = quotaRates[tokenAddressLC] || {};
176
177
  const quotaAPYMoney = quotaMoney * BigInt(quotaAPY);
177
178
  return acc + apyMoney - quotaAPYMoney;
178
179
  }, 0n);
@@ -191,7 +192,7 @@ class CreditAccountData {
191
192
  static hash(creditManager, borrower) {
192
193
  return `${creditManager.toLowerCase()}:${borrower.toLowerCase()}`;
193
194
  }
194
- static calcHealthFactor({ assets, quotas, liquidationThresholds, underlyingToken, borrowed, prices, }) {
195
+ static calcHealthFactor({ assets, quotas, quotasInfo, liquidationThresholds, underlyingToken, borrowed, prices, }) {
195
196
  const [, underlyingDecimals] = (0, sdk_gov_1.extractTokenData)(underlyingToken);
196
197
  const underlyingPrice = prices[underlyingToken] || 0n;
197
198
  const assetLTMoney = assets.reduce((acc, { token: tokenAddress, balance: amount }) => {
@@ -199,8 +200,10 @@ class CreditAccountData {
199
200
  const lt = liquidationThresholds[tokenAddress] || 0n;
200
201
  const price = prices[tokenAddress] || 0n;
201
202
  const tokenMoney = price_1.PriceUtils.calcTotalPrice(price, amount, tokenDecimals);
203
+ const { isActive = false } = quotasInfo?.[tokenAddress] || {};
202
204
  const quota = quotas[tokenAddress];
203
- const quotaMoney = price_1.PriceUtils.calcTotalPrice(underlyingPrice, quota?.balance || 0n, underlyingDecimals);
205
+ const quotaBalance = isActive ? quota?.balance || 0n : 0n;
206
+ const quotaMoney = price_1.PriceUtils.calcTotalPrice(underlyingPrice, quotaBalance, underlyingDecimals);
204
207
  // if quota is undefined, then it is not a quoted token
205
208
  const money = quota
206
209
  ? math_1.BigIntMath.min(quotaMoney, tokenMoney)
@@ -214,8 +217,15 @@ class CreditAccountData {
214
217
  }
215
218
  static calcQuotaUpdate({ quotas, initialQuotas, assetsAfterUpdate, allowedToSpend, allowedToObtain, }) {
216
219
  const r = Object.values(quotas).reduce((acc, cmQuota) => {
217
- const { token } = cmQuota;
220
+ const { token, isActive } = cmQuota;
218
221
  const { quota: initialQuota = 0n } = initialQuotas[token] || {};
222
+ if (!isActive) {
223
+ acc.desiredQuota[token] = {
224
+ balance: initialQuota,
225
+ token,
226
+ };
227
+ return acc;
228
+ }
219
229
  const after = assetsAfterUpdate[token];
220
230
  const { amountInTarget = 0n } = after || {};
221
231
  const desiredQuota = (amountInTarget * 101n) / 100n;
@@ -254,8 +264,9 @@ class CreditAccountData {
254
264
  if (borrowAmount <= 0)
255
265
  return 0;
256
266
  const totalRateBalance = Object.values(quotas).reduce((acc, { token, balance }) => {
257
- const { rate = 0 } = quotaRates[token] || {};
258
- const rateBalance = balance * BigInt(rate);
267
+ const { rate = 0, isActive = false } = quotaRates?.[token] || {};
268
+ const quotaBalance = isActive ? balance : 0n;
269
+ const rateBalance = quotaBalance * BigInt(rate);
259
270
  return acc + rateBalance;
260
271
  }, 0n);
261
272
  const quotaBorrowRate = Number(totalRateBalance / borrowAmount);
@@ -36,6 +36,7 @@ const caWithoutLP = {
36
36
  rates: {
37
37
  [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase()]: {
38
38
  rate: 38434,
39
+ isActive: true,
39
40
  },
40
41
  },
41
42
  };
@@ -63,6 +64,7 @@ const caWithLP = {
63
64
  rates: {
64
65
  [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH.toLowerCase()]: {
65
66
  rate: 38434,
67
+ isActive: true,
66
68
  },
67
69
  },
68
70
  };
@@ -225,11 +227,17 @@ const defaultCA = {
225
227
  token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase(),
226
228
  },
227
229
  },
230
+ quotasInfo: {
231
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase()]: {
232
+ isActive: true,
233
+ },
234
+ },
228
235
  };
229
236
  describe("CreditAccount calcHealthFactor test", () => {
230
237
  it("health factor is calculated correctly", () => {
231
238
  const result = creditAccount_1.CreditAccountData.calcHealthFactor({
232
239
  quotas: {},
240
+ quotasInfo: {},
233
241
  assets: defaultCA.assets,
234
242
  prices,
235
243
  liquidationThresholds,
@@ -241,6 +249,7 @@ describe("CreditAccount calcHealthFactor test", () => {
241
249
  it("health factor calculation has no division by zero error", () => {
242
250
  const result = creditAccount_1.CreditAccountData.calcHealthFactor({
243
251
  quotas: {},
252
+ quotasInfo: {},
244
253
  assets: [],
245
254
  prices: {},
246
255
  liquidationThresholds: {},
@@ -257,6 +266,7 @@ describe("CreditAccount calcHealthFactor test", () => {
257
266
  const afterAdd = assets_1.AssetUtils.sumAssets(defaultCA.assets, [collateral]);
258
267
  const result = creditAccount_1.CreditAccountData.calcHealthFactor({
259
268
  quotas: {},
269
+ quotasInfo: {},
260
270
  assets: afterAdd,
261
271
  prices,
262
272
  liquidationThresholds,
@@ -276,6 +286,7 @@ describe("CreditAccount calcHealthFactor test", () => {
276
286
  ]);
277
287
  const result = creditAccount_1.CreditAccountData.calcHealthFactor({
278
288
  quotas: {},
289
+ quotasInfo: {},
279
290
  assets: afterDecrease,
280
291
  prices,
281
292
  liquidationThresholds,
@@ -295,6 +306,7 @@ describe("CreditAccount calcHealthFactor test", () => {
295
306
  ]);
296
307
  const result = creditAccount_1.CreditAccountData.calcHealthFactor({
297
308
  quotas: {},
309
+ quotasInfo: {},
298
310
  assets: afterIncrease,
299
311
  prices,
300
312
  liquidationThresholds,
@@ -319,6 +331,7 @@ describe("CreditAccount calcHealthFactor test", () => {
319
331
  const afterSwap = assets_1.AssetUtils.sumAssets(afterSub, [getAsset]);
320
332
  const result = creditAccount_1.CreditAccountData.calcHealthFactor({
321
333
  quotas: {},
334
+ quotasInfo: {},
322
335
  assets: afterSwap,
323
336
  prices,
324
337
  liquidationThresholds,
@@ -330,6 +343,7 @@ describe("CreditAccount calcHealthFactor test", () => {
330
343
  it("health factor with sufficient quotas is calculated correctly", () => {
331
344
  const result = creditAccount_1.CreditAccountData.calcHealthFactor({
332
345
  quotas: defaultCA.quotas,
346
+ quotasInfo: defaultCA.quotasInfo,
333
347
  assets: defaultCA.assets,
334
348
  prices,
335
349
  liquidationThresholds,
@@ -346,6 +360,23 @@ describe("CreditAccount calcHealthFactor test", () => {
346
360
  token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase(),
347
361
  },
348
362
  },
363
+ quotasInfo: defaultCA.quotasInfo,
364
+ assets: defaultCA.assets,
365
+ prices,
366
+ liquidationThresholds,
367
+ underlyingToken: defaultCA.underlyingToken,
368
+ borrowed: defaultCA.debt,
369
+ });
370
+ (0, chai_1.expect)(result).to.be.eq(9300);
371
+ });
372
+ it("health factor with disabled quota is calculated correctly", () => {
373
+ const result = creditAccount_1.CreditAccountData.calcHealthFactor({
374
+ quotas: defaultCA.quotas,
375
+ quotasInfo: {
376
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH.toLowerCase()]: {
377
+ isActive: false,
378
+ },
379
+ },
349
380
  assets: defaultCA.assets,
350
381
  prices,
351
382
  liquidationThresholds,
@@ -678,15 +709,15 @@ describe("CreditAccount calcQuotaUpdate test", () => {
678
709
  quotas: cmQuotas,
679
710
  initialQuotas: caQuota,
680
711
  assetsAfterUpdate: {
681
- [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
712
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
682
713
  amountInTarget: 10n,
683
714
  balance: 0n,
684
- token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
715
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
685
716
  },
686
- [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
717
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
687
718
  amountInTarget: 0n,
688
719
  balance: 0n,
689
- token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
720
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
690
721
  },
691
722
  },
692
723
  allowedToObtain: {},
@@ -709,6 +740,59 @@ describe("CreditAccount calcQuotaUpdate test", () => {
709
740
  },
710
741
  });
711
742
  });
743
+ it("shouldn't change quota if it is disabled", () => {
744
+ const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
745
+ quotas: {
746
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
747
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
748
+ isActive: false,
749
+ },
750
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
751
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
752
+ isActive: false,
753
+ },
754
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: {
755
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.STETH,
756
+ isActive: false,
757
+ },
758
+ },
759
+ initialQuotas: caQuota,
760
+ assetsAfterUpdate: {
761
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
762
+ amountInTarget: 10n,
763
+ balance: 0n,
764
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
765
+ },
766
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
767
+ amountInTarget: 0n,
768
+ balance: 0n,
769
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
770
+ },
771
+ },
772
+ allowedToObtain: {
773
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {},
774
+ },
775
+ allowedToSpend: {
776
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {},
777
+ },
778
+ });
779
+ (0, chai_1.expect)(result.quotaIncrease).to.be.deep.eq([]);
780
+ (0, chai_1.expect)(result.quotaDecrease).to.be.deep.eq([]);
781
+ (0, chai_1.expect)(result.desiredQuota).to.be.deep.eq({
782
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
783
+ balance: 5n,
784
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
785
+ },
786
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
787
+ balance: 10n,
788
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
789
+ },
790
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: {
791
+ balance: 0n,
792
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.STETH,
793
+ },
794
+ });
795
+ });
712
796
  });
713
797
  describe("CreditAccount calcQuotaBorrowRate test", () => {
714
798
  it("should calculate quota rate (same amounts, different rates)", () => {
@@ -730,12 +814,15 @@ describe("CreditAccount calcQuotaBorrowRate test", () => {
730
814
  quotaRates: {
731
815
  [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
732
816
  rate: 5,
817
+ isActive: true,
733
818
  },
734
819
  [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
735
820
  rate: 10,
821
+ isActive: true,
736
822
  },
737
823
  [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: {
738
824
  rate: 15,
825
+ isActive: true,
739
826
  },
740
827
  },
741
828
  borrowAmount: 30n,
@@ -761,12 +848,15 @@ describe("CreditAccount calcQuotaBorrowRate test", () => {
761
848
  quotaRates: {
762
849
  [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
763
850
  rate: 10,
851
+ isActive: true,
764
852
  },
765
853
  [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
766
854
  rate: 10,
855
+ isActive: true,
767
856
  },
768
857
  [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: {
769
858
  rate: 10,
859
+ isActive: true,
770
860
  },
771
861
  },
772
862
  borrowAmount: 30n,
@@ -792,16 +882,53 @@ describe("CreditAccount calcQuotaBorrowRate test", () => {
792
882
  quotaRates: {
793
883
  [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
794
884
  rate: 10,
885
+ isActive: true,
795
886
  },
796
887
  [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
797
888
  rate: 10,
889
+ isActive: true,
798
890
  },
799
891
  [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: {
800
892
  rate: 10,
893
+ isActive: true,
801
894
  },
802
895
  },
803
896
  borrowAmount: 60n,
804
897
  });
805
898
  (0, chai_1.expect)(result).to.be.eq(5);
806
899
  });
900
+ it("should calculate quota rate (disabled quota)", () => {
901
+ const result = creditAccount_1.CreditAccountData.calcQuotaBorrowRate({
902
+ quotas: {
903
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
904
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
905
+ balance: 5n,
906
+ },
907
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
908
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
909
+ balance: 10n,
910
+ },
911
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: {
912
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.STETH,
913
+ balance: 15n,
914
+ },
915
+ },
916
+ quotaRates: {
917
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
918
+ rate: 10,
919
+ isActive: true,
920
+ },
921
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
922
+ rate: 10,
923
+ isActive: false,
924
+ },
925
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: {
926
+ rate: 10,
927
+ isActive: true,
928
+ },
929
+ },
930
+ borrowAmount: 50n,
931
+ });
932
+ (0, chai_1.expect)(result).to.be.eq(4);
933
+ });
807
934
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "3.0.0-next.30",
3
+ "version": "3.0.0-next.31",
4
4
  "description": "Gearbox SDK",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",