@curvefi/llamalend-api 2.0.3 → 2.0.5

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.
@@ -143,6 +143,48 @@ This document tracks feature support across market versions.
143
143
  | ammBalances() | ✅ | ✅ | ✅ | ✅ | ✅ |
144
144
  | capAndAvailable() | ✅ | ✅ | ❌ | ✅ | ❌ |
145
145
 
146
+ ### Update for `capAndAvailable` method
147
+
148
+ Previously the `capAndAvailable` method returned:
149
+
150
+ ```ts
151
+ {
152
+ cap: string
153
+ available: string
154
+ }
155
+ ```
156
+
157
+ Now it returns:
158
+
159
+ ```ts
160
+ {
161
+ totalAssets: string
162
+ borrowCap: string
163
+ available: string
164
+ availableForBorrow: string
165
+ }
166
+ ```
167
+
168
+ #### Important clarification
169
+
170
+ Previously the value called **`cap`** was incorrectly named.
171
+
172
+ On the frontend, the value that we now return as **`totalAssets`** corresponds to what was previously treated as **`cap`**.
173
+
174
+ #### Summary
175
+
176
+ - `totalAssets` → total assets deposited in the vault (what was previously used as `cap` on the frontend)
177
+ - `borrowCap` → maximum total debt allowed by the controller (LLv2 only; `Infinity` for LLv1)
178
+ - `available` → balance of borrowed token available in the controller
179
+ - `availableForBorrow` → effective amount available to borrow: `min(available, borrowCap - totalDebt)`
180
+
181
+
182
+ ## Stats Module (`market.stats`) new methods
183
+ | Method | v1 | v2 | Same logic | Same params | Same type |
184
+ |--------|----|----|-----------------|----------------------|-----------------------|
185
+ | adminPercentage() | ✅ | ✅ | ✅ | ✅ | ✅ |
186
+
187
+
146
188
  ---
147
189
 
148
190
  ## Wallet Module (`market.wallet`)
@@ -186,6 +186,7 @@ export interface IMarketDataAPI {
186
186
  totalSupplied: Total;
187
187
  borrowed: Total;
188
188
  availableToBorrow: Total;
189
+ borrowCap: Total;
189
190
  lendingVaultUrls: LendingVaultUrls;
190
191
  usdTotal: number;
191
192
  ammBalances: AmmBalances;
@@ -68,19 +68,20 @@ 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
- balances: wallet.balances.bind(this),
84
+ balances: wallet.balances.bind(wallet),
84
85
  };
85
86
  this.prices = {
86
87
  A: prices.A.bind(prices),
@@ -43,7 +43,10 @@ export interface IStatsV1 {
43
43
  collateral: string;
44
44
  }>;
45
45
  capAndAvailable: (isGetter?: boolean, useAPI?: boolean) => Promise<{
46
- cap: string;
46
+ borrowCap: string;
47
47
  available: string;
48
+ totalAssets: string;
49
+ availableForBorrow: string;
48
50
  }>;
51
+ adminPercentage: () => Promise<string>;
49
52
  }
@@ -43,7 +43,10 @@ export interface IStatsV2 {
43
43
  collateral: string;
44
44
  }>;
45
45
  capAndAvailable: (isGetter?: boolean, useAPI?: boolean) => Promise<{
46
- cap: string;
46
+ borrowCap: string;
47
47
  available: string;
48
+ totalAssets: string;
49
+ availableForBorrow: string;
48
50
  }>;
51
+ adminPercentage: () => Promise<string>;
49
52
  }
@@ -1,11 +1,17 @@
1
1
  import memoize from "memoizee";
2
- import { TAmount } from "../../../interfaces";
2
+ import { TAmount, IMarketDataAPI } from "../../../interfaces";
3
3
  import type { LendMarketTemplate } from "../../LendMarketTemplate";
4
4
  import { Llamalend } from "../../../llamalend";
