@curvefi/llamalend-api 2.0.2 → 2.0.4

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.
Files changed (39) hide show
  1. package/docs/SUPPORT_LLv2.md +6 -0
  2. package/lib/constants/abis/ControllerV2.json +1891 -0
  3. package/lib/index.d.ts +2 -2
  4. package/lib/lendMarkets/LendMarketTemplate.d.ts +9 -5
  5. package/lib/lendMarkets/LendMarketTemplate.js +12 -11
  6. package/lib/lendMarkets/fetch/fetchLendMarkets.js +6 -1
  7. package/lib/lendMarkets/interfaces/v1/statsV1.d.ts +1 -0
  8. package/lib/lendMarkets/interfaces/v2/loanV2.d.ts +1 -1
  9. package/lib/lendMarkets/interfaces/v2/statsV2.d.ts +1 -0
  10. package/lib/lendMarkets/lendMarketConstructor.d.ts +1 -1
  11. package/lib/lendMarkets/lendMarketConstructor.js +6 -1
  12. package/lib/lendMarkets/modules/common/loanBase.d.ts +0 -1
  13. package/lib/lendMarkets/modules/common/loanBase.js +8 -23
  14. package/lib/lendMarkets/modules/common/statsBase.d.ts +4 -2
  15. package/lib/lendMarkets/modules/common/statsBase.js +56 -85
  16. package/lib/lendMarkets/modules/v1/loanV1.d.ts +1 -0
  17. package/lib/lendMarkets/modules/v1/loanV1.js +19 -0
  18. package/lib/lendMarkets/modules/v2/loanV2.d.ts +5 -0
  19. package/lib/lendMarkets/modules/v2/loanV2.js +57 -0
  20. package/lib/lendMarkets/modules/v2/statsV2.d.ts +2 -0
  21. package/lib/lendMarkets/modules/v2/statsV2.js +19 -0
  22. package/lib/lendMarkets/utils.d.ts +14 -0
  23. package/lib/lendMarkets/utils.js +31 -0
  24. package/lib/llamalend.d.ts +1 -1
  25. package/package.json +9 -3
  26. package/src/constants/abis/ControllerV2.json +1891 -0
  27. package/src/lendMarkets/LendMarketTemplate.ts +24 -19
  28. package/src/lendMarkets/fetch/fetchLendMarkets.ts +7 -1
  29. package/src/lendMarkets/interfaces/v1/statsV1.ts +1 -0
  30. package/src/lendMarkets/interfaces/v2/loanV2.ts +1 -1
  31. package/src/lendMarkets/interfaces/v2/statsV2.ts +1 -0
  32. package/src/lendMarkets/lendMarketConstructor.ts +6 -2
  33. package/src/lendMarkets/modules/common/loanBase.ts +9 -24
  34. package/src/lendMarkets/modules/common/statsBase.ts +74 -92
  35. package/src/lendMarkets/modules/v1/loanV1.ts +12 -1
  36. package/src/lendMarkets/modules/v2/loanV2.ts +55 -1
  37. package/src/lendMarkets/modules/v2/statsV2.ts +9 -1
  38. package/src/lendMarkets/utils.ts +44 -0
  39. package/src/llamalend.ts +1 -1
