impermax-sdk 2.1.31 → 2.1.32
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.
|
@@ -5,6 +5,8 @@ import OffchainLendingPool from './offchainLendingPool';
|
|
|
5
5
|
export default class OffchainBorrowable extends OffchainPoolToken {
|
|
6
6
|
private readonly lendingPool;
|
|
7
7
|
private readonly poolTokenType;
|
|
8
|
+
private _accrueInterest;
|
|
9
|
+
private _calculateBorrowRate;
|
|
8
10
|
constructor(lendingPool: OffchainLendingPool, poolTokenType: PoolTokenType);
|
|
9
11
|
getOffchain: () => import("..").default;
|
|
10
12
|
getLendingPool: () => OffchainLendingPool;
|
|
@@ -18,14 +20,12 @@ export default class OffchainBorrowable extends OffchainPoolToken {
|
|
|
18
20
|
getBorrowIndex(): Promise<number>;
|
|
19
21
|
getAccrualTimestamp(): Promise<number>;
|
|
20
22
|
getTotalBorrows(): Promise<number>;
|
|
21
|
-
getCurrentTotalBorrows(): Promise<number>;
|
|
22
23
|
getTotalBorrowsUSD(): Promise<number>;
|
|
23
24
|
getBorrowRate(): Promise<number>;
|
|
24
25
|
getBorrowAPR(): Promise<number>;
|
|
25
26
|
getNextBorrowRate(borrowAmount: number): Promise<number>;
|
|
26
27
|
getNextBorrowAPR(borrowAmount: number): Promise<number>;
|
|
27
28
|
getSupply(): Promise<number>;
|
|
28
|
-
getCurrentSupply(): Promise<number>;
|
|
29
29
|
getSupplyUSD(): Promise<number>;
|
|
30
30
|
getUtilizationRate(): Promise<number>;
|
|
31
31
|
getSupplyRate(): Promise<number>;
|
|
@@ -16,6 +16,82 @@ const utils_1 = require("../../utils");
|
|
|
16
16
|
const imxes_1 = require("../../config/contracts/imxes");
|
|
17
17
|
const offchainPoolToken_1 = __importDefault(require("../offchainPoolToken"));
|
|
18
18
|
class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
19
|
+
// Simulates `accrueInterest` from `BInterestRateModel.sol`
|
|
20
|
+
_accrueInterest() {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
const [totalBalance, borrows, index, accrualTimestamp, borrowRate] = yield Promise.all([
|
|
23
|
+
this.getPoolTokenParamFloat("totalBalance"),
|
|
24
|
+
this.getPoolTokenParamFloat("totalBorrows"),
|
|
25
|
+
this.getPoolTokenParamFloat("borrowIndex"),
|
|
26
|
+
this.getPoolTokenParamFloat("accrualTimestamp"),
|
|
27
|
+
this.getPoolTokenParamFloat("borrowRate"),
|
|
28
|
+
]);
|
|
29
|
+
const timeElapsed = Date.now() / 1000 - accrualTimestamp;
|
|
30
|
+
if (timeElapsed === 0)
|
|
31
|
+
return {
|
|
32
|
+
totalBalance,
|
|
33
|
+
totalBorrows: borrows,
|
|
34
|
+
borrowIndex: index,
|
|
35
|
+
timeElapsed,
|
|
36
|
+
interest: 0,
|
|
37
|
+
};
|
|
38
|
+
const interestFactor = borrowRate * timeElapsed;
|
|
39
|
+
const interest = interestFactor * borrows;
|
|
40
|
+
const totalBorrows = borrows + interest;
|
|
41
|
+
const borrowIndex = index + interestFactor * index;
|
|
42
|
+
return { totalBalance, totalBorrows, borrowIndex, timeElapsed, interest };
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
// Simulates `_calculateBorrowRate` from `BInterestRateModel.sol`, uses `accruedInterestIndices`
|
|
46
|
+
// to simulate interest accrual first since this function is always called after `accrueInterest`.
|
|
47
|
+
_calculateBorrowRate() {
|
|
48
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
let borrowRate = 0;
|
|
50
|
+
const KINK_MULTIPLIER = this.lendingPool.getKinkMultiplier();
|
|
51
|
+
const KINK_BORROW_RATE_MAX = 792.7448 / 1e9; // 2500% per year
|
|
52
|
+
const KINK_BORROW_RATE_MIN = 0.31709792 / 1e9; // 1% per year
|
|
53
|
+
const [_kinkUtilizationRate, _adjustSpeed, _borrowRate, _kinkBorrowRate, _rateUpdateTimestamp,] = yield Promise.all([
|
|
54
|
+
this.getPoolTokenParamFloat("kinkUtilizationRate"),
|
|
55
|
+
this.getPoolTokenParamFloat("adjustSpeed"),
|
|
56
|
+
this.getPoolTokenParamFloat("borrowRate"),
|
|
57
|
+
this.getPoolTokenParamFloat("kinkBorrowRate"),
|
|
58
|
+
// This should be same most of time, cant get it from subgraph since no event
|
|
59
|
+
this.getPoolTokenParamFloat("accrualTimestamp"),
|
|
60
|
+
]);
|
|
61
|
+
// Calculate new kink borrow rate
|
|
62
|
+
const timeElapsed = Date.now() / 1000 - _rateUpdateTimestamp;
|
|
63
|
+
let kinkBorrowRate = 0;
|
|
64
|
+
if (timeElapsed > 0) {
|
|
65
|
+
let adjustFactor = 0;
|
|
66
|
+
if (_borrowRate < _kinkBorrowRate) {
|
|
67
|
+
const tmp = (_kinkBorrowRate - _borrowRate) / _kinkBorrowRate * _adjustSpeed * timeElapsed;
|
|
68
|
+
adjustFactor = tmp > 1 ? 0 : 1 - tmp;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
const tmp = (_borrowRate - _kinkBorrowRate) / _kinkBorrowRate * _adjustSpeed * timeElapsed;
|
|
72
|
+
adjustFactor = 1 + tmp;
|
|
73
|
+
}
|
|
74
|
+
kinkBorrowRate = _kinkBorrowRate * adjustFactor;
|
|
75
|
+
if (kinkBorrowRate > KINK_BORROW_RATE_MAX)
|
|
76
|
+
kinkBorrowRate = KINK_BORROW_RATE_MAX;
|
|
77
|
+
if (kinkBorrowRate < KINK_BORROW_RATE_MIN)
|
|
78
|
+
kinkBorrowRate = KINK_BORROW_RATE_MIN;
|
|
79
|
+
}
|
|
80
|
+
// Simulate accrual
|
|
81
|
+
const { totalBalance, totalBorrows } = yield this._accrueInterest();
|
|
82
|
+
;
|
|
83
|
+
const _actualBalance = totalBalance + totalBorrows;
|
|
84
|
+
const _utilizationRate = _actualBalance === 0 ? 0 : totalBorrows / _actualBalance;
|
|
85
|
+
if (_utilizationRate <= _kinkUtilizationRate) {
|
|
86
|
+
borrowRate = kinkBorrowRate * _utilizationRate / _kinkUtilizationRate;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
const overUtil = (_utilizationRate - _kinkUtilizationRate) / (1 - _kinkUtilizationRate);
|
|
90
|
+
borrowRate = ((KINK_MULTIPLIER - 1) * overUtil + 1) * kinkBorrowRate;
|
|
91
|
+
}
|
|
92
|
+
return { borrowRate, kinkBorrowRate };
|
|
93
|
+
});
|
|
94
|
+
}
|
|
19
95
|
constructor(lendingPool, poolTokenType) {
|
|
20
96
|
super();
|
|
21
97
|
this.getOffchain = () => this.lendingPool.getOffchain();
|
|
@@ -39,7 +115,8 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
39
115
|
// Kink Borrow Rate
|
|
40
116
|
getKinkBorrowRate() {
|
|
41
117
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
-
|
|
118
|
+
const { kinkBorrowRate } = yield this._calculateBorrowRate();
|
|
119
|
+
return kinkBorrowRate;
|
|
43
120
|
});
|
|
44
121
|
}
|
|
45
122
|
// Kink Utilization Rate
|
|
@@ -64,7 +141,8 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
64
141
|
// Borrow Index
|
|
65
142
|
getBorrowIndex() {
|
|
66
143
|
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
-
|
|
144
|
+
const { borrowIndex } = yield this._accrueInterest();
|
|
145
|
+
return borrowIndex;
|
|
68
146
|
});
|
|
69
147
|
}
|
|
70
148
|
// Accrue Timestamp
|
|
@@ -76,20 +154,13 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
76
154
|
// Total borrows
|
|
77
155
|
getTotalBorrows() {
|
|
78
156
|
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
getCurrentTotalBorrows() {
|
|
83
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
-
const storedAmount = yield this.getTotalBorrows();
|
|
85
|
-
const accrualTimestamp = yield this.getAccrualTimestamp();
|
|
86
|
-
const borrowRate = yield this.getBorrowRate();
|
|
87
|
-
return storedAmount * (1 + (Date.now() / 1000 - accrualTimestamp) * borrowRate);
|
|
157
|
+
const { totalBorrows } = yield this._accrueInterest();
|
|
158
|
+
return totalBorrows;
|
|
88
159
|
});
|
|
89
160
|
}
|
|
90
161
|
getTotalBorrowsUSD() {
|
|
91
162
|
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
-
const totalBorrows = yield this.
|
|
163
|
+
const totalBorrows = yield this.getTotalBorrows();
|
|
93
164
|
const tokenPrice = yield this.getTokenPriceFast();
|
|
94
165
|
return totalBorrows * tokenPrice;
|
|
95
166
|
});
|
|
@@ -97,7 +168,8 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
97
168
|
// Borrow rate
|
|
98
169
|
getBorrowRate() {
|
|
99
170
|
return __awaiter(this, void 0, void 0, function* () {
|
|
100
|
-
|
|
171
|
+
const { borrowRate } = yield this._calculateBorrowRate();
|
|
172
|
+
return borrowRate;
|
|
101
173
|
});
|
|
102
174
|
}
|
|
103
175
|
getBorrowAPR() {
|
|
@@ -108,10 +180,10 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
108
180
|
}
|
|
109
181
|
getNextBorrowRate(borrowAmount) {
|
|
110
182
|
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
-
const totalBorrows = yield this.
|
|
112
|
-
const supply =
|
|
183
|
+
const { totalBalance, totalBorrows } = yield this._accrueInterest();
|
|
184
|
+
const supply = totalBalance + totalBorrows;
|
|
113
185
|
const UR = (borrowAmount + totalBorrows) / supply;
|
|
114
|
-
const kinkBR = yield this.
|
|
186
|
+
const { kinkBorrowRate: kinkBR } = yield this._calculateBorrowRate();
|
|
115
187
|
const kinkUR = yield this.getKinkUtilizationRate();
|
|
116
188
|
if (UR < kinkUR)
|
|
117
189
|
return UR / kinkUR * kinkBR;
|
|
@@ -128,22 +200,13 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
128
200
|
// Supply
|
|
129
201
|
getSupply() {
|
|
130
202
|
return __awaiter(this, void 0, void 0, function* () {
|
|
131
|
-
const totalBalance = yield this.
|
|
132
|
-
const totalBorrows = yield this.getTotalBorrows();
|
|
203
|
+
const { totalBalance, totalBorrows } = yield this._accrueInterest();
|
|
133
204
|
return totalBalance + totalBorrows;
|
|
134
205
|
});
|
|
135
206
|
}
|
|
136
|
-
getCurrentSupply() {
|
|
137
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
138
|
-
const storedAmount = yield this.getSupply();
|
|
139
|
-
const accrualTimestamp = yield this.getAccrualTimestamp();
|
|
140
|
-
const supplyRate = yield this.getSupplyRate();
|
|
141
|
-
return storedAmount * (1 + (Date.now() / 1000 - accrualTimestamp) * supplyRate);
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
207
|
getSupplyUSD() {
|
|
145
208
|
return __awaiter(this, void 0, void 0, function* () {
|
|
146
|
-
const supply = yield this.
|
|
209
|
+
const supply = yield this.getSupply();
|
|
147
210
|
const tokenPrice = yield this.getTokenPriceFast();
|
|
148
211
|
return supply * tokenPrice;
|
|
149
212
|
});
|
|
@@ -151,11 +214,10 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
151
214
|
// Utilization Rate
|
|
152
215
|
getUtilizationRate() {
|
|
153
216
|
return __awaiter(this, void 0, void 0, function* () {
|
|
154
|
-
const
|
|
155
|
-
if (
|
|
217
|
+
const { totalBalance, totalBorrows } = yield this._accrueInterest();
|
|
218
|
+
if (totalBorrows == 0)
|
|
156
219
|
return 0;
|
|
157
|
-
|
|
158
|
-
return totalBalance / supply;
|
|
220
|
+
return totalBorrows / (totalBalance + totalBorrows);
|
|
159
221
|
});
|
|
160
222
|
}
|
|
161
223
|
// Supply Rate
|
|
@@ -175,10 +237,10 @@ class OffchainBorrowable extends offchainPoolToken_1.default {
|
|
|
175
237
|
}
|
|
176
238
|
getNextSupplyRate(supplyAmount) {
|
|
177
239
|
return __awaiter(this, void 0, void 0, function* () {
|
|
178
|
-
const totalBorrows = yield this.
|
|
179
|
-
const supply =
|
|
240
|
+
const { totalBalance, totalBorrows } = yield this._accrueInterest();
|
|
241
|
+
const supply = totalBalance + totalBorrows;
|
|
180
242
|
const UR = totalBorrows / (supply + supplyAmount);
|
|
181
|
-
const kinkBR = yield this.
|
|
243
|
+
const { kinkBorrowRate: kinkBR } = yield this._calculateBorrowRate();
|
|
182
244
|
const kinkUR = yield this.getKinkUtilizationRate();
|
|
183
245
|
const reserveFactor = yield this.getReserveFactor();
|
|
184
246
|
if (UR < kinkUR)
|