5
5
  export declare class StatsBaseModule {
6
6
  protected market: LendMarketTemplate;
7
7
  protected llamalend: Llamalend;
8
8
  constructor(market: LendMarketTemplate);
9
+ protected _fetchMarketDataFromAPI(): Promise<IMarketDataAPI>;
10
+ protected _fetchAdminPercentage: () => Promise<bigint>;
11
+ protected _fetchAdminFee: () => Promise<bigint>;
12
+ protected _getAdminFeesXY(isGetter: boolean): Promise<[bigint, bigint]>;
13
+ private _getRate;
14
+ private _getFutureRate;
9
15
  statsParameters: (() => Promise<{
10
16
  fee: string;
11
17
  admin_fee: string;
@@ -21,8 +27,6 @@ export declare class StatsBaseModule {
21
27
  base_price: string;
22
28
  A: string;
23
29
  }>>;
24
- private _getRate;
25
- private _getFutureRate;
26
30
  statsRates(isGetter?: boolean, useAPI?: boolean): Promise<{
27
31
  borrowApr: string;
28
32
  lendApr: string;
@@ -62,8 +66,23 @@ export declare class StatsBaseModule {
62
66
  borrowed: string;
63
67
  collateral: string;
64
68
  }>;
69
+ protected _statsCapAndAvailableFromAPI(): Promise<{
70
+ borrowCap: string;
71
+ available: string;
72
+ totalAssets: string;
73
+ availableForBorrow: string;
74
+ }>;
75
+ protected _statsCapAndAvailableOnChain(isGetter: boolean): Promise<{
76
+ borrowCap: string;
77
+ available: string;
78
+ totalAssets: string;
79
+ availableForBorrow: string;
80
+ }>;
65
81
  statsCapAndAvailable(isGetter?: boolean, useAPI?: boolean): Promise<{
66
- cap: string;
82
+ borrowCap: string;
67
83
  available: string;
84
+ totalAssets: string;
85
+ availableForBorrow: string;
68
86
  }>;
87
+ statsAdminPercentage: () => Promise<string>;
69
88
  }
@@ -8,23 +8,55 @@ 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._fetchAdminFee = () => __awaiter(this, void 0, void 0, function* () {
22
+ return this.llamalend.contracts[this.market.addresses.amm].contract.admin_fee(this.llamalend.constantOptions);
23
+ });
24
+ this._getRate = (...args_1) => __awaiter(this, [...args_1], void 0, function* (isGetter = true) {
25
+ if (isGetter) {
26
+ const _rate = cacheStats.get(cacheKey(this.market.addresses.amm, 'rate'));
27
+ const _adminPercentage = yield this._fetchAdminPercentage();
28
+ return _rate * (PRECISION - _adminPercentage) / PRECISION;
29
+ }
30
+ else {
31
+ const [_rate, _adminPercentage] = yield Promise.all([
32
+ this.llamalend.contracts[this.market.addresses.amm].contract.rate(this.llamalend.constantOptions),
33
+ this._fetchAdminPercentage(),
34
+ ]);
35
+ cacheStats.set(cacheKey(this.market.addresses.controller, 'rate'), _rate);
36
+ return _rate * (PRECISION - _adminPercentage) / PRECISION;
37
+ }
38
+ });
39
+ this._getFutureRate = (_dReserves, _dDebt) => __awaiter(this, void 0, void 0, function* () {
40
+ const mpContract = this.llamalend.contracts[this.market.addresses.monetary_policy].contract;
41
+ const [_rate, _adminPercentage] = yield Promise.all([
42
+ mpContract.future_rate(this.market.addresses.controller, _dReserves, _dDebt),
43
+ this._fetchAdminPercentage(),
44
+ ]);
45
+ return _rate * (PRECISION - _adminPercentage) / PRECISION;
46
+ });
16
47
  this.statsParameters = memoize(() => __awaiter(this, void 0, void 0, function* () {
17
48
  const llammaContract = this.llamalend.contracts[this.market.addresses.amm].multicallContract;
18
49
  const controllerContract = this.llamalend.contracts[this.market.addresses.controller].multicallContract;
19
- const calls = [
20
- llammaContract.fee(),
21
- llammaContract.admin_fee(), // TODO: removed
22
- controllerContract.liquidation_discount(),
23
- controllerContract.loan_discount(),
24
- llammaContract.get_base_price(),
25
- llammaContract.A(),
26
- ];
27
- const [_fee, _admin_fee, _liquidation_discount, _loan_discount, _base_price, _A] = yield this.llamalend.multicallProvider.all(calls);
50
+ const [[_fee, _liquidation_discount, _loan_discount, _base_price, _A], _admin_fee] = yield Promise.all([
51
+ this.llamalend.multicallProvider.all([
52
+ llammaContract.fee(),
53
+ controllerContract.liquidation_discount(),
54
+ controllerContract.loan_discount(),
55
+ llammaContract.get_base_price(),
56
+ llammaContract.A(),
57
+ ]),
58
+ this._fetchAdminFee(),
59
+ ]);
28
60
  const A = formatUnits(_A, 0);
29
61
  const base_price = formatUnits(_base_price);
30
62
  const [fee, admin_fee, liquidation_discount, loan_discount] = [_fee, _admin_fee, _liquidation_discount, _loan_discount]
@@ -34,21 +66,6 @@ export class StatsBaseModule {
34
66
  promise: true,
35
67
  maxAge: 5 * 60 * 1000, // 5m
36
68
  });
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
69
  this.statsBandsInfo = memoize(() => __awaiter(this, void 0, void 0, function* () {
53
70
  const ammContract = this.llamalend.contracts[this.market.addresses.amm].multicallContract;
54
71
  const calls = [
@@ -68,42 +85,32 @@ export class StatsBaseModule {
68
85
  });
69
86
  this.statsAmmBalances = (...args_1) => __awaiter(this, [...args_1], void 0, function* (isGetter = true, useAPI = false) {
70
87
  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
- }
88
+ const market = yield this._fetchMarketDataFromAPI();
89
+ return {
90
+ borrowed: market.ammBalances.ammBalanceBorrowed.toString(),
91
+ collateral: market.ammBalances.ammBalanceCollateral.toString(),
92
+ };
82
93
  }
83
94
  else {
84
95
  const borrowedContract = this.llamalend.contracts[this.market.addresses.borrowed_token].multicallContract;
85
96
  const collateralContract = this.llamalend.contracts[this.market.addresses.collateral_token].multicallContract;
86
- const ammContract = this.llamalend.contracts[this.market.addresses.amm].multicallContract;
87
- let _balance_x, _fee_x, _balance_y, _fee_y; // TODO: fees are always 0
97
+ let _balance_x, _balance_y;
98
+ let _fee_x, _fee_y;
88
99
  if (isGetter) {
89
- [_balance_x, _fee_x, _balance_y, _fee_y] = [
90
- cacheStats.get(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.amm)),
91
- cacheStats.get(cacheKey(this.market.addresses.amm, 'admin_fees_x')),
92
- cacheStats.get(cacheKey(this.market.addresses.collateral_token, 'balanceOf', this.market.addresses.amm)),
93
- cacheStats.get(cacheKey(this.market.addresses.amm, 'admin_fees_y')),
94
- ];
100
+ _balance_x = cacheStats.get(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.amm));
101
+ _balance_y = cacheStats.get(cacheKey(this.market.addresses.collateral_token, 'balanceOf', this.market.addresses.amm));
102
+ [_fee_x, _fee_y] = yield this._getAdminFeesXY(true);
95
103
  }
96
104
  else {
97
- [_balance_x, _fee_x, _balance_y, _fee_y] = yield this.llamalend.multicallProvider.all([
98
- borrowedContract.balanceOf(this.market.addresses.amm),
99
- ammContract.admin_fees_x(),
100
- collateralContract.balanceOf(this.market.addresses.amm),
101
- ammContract.admin_fees_y(),
102
- ]);
105
+ [[_balance_x, _balance_y], [_fee_x, _fee_y]] = (yield Promise.all([
106
+ this.llamalend.multicallProvider.all([
107
+ borrowedContract.balanceOf(this.market.addresses.amm),
108
+ collateralContract.balanceOf(this.market.addresses.amm),
109
+ ]),
110
+ this._getAdminFeesXY(false),
111
+ ]));
103
112
  cacheStats.set(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.amm), _balance_x);
104
- cacheStats.set(cacheKey(this.market.addresses.amm, 'admin_fees_x'), _fee_x);
105
113
  cacheStats.set(cacheKey(this.market.addresses.collateral_token, 'balanceOf', this.market.addresses.amm), _balance_y);
106
- cacheStats.set(cacheKey(this.market.addresses.amm, 'admin_fees_y'), _fee_y);
107
114
  }
108
115
  return {
109
116
  borrowed: toBN(_balance_x, this.market.borrowed_token.decimals).minus(toBN(_fee_x, this.market.borrowed_token.decimals)).toString(),
@@ -111,42 +118,52 @@ 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
  }
128
+ _fetchMarketDataFromAPI() {
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ return fetchMarketDataByVault(this.llamalend.constants.NETWORK_NAME, this.market.addresses.vault, _getMarketsData);
131
+ });
132
+ }
133
+ _getAdminFeesXY(isGetter) {
134
+ return __awaiter(this, void 0, void 0, function* () {
135
+ if (isGetter) {
136
+ return [
137
+ cacheStats.get(cacheKey(this.market.addresses.amm, 'admin_fees_x')),
138
+ cacheStats.get(cacheKey(this.market.addresses.amm, 'admin_fees_y')),
139
+ ];
140
+ }
141
+ const ammContract = this.llamalend.contracts[this.market.addresses.amm].multicallContract;
142
+ const [_fee_x, _fee_y] = yield this.llamalend.multicallProvider.all([
143
+ ammContract.admin_fees_x(),
144
+ ammContract.admin_fees_y(),
145
+ ]);
146
+ cacheStats.set(cacheKey(this.market.addresses.amm, 'admin_fees_x'), _fee_x);
147
+ cacheStats.set(cacheKey(this.market.addresses.amm, 'admin_fees_y'), _fee_y);
148
+ return [_fee_x, _fee_y];
149
+ });
150
+ }
117
151
  statsRates() {
118
152
  return __awaiter(this, arguments, void 0, function* (isGetter = true, useAPI = false) {
119
153
  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
- }
154
+ const market = yield this._fetchMarketDataFromAPI();
155
+ return {
156
+ borrowApr: (market.rates.borrowApr * 100).toString(),
157
+ lendApr: (market.rates.lendApr * 100).toString(),
158
+ borrowApy: (market.rates.borrowApy * 100).toString(),
159
+ lendApy: (market.rates.lendApy * 100).toString(),
160
+ };
133
161
  }
134
162
  else {
135
163
  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
- 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 };
164
+ const debt = yield this.statsTotalDebt(isGetter, false);
165
+ const { totalAssets } = Number(debt) > 0 ? yield this.statsCapAndAvailable(isGetter, false) : { totalAssets: "0" };
166
+ return computeRatesFromRate(_rate, debt, totalAssets);
150
167
  }
151
168
  });
152
169
  }
@@ -155,34 +172,22 @@ export class StatsBaseModule {
155
172
  const _dReserves = parseUnits(dReserves, this.market.borrowed_token.decimals);
156
173
  const _dDebt = parseUnits(dDebt, this.market.borrowed_token.decimals);
157
174
  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
175
  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 };
176
+ const cap = Number((yield this.statsCapAndAvailable(true, useAPI)).totalAssets) + Number(dReserves);
177
+ return computeRatesFromRate(_rate, debt, cap);
172
178
  });
