@curvefi/llamalend-api 2.0.4 → 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.
- package/docs/SUPPORT_LLv2.md +36 -0
- package/lib/interfaces.d.ts +1 -0
- package/lib/lendMarkets/LendMarketTemplate.js +1 -1
- package/lib/lendMarkets/interfaces/v1/statsV1.d.ts +3 -1
- package/lib/lendMarkets/interfaces/v2/statsV2.d.ts +3 -1
- package/lib/lendMarkets/modules/common/statsBase.d.ts +19 -2
- package/lib/lendMarkets/modules/common/statsBase.js +101 -69
- package/lib/lendMarkets/modules/common/vault.js +2 -2
- package/lib/lendMarkets/modules/v2/statsV2.d.ts +14 -0
- package/lib/lendMarkets/modules/v2/statsV2.js +47 -0
- package/lib/lendMarkets/utils.js +4 -2
- package/package.json +1 -1
- package/src/interfaces.ts +1 -0
- package/src/lendMarkets/LendMarketTemplate.ts +1 -1
- package/src/lendMarkets/interfaces/v1/statsV1.ts +1 -1
- package/src/lendMarkets/interfaces/v2/statsV2.ts +1 -1
- package/src/lendMarkets/modules/common/statsBase.ts +104 -85
- package/src/lendMarkets/modules/common/vault.ts +2 -2
- package/src/lendMarkets/modules/v2/statsV2.ts +50 -0
- package/src/lendMarkets/utils.ts +4 -2
package/docs/SUPPORT_LLv2.md
CHANGED
|
@@ -143,6 +143,42 @@ 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
|
+
|
|
146
182
|
## Stats Module (`market.stats`) new methods
|
|
147
183
|
| Method | v1 | v2 | Same logic | Same params | Same type |
|
|
148
184
|
|--------|----|----|-----------------|----------------------|-----------------------|
|
package/lib/interfaces.d.ts
CHANGED
|
@@ -43,8 +43,10 @@ export interface IStatsV1 {
|
|
|
43
43
|
collateral: string;
|
|
44
44
|
}>;
|
|
45
45
|
capAndAvailable: (isGetter?: boolean, useAPI?: boolean) => Promise<{
|
|
46
|
-
|
|
46
|
+
borrowCap: string;
|
|
47
47
|
available: string;
|
|
48
|
+
totalAssets: string;
|
|
49
|
+
availableForBorrow: string;
|
|
48
50
|
}>;
|
|
49
51
|
adminPercentage: () => Promise<string>;
|
|
50
52
|
}
|
|
@@ -43,8 +43,10 @@ export interface IStatsV2 {
|
|
|
43
43
|
collateral: string;
|
|
44
44
|
}>;
|
|
45
45
|
capAndAvailable: (isGetter?: boolean, useAPI?: boolean) => Promise<{
|
|
46
|
-
|
|
46
|
+
borrowCap: string;
|
|
47
47
|
available: string;
|
|
48
|
+
totalAssets: string;
|
|
49
|
+
availableForBorrow: string;
|
|
48
50
|
}>;
|
|
49
51
|
adminPercentage: () => Promise<string>;
|
|
50
52
|
}
|
|
@@ -1,12 +1,15 @@
|
|
|
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>;
|
|
9
10
|
protected _fetchAdminPercentage: () => Promise<bigint>;
|
|
11
|
+
protected _fetchAdminFee: () => Promise<bigint>;
|
|
12
|
+
protected _getAdminFeesXY(isGetter: boolean): Promise<[bigint, bigint]>;
|
|
10
13
|
private _getRate;
|
|
11
14
|
private _getFutureRate;
|
|
12
15
|
statsParameters: (() => Promise<{
|
|
@@ -63,9 +66,23 @@ export declare class StatsBaseModule {
|
|
|
63
66
|
borrowed: string;
|
|
64
67
|
collateral: string;
|
|
65
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
|
+
}>;
|
|
66
81
|
statsCapAndAvailable(isGetter?: boolean, useAPI?: boolean): Promise<{
|
|
67
|
-
|
|
82
|
+
borrowCap: string;
|
|
68
83
|
available: string;
|
|
84
|
+
totalAssets: string;
|
|
85
|
+
availableForBorrow: string;
|
|
69
86
|
}>;
|
|
70
87
|
statsAdminPercentage: () => Promise<string>;
|
|
71
88
|
}
|
|
@@ -18,6 +18,9 @@ export class StatsBaseModule {
|
|
|
18
18
|
this._fetchAdminPercentage = () => __awaiter(this, void 0, void 0, function* () {
|
|
19
19
|
return BigInt(0);
|
|
20
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
|
+
});
|
|
21
24
|
this._getRate = (...args_1) => __awaiter(this, [...args_1], void 0, function* (isGetter = true) {
|
|
22
25
|
if (isGetter) {
|
|
23
26
|
const _rate = cacheStats.get(cacheKey(this.market.addresses.amm, 'rate'));
|
|
@@ -44,15 +47,16 @@ export class StatsBaseModule {
|
|
|
44
47
|
this.statsParameters = memoize(() => __awaiter(this, void 0, void 0, function* () {
|
|
45
48
|
const llammaContract = this.llamalend.contracts[this.market.addresses.amm].multicallContract;
|
|
46
49
|
const controllerContract = this.llamalend.contracts[this.market.addresses.controller].multicallContract;
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
+
]);
|
|
56
60
|
const A = formatUnits(_A, 0);
|
|
57
61
|
const base_price = formatUnits(_base_price);
|
|
58
62
|
const [fee, admin_fee, liquidation_discount, loan_discount] = [_fee, _admin_fee, _liquidation_discount, _loan_discount]
|
|
@@ -81,7 +85,7 @@ export class StatsBaseModule {
|
|
|
81
85
|
});
|
|
82
86
|
this.statsAmmBalances = (...args_1) => __awaiter(this, [...args_1], void 0, function* (isGetter = true, useAPI = false) {
|
|
83
87
|
if (useAPI) {
|
|
84
|
-
const market = yield
|
|
88
|
+
const market = yield this._fetchMarketDataFromAPI();
|
|
85
89
|
return {
|
|
86
90
|
borrowed: market.ammBalances.ammBalanceBorrowed.toString(),
|
|
87
91
|
collateral: market.ammBalances.ammBalanceCollateral.toString(),
|
|
@@ -90,27 +94,23 @@ export class StatsBaseModule {
|
|
|
90
94
|
else {
|
|
91
95
|
const borrowedContract = this.llamalend.contracts[this.market.addresses.borrowed_token].multicallContract;
|
|
92
96
|
const collateralContract = this.llamalend.contracts[this.market.addresses.collateral_token].multicallContract;
|
|
93
|
-
|
|
94
|
-
let
|
|
97
|
+
let _balance_x, _balance_y;
|
|
98
|
+
let _fee_x, _fee_y;
|
|
95
99
|
if (isGetter) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
cacheStats.get(cacheKey(this.market.addresses.collateral_token, 'balanceOf', this.market.addresses.amm)),
|
|
100
|
-
cacheStats.get(cacheKey(this.market.addresses.amm, 'admin_fees_y')),
|
|
101
|
-
];
|
|
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);
|
|
102
103
|
}
|
|
103
104
|
else {
|
|
104
|
-
[_balance_x,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
+
]));
|
|
110
112
|
cacheStats.set(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.amm), _balance_x);
|
|
111
|
-
cacheStats.set(cacheKey(this.market.addresses.amm, 'admin_fees_x'), _fee_x);
|
|
112
113
|
cacheStats.set(cacheKey(this.market.addresses.collateral_token, 'balanceOf', this.market.addresses.amm), _balance_y);
|
|
113
|
-
cacheStats.set(cacheKey(this.market.addresses.amm, 'admin_fees_y'), _fee_y);
|
|
114
114
|
}
|
|
115
115
|
return {
|
|
116
116
|
borrowed: toBN(_balance_x, this.market.borrowed_token.decimals).minus(toBN(_fee_x, this.market.borrowed_token.decimals)).toString(),
|
|
@@ -125,10 +125,33 @@ export class StatsBaseModule {
|
|
|
125
125
|
this.market = market;
|
|
126
126
|
this.llamalend = market.getLlamalend();
|
|
127
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
|
+
}
|
|
128
151
|
statsRates() {
|
|
129
152
|
return __awaiter(this, arguments, void 0, function* (isGetter = true, useAPI = false) {
|
|
130
153
|
if (useAPI) {
|
|
131
|
-
const market = yield
|
|
154
|
+
const market = yield this._fetchMarketDataFromAPI();
|
|
132
155
|
return {
|
|
133
156
|
borrowApr: (market.rates.borrowApr * 100).toString(),
|
|
134
157
|
lendApr: (market.rates.lendApr * 100).toString(),
|
|
@@ -138,9 +161,9 @@ export class StatsBaseModule {
|
|
|
138
161
|
}
|
|
139
162
|
else {
|
|
140
163
|
const _rate = yield this._getRate(isGetter);
|
|
141
|
-
const debt = yield this.statsTotalDebt(isGetter);
|
|
142
|
-
const {
|
|
143
|
-
return computeRatesFromRate(_rate, debt,
|
|
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);
|
|
144
167
|
}
|
|
145
168
|
});
|
|
146
169
|
}
|
|
@@ -150,7 +173,7 @@ export class StatsBaseModule {
|
|
|
150
173
|
const _dDebt = parseUnits(dDebt, this.market.borrowed_token.decimals);
|
|
151
174
|
const _rate = yield this._getFutureRate(_dReserves, _dDebt);
|
|
152
175
|
const debt = Number(yield this.statsTotalDebt()) + Number(dDebt);
|
|
153
|
-
const cap = Number((yield this.statsCapAndAvailable(true, useAPI)).
|
|
176
|
+
const cap = Number((yield this.statsCapAndAvailable(true, useAPI)).totalAssets) + Number(dReserves);
|
|
154
177
|
return computeRatesFromRate(_rate, debt, cap);
|
|
155
178
|
});
|
|
156
179
|
}
|
|
@@ -158,14 +181,13 @@ export class StatsBaseModule {
|
|
|
158
181
|
return __awaiter(this, void 0, void 0, function* () {
|
|
159
182
|
const borrowedContract = this.llamalend.contracts[this.market.borrowed_token.address].multicallContract;
|
|
160
183
|
const collateralContract = this.llamalend.contracts[this.market.collateral_token.address].multicallContract;
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
];
|
|
168
|
-
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
|
+
]);
|
|
169
191
|
return [
|
|
170
192
|
formatUnits(_borrowedBalance - _borrowedAdminFees, this.market.borrowed_token.decimals),
|
|
171
193
|
formatUnits(_collateralBalance - _collateralAdminFees, this.market.collateral_token.decimals),
|
|
@@ -209,7 +231,7 @@ export class StatsBaseModule {
|
|
|
209
231
|
statsTotalDebt() {
|
|
210
232
|
return __awaiter(this, arguments, void 0, function* (isGetter = true, useAPI = true) {
|
|
211
233
|
if (useAPI) {
|
|
212
|
-
const market = yield
|
|
234
|
+
const market = yield this._fetchMarketDataFromAPI();
|
|
213
235
|
return market.borrowed.total.toString();
|
|
214
236
|
}
|
|
215
237
|
else {
|
|
@@ -225,38 +247,48 @@ export class StatsBaseModule {
|
|
|
225
247
|
}
|
|
226
248
|
});
|
|
227
249
|
}
|
|
228
|
-
|
|
229
|
-
return __awaiter(this,
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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));
|
|
236
269
|
}
|
|
237
270
|
else {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
}
|
|
245
|
-
else {
|
|
246
|
-
[_cap, _available] = yield this.llamalend.multicallProvider.all([
|
|
247
|
-
vaultContract.totalAssets(this.market.addresses.controller),
|
|
248
|
-
borrowedContract.balanceOf(this.market.addresses.controller),
|
|
249
|
-
]);
|
|
250
|
-
cacheStats.set(cacheKey(this.market.addresses.vault, 'totalAssets', this.market.addresses.controller), _cap);
|
|
251
|
-
cacheStats.set(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.controller), _available);
|
|
252
|
-
}
|
|
253
|
-
return {
|
|
254
|
-
cap: this.llamalend.formatUnits(_cap, this.market.borrowed_token.decimals),
|
|
255
|
-
available: this.llamalend.formatUnits(_available, this.market.borrowed_token.decimals),
|
|
256
|
-
};
|
|
257
|
-
// cap -> totalAssets
|
|
258
|
-
// 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);
|
|
259
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);
|
|
260
292
|
});
|
|
261
293
|
}
|
|
262
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 {
|
|
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(
|
|
420
|
+
return BN(totalAssets).times(price).toFixed(6);
|
|
421
421
|
});
|
|
422
422
|
}
|
|
423
423
|
vaultCrvApr() {
|
|
@@ -2,4 +2,18 @@ import memoize from "memoizee";
|
|
|
2
2
|
import { StatsBaseModule } from "../common/statsBase.js";
|
|
3
3
|
export declare class StatsV2Module extends StatsBaseModule {
|
|
4
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
|
+
}>;
|
|
5
19
|
}
|
|
@@ -9,6 +9,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import memoize from "memoizee";
|
|
11
11
|
import { StatsBaseModule } from "../common/statsBase.js";
|
|
12
|
+
import { cacheKey, cacheStats } from "../../../cache";
|
|
13
|
+
import BigNumber from "bignumber.js";
|
|
14
|
+
import { BN } from "../../../utils";
|
|
12
15
|
export class StatsV2Module extends StatsBaseModule {
|
|
13
16
|
constructor() {
|
|
14
17
|
super(...arguments);
|
|
@@ -18,5 +21,49 @@ export class StatsV2Module extends StatsBaseModule {
|
|
|
18
21
|
promise: true,
|
|
19
22
|
maxAge: 30 * 60 * 1000, // 30m
|
|
20
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
|
+
});
|
|
21
68
|
}
|
|
22
69
|
}
|
package/lib/lendMarkets/utils.js
CHANGED
|
@@ -18,8 +18,10 @@ export const computeRatesFromRate = (_rate, debt, cap) => {
|
|
|
18
18
|
const expFactor = Math.pow(Math.E, annualFactor.toNumber());
|
|
19
19
|
const borrowApr = annualFactor.times(100).toString();
|
|
20
20
|
const borrowApy = String((expFactor - 1) * 100);
|
|
21
|
-
const
|
|
22
|
-
const
|
|
21
|
+
const lendAprRaw = annualFactor.times(debt).div(cap).times(100);
|
|
22
|
+
const lendApr = lendAprRaw.isNaN() ? "0" : lendAprRaw.toString();
|
|
23
|
+
const lendApyRaw = BN(debt).times(expFactor).minus(debt).div(cap).times(100);
|
|
24
|
+
const lendApy = lendApyRaw.isNaN() ? "0" : lendApyRaw.toString();
|
|
23
25
|
return { borrowApr, lendApr, borrowApy, lendApy };
|
|
24
26
|
};
|
|
25
27
|
export const fetchMarketDataByVault = (networkName, vaultAddress, getData) => __awaiter(void 0, void 0, void 0, function* () {
|
package/package.json
CHANGED
package/src/interfaces.ts
CHANGED
|
@@ -17,6 +17,6 @@ export interface IStatsV1 {
|
|
|
17
17
|
bandsBalances: () => Promise<{ [index: number]: { borrowed: string, collateral: string } }>,
|
|
18
18
|
totalDebt: (isGetter?: boolean, useAPI?: boolean) => Promise<string>,
|
|
19
19
|
ammBalances: (isGetter?: boolean, useAPI?: boolean) => Promise<{ borrowed: string, collateral: string }>,
|
|
20
|
-
capAndAvailable: (isGetter?: boolean, useAPI?: boolean) => Promise<{
|
|
20
|
+
capAndAvailable: (isGetter?: boolean, useAPI?: boolean) => Promise<{ borrowCap: string, available: string, totalAssets: string, availableForBorrow: string }>,
|
|
21
21
|
adminPercentage: () => Promise<string>,
|
|
22
22
|
}
|
|
@@ -17,6 +17,6 @@ export interface IStatsV2 {
|
|
|
17
17
|
bandsBalances: () => Promise<{ [index: number]: { borrowed: string, collateral: string } }>,
|
|
18
18
|
totalDebt: (isGetter?: boolean, useAPI?: boolean) => Promise<string>,
|
|
19
19
|
ammBalances: (isGetter?: boolean, useAPI?: boolean) => Promise<{ borrowed: string, collateral: string }>,
|
|
20
|
-
capAndAvailable: (isGetter?: boolean, useAPI?: boolean) => Promise<{
|
|
20
|
+
capAndAvailable: (isGetter?: boolean, useAPI?: boolean) => Promise<{ borrowCap: string, available: string, totalAssets: string, availableForBorrow: string }>,
|
|
21
21
|
adminPercentage: () => Promise<string>,
|
|
22
22
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
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 {
|
|
5
5
|
parseUnits,
|
|
@@ -22,10 +22,39 @@ export class StatsBaseModule {
|
|
|
22
22
|
this.llamalend = market.getLlamalend();
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
protected async _fetchMarketDataFromAPI(): Promise<IMarketDataAPI> {
|
|
26
|
+
return fetchMarketDataByVault(
|
|
27
|
+
this.llamalend.constants.NETWORK_NAME,
|
|
28
|
+
this.market.addresses.vault,
|
|
29
|
+
_getMarketsData
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
protected _fetchAdminPercentage = async (): Promise<bigint> => {
|
|
26
34
|
return BigInt(0)
|
|
27
35
|
}
|
|
28
36
|
|
|
37
|
+
protected _fetchAdminFee = async (): Promise<bigint> => {
|
|
38
|
+
return this.llamalend.contracts[this.market.addresses.amm].contract.admin_fee(this.llamalend.constantOptions);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
protected async _getAdminFeesXY(isGetter: boolean): Promise<[bigint, bigint]> {
|
|
42
|
+
if(isGetter) {
|
|
43
|
+
return [
|
|
44
|
+
cacheStats.get(cacheKey(this.market.addresses.amm, 'admin_fees_x')),
|
|
45
|
+
cacheStats.get(cacheKey(this.market.addresses.amm, 'admin_fees_y')),
|
|
46
|
+
];
|
|
47
|
+
}
|
|
48
|
+
const ammContract = this.llamalend.contracts[this.market.addresses.amm].multicallContract;
|
|
49
|
+
const [_fee_x, _fee_y] = await this.llamalend.multicallProvider.all([
|
|
50
|
+
ammContract.admin_fees_x(),
|
|
51
|
+
ammContract.admin_fees_y(),
|
|
52
|
+
]) as [bigint, bigint];
|
|
53
|
+
cacheStats.set(cacheKey(this.market.addresses.amm, 'admin_fees_x'), _fee_x);
|
|
54
|
+
cacheStats.set(cacheKey(this.market.addresses.amm, 'admin_fees_y'), _fee_y);
|
|
55
|
+
return [_fee_x, _fee_y];
|
|
56
|
+
}
|
|
57
|
+
|
|
29
58
|
private _getRate = async (isGetter = true): Promise<bigint> => {
|
|
30
59
|
if (isGetter) {
|
|
31
60
|
const _rate: bigint = cacheStats.get(cacheKey(this.market.addresses.amm, 'rate'));
|
|
@@ -61,16 +90,17 @@ export class StatsBaseModule {
|
|
|
61
90
|
const llammaContract = this.llamalend.contracts[this.market.addresses.amm].multicallContract;
|
|
62
91
|
const controllerContract = this.llamalend.contracts[this.market.addresses.controller].multicallContract;
|
|
63
92
|
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
93
|
+
const [[_fee, _liquidation_discount, _loan_discount, _base_price, _A], _admin_fee] = await Promise.all([
|
|
94
|
+
this.llamalend.multicallProvider.all([
|
|
95
|
+
llammaContract.fee(),
|
|
96
|
+
controllerContract.liquidation_discount(),
|
|
97
|
+
controllerContract.loan_discount(),
|
|
98
|
+
llammaContract.get_base_price(),
|
|
99
|
+
llammaContract.A(),
|
|
100
|
+
]),
|
|
101
|
+
this._fetchAdminFee(),
|
|
102
|
+
]) as [bigint[], bigint];
|
|
72
103
|
|
|
73
|
-
const [_fee, _admin_fee, _liquidation_discount, _loan_discount, _base_price, _A]: bigint[] = await this.llamalend.multicallProvider.all(calls) as bigint[];
|
|
74
104
|
const A = formatUnits(_A, 0)
|
|
75
105
|
const base_price = formatUnits(_base_price)
|
|
76
106
|
const [fee, admin_fee, liquidation_discount, loan_discount] = [_fee, _admin_fee, _liquidation_discount, _loan_discount]
|
|
@@ -84,11 +114,7 @@ export class StatsBaseModule {
|
|
|
84
114
|
|
|
85
115
|
public async statsRates(isGetter = true, useAPI = false): Promise<{borrowApr: string, lendApr: string, borrowApy: string, lendApy: string}> {
|
|
86
116
|
if(useAPI) {
|
|
87
|
-
const market = await
|
|
88
|
-
this.llamalend.constants.NETWORK_NAME,
|
|
89
|
-
this.market.addresses.vault,
|
|
90
|
-
_getMarketsData
|
|
91
|
-
);
|
|
117
|
+
const market = await this._fetchMarketDataFromAPI();
|
|
92
118
|
return {
|
|
93
119
|
borrowApr: (market.rates.borrowApr * 100).toString(),
|
|
94
120
|
lendApr: (market.rates.lendApr * 100).toString(),
|
|
@@ -97,9 +123,9 @@ export class StatsBaseModule {
|
|
|
97
123
|
};
|
|
98
124
|
} else {
|
|
99
125
|
const _rate = await this._getRate(isGetter);
|
|
100
|
-
const debt = await this.statsTotalDebt(isGetter);
|
|
101
|
-
const {
|
|
102
|
-
return computeRatesFromRate(_rate, debt,
|
|
126
|
+
const debt = await this.statsTotalDebt(isGetter, false);
|
|
127
|
+
const { totalAssets } = Number(debt) > 0 ? await this.statsCapAndAvailable(isGetter, false) : { totalAssets: "0" };
|
|
128
|
+
return computeRatesFromRate(_rate, debt, totalAssets);
|
|
103
129
|
}
|
|
104
130
|
}
|
|
105
131
|
|
|
@@ -108,21 +134,21 @@ export class StatsBaseModule {
|
|
|
108
134
|
const _dDebt = parseUnits(dDebt, this.market.borrowed_token.decimals);
|
|
109
135
|
const _rate = await this._getFutureRate(_dReserves, _dDebt);
|
|
110
136
|
const debt = Number(await this.statsTotalDebt()) + Number(dDebt);
|
|
111
|
-
const cap = Number((await this.statsCapAndAvailable(true, useAPI)).
|
|
137
|
+
const cap = Number((await this.statsCapAndAvailable(true, useAPI)).totalAssets) + Number(dReserves);
|
|
112
138
|
return computeRatesFromRate(_rate, debt, cap);
|
|
113
139
|
}
|
|
114
140
|
|
|
115
141
|
public async statsBalances(): Promise<[string, string]> {
|
|
116
142
|
const borrowedContract = this.llamalend.contracts[this.market.borrowed_token.address].multicallContract;
|
|
117
143
|
const collateralContract = this.llamalend.contracts[this.market.collateral_token.address].multicallContract;
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
144
|
+
|
|
145
|
+
const [[_borrowedBalance, _collateralBalance], [_borrowedAdminFees, _collateralAdminFees]] = await Promise.all([
|
|
146
|
+
this.llamalend.multicallProvider.all([
|
|
147
|
+
borrowedContract.balanceOf(this.market.addresses.amm),
|
|
148
|
+
collateralContract.balanceOf(this.market.addresses.amm),
|
|
149
|
+
]),
|
|
150
|
+
this._getAdminFeesXY(false),
|
|
151
|
+
]) as [bigint[], [bigint, bigint]];
|
|
126
152
|
|
|
127
153
|
return [
|
|
128
154
|
formatUnits(_borrowedBalance - _borrowedAdminFees, this.market.borrowed_token.decimals),
|
|
@@ -188,11 +214,7 @@ export class StatsBaseModule {
|
|
|
188
214
|
|
|
189
215
|
public async statsTotalDebt(isGetter = true, useAPI = true): Promise<string> {
|
|
190
216
|
if(useAPI) {
|
|
191
|
-
const market = await
|
|
192
|
-
this.llamalend.constants.NETWORK_NAME,
|
|
193
|
-
this.market.addresses.vault,
|
|
194
|
-
_getMarketsData
|
|
195
|
-
);
|
|
217
|
+
const market = await this._fetchMarketDataFromAPI();
|
|
196
218
|
return market.borrowed.total.toString();
|
|
197
219
|
} else {
|
|
198
220
|
let _debt;
|
|
@@ -209,11 +231,7 @@ export class StatsBaseModule {
|
|
|
209
231
|
|
|
210
232
|
public statsAmmBalances = async (isGetter = true, useAPI = false): Promise<{ borrowed: string, collateral: string }> => {
|
|
211
233
|
if(useAPI) {
|
|
212
|
-
const market = await
|
|
213
|
-
this.llamalend.constants.NETWORK_NAME,
|
|
214
|
-
this.market.addresses.vault,
|
|
215
|
-
_getMarketsData
|
|
216
|
-
);
|
|
234
|
+
const market = await this._fetchMarketDataFromAPI();
|
|
217
235
|
return {
|
|
218
236
|
borrowed: market.ammBalances.ammBalanceBorrowed.toString(),
|
|
219
237
|
collateral: market.ammBalances.ammBalanceCollateral.toString(),
|
|
@@ -221,27 +239,24 @@ export class StatsBaseModule {
|
|
|
221
239
|
} else {
|
|
222
240
|
const borrowedContract = this.llamalend.contracts[this.market.addresses.borrowed_token].multicallContract;
|
|
223
241
|
const collateralContract = this.llamalend.contracts[this.market.addresses.collateral_token].multicallContract;
|
|
224
|
-
const ammContract = this.llamalend.contracts[this.market.addresses.amm].multicallContract;
|
|
225
242
|
|
|
226
|
-
let _balance_x
|
|
243
|
+
let _balance_x: bigint, _balance_y: bigint;
|
|
244
|
+
let _fee_x: bigint, _fee_y: bigint;
|
|
245
|
+
|
|
227
246
|
if(isGetter) {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
cacheStats.get(cacheKey(this.market.addresses.collateral_token, 'balanceOf', this.market.addresses.amm)),
|
|
232
|
-
cacheStats.get(cacheKey(this.market.addresses.amm, 'admin_fees_y')),
|
|
233
|
-
]
|
|
247
|
+
_balance_x = cacheStats.get(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.amm));
|
|
248
|
+
_balance_y = cacheStats.get(cacheKey(this.market.addresses.collateral_token, 'balanceOf', this.market.addresses.amm));
|
|
249
|
+
[_fee_x, _fee_y] = await this._getAdminFeesXY(true);
|
|
234
250
|
} else {
|
|
235
|
-
[_balance_x,
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
251
|
+
[[_balance_x, _balance_y], [_fee_x, _fee_y]] = await Promise.all([
|
|
252
|
+
this.llamalend.multicallProvider.all([
|
|
253
|
+
borrowedContract.balanceOf(this.market.addresses.amm),
|
|
254
|
+
collateralContract.balanceOf(this.market.addresses.amm),
|
|
255
|
+
]),
|
|
256
|
+
this._getAdminFeesXY(false),
|
|
257
|
+
]) as [[bigint, bigint], [bigint, bigint]];
|
|
241
258
|
cacheStats.set(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.amm), _balance_x);
|
|
242
|
-
cacheStats.set(cacheKey(this.market.addresses.amm, 'admin_fees_x'), _fee_x);
|
|
243
259
|
cacheStats.set(cacheKey(this.market.addresses.collateral_token, 'balanceOf', this.market.addresses.amm), _balance_y);
|
|
244
|
-
cacheStats.set(cacheKey(this.market.addresses.amm, 'admin_fees_y'), _fee_y);
|
|
245
260
|
}
|
|
246
261
|
|
|
247
262
|
return {
|
|
@@ -251,43 +266,47 @@ export class StatsBaseModule {
|
|
|
251
266
|
}
|
|
252
267
|
}
|
|
253
268
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
available: market.availableToBorrow.total.toString(),
|
|
264
|
-
};
|
|
265
|
-
} else {
|
|
266
|
-
const vaultContract = this.llamalend.contracts[this.market.addresses.vault].multicallContract;
|
|
267
|
-
const borrowedContract = this.llamalend.contracts[this.market.addresses.borrowed_token].multicallContract;
|
|
269
|
+
protected async _statsCapAndAvailableFromAPI(): Promise<{ borrowCap: string, available: string, totalAssets: string, availableForBorrow: string }> {
|
|
270
|
+
const market = await this._fetchMarketDataFromAPI();
|
|
271
|
+
return {
|
|
272
|
+
totalAssets: market.totalSupplied.total.toString(),
|
|
273
|
+
borrowCap: Infinity.toString(),
|
|
274
|
+
available: market.availableToBorrow.total.toString(),
|
|
275
|
+
availableForBorrow: market.availableToBorrow.total.toString(),
|
|
276
|
+
};
|
|
277
|
+
}
|
|
268
278
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
_available = cacheStats.get(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.controller));
|
|
273
|
-
} else {
|
|
274
|
-
[_cap, _available] =await this.llamalend.multicallProvider.all([
|
|
275
|
-
vaultContract.totalAssets(this.market.addresses.controller),
|
|
276
|
-
borrowedContract.balanceOf(this.market.addresses.controller),
|
|
277
|
-
]);
|
|
278
|
-
cacheStats.set(cacheKey(this.market.addresses.vault, 'totalAssets', this.market.addresses.controller), _cap);
|
|
279
|
-
cacheStats.set(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.controller), _available);
|
|
280
|
-
}
|
|
279
|
+
protected async _statsCapAndAvailableOnChain(isGetter: boolean): Promise<{ borrowCap: string, available: string, totalAssets: string, availableForBorrow: string }> {
|
|
280
|
+
const vaultContract = this.llamalend.contracts[this.market.addresses.vault].multicallContract;
|
|
281
|
+
const borrowedContract = this.llamalend.contracts[this.market.addresses.borrowed_token].multicallContract;
|
|
281
282
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
283
|
+
let _cap, _available;
|
|
284
|
+
if(isGetter) {
|
|
285
|
+
_cap = cacheStats.get(cacheKey(this.market.addresses.vault, 'totalAssets', this.market.addresses.controller));
|
|
286
|
+
_available = cacheStats.get(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.controller));
|
|
287
|
+
} else {
|
|
288
|
+
[_cap, _available] = await this.llamalend.multicallProvider.all([
|
|
289
|
+
vaultContract.totalAssets(this.market.addresses.controller),
|
|
290
|
+
borrowedContract.balanceOf(this.market.addresses.controller),
|
|
291
|
+
]);
|
|
292
|
+
cacheStats.set(cacheKey(this.market.addresses.vault, 'totalAssets', this.market.addresses.controller), _cap);
|
|
293
|
+
cacheStats.set(cacheKey(this.market.addresses.borrowed_token, 'balanceOf', this.market.addresses.controller), _available);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const available = this.llamalend.formatUnits(_available, this.market.borrowed_token.decimals);
|
|
297
|
+
return {
|
|
298
|
+
totalAssets: this.llamalend.formatUnits(_cap, this.market.borrowed_token.decimals),
|
|
299
|
+
borrowCap: Infinity.toString(),
|
|
300
|
+
available,
|
|
301
|
+
availableForBorrow: available,
|
|
288
302
|
}
|
|
289
303
|
}
|
|
290
304
|
|
|
305
|
+
public async statsCapAndAvailable(isGetter = true, useAPI = false): Promise<{ borrowCap: string, available: string, totalAssets: string, availableForBorrow: string }> {
|
|
306
|
+
if(useAPI) return this._statsCapAndAvailableFromAPI();
|
|
307
|
+
return this._statsCapAndAvailableOnChain(isGetter);
|
|
308
|
+
}
|
|
309
|
+
|
|
291
310
|
public statsAdminPercentage = async (): Promise<string> => {
|
|
292
311
|
const _adminPercentage = await this._fetchAdminPercentage();
|
|
293
312
|
return formatUnits(_adminPercentage * BigInt(100));
|
|
@@ -289,10 +289,10 @@ export class VaultModule {
|
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
public async vaultTotalLiquidity(useAPI = true): Promise<string> {
|
|
292
|
-
const {
|
|
292
|
+
const { totalAssets } = await this.market.stats.capAndAvailable(true, useAPI);
|
|
293
293
|
const price = await _getUsdRate.call(this.llamalend, this.market.addresses.borrowed_token);
|
|
294
294
|
|
|
295
|
-
return BN(
|
|
295
|
+
return BN(totalAssets).times(price).toFixed(6)
|
|
296
296
|
}
|
|
297
297
|
|
|
298
298
|
private _calcCrvApr = async (futureWorkingSupplyBN: BigNumber | null = null): Promise<[baseApy: number, boostedApy: number]> => {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import memoize from "memoizee";
|
|
2
2
|
import { StatsBaseModule } from "../common/statsBase.js";
|
|
3
|
+
import {cacheKey, cacheStats} from "../../../cache";
|
|
4
|
+
import BigNumber from "bignumber.js";
|
|
5
|
+
import {BN} from "../../../utils";
|
|
3
6
|
|
|
4
7
|
export class StatsV2Module extends StatsBaseModule {
|
|
5
8
|
protected _fetchAdminPercentage = memoize(async (): Promise<bigint> => {
|
|
@@ -8,4 +11,51 @@ export class StatsV2Module extends StatsBaseModule {
|
|
|
8
11
|
promise: true,
|
|
9
12
|
maxAge: 30 * 60 * 1000, // 30m
|
|
10
13
|
});
|
|
14
|
+
|
|
15
|
+
protected _fetchAdminFee = async (): Promise<bigint> => BigInt(0);
|
|
16
|
+
|
|
17
|
+
protected _getAdminFeesXY = async (): Promise<[bigint, bigint]> => [BigInt(0), BigInt(0)];
|
|
18
|
+
|
|
19
|
+
protected async _statsCapAndAvailableFromAPI() {
|
|
20
|
+
const market = await this._fetchMarketDataFromAPI();
|
|
21
|
+
return {
|
|
22
|
+
totalAssets: market.totalSupplied.total.toString(),
|
|
23
|
+
borrowCap: market.borrowCap.total.toString(),
|
|
24
|
+
available: market.availableToBorrow.total.toString(),
|
|
25
|
+
availableForBorrow: market.availableToBorrow.total.toString(),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
protected async _statsCapAndAvailableOnChain(isGetter: boolean): Promise<{ borrowCap: string, available: string, totalAssets: string, availableForBorrow: string }> {
|
|
30
|
+
const vaultContract = this.llamalend.contracts[this.market.addresses.vault].multicallContract;
|
|
31
|
+
const controllerContract = this.llamalend.contracts[this.market.addresses.controller].multicallContract;
|
|
32
|
+
|
|
33
|
+
let _cap: bigint, _available: bigint, _totalAssets: bigint, _totalDebt: bigint;
|
|
34
|
+
if(isGetter) {
|
|
35
|
+
_totalAssets = cacheStats.get(cacheKey(this.market.addresses.vault, 'totalAssets', this.market.addresses.controller));
|
|
36
|
+
_cap = cacheStats.get(cacheKey(this.market.addresses.controller, 'borrow_cap'));
|
|
37
|
+
_available = cacheStats.get(cacheKey(this.market.addresses.controller, 'available_balance'));
|
|
38
|
+
_totalDebt = cacheStats.get(cacheKey(this.market.addresses.controller, 'total_debt'));
|
|
39
|
+
} else {
|
|
40
|
+
[_totalAssets, _available, _cap, _totalDebt] = await this.llamalend.multicallProvider.all([
|
|
41
|
+
vaultContract.totalAssets(this.market.addresses.controller),
|
|
42
|
+
controllerContract.available_balance(),
|
|
43
|
+
controllerContract.borrow_cap(),
|
|
44
|
+
controllerContract.total_debt(),
|
|
45
|
+
]);
|
|
46
|
+
|
|
47
|
+
cacheStats.set(cacheKey(this.market.addresses.vault, 'totalAssets', this.market.addresses.controller), _totalAssets);
|
|
48
|
+
cacheStats.set(cacheKey(this.market.addresses.controller, 'borrow_cap'), _cap);
|
|
49
|
+
cacheStats.set(cacheKey(this.market.addresses.controller, 'available_balance'), _available);
|
|
50
|
+
cacheStats.set(cacheKey(this.market.addresses.controller, 'total_debt'), _totalDebt);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const totalAssets = this.llamalend.formatUnits(_totalAssets, this.market.borrowed_token.decimals);
|
|
54
|
+
const borrowCap = this.llamalend.formatUnits(_cap, this.market.borrowed_token.decimals);
|
|
55
|
+
const available = this.llamalend.formatUnits(_available, this.market.borrowed_token.decimals);
|
|
56
|
+
const totalDebt = this.llamalend.formatUnits(_totalDebt, this.market.borrowed_token.decimals);
|
|
57
|
+
const availableForBorrow = BigNumber.min(BN(available), BN(borrowCap).minus(BN(totalDebt))).toFixed();
|
|
58
|
+
|
|
59
|
+
return { totalAssets, borrowCap, available, availableForBorrow }
|
|
60
|
+
}
|
|
11
61
|
}
|
package/src/lendMarkets/utils.ts
CHANGED
|
@@ -24,8 +24,10 @@ export const computeRatesFromRate = (
|
|
|
24
24
|
const borrowApr = annualFactor.times(100).toString();
|
|
25
25
|
const borrowApy = String((expFactor - 1) * 100);
|
|
26
26
|
|
|
27
|
-
const
|
|
28
|
-
const
|
|
27
|
+
const lendAprRaw = annualFactor.times(debt).div(cap).times(100);
|
|
28
|
+
const lendApr = lendAprRaw.isNaN() ? "0" : lendAprRaw.toString();
|
|
29
|
+
const lendApyRaw = BN(debt).times(expFactor).minus(debt).div(cap).times(100);
|
|
30
|
+
const lendApy = lendApyRaw.isNaN() ? "0" : lendApyRaw.toString();
|
|
29
31
|
|
|
30
32
|
return { borrowApr, lendApr, borrowApy, lendApy };
|
|
31
33
|
}
|