impermax-sdk 2.1.76 → 2.1.77
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/lib/offchain/account/lendingPool/offchainAccountBorrowable.d.ts +2 -0
- package/lib/offchain/account/lendingPool/offchainAccountBorrowable.js +25 -2
- package/lib/offchain/lendingPool/offchainBorrowable.d.ts +5 -3
- package/lib/offchain/lendingPool/offchainBorrowable.js +76 -29
- package/lib/offchain/offchainInitializer.js +2 -2
- package/lib/offchain/queries/apis/thegraph/index.js +3 -0
- package/package.json +1 -1
|
@@ -30,16 +30,39 @@ class OffchainAccountBorrowable extends offchainAccountPoolToken_1.default {
|
|
|
30
30
|
return lendingPoolPosition[`borrowable${this.borrowable}`];
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
|
-
// TODO update to support real time exchange rate
|
|
34
33
|
getAmount() {
|
|
35
34
|
return __awaiter(this, void 0, void 0, function* () {
|
|
36
35
|
const supplyPosition = yield this.getSupplyPosition();
|
|
37
36
|
if (!supplyPosition)
|
|
38
37
|
return 0;
|
|
39
|
-
const exchangeRate = yield this.poolToken.
|
|
38
|
+
const exchangeRate = yield this.poolToken.getCurrentExchangeRate();
|
|
40
39
|
const supplyBalance = parseFloat(supplyPosition.balance);
|
|
41
40
|
return supplyBalance * exchangeRate;
|
|
42
41
|
});
|
|
43
42
|
}
|
|
43
|
+
// WARN: Not all networks support cumulativeEarnings for now, see the `userQuery` in
|
|
44
|
+
// queries/apis/thegraph/index.ts. atm only available on Blast
|
|
45
|
+
getEarnings() {
|
|
46
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
const supplyPosition = yield this.getSupplyPosition();
|
|
48
|
+
if (!supplyPosition)
|
|
49
|
+
return 0;
|
|
50
|
+
const exchangeRate = yield this.poolToken.getCurrentExchangeRate();
|
|
51
|
+
if (!supplyPosition.cumulativeEarnings)
|
|
52
|
+
return 0;
|
|
53
|
+
const cumulativeEarnings = parseFloat(supplyPosition.cumulativeEarnings);
|
|
54
|
+
const lastExchangeRate = parseFloat(supplyPosition.lastExchangeRate);
|
|
55
|
+
const tokenBalance = parseFloat(supplyPosition.balance);
|
|
56
|
+
const newEarnings = (exchangeRate - lastExchangeRate) * tokenBalance;
|
|
57
|
+
return cumulativeEarnings + newEarnings;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
getEarningsUSD() {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
const tokenPrice = yield this.poolToken.getTokenPriceAccurate();
|
|
63
|
+
const earnings = yield this.getEarnings();
|
|
64
|
+
return earnings * tokenPrice;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
44
67
|
}
|
|
45
68
|
exports.default = OffchainAccountBorrowable;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BorrowablePastData, PoolTokenData } from "../offchainTypes";
|
|
2
|
-
import { Address, Borrowable } from
|
|
3
|
-
import OffchainPoolToken from
|
|
4
|
-
import OffchainLendingPool from
|
|
2
|
+
import { Address, Borrowable } from "../../config/types";
|
|
3
|
+
import OffchainPoolToken from "../offchainPoolToken";
|
|
4
|
+
import OffchainLendingPool from "./offchainLendingPool";
|
|
5
5
|
export default class OffchainBorrowable extends OffchainPoolToken {
|
|
6
6
|
protected readonly lendingPool: OffchainLendingPool;
|
|
7
7
|
protected readonly borrowable: Borrowable;
|
|
@@ -56,4 +56,6 @@ export default class OffchainBorrowable extends OffchainPoolToken {
|
|
|
56
56
|
getAverage7dSupplyAPR(): Promise<number>;
|
|
57
57
|
getTokenPriceFast(fallback?: boolean): Promise<number>;
|
|
58
58
|
getTokenPriceAccurate(): Promise<number>;
|
|
59
|
+
private getAccrueFactor;
|
|
60
|
+
getCurrentExchangeRate(): Promise<number>;
|
|
59
61
|
}
|
|
@@ -48,7 +48,7 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
48
48
|
return __awaiter(this, void 0, void 0, function* () {
|
|
49
49
|
let borrowRate = 0;
|
|
50
50
|
const KINK_MULTIPLIER = this.lendingPool.getKinkMultiplier();
|
|
51
|
-
const KINK_BORROW_RATE_MAX = 792.7448 / 1e9; // 2500% per year
|
|
51
|
+
const KINK_BORROW_RATE_MAX = 792.7448 / 1e9; // 2500% per year
|
|
52
52
|
const KINK_BORROW_RATE_MIN = 0.31709792 / 1e9; // 1% per year
|
|
53
53
|
const [_kinkUtilizationRate, _adjustSpeed, _borrowRate, _kinkBorrowRate, _rateUpdateTimestamp,] = yield Promise.all([
|
|
54
54
|
this.getPoolTokenParamFloat("kinkUtilizationRate"),
|
|
@@ -64,11 +64,15 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
64
64
|
if (timeElapsed > 0) {
|
|
65
65
|
let adjustFactor = 0;
|
|
66
66
|
if (_borrowRate < _kinkBorrowRate) {
|
|
67
|
-
const tmp = (_kinkBorrowRate - _borrowRate) / _kinkBorrowRate *
|
|
67
|
+
const tmp = ((_kinkBorrowRate - _borrowRate) / _kinkBorrowRate) *
|
|
68
|
+
_adjustSpeed *
|
|
69
|
+
timeElapsed;
|
|
68
70
|
adjustFactor = tmp > 1 ? 0 : 1 - tmp;
|
|
69
71
|
}
|
|
70
72
|
else {
|
|
71
|
-
const tmp = (_borrowRate - _kinkBorrowRate) / _kinkBorrowRate *
|
|
73
|
+
const tmp = ((_borrowRate - _kinkBorrowRate) / _kinkBorrowRate) *
|
|
74
|
+
_adjustSpeed *
|
|
75
|
+
timeElapsed;
|
|
72
76
|
adjustFactor = 1 + tmp;
|
|
73
77
|
}
|
|
74
78
|
kinkBorrowRate = _kinkBorrowRate * adjustFactor;
|
|
@@ -79,11 +83,10 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
79
83
|
}
|
|
80
84
|
// Simulate accrual
|
|
81
85
|
const { totalBalance, totalBorrows } = yield this._accrueInterest();
|
|
82
|
-
;
|
|
83
86
|
const _actualBalance = totalBalance + totalBorrows;
|
|
84
87
|
const _utilizationRate = _actualBalance === 0 ? 0 : totalBorrows / _actualBalance;
|
|
85
88
|
if (_utilizationRate <= _kinkUtilizationRate) {
|
|
86
|
-
borrowRate = kinkBorrowRate * _utilizationRate / _kinkUtilizationRate;
|
|
89
|
+
borrowRate = (kinkBorrowRate * _utilizationRate) / _kinkUtilizationRate;
|
|
87
90
|
}
|
|
88
91
|
else {
|
|
89
92
|
const overUtil = (_utilizationRate - _kinkUtilizationRate) / (1 - _kinkUtilizationRate);
|
|
@@ -186,9 +189,9 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
186
189
|
const { kinkBorrowRate: kinkBR } = yield this._calculateBorrowRate();
|
|
187
190
|
const kinkUR = yield this.getKinkUtilizationRate();
|
|
188
191
|
if (UR < kinkUR)
|
|
189
|
-
return UR / kinkUR * kinkBR;
|
|
192
|
+
return (UR / kinkUR) * kinkBR;
|
|
190
193
|
const kinkMultiplier = this.lendingPool.getKinkMultiplier();
|
|
191
|
-
return ((UR - kinkUR) / (1 - kinkUR) * (kinkMultiplier - 1) + 1) * kinkBR;
|
|
194
|
+
return (((UR - kinkUR) / (1 - kinkUR)) * (kinkMultiplier - 1) + 1) * kinkBR;
|
|
192
195
|
});
|
|
193
196
|
}
|
|
194
197
|
getNextBorrowAPR(borrowAmount) {
|
|
@@ -244,9 +247,12 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
244
247
|
const kinkUR = yield this.getKinkUtilizationRate();
|
|
245
248
|
const reserveFactor = yield this.getReserveFactor();
|
|
246
249
|
if (UR < kinkUR)
|
|
247
|
-
return UR / kinkUR * kinkBR * UR * (1 - reserveFactor);
|
|
250
|
+
return (UR / kinkUR) * kinkBR * UR * (1 - reserveFactor);
|
|
248
251
|
const kinkMultiplier = this.lendingPool.getKinkMultiplier();
|
|
249
|
-
return ((UR - kinkUR) / (1 - kinkUR) * (kinkMultiplier - 1) + 1) *
|
|
252
|
+
return ((((UR - kinkUR) / (1 - kinkUR)) * (kinkMultiplier - 1) + 1) *
|
|
253
|
+
kinkBR *
|
|
254
|
+
UR *
|
|
255
|
+
(1 - reserveFactor));
|
|
250
256
|
});
|
|
251
257
|
}
|
|
252
258
|
getNextSupplyAPR(supplyAmount) {
|
|
@@ -258,7 +264,7 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
258
264
|
// Reward Speed
|
|
259
265
|
getFarmingRewardsRate() {
|
|
260
266
|
return __awaiter(this, void 0, void 0, function* () {
|
|
261
|
-
const poolTokenData = yield this.getPoolTokenData();
|
|
267
|
+
const poolTokenData = (yield this.getPoolTokenData());
|
|
262
268
|
const rewards = poolTokenData.rewards;
|
|
263
269
|
if (rewards && rewards.length > 0)
|
|
264
270
|
return rewards;
|
|
@@ -270,15 +276,17 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
270
276
|
const epochAmount = parseFloat(farmingPoolData.epochAmount);
|
|
271
277
|
const epochBegin = parseInt(farmingPoolData.epochBegin);
|
|
272
278
|
const epochEnd = epochBegin + segmentLength;
|
|
273
|
-
const timestamp =
|
|
279
|
+
const timestamp = new Date().getTime() / 1000;
|
|
274
280
|
if (timestamp - FINISH_DELAY > epochEnd) {
|
|
275
281
|
// How to manage better this case? Maybe check shares on distributor
|
|
276
282
|
return [];
|
|
277
283
|
}
|
|
278
|
-
return [
|
|
284
|
+
return [
|
|
285
|
+
{
|
|
279
286
|
rewardToken: imxes_1.IMX[this.getOffchain().network],
|
|
280
|
-
rewardRate: epochAmount / segmentLength
|
|
281
|
-
}
|
|
287
|
+
rewardRate: epochAmount / segmentLength,
|
|
288
|
+
},
|
|
289
|
+
];
|
|
282
290
|
});
|
|
283
291
|
}
|
|
284
292
|
// Farming
|
|
@@ -298,19 +306,37 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
298
306
|
return [];
|
|
299
307
|
const rewards = [];
|
|
300
308
|
for (const reward of farmingRewards) {
|
|
301
|
-
const rewardPrice = yield this.getOffchain()
|
|
309
|
+
const rewardPrice = yield this.getOffchain()
|
|
310
|
+
.getPriceHelper()
|
|
311
|
+
.getDebankTokenPrice(this.getOffchain().network, reward.rewardToken);
|
|
302
312
|
rewards.push({
|
|
303
313
|
APR: (0, utils_1.toAPR)((rewardPrice * reward.rewardRate) / totalBorrowedUSD),
|
|
304
|
-
symbol: reward.rewardToken == "0x98878b06940ae243284ca214f92bb71a2b032b8a"
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
+
symbol: reward.rewardToken == "0x98878b06940ae243284ca214f92bb71a2b032b8a"
|
|
315
|
+
? "WMOVR"
|
|
316
|
+
: reward.rewardToken == "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270"
|
|
317
|
+
? "WMATIC"
|
|
318
|
+
: reward.rewardToken ==
|
|
319
|
+
"0x6659a9c5cd313974343e30b4fdffd95bd4b4dcd2"
|
|
320
|
+
? "IMX"
|
|
321
|
+
: reward.rewardToken ==
|
|
322
|
+
"0x7b35ce522cb72e4077baeb96cb923a5529764a00"
|
|
323
|
+
? "IMX"
|
|
324
|
+
: reward.rewardToken ==
|
|
325
|
+
"0x60bb3d364b765c497c8ce50ae0ae3f0882c5bd05"
|
|
326
|
+
? "IMX"
|
|
327
|
+
: reward.rewardToken ==
|
|
328
|
+
"0x9c67ee39e3c4954396b9142010653f17257dd39c"
|
|
329
|
+
? "IMX"
|
|
330
|
+
: reward.rewardToken ==
|
|
331
|
+
"0xea6887e4a9cda1b77e70129e5fba830cdb5cddef"
|
|
332
|
+
? "IMX"
|
|
333
|
+
: reward.rewardToken ==
|
|
334
|
+
"0x900f1Ec5819FA087d368877cD03B265Bf1802667"
|
|
335
|
+
? "IMX"
|
|
336
|
+
: reward.rewardToken ==
|
|
337
|
+
"0xea38f1ccf77bf43f352636241b05dd8f6f5f52b2"
|
|
338
|
+
? "IMX"
|
|
339
|
+
: "IBEX",
|
|
314
340
|
});
|
|
315
341
|
}
|
|
316
342
|
return rewards;
|
|
@@ -357,7 +383,8 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
357
383
|
const accrualTimestampNow = yield this.getAccrualTimestamp();
|
|
358
384
|
const borrowIndexNow = yield this.getBorrowIndex();
|
|
359
385
|
if (accrualTimestampNow > accrualTimestampPast) {
|
|
360
|
-
const borrowRate = (borrowIndexNow / borrowIndexPast - 1) /
|
|
386
|
+
const borrowRate = (borrowIndexNow / borrowIndexPast - 1) /
|
|
387
|
+
(accrualTimestampNow - accrualTimestampPast);
|
|
361
388
|
return borrowRate * 3600 * 24 * 365;
|
|
362
389
|
}
|
|
363
390
|
}
|
|
@@ -385,7 +412,8 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
385
412
|
const accrualTimestampNow = yield this.getAccrualTimestamp();
|
|
386
413
|
const exchangeRateNow = yield this.getExchangeRate();
|
|
387
414
|
if (accrualTimestampNow > accrualTimestampPast) {
|
|
388
|
-
const supplyRate = (exchangeRateNow / exchangeRatePast - 1) /
|
|
415
|
+
const supplyRate = (exchangeRateNow / exchangeRatePast - 1) /
|
|
416
|
+
(accrualTimestampNow - accrualTimestampPast);
|
|
389
417
|
return supplyRate * 3600 * 24 * 365;
|
|
390
418
|
}
|
|
391
419
|
}
|
|
@@ -411,7 +439,9 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
411
439
|
});
|
|
412
440
|
return __awaiter(this, void 0, void 0, function* () {
|
|
413
441
|
let tokenAddress = yield this.getUnderlyingAddress();
|
|
414
|
-
let tokenPrices = yield this.getOffchain()
|
|
442
|
+
let tokenPrices = yield this.getOffchain()
|
|
443
|
+
.getPriceHelper()
|
|
444
|
+
.getSubgraphTokensPrice(this.getOffchain().network);
|
|
415
445
|
let tokenPrice = tokenPrices[tokenAddress];
|
|
416
446
|
if (tokenPrice !== undefined && tokenPrice > 0)
|
|
417
447
|
return tokenPrice;
|
|
@@ -421,7 +451,24 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
421
451
|
getTokenPriceAccurate() {
|
|
422
452
|
return __awaiter(this, void 0, void 0, function* () {
|
|
423
453
|
let tokenAddress = yield this.getUnderlyingAddress();
|
|
424
|
-
return this.getOffchain()
|
|
454
|
+
return this.getOffchain()
|
|
455
|
+
.getPriceHelper()
|
|
456
|
+
.getDebankTokenPrice(this.getOffchain().network, tokenAddress);
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
getAccrueFactor() {
|
|
460
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
461
|
+
const now = Date.now() / 1000;
|
|
462
|
+
const timeElapsed = now - (yield this.getAccrualTimestamp());
|
|
463
|
+
const supplyRate = yield this.getSupplyRate();
|
|
464
|
+
return 1 + timeElapsed * supplyRate;
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
getCurrentExchangeRate() {
|
|
468
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
469
|
+
const lastExchangeRate = yield this.getExchangeRate();
|
|
470
|
+
const accrueFactor = yield this.getAccrueFactor();
|
|
471
|
+
return lastExchangeRate * accrueFactor;
|
|
425
472
|
});
|
|
426
473
|
}
|
|
427
474
|
}
|
|
@@ -631,8 +631,8 @@ function initializeUserData(account) {
|
|
|
631
631
|
for (const borrowPositions of rawUserData.borrowPositions) {
|
|
632
632
|
const uniswapV2PairAddress = borrowPositions.borrowable.lendingPool.id;
|
|
633
633
|
const underlyingAddress = borrowPositions.borrowable.underlying.id;
|
|
634
|
-
const
|
|
635
|
-
const addressA = yield
|
|
634
|
+
const borrowableA = (yield this.getLendingPool(factory, uniswapV2PairAddress)).getBorrowableA();
|
|
635
|
+
const addressA = yield borrowableA.getUnderlyingAddress();
|
|
636
636
|
const poolTokenType = underlyingAddress === addressA
|
|
637
637
|
? types_1.PoolTokenType.BorrowableA
|
|
638
638
|
: types_1.PoolTokenType.BorrowableB;
|
|
@@ -133,12 +133,14 @@ class TheGraphQueryBuilder {
|
|
|
133
133
|
}
|
|
134
134
|
}`;
|
|
135
135
|
}
|
|
136
|
+
// TODO: Fix earnings once all networks support
|
|
136
137
|
userQuery(account, network, factory) {
|
|
137
138
|
if (factory === types_1.Factory.V3)
|
|
138
139
|
return this.userQueryV3(account, network, factory);
|
|
139
140
|
// Shh
|
|
140
141
|
network;
|
|
141
142
|
factory;
|
|
143
|
+
const earnings = network === types_1.Networks.Blast && factory === types_1.Factory.SOLV2 ? "cumulativeEarnings lastExchangeRate" : "";
|
|
142
144
|
return (0, graphql_tag_1.default) `{
|
|
143
145
|
user(id: "${account.toLowerCase()}") {
|
|
144
146
|
collateralPositions(first:1000) {
|
|
@@ -151,6 +153,7 @@ class TheGraphQueryBuilder {
|
|
|
151
153
|
}
|
|
152
154
|
supplyPositions(first:1000) {
|
|
153
155
|
balance
|
|
156
|
+
${earnings}
|
|
154
157
|
borrowable {
|
|
155
158
|
underlying {
|
|
156
159
|
id
|