173
179
  }
174
180
  statsBalances() {
175
181
  return __awaiter(this, void 0, void 0, function* () {
176
182
  const borrowedContract = this.llamalend.contracts[this.market.borrowed_token.address].multicallContract;
177
183
  const collateralContract = this.llamalend.contracts[this.market.collateral_token.address].multicallContract;
178
- const ammContract = this.llamalend.contracts[this.market.addresses.amm].multicallContract;
179
- const calls = [
180
- borrowedContract.balanceOf(this.market.addresses.amm),
181
- collateralContract.balanceOf(this.market.addresses.amm),
182
- ammContract.admin_fees_x(), // TODO: always 0
183
- ammContract.admin_fees_y(), // TODO: always 0
184
- ];
185
- const [_borrowedBalance, _collateralBalance, _borrowedAdminFees, _collateralAdminFees] = yield this.llamalend.multicallProvider.all(calls);
184
+ const [[_borrowedBalance, _collateralBalance], [_borrowedAdminFees, _collateralAdminFees]] = yield Promise.all([
185
+ this.llamalend.multicallProvider.all([
186
+ borrowedContract.balanceOf(this.market.addresses.amm),
187
+ collateralContract.balanceOf(this.market.addresses.amm),
188
+ ]),
189
+ this._getAdminFeesXY(false),
190
+ ]);
186
191
  return [
187
192
  formatUnits(_borrowedBalance - _borrowedAdminFees, this.market.borrowed_token.decimals),
188
193
  formatUnits(_collateralBalance - _collateralAdminFees, this.market.collateral_token.decimals),
@@ -226,14 +231,8 @@ export class StatsBaseModule {
226
231
  statsTotalDebt() {
227
232
  return __awaiter(this, arguments, void 0, function* (isGetter = true, useAPI = true) {
228
233
  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
- }
234
+ const market = yield this._fetchMarketDataFromAPI();
235
+ return market.borrowed.total.toString();
237
236
  }
238
237
  else {
239
238
  let _debt;
@@ -248,44 +247,48 @@ export class StatsBaseModule {
248
247
  }
249
248
  });
250
249
  }
251
- statsCapAndAvailable() {
252
- return __awaiter(this, arguments, void 0, function* (isGetter = true, useAPI = false) {
253
- 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
- }
250
+ _statsCapAndAvailableFromAPI() {
251
+ return __awaiter(this, void 0, void 0, function* () {
252
+ const market = yield this._fetchMarketDataFromAPI();
253
+ return {
254
+ totalAssets: market.totalSupplied.total.toString(),
255
+ borrowCap: Infinity.toString(),
256
+ available: market.availableToBorrow.total.toString(),
257
+ availableForBorrow: market.availableToBorrow.total.toString(),
258
+ };
259
+ });
260
+ }
261
+ _statsCapAndAvailableOnChain(isGetter) {
262
+ return __awaiter(this, void 0, void 0, function* () {
263
+ const vaultContract = this.llamalend.contracts[this.market.addresses.vault].multicallContract;
264
+ const borrowedContract = this.llamalend.contracts[this.market.addresses.borrowed_token].multicallContract;
265
+ let _cap, _available;
266
+ if (isGetter) {
267
+ _cap = cacheStats.get(cacheKey(this.market.addresses.vault, 'totalAssets', this.market.addresses.controller));
268
+ _available = cacheStats.get(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.controller));
265
269
  }
266
270
  else {
267
- const vaultContract = this.llamalend.contracts[this.market.addresses.vault].multicallContract;
268
- const borrowedContract = this.llamalend.contracts[this.market.addresses.borrowed_token].multicallContract;
269
- let _cap, _available;
270
- if (isGetter) { // TODO: should call controller.available_balance() instead of borrowed_token.balanceOf(controller)
271
- _cap = cacheStats.get(cacheKey(this.market.addresses.vault, 'totalAssets', this.market.addresses.controller));
272
- _available = cacheStats.get(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.controller));
273
- }
274
- else {
275
- [_cap, _available] = yield this.llamalend.multicallProvider.all([
276
- vaultContract.totalAssets(this.market.addresses.controller),
277
- borrowedContract.balanceOf(this.market.addresses.controller),
278
- ]);
279
- cacheStats.set(cacheKey(this.market.addresses.vault, 'totalAssets', this.market.addresses.controller), _cap);
280
- cacheStats.set(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.controller), _available);
281
- }
282
- return {
283
- cap: this.llamalend.formatUnits(_cap, this.market.borrowed_token.decimals),
284
- available: this.llamalend.formatUnits(_available, this.market.borrowed_token.decimals),
285
- };
286
- // cap -> totalAssets
287
- // add cap: controller.borrow_cap() // Display
271
+ [_cap, _available] = yield this.llamalend.multicallProvider.all([
272
+ vaultContract.totalAssets(this.market.addresses.controller),
273
+ borrowedContract.balanceOf(this.market.addresses.controller),
274
+ ]);
275
+ cacheStats.set(cacheKey(this.market.addresses.vault, 'totalAssets', this.market.addresses.controller), _cap);
276
+ cacheStats.set(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.controller), _available);
288
277
  }
278
+ const available = this.llamalend.formatUnits(_available, this.market.borrowed_token.decimals);
279
+ return {
280
+ totalAssets: this.llamalend.formatUnits(_cap, this.market.borrowed_token.decimals),
281
+ borrowCap: Infinity.toString(),
282
+ available,
283
+ availableForBorrow: available,
284
+ };
285
+ });
286
+ }
287
+ statsCapAndAvailable() {
288
+ return __awaiter(this, arguments, void 0, function* (isGetter = true, useAPI = false) {
289
+ if (useAPI)
290
+ return this._statsCapAndAvailableFromAPI();
291
+ return this._statsCapAndAvailableOnChain(isGetter);
289
292
  });
290
293
  }
291
294
  }
@@ -415,9 +415,9 @@ export class VaultModule {
415
415
  }
416
416
  vaultTotalLiquidity() {
417
417
  return __awaiter(this, arguments, void 0, function* (useAPI = true) {
418
- const { cap } = yield this.market.stats.capAndAvailable(true, useAPI);
418
+ const { totalAssets } = yield this.market.stats.capAndAvailable(true, useAPI);
419
419
  const price = yield _getUsdRate.call(this.llamalend, this.market.addresses.borrowed_token);
420
- return BN(cap).times(price).toFixed(6);
420
+ return BN(totalAssets).times(price).toFixed(6);
421
421
  });
422
422
  }
423
423
  vaultCrvApr() {
@@ -1,3 +1,19 @@
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>>;
5
+ protected _fetchAdminFee: () => Promise<bigint>;
6
+ protected _getAdminFeesXY: () => Promise<[bigint, bigint]>;
7
+ protected _statsCapAndAvailableFromAPI(): Promise<{
8
+ totalAssets: string;
9
+ borrowCap: string;
10
+ available: string;
11
+ availableForBorrow: string;
12
+ }>;
13
+ protected _statsCapAndAvailableOnChain(isGetter: boolean): Promise<{
14
+ borrowCap: string;
15
+ available: string;
16
+ totalAssets: string;
17
+ availableForBorrow: string;
18
+ }>;
3
19
  }
@@ -1,3 +1,69 @@
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";
12
+ import { cacheKey, cacheStats } from "../../../cache";
13
+ import BigNumber from "bignumber.js";
14
+ import { BN } from "../../../utils";
2
15
  export class StatsV2Module extends StatsBaseModule {
16
+ constructor() {
17
+ super(...arguments);
18
+ this._fetchAdminPercentage = memoize(() => __awaiter(this, void 0, void 0, function* () {
19
+ return yield this.llamalend.contracts[this.market.addresses.controller].contract.admin_percentage(this.llamalend.constantOptions);
20
+ }), {
21
+ promise: true,
22
+ maxAge: 30 * 60 * 1000, // 30m
23
+ });
24
+ this._fetchAdminFee = () => __awaiter(this, void 0, void 0, function* () { return BigInt(0); });
25
+ this._getAdminFeesXY = () => __awaiter(this, void 0, void 0, function* () { return [BigInt(0), BigInt(0)]; });
26
+ }
27
+ _statsCapAndAvailableFromAPI() {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ const market = yield this._fetchMarketDataFromAPI();
30
+ return {
31
+ totalAssets: market.totalSupplied.total.toString(),
32
+ borrowCap: market.borrowCap.total.toString(),
33
+ available: market.availableToBorrow.total.toString(),
34
+ availableForBorrow: market.availableToBorrow.total.toString(),
35
+ };
36
+ });
37
+ }
38
+ _statsCapAndAvailableOnChain(isGetter) {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ const vaultContract = this.llamalend.contracts[this.market.addresses.vault].multicallContract;
41
+ const controllerContract = this.llamalend.contracts[this.market.addresses.controller].multicallContract;
42
+ let _cap, _available, _totalAssets, _totalDebt;
43
+ if (isGetter) {
44
+ _totalAssets = cacheStats.get(cacheKey(this.market.addresses.vault, 'totalAssets', this.market.addresses.controller));
45
+ _cap = cacheStats.get(cacheKey(this.market.addresses.controller, 'borrow_cap'));
46
+ _available = cacheStats.get(cacheKey(this.market.addresses.controller, 'available_balance'));
47
+ _totalDebt = cacheStats.get(cacheKey(this.market.addresses.controller, 'total_debt'));
48
+ }
49
+ else {
50
+ [_totalAssets, _available, _cap, _totalDebt] = yield this.llamalend.multicallProvider.all([
51
+ vaultContract.totalAssets(this.market.addresses.controller),
52
+ controllerContract.available_balance(),
53
+ controllerContract.borrow_cap(),
54
+ controllerContract.total_debt(),
55
+ ]);
56
+ cacheStats.set(cacheKey(this.market.addresses.vault, 'totalAssets', this.market.addresses.controller), _totalAssets);
57
+ cacheStats.set(cacheKey(this.market.addresses.controller, 'borrow_cap'), _cap);
58
+ cacheStats.set(cacheKey(this.market.addresses.controller, 'available_balance'), _available);
59
+ cacheStats.set(cacheKey(this.market.addresses.controller, 'total_debt'), _totalDebt);
60
+ }
61
+ const totalAssets = this.llamalend.formatUnits(_totalAssets, this.market.borrowed_token.decimals);
62
+ const borrowCap = this.llamalend.formatUnits(_cap, this.market.borrowed_token.decimals);
63
+ const available = this.llamalend.formatUnits(_available, this.market.borrowed_token.decimals);
64
+ const totalDebt = this.llamalend.formatUnits(_totalDebt, this.market.borrowed_token.decimals);
65
+ const availableForBorrow = BigNumber.min(BN(available), BN(borrowCap).minus(BN(totalDebt))).toFixed();
66
+ return { totalAssets, borrowCap, available, availableForBorrow };
67
+ });
68
+ }
3
69
  }