package/lib/index.d.ts CHANGED
@@ -26,7 +26,7 @@ export declare function createLlamalend(): {
26
26
  readonly signerAddress: string;
27
27
  LendMarketTemplate: typeof LendMarketTemplate;
28
28
  MintMarketTemplate: typeof MintMarketTemplate;
29
- getLendMarket: (lendMarketId: string) => LendMarketTemplate;
29
+ getLendMarket: (lendMarketId: string) => LendMarketTemplate<"v1"> | LendMarketTemplate<"v2">;
30
30
  getMintMarket: (mintMarketId: string) => MintMarketTemplate;
31
31
  totalSupply: () => Promise<{
32
32
  total: string;
@@ -128,7 +128,7 @@ declare const _default: {
128
128
  readonly signerAddress: string;
129
129
  LendMarketTemplate: typeof LendMarketTemplate;
130
130
  MintMarketTemplate: typeof MintMarketTemplate;
131
- getLendMarket: (lendMarketId: string) => LendMarketTemplate;
131
+ getLendMarket: (lendMarketId: string) => LendMarketTemplate<"v1"> | LendMarketTemplate<"v2">;
132
132
  getMintMarket: (mintMarketId: string) => MintMarketTemplate;
133
133
  totalSupply: () => Promise<{
134
134
  total: string;
@@ -4,11 +4,14 @@ import { ILeverageZapV2 } from "./interfaces/leverageZapV2.js";
4
4
  import { IUserPosition, IWallet, IPrices, IAmm, IVault } from "./interfaces/common";
5
5
  import { IStatsV1, ILoanV1, ILeverageV1 } from "./interfaces/v1";
6
6
  import { IStatsV2, ILoanV2, ILeverageV2 } from "./interfaces/v2";
7
- export declare class LendMarketTemplate {
7
+ type LoanForVersion<V extends 'v1' | 'v2'> = V extends 'v1' ? ILoanV1 : ILoanV2;
8
+ type StatsForVersion<V extends 'v1' | 'v2'> = V extends 'v1' ? IStatsV1 : IStatsV2;
9
+ type LeverageForVersion<V extends 'v1' | 'v2'> = V extends 'v1' ? ILeverageV1 : ILeverageV2;
10
+ export declare class LendMarketTemplate<V extends 'v1' | 'v2' = 'v1' | 'v2'> {
8
11
  private llamalend;
9
12
  id: string;
10
13
  name: string;
11
- version: 'v1' | 'v2';
14
+ version: V;
12
15
  addresses: {
13
16
  amm: string;
14
17
  controller: string;
@@ -41,10 +44,11 @@ export declare class LendMarketTemplate {
41
44
  prices: IPrices;
42
45
  amm: IAmm;
43
46
  vault: IVault;
44
- stats: IStatsV1 | IStatsV2;
45
- loan: ILoanV1 | ILoanV2;
46
- leverage: ILeverageV1 | ILeverageV2;
47
+ stats: StatsForVersion<V>;
48
+ loan: LoanForVersion<V>;
49
+ leverage: LeverageForVersion<V>;
47
50
  leverageZapV2: ILeverageZapV2;
48
51
  constructor(id: string, marketData: IOneWayMarket, llamalend: Llamalend);
49
52
  getLlamalend(): Llamalend;
50
53
  }
54
+ export {};
@@ -29,7 +29,7 @@ export class LendMarketTemplate {
29
29
  constructor(id, marketData, llamalend) {
30
30
  this.swapDataCache = {};
31
31
  this.llamalend = llamalend;
32
- this.version = marketData.version || 'v1';
32
+ this.version = (marketData.version || 'v1');
33
33
  this.id = id;
34
34
  this.name = marketData.name;
35
35
  this.addresses = marketData.addresses;
@@ -68,16 +68,17 @@ export class LendMarketTemplate {
68
68
  getCurrentLeverageParams: userPosition.getCurrentLeverageParams.bind(userPosition),
69
69
  };
70
70
  this.stats = {
71
- parameters: stats.statsParameters.bind(this),
72
- rates: stats.statsRates.bind(this),
73
- futureRates: stats.statsFutureRates.bind(this),
74
- balances: stats.statsBalances.bind(this),
75
- bandsInfo: stats.statsBandsInfo.bind(this),
76
- bandBalances: stats.statsBandBalances.bind(this),
77
- bandsBalances: stats.statsBandsBalances.bind(this),
78
- totalDebt: stats.statsTotalDebt.bind(this),
79
- ammBalances: stats.statsAmmBalances.bind(this),
80
- capAndAvailable: stats.statsCapAndAvailable.bind(this),
71
+ parameters: stats.statsParameters.bind(stats),
72
+ rates: stats.statsRates.bind(stats),
73
+ futureRates: stats.statsFutureRates.bind(stats),
74
+ balances: stats.statsBalances.bind(stats),
75
+ bandsInfo: stats.statsBandsInfo.bind(stats),
76
+ bandBalances: stats.statsBandBalances.bind(stats),
77
+ bandsBalances: stats.statsBandsBalances.bind(stats),
78
+ totalDebt: stats.statsTotalDebt.bind(stats),
79
+ ammBalances: stats.statsAmmBalances.bind(stats),
80
+ capAndAvailable: stats.statsCapAndAvailable.bind(stats),
81
+ adminPercentage: stats.statsAdminPercentage.bind(stats),
81
82
  };
82
83
  this.wallet = {
83
84
  balances: wallet.balances.bind(this),
@@ -10,14 +10,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import { getFactoryMarketDataV1, getFactoryMarketDataV2, getFactoryMarketDataByAPI } from "./fetchFactoryData.js";
11
11
  import LlammaABI from '../../constants/abis/Llamma.json' with { type: 'json' };
12
12
  import ControllerABI from '../../constants/abis/Controller.json' with { type: 'json' };
13
+ import ControllerV2ABI from '../../constants/abis/ControllerV2.json' with { type: 'json' };
13
14
  import MonetaryPolicyABI from '../../constants/abis/MonetaryPolicy.json' with { type: 'json' };
14
15
  import VaultABI from '../../constants/abis/Vault.json' with { type: 'json' };
15
16
  import GaugeABI from '../../constants/abis/GaugeV5.json' with { type: 'json' };
16
17
  import SidechainGaugeABI from '../../constants/abis/SidechainGauge.json' with { type: 'json' };
18
+ const controllerAbiMap = {
19
+ 'v1': ControllerABI,
20
+ 'v2': ControllerV2ABI,
21
+ };
17
22
  const registerMarkets = (llamalend, names, amms, controllers, borrowed_tokens, collateral_tokens, monetary_policies, vaults, gauges, COIN_DATA, version) => {
18
23
  amms.forEach((amm, index) => {
19
24
  llamalend.setContract(amms[index], LlammaABI);
20
- llamalend.setContract(controllers[index], ControllerABI);
25
+ llamalend.setContract(controllers[index], controllerAbiMap[version]);
21
26
  llamalend.setContract(monetary_policies[index], MonetaryPolicyABI);
22
27
  llamalend.setContract(vaults[index], VaultABI);
23
28
  if (gauges[index]) {
@@ -46,4 +46,5 @@ export interface IStatsV1 {
46
46
  cap: string;
47
47
  available: string;
48
48
  }>;
49
+ adminPercentage: () => Promise<string>;
49
50
  }
@@ -42,7 +42,7 @@ export interface ILoanV2 {
42
42
  repayPrices: (debt: TAmount, address?: string) => Promise<string[]>;
43
43
  repayIsApproved: (debt: TAmount) => Promise<boolean>;
44
44
  repayApprove: (debt: TAmount) => Promise<string[]>;
45
- repayHealth: (debt: TAmount, full?: boolean, address?: string) => Promise<string>;
45
+ repayHealth: (debt: TAmount, shrink?: boolean, full?: boolean, address?: string) => Promise<string>;
46
46
  repay: (debt: TAmount, address?: string) => Promise<string>;
47
47
  repayFutureLeverage: (debt: TAmount, userAddress?: string) => Promise<string>;
48
48
  fullRepayIsApproved: (address?: string) => Promise<boolean>;
@@ -46,4 +46,5 @@ export interface IStatsV2 {
46
46
  cap: string;
47
47
  available: string;
48
48
  }>;
49
+ adminPercentage: () => Promise<string>;
49
50
  }
@@ -1,3 +1,3 @@
1
1
  import { LendMarketTemplate } from "./LendMarketTemplate.js";
2
2
  import type { Llamalend } from "../llamalend.js";
3
- export declare const getLendMarket: (this: Llamalend, lendMarketId: string) => LendMarketTemplate;
3
+ export declare const getLendMarket: (this: Llamalend, lendMarketId: string) => LendMarketTemplate<"v1"> | LendMarketTemplate<"v2">;
@@ -4,7 +4,12 @@ export const getLendMarket = function (lendMarketId) {
4
4
  const marketData = this.constants.ONE_WAY_MARKETS[lendMarketId] || this.constants.ONE_WAY_MARKETS_V2[lendMarketId];
5
5
  if (!marketData)
6
6
  throw new Error(`Lend market with id ${lendMarketId} not found`);
7
- this.lendMarkets[lendMarketId] = new LendMarketTemplate(lendMarketId, marketData, this);
7
+ if (marketData.version === 'v2') {
8
+ this.lendMarkets[lendMarketId] = new LendMarketTemplate(lendMarketId, marketData, this);
9
+ }
10
+ else {
11
+ this.lendMarkets[lendMarketId] = new LendMarketTemplate(lendMarketId, marketData, this);
12
+ }
8
13
  }
9
14
  return this.lendMarkets[lendMarketId];
10
15
  };
@@ -71,7 +71,6 @@ export declare class LoanBaseModule {
71
71
  repayIsApproved(debt: number | string): Promise<boolean>;
72
72
  private repayApproveEstimateGas;
73
73
  repayApprove(debt: number | string): Promise<string[]>;
74
- repayHealth(debt: number | string, full?: boolean, address?: string): Promise<string>;
75
74
  private _repay;
76
75
  repayEstimateGas(debt: number | string, address?: string): Promise<TGas>;
77
76
  repay(debt: number | string, address?: string): Promise<string>;
@@ -162,10 +162,8 @@ export class LoanBaseModule {
162
162
  const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
163
163
  const _debt = parseUnits(debt, this.market.borrowed_token.decimals);
164
164
  const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
165
- // TODO: verify parameters
166
- let _health = yield contract.health_calculator(this.llamalend.constants.ZERO_ADDRESS, _collateral, _debt, full, range, this.llamalend.constantOptions);
167
- _health = _health * BigInt(100);
168
- return formatUnits(_health);
165
+ const _health = yield contract.health_calculator(this.llamalend.constants.ZERO_ADDRESS, _collateral, _debt, full, range, this.llamalend.constantOptions);
166
+ return formatUnits(_health * BigInt(100));
169
167
  });
170
168
  }
171
169
  createLoanIsApproved(collateral) {
@@ -254,9 +252,8 @@ export class LoanBaseModule {
254
252
  const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
255
253
  const _debt = parseUnits(debt, this.market.borrowed_token.decimals);
256
254
  const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
257
- let _health = yield contract.health_calculator(address, _collateral, _debt, full, 0, this.llamalend.constantOptions);
258
- _health = _health * BigInt(100);
259
- return formatUnits(_health);
255
+ const _health = yield contract.health_calculator(address, _collateral, _debt, full, 0, this.llamalend.constantOptions);
256
+ return formatUnits(_health * BigInt(100));
260
257
  });
261
258
  }
262
259
  borrowMoreIsApproved(collateral) {
@@ -345,9 +342,8 @@ export class LoanBaseModule {
345
342
  address = _getAddress.call(this.llamalend, address);
346
343
  const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
347
344
  const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
348
- let _health = yield contract.health_calculator(address, _collateral, 0, full, 0, this.llamalend.constantOptions);
349
- _health = _health * BigInt(100);
350
- return formatUnits(_health);
345
+ const _health = yield contract.health_calculator(address, _collateral, 0, full, 0, this.llamalend.constantOptions);
346
+ return formatUnits(_health * BigInt(100));
351
347
  });
352
348
  }
353
349
  addCollateralIsApproved(collateral) {
@@ -444,9 +440,8 @@ export class LoanBaseModule {
444
440
  address = _getAddress.call(this.llamalend, address);
445
441
  const _collateral = parseUnits(collateral, this.market.collateral_token.decimals) * BigInt(-1);
446
442
  const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
447
- let _health = yield contract.health_calculator(address, _collateral, 0, full, 0, this.llamalend.constantOptions);
448
- _health = _health * BigInt(100);
449
- return formatUnits(_health);
443
+ const _health = yield contract.health_calculator(address, _collateral, 0, full, 0, this.llamalend.constantOptions);
444
+ return formatUnits(_health * BigInt(100));
450
445
  });
451
446
  }
452
447
  _removeCollateral(collateral, estimateGas) {
@@ -532,16 +527,6 @@ export class LoanBaseModule {
532
527
  return yield ensureAllowance.call(this.llamalend, [this.market.borrowed_token.address], [debt], this.market.addresses.controller);
533
528
  });
534
529
  }
535
- repayHealth(debt_1) {
536
- return __awaiter(this, arguments, void 0, function* (debt, full = true, address = "") {
537
- address = _getAddress.call(this.llamalend, address);
538
- const _debt = parseUnits(debt) * BigInt(-1);
539
- const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
540
- let _health = yield contract.health_calculator(address, 0, _debt, full, 0, this.llamalend.constantOptions);
541
- _health = _health * BigInt(100);
542
- return formatUnits(_health);
543
- });
544
- }
545
530
  _repay(debt, address, estimateGas) {
546
531
  return __awaiter(this, void 0, void 0, function* () {
547
532
  address = _getAddress.call(this.llamalend, address);
@@ -6,6 +6,9 @@ export declare class StatsBaseModule {
6
6
  protected market: LendMarketTemplate;
7
7
  protected llamalend: Llamalend;
8
8
  constructor(market: LendMarketTemplate);
9
+ protected _fetchAdminPercentage: () => Promise<bigint>;
10
+ private _getRate;
11
+ private _getFutureRate;
9
12
  statsParameters: (() => Promise<{
10
13
  fee: string;
11
14
  admin_fee: string;
@@ -21,8 +24,6 @@ export declare class StatsBaseModule {
21
24
  base_price: string;
22
25
  A: string;
23
26
  }>>;
24
- private _getRate;
25
- private _getFutureRate;
26
27
  statsRates(isGetter?: boolean, useAPI?: boolean): Promise<{
27
28
  borrowApr: string;
28
29
  lendApr: string;
@@ -66,4 +67,5 @@ export declare class StatsBaseModule {
66
67
  cap: string;
67
68
  available: string;
68
69
  }>;
70
+ statsAdminPercentage: () => Promise<string>;
69
71
  }
@@ -8,11 +8,39 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import memoize from "memoizee";
11
- import { parseUnits, BN, toBN, formatUnits, formatNumber, } from "../../../utils";
11
+ import { parseUnits, toBN, formatUnits, formatNumber, } from "../../../utils";
12
12
  import { _getMarketsData } from "../../../external-api";
13
13
  import { cacheKey, cacheStats } from "../../../cache";
14
+ import { computeRatesFromRate, fetchMarketDataByVault } from "../../utils";
15
+ const PRECISION = BigInt("1000000000000000000"); // 1e18
14
16
  export class StatsBaseModule {
15
17
  constructor(market) {
18
+ this._fetchAdminPercentage = () => __awaiter(this, void 0, void 0, function* () {
19
+ return BigInt(0);
20
+ });
21
+ this._getRate = (...args_1) => __awaiter(this, [...args_1], void 0, function* (isGetter = true) {
22
+ if (isGetter) {
23
+ const _rate = cacheStats.get(cacheKey(this.market.addresses.amm, 'rate'));
24
+ const _adminPercentage = yield this._fetchAdminPercentage();
25
+ return _rate * (PRECISION - _adminPercentage) / PRECISION;
26
+ }
27
+ else {
28
+ const [_rate, _adminPercentage] = yield Promise.all([
29
+ this.llamalend.contracts[this.market.addresses.amm].contract.rate(this.llamalend.constantOptions),
30
+ this._fetchAdminPercentage(),
31
+ ]);
32
+ cacheStats.set(cacheKey(this.market.addresses.controller, 'rate'), _rate);
33
+ return _rate * (PRECISION - _adminPercentage) / PRECISION;
34
+ }
35
+ });
36
+ this._getFutureRate = (_dReserves, _dDebt) => __awaiter(this, void 0, void 0, function* () {
37
+ const mpContract = this.llamalend.contracts[this.market.addresses.monetary_policy].contract;
38
+ const [_rate, _adminPercentage] = yield Promise.all([
39
+ mpContract.future_rate(this.market.addresses.controller, _dReserves, _dDebt),
40
+ this._fetchAdminPercentage(),
41
+ ]);
42
+ return _rate * (PRECISION - _adminPercentage) / PRECISION;
43
+ });
16
44
  this.statsParameters = memoize(() => __awaiter(this, void 0, void 0, function* () {
17
45
  const llammaContract = this.llamalend.contracts[this.market.addresses.amm].multicallContract;
18
46
  const controllerContract = this.llamalend.contracts[this.market.addresses.controller].multicallContract;
@@ -34,21 +62,6 @@ export class StatsBaseModule {
34
62
  promise: true,
35
63
  maxAge: 5 * 60 * 1000, // 5m
36
64
  });
37
- this._getRate = (...args_1) => __awaiter(this, [...args_1], void 0, function* (isGetter = true) {
38
- let _rate;
39
- if (isGetter) {
40
- _rate = cacheStats.get(cacheKey(this.market.addresses.amm, 'rate'));
41
- }
42
- else {
43
- _rate = yield this.llamalend.contracts[this.market.addresses.amm].contract.rate(this.llamalend.constantOptions);
44
- cacheStats.set(cacheKey(this.market.addresses.controller, 'rate'), _rate);
45
- }
46
- return _rate;
47
- });
48
- this._getFutureRate = (_dReserves, _dDebt) => __awaiter(this, void 0, void 0, function* () {
49
- const mpContract = this.llamalend.contracts[this.market.addresses.monetary_policy].contract;
50
- return yield mpContract.future_rate(this.market.addresses.controller, _dReserves, _dDebt);
51
- });
52
65
  this.statsBandsInfo = memoize(() => __awaiter(this, void 0, void 0, function* () {
53
66
  const ammContract = this.llamalend.contracts[this.market.addresses.amm].multicallContract;
54
67
  const calls = [
@@ -68,17 +81,11 @@ export class StatsBaseModule {
68
81
  });
69
82
  this.statsAmmBalances = (...args_1) => __awaiter(this, [...args_1], void 0, function* (isGetter = true, useAPI = false) {
70
83
  if (useAPI) {
71
- const response = yield _getMarketsData(this.llamalend.constants.NETWORK_NAME);
72
- const market = response.lendingVaultData.find((item) => item.address.toLowerCase() === this.market.addresses.vault.toLowerCase());
73
- if (market) {
74
- return {
75
- borrowed: market.ammBalances.ammBalanceBorrowed.toString(),
76
- collateral: market.ammBalances.ammBalanceCollateral.toString(),
77
- };
78
- }
79
- else {
80
- throw new Error('Market not found in API');
81
- }
84
+ const market = yield fetchMarketDataByVault(this.llamalend.constants.NETWORK_NAME, this.market.addresses.vault, _getMarketsData);
85
+ return {
86
+ borrowed: market.ammBalances.ammBalanceBorrowed.toString(),
87
+ collateral: market.ammBalances.ammBalanceCollateral.toString(),
88
+ };
82
89
  }
83
90
  else {
84
91
  const borrowedContract = this.llamalend.contracts[this.market.addresses.borrowed_token].multicallContract;
@@ -111,42 +118,29 @@ export class StatsBaseModule {
111
118
  };
112
119
  }
113
120
  });
121
+ this.statsAdminPercentage = () => __awaiter(this, void 0, void 0, function* () {
122
+ const _adminPercentage = yield this._fetchAdminPercentage();
123
+ return formatUnits(_adminPercentage * BigInt(100));
124
+ });
114
125
  this.market = market;
115
126
  this.llamalend = market.getLlamalend();
116
127
  }
117
128
  statsRates() {
118
129
  return __awaiter(this, arguments, void 0, function* (isGetter = true, useAPI = false) {
119
130
  if (useAPI) {
120
- const response = yield _getMarketsData(this.llamalend.constants.NETWORK_NAME);
121
- const market = response.lendingVaultData.find((item) => item.address.toLowerCase() === this.market.addresses.vault.toLowerCase());
122
- if (market) {
123
- return {
124
- borrowApr: (market.rates.borrowApr * 100).toString(),
125
- lendApr: (market.rates.lendApr * 100).toString(),
126
- borrowApy: (market.rates.borrowApy * 100).toString(),
127
- lendApy: (market.rates.lendApy * 100).toString(),
128
- };
129
- }
130
- else {
131
- throw new Error('Market not found in API');
132
- }
131
+ const market = yield fetchMarketDataByVault(this.llamalend.constants.NETWORK_NAME, this.market.addresses.vault, _getMarketsData);
132
+ return {
133
+ borrowApr: (market.rates.borrowApr * 100).toString(),
134
+ lendApr: (market.rates.lendApr * 100).toString(),
135
+ borrowApy: (market.rates.borrowApy * 100).toString(),
136
+ lendApy: (market.rates.lendApy * 100).toString(),
137
+ };
133
138
  }
134
139
  else {
135
140
  const _rate = yield this._getRate(isGetter);
136
- const borrowApr = toBN(_rate).times(365).times(86400).times(100).toString();
137
- // borrowApy = e**(rate*365*86400) - 1
138
- const borrowApy = String(((Math.pow(2.718281828459, (toBN(_rate).times(365).times(86400)).toNumber())) - 1) * 100);
139
- let lendApr = "0";
140
- let lendApy = "0";
141
141
  const debt = yield this.statsTotalDebt(isGetter);
142
- if (Number(debt) > 0) {
143
- const { cap } = yield this.statsCapAndAvailable(isGetter);
144
- lendApr = toBN(_rate).times(365).times(86400).times(debt).div(cap).times(100).toString();
145
- // lendApy = (debt * e**(rate*365*86400) - debt) / cap
146
- const debtInAYearBN = BN(debt).times(Math.pow(2.718281828459, (toBN(_rate).times(365).times(86400)).toNumber()));
147
- lendApy = debtInAYearBN.minus(debt).div(cap).times(100).toString();
148
- }
149
- return { borrowApr, lendApr, borrowApy, lendApy };
142
+ const { cap } = Number(debt) > 0 ? yield this.statsCapAndAvailable(isGetter) : { cap: "0" };
143
+ return computeRatesFromRate(_rate, debt, cap);
150
144
  }
151
145
  });
152
146
  }
@@ -155,20 +149,9 @@ export class StatsBaseModule {
155
149
  const _dReserves = parseUnits(dReserves, this.market.borrowed_token.decimals);
156
150
  const _dDebt = parseUnits(dDebt, this.market.borrowed_token.decimals);
157
151
  const _rate = yield this._getFutureRate(_dReserves, _dDebt);
158
- const borrowApr = toBN(_rate).times(365).times(86400).times(100).toString();
159
- // borrowApy = e**(rate*365*86400) - 1
160
- const borrowApy = String(((Math.pow(2.718281828459, (toBN(_rate).times(365).times(86400)).toNumber())) - 1) * 100);
161
- let lendApr = "0";
162
- let lendApy = "0";
163
152
  const debt = Number(yield this.statsTotalDebt()) + Number(dDebt);
164
- if (Number(debt) > 0) {
165
- const cap = Number((yield this.statsCapAndAvailable(true, useAPI)).cap) + Number(dReserves);
166
- lendApr = toBN(_rate).times(365).times(86400).times(debt).div(cap).times(100).toString();
167
- // lendApy = (debt * e**(rate*365*86400) - debt) / cap
168
- const debtInAYearBN = BN(debt).times(Math.pow(2.718281828459, (toBN(_rate).times(365).times(86400)).toNumber()));
169
- lendApy = debtInAYearBN.minus(debt).div(cap).times(100).toString();
170
- }
171
- return { borrowApr, lendApr, borrowApy, lendApy };
153
+ const cap = Number((yield this.statsCapAndAvailable(true, useAPI)).cap) + Number(dReserves);
154
+ return computeRatesFromRate(_rate, debt, cap);
172
155
  });
173
156
  }
174
157
  statsBalances() {
@@ -226,14 +209,8 @@ export class StatsBaseModule {
226
209
  statsTotalDebt() {
227
210
  return __awaiter(this, arguments, void 0, function* (isGetter = true, useAPI = true) {
228
211
  if (useAPI) {
229
- const response = yield _getMarketsData(this.llamalend.constants.NETWORK_NAME);
230
- const market = response.lendingVaultData.find((item) => item.address.toLowerCase() === this.market.addresses.vault.toLowerCase());
231
- if (market) {
232
- return market.borrowed.total.toString();
233
- }
234
- else {
235
- throw new Error('Market not found in API');
236
- }
212
+ const market = yield fetchMarketDataByVault(this.llamalend.constants.NETWORK_NAME, this.market.addresses.vault, _getMarketsData);
213
+ return market.borrowed.total.toString();
237
214
  }
238
215
  else {
239
216
  let _debt;
@@ -251,17 +228,11 @@ export class StatsBaseModule {
251
228
  statsCapAndAvailable() {
252
229
  return __awaiter(this, arguments, void 0, function* (isGetter = true, useAPI = false) {
253
230
  if (useAPI) {
254
- const response = yield _getMarketsData(this.llamalend.constants.NETWORK_NAME);
255
- const market = response.lendingVaultData.find((item) => item.address.toLowerCase() === this.market.addresses.vault.toLowerCase());
256
- if (market) {
257
- return {
258
- cap: market.totalSupplied.total.toString(),
259
- available: market.availableToBorrow.total.toString(),
260
- };
261
- }
262
- else {
263
- throw new Error('Market not found in API');
264
- }
231
+ const market = yield fetchMarketDataByVault(this.llamalend.constants.NETWORK_NAME, this.market.addresses.vault, _getMarketsData);
232
+ return {
233
+ cap: market.totalSupplied.total.toString(),
234
+ available: market.availableToBorrow.total.toString(),
235
+ };
265
236
  }
266
237
  else {
267
238
  const vaultContract = this.llamalend.contracts[this.market.addresses.vault].multicallContract;
@@ -1,4 +1,5 @@
1
1
  import { LoanBaseModule } from "../common/loanBase.js";
2
2
  import { ILoanV1 } from "../../interfaces/v1/loanV1";
3
3
  export declare class LoanV1Module extends LoanBaseModule implements ILoanV1 {
4
+ repayHealth(debt: number | string, full?: boolean, address?: string): Promise<string>;
4
5
  }
@@ -1,3 +1,22 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import { LoanBaseModule } from "../common/loanBase.js";
11
+ import { _getAddress, formatUnits, parseUnits } from "../../../utils";
2
12
  export class LoanV1Module extends LoanBaseModule {
13
+ repayHealth(debt_1) {
14
+ return __awaiter(this, arguments, void 0, function* (debt, full = true, address = "") {
15
+ address = _getAddress.call(this.llamalend, address);
16
+ const _debt = parseUnits(debt) * BigInt(-1);
17
+ const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
18
+ const _health = yield contract.health_calculator(address, 0, _debt, full, 0, this.llamalend.constantOptions);
19
+ return formatUnits(_health * BigInt(100));
20
+ });
21
+ }
3
22
  }
@@ -1,4 +1,9 @@
1
1
  import { LoanBaseModule } from "../common/loanBase.js";
2
2
  import { ILoanV2 } from "../../interfaces/v2";
3
3
  export declare class LoanV2Module extends LoanBaseModule implements ILoanV2 {
4
+ createLoanHealth(collateral: number | string, debt: number | string, range: number, full?: boolean): Promise<string>;
5
+ addCollateralHealth(collateral: number | string, full?: boolean, address?: string): Promise<string>;
6
+ removeCollateralHealth(collateral: number | string, full?: boolean, address?: string): Promise<string>;
7
+ borrowMoreHealth(collateral: number | string, debt: number | string, full?: boolean, address?: string): Promise<string>;
8
+ repayHealth(debt: number | string, shrink?: boolean, full?: boolean, address?: string): Promise<string>;
4
9
  }
@@ -1,3 +1,60 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import { LoanBaseModule } from "../common/loanBase.js";
11
+ import { _getAddress, formatUnits, parseUnits } from "../../../utils";
2
12
  export class LoanV2Module extends LoanBaseModule {
13
+ createLoanHealth(collateral_1, debt_1, range_1) {
14
+ return __awaiter(this, arguments, void 0, function* (collateral, debt, range, full = true) {
15
+ const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
16
+ const _debt = parseUnits(debt, this.market.borrowed_token.decimals);
17
+ const address = _getAddress.call(this.llamalend, '');
18
+ const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
19
+ const _health = yield contract.create_loan_health_preview(_collateral, _debt, range, address, full, this.llamalend.constantOptions);
20
+ return formatUnits(_health * BigInt(100));
21
+ });
22
+ }
23
+ addCollateralHealth(collateral_1) {
24
+ return __awaiter(this, arguments, void 0, function* (collateral, full = true, address = "") {
25
+ address = _getAddress.call(this.llamalend, address);
26
+ const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
27
+ const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
28
+ const _health = yield contract.add_collateral_health_preview(_collateral, address, address, full, this.llamalend.constantOptions);
29
+ return formatUnits(_health * BigInt(100));
30
+ });
31
+ }
32
+ removeCollateralHealth(collateral_1) {
33
+ return __awaiter(this, arguments, void 0, function* (collateral, full = true, address = "") {
34
+ address = _getAddress.call(this.llamalend, address);
35
+ const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
36
+ const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
37
+ const _health = yield contract.remove_collateral_health_preview(_collateral, address, full, this.llamalend.constantOptions);
38
+ return formatUnits(_health * BigInt(100));
39
+ });
40
+ }
41
+ borrowMoreHealth(collateral_1, debt_1) {
42
+ return __awaiter(this, arguments, void 0, function* (collateral, debt, full = true, address = "") {
43
+ address = _getAddress.call(this.llamalend, address);
44
+ const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
45
+ const _debt = parseUnits(debt, this.market.borrowed_token.decimals);
46
+ const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
47
+ const _health = yield contract.borrow_more_health_preview(_collateral, _debt, address, full, this.llamalend.constantOptions);
48
+ return formatUnits(_health * BigInt(100));
49
+ });
50
+ }
51
+ repayHealth(debt_1) {
52
+ return __awaiter(this, arguments, void 0, function* (debt, shrink = false, full = true, address = "") {
53
+ address = _getAddress.call(this.llamalend, address);
54
+ const _debt = parseUnits(debt);
55
+ const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
56
+ const _health = yield contract.repay_health_preview(0, _debt, address, address, shrink, full, this.llamalend.constantOptions);
57
+ return formatUnits(_health * BigInt(100));
58
+ });
59
+ }
3
60
  }
@@ -1,3 +1,5 @@
1
+ import memoize from "memoizee";
1
2
  import { StatsBaseModule } from "../common/statsBase.js";
2
3
  export declare class StatsV2Module extends StatsBaseModule {
4
+ protected _fetchAdminPercentage: (() => Promise<bigint>) & memoize.Memoized<() => Promise<bigint>>;
3
5
  }
@@ -1,3 +1,22 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import memoize from "memoizee";
1
11
  import { StatsBaseModule } from "../common/statsBase.js";
2
12
  export class StatsV2Module extends StatsBaseModule {
13
+ constructor() {
14
+ super(...arguments);
15
+ this._fetchAdminPercentage = memoize(() => __awaiter(this, void 0, void 0, function* () {
16
+ return yield this.llamalend.contracts[this.market.addresses.controller].contract.admin_percentage(this.llamalend.constantOptions);
17
+ }), {
18
+ promise: true,
19
+ maxAge: 30 * 60 * 1000, // 30m
20
+ });
21
+ }
3
22
  }
@@ -0,0 +1,14 @@
1
+ import { INetworkName, IMarketData, IMarketDataAPI } from "../interfaces";
2
+ export type RatesResult = {
3
+ borrowApr: string;
4
+ lendApr: string;
5
+ borrowApy: string;
6
+ lendApy: string;
7
+ };
8
+ /**
9
+ * Computes borrow/lend APR and APY from a raw per-second rate and current debt/cap.
10
+ * borrowApy = e^(rate * 365 * 86400) - 1
11
+ * lendApy = (debt * e^(rate * 365 * 86400) - debt) / cap
12
+ */
13
+ export declare const computeRatesFromRate: (_rate: bigint, debt: string | number, cap: string | number) => RatesResult;
14
+ export declare const fetchMarketDataByVault: (networkName: INetworkName, vaultAddress: string, getData: (network: INetworkName) => Promise<IMarketData>) => Promise<IMarketDataAPI>;