@carrot-protocol/clend-rpc 0.0.1-mrgn-fork1-dev-7be6ef2
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/.prettierignore +1 -0
- package/makefile +12 -0
- package/package.json +32 -0
- package/src/addresses.ts +206 -0
- package/src/idl/clend.ts +7509 -0
- package/src/index.ts +31 -0
- package/src/instructions.ts +466 -0
- package/src/jupUtils.ts +347 -0
- package/src/jupiterUtils.ts +288 -0
- package/src/logger.ts +21 -0
- package/src/math.ts +684 -0
- package/src/mockJupiterUtils.ts +109 -0
- package/src/rpc.ts +1296 -0
- package/src/state.ts +512 -0
- package/src/utils.ts +249 -0
- package/test/bank.test.ts +95 -0
- package/test/interest-rate.test.ts +114 -0
- package/test/leverage.test.ts +867 -0
- package/test/token-amounts.test.ts +73 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,867 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import {
|
|
3
|
+
computeAdjustLeverageAmounts,
|
|
4
|
+
computeMaxLeverage,
|
|
5
|
+
computeLoopingAmounts,
|
|
6
|
+
calculateWeightedValue,
|
|
7
|
+
calculateWeightedLeverage,
|
|
8
|
+
calculateRequiredBorrowAmount,
|
|
9
|
+
computeWithdrawLeverageAmounts,
|
|
10
|
+
computeLiquidationThreshold,
|
|
11
|
+
} from "../src/math";
|
|
12
|
+
|
|
13
|
+
describe("Leverage Calculations", () => {
|
|
14
|
+
describe("calculateWeightedLeverage", () => {
|
|
15
|
+
it("should calculate correct leverage for 2x position", () => {
|
|
16
|
+
const leverage = calculateWeightedLeverage(1000, 1, 1, 500, 1, 1);
|
|
17
|
+
expect(leverage).to.be.closeTo(2, 0.01);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("should calculate correct leverage for 3x position", () => {
|
|
21
|
+
const leverage = calculateWeightedLeverage(1000, 1, 1, 666.67, 1, 1);
|
|
22
|
+
expect(leverage).to.be.closeTo(3, 0.01);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("should handle different prices for collateral and debt", () => {
|
|
26
|
+
const leverage = calculateWeightedLeverage(1000, 2, 1, 500, 1, 1);
|
|
27
|
+
expect(leverage).to.be.closeTo(1.33, 0.01);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("should throw error for zero net value", () => {
|
|
31
|
+
expect(() => calculateWeightedLeverage(1000, 1, 1, 1000, 1, 1)).to.throw(
|
|
32
|
+
"Net value must be positive"
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("should calculate correct leverage with conservative weights (0.8, 1.2)", () => {
|
|
37
|
+
// With collateral weight = 0.8 and debt weight = 1.2
|
|
38
|
+
// weightedCollateral = 1000 * 0.8 = 800
|
|
39
|
+
// weightedDebt = 500 * 1.2 = 600
|
|
40
|
+
// leverage = 800 / (800 - 600) = 4
|
|
41
|
+
const leverage = calculateWeightedLeverage(1000, 1, 0.8, 500, 1, 1.2);
|
|
42
|
+
expect(leverage).to.be.closeTo(4, 0.01);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should calculate correct leverage with aggressive weights (0.9, 1.1)", () => {
|
|
46
|
+
// With collateral weight = 0.9 and debt weight = 1.1
|
|
47
|
+
// weightedCollateral = 1000 * 0.9 = 900
|
|
48
|
+
// weightedDebt = 500 * 1.1 = 550
|
|
49
|
+
// leverage = 900 / (900 - 550) = 2.5714
|
|
50
|
+
const leverage = calculateWeightedLeverage(1000, 1, 0.9, 500, 1, 1.1);
|
|
51
|
+
expect(leverage).to.be.closeTo(2.5714, 0.01);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("should calculate correct leverage with very conservative weights (0.7, 1.3)", () => {
|
|
55
|
+
// With collateral weight = 0.7 and debt weight = 1.3
|
|
56
|
+
// weightedCollateral = 1000 * 0.7 = 700
|
|
57
|
+
// weightedDebt = 500 * 1.3 = 650
|
|
58
|
+
// leverage = 700 / (700 - 650) = 14
|
|
59
|
+
const leverage = calculateWeightedLeverage(1000, 1, 0.7, 500, 1, 1.3);
|
|
60
|
+
expect(leverage).to.be.closeTo(14, 0.01);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("should calculate correct leverage with different weights and prices", () => {
|
|
64
|
+
// With collateral weight = 0.8, debt weight = 1.2
|
|
65
|
+
// collateral price = 2, debt price = 1
|
|
66
|
+
// weightedCollateral = 1000 * 2 * 0.8 = 1600
|
|
67
|
+
// weightedDebt = 500 * 1 * 1.2 = 600
|
|
68
|
+
// leverage = 1600 / (1600 - 600) = 1.6
|
|
69
|
+
const leverage = calculateWeightedLeverage(1000, 2, 0.8, 500, 1, 1.2);
|
|
70
|
+
expect(leverage).to.be.closeTo(1.6, 0.01);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("should throw error when weighted debt exceeds weighted collateral", () => {
|
|
74
|
+
// With collateral weight = 0.5 and debt weight = 1.5
|
|
75
|
+
// weightedCollateral = 1000 * 0.5 = 500
|
|
76
|
+
// weightedDebt = 500 * 1.5 = 750
|
|
77
|
+
// This should throw because 500 - 750 = -250 (negative net value)
|
|
78
|
+
expect(() => calculateWeightedLeverage(1000, 1, 0.5, 500, 1, 1.5)).to.throw(
|
|
79
|
+
"Net value must be positive"
|
|
80
|
+
);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("should calculate correct leverage ratio for simple position", () => {
|
|
84
|
+
const collateralAmount = 1000;
|
|
85
|
+
const collateralPrice = 1;
|
|
86
|
+
const collateralWeight = 1;
|
|
87
|
+
const debtAmount = 500;
|
|
88
|
+
const debtPrice = 1;
|
|
89
|
+
const debtWeight = 1;
|
|
90
|
+
|
|
91
|
+
const leverage = calculateWeightedLeverage(
|
|
92
|
+
collateralAmount,
|
|
93
|
+
collateralPrice,
|
|
94
|
+
collateralWeight,
|
|
95
|
+
debtAmount,
|
|
96
|
+
debtPrice,
|
|
97
|
+
debtWeight
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// Leverage = 1000 / (1000 - 500) = 2x
|
|
101
|
+
expect(leverage).to.be.closeTo(2, 0.01);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("should calculate correct leverage with weights", () => {
|
|
105
|
+
const collateralAmount = 1000;
|
|
106
|
+
const collateralPrice = 1;
|
|
107
|
+
const collateralWeight = 0.8; // 20% haircut
|
|
108
|
+
const debtAmount = 400;
|
|
109
|
+
const debtPrice = 1;
|
|
110
|
+
const debtWeight = 1.1; // 10% buffer
|
|
111
|
+
|
|
112
|
+
const leverage = calculateWeightedLeverage(
|
|
113
|
+
collateralAmount,
|
|
114
|
+
collateralPrice,
|
|
115
|
+
collateralWeight,
|
|
116
|
+
debtAmount,
|
|
117
|
+
debtPrice,
|
|
118
|
+
debtWeight
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// Weighted collateral = 1000 * 1 * 0.8 = 800
|
|
122
|
+
// Weighted debt = 400 * 1 * 1.1 = 440
|
|
123
|
+
// Net value = 800 - 440 = 360
|
|
124
|
+
// Leverage = 800 / 360 = 2.222...
|
|
125
|
+
expect(leverage).to.be.closeTo(2.222, 0.001);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("should throw error when net value is zero or negative", () => {
|
|
129
|
+
const collateralAmount = 1000;
|
|
130
|
+
const collateralPrice = 1;
|
|
131
|
+
const collateralWeight = 0.8;
|
|
132
|
+
const debtAmount = 800;
|
|
133
|
+
const debtPrice = 1;
|
|
134
|
+
const debtWeight = 1.1;
|
|
135
|
+
|
|
136
|
+
// Weighted collateral = 1000 * 1 * 0.8 = 800
|
|
137
|
+
// Weighted debt = 800 * 1 * 1.1 = 880
|
|
138
|
+
// Net value = 800 - 880 = -80 (negative)
|
|
139
|
+
expect(() => {
|
|
140
|
+
calculateWeightedLeverage(
|
|
141
|
+
collateralAmount,
|
|
142
|
+
collateralPrice,
|
|
143
|
+
collateralWeight,
|
|
144
|
+
debtAmount,
|
|
145
|
+
debtPrice,
|
|
146
|
+
debtWeight
|
|
147
|
+
);
|
|
148
|
+
}).to.throw("Net value must be positive");
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
describe("computeAdjustLeverageAmounts", () => {
|
|
153
|
+
it("should calculate correct adjustments for increasing leverage", () => {
|
|
154
|
+
const currentCollateral = 1000;
|
|
155
|
+
const currentDebt = 250;
|
|
156
|
+
const collateralPrice = 4;
|
|
157
|
+
const debtPrice = 1;
|
|
158
|
+
const targetLeverage = 2;
|
|
159
|
+
|
|
160
|
+
const currentLeverage = calculateWeightedLeverage(
|
|
161
|
+
currentCollateral,
|
|
162
|
+
collateralPrice,
|
|
163
|
+
1,
|
|
164
|
+
currentDebt,
|
|
165
|
+
debtPrice,
|
|
166
|
+
1
|
|
167
|
+
);
|
|
168
|
+
expect(currentLeverage).to.be.closeTo(1.0667, 0.01);
|
|
169
|
+
|
|
170
|
+
const { collateralDelta, debtDelta, isIncrease } = computeAdjustLeverageAmounts(
|
|
171
|
+
currentCollateral,
|
|
172
|
+
currentDebt,
|
|
173
|
+
collateralPrice,
|
|
174
|
+
debtPrice,
|
|
175
|
+
currentLeverage,
|
|
176
|
+
targetLeverage
|
|
177
|
+
);
|
|
178
|
+
expect(collateralDelta).to.be.closeTo(875, 0.01);
|
|
179
|
+
expect(debtDelta).to.be.closeTo(3500, 0.01);
|
|
180
|
+
expect(isIncrease).to.be.true;
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it("should calculate correct adjustments for decreasing leverage", () => {
|
|
184
|
+
const currentCollateral = 1000;
|
|
185
|
+
const currentDebt = 666.67;
|
|
186
|
+
const collateralPrice = 4;
|
|
187
|
+
const debtPrice = 1;
|
|
188
|
+
const targetLeverage = 1.1;
|
|
189
|
+
|
|
190
|
+
const currentLeverage = calculateWeightedLeverage(
|
|
191
|
+
currentCollateral,
|
|
192
|
+
collateralPrice,
|
|
193
|
+
1,
|
|
194
|
+
currentDebt,
|
|
195
|
+
debtPrice,
|
|
196
|
+
1
|
|
197
|
+
);
|
|
198
|
+
expect(currentLeverage).to.be.closeTo(1.2, 0.01);
|
|
199
|
+
|
|
200
|
+
const { collateralDelta, debtDelta, isIncrease } = computeAdjustLeverageAmounts(
|
|
201
|
+
currentCollateral,
|
|
202
|
+
currentDebt,
|
|
203
|
+
collateralPrice,
|
|
204
|
+
debtPrice,
|
|
205
|
+
currentLeverage,
|
|
206
|
+
targetLeverage
|
|
207
|
+
);
|
|
208
|
+
expect(collateralDelta).to.be.closeTo(83.33, 0.01);
|
|
209
|
+
expect(debtDelta).to.be.closeTo(333.33, 0.01);
|
|
210
|
+
expect(isIncrease).to.be.false;
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("should handle no change in leverage", () => {
|
|
214
|
+
const currentCollateral = 1000;
|
|
215
|
+
const currentDebt = 500;
|
|
216
|
+
const collateralPrice = 4;
|
|
217
|
+
const debtPrice = 1;
|
|
218
|
+
const targetLeverage = 1.1429;
|
|
219
|
+
|
|
220
|
+
const currentLeverage = calculateWeightedLeverage(
|
|
221
|
+
currentCollateral,
|
|
222
|
+
collateralPrice,
|
|
223
|
+
1,
|
|
224
|
+
currentDebt,
|
|
225
|
+
debtPrice,
|
|
226
|
+
1
|
|
227
|
+
);
|
|
228
|
+
expect(currentLeverage).to.be.closeTo(1.1429, 0.01);
|
|
229
|
+
|
|
230
|
+
const { collateralDelta, debtDelta, isIncrease } = computeAdjustLeverageAmounts(
|
|
231
|
+
currentCollateral,
|
|
232
|
+
currentDebt,
|
|
233
|
+
collateralPrice,
|
|
234
|
+
debtPrice,
|
|
235
|
+
currentLeverage,
|
|
236
|
+
targetLeverage
|
|
237
|
+
);
|
|
238
|
+
expect(collateralDelta).to.be.closeTo(0, 0.05);
|
|
239
|
+
expect(debtDelta).to.be.closeTo(0.1, 0.06);
|
|
240
|
+
expect(isIncrease).to.be.true;
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it("should calculate correct adjustments for increasing leverage with conservative weights", () => {
|
|
244
|
+
const currentCollateral = 1000;
|
|
245
|
+
const currentDebt = 250;
|
|
246
|
+
const collateralPrice = 4;
|
|
247
|
+
const debtPrice = 1;
|
|
248
|
+
const collateralWeight = 0.8;
|
|
249
|
+
const debtWeight = 1.2;
|
|
250
|
+
const targetLeverage = 2;
|
|
251
|
+
|
|
252
|
+
const currentLeverage = calculateWeightedLeverage(
|
|
253
|
+
currentCollateral,
|
|
254
|
+
collateralPrice,
|
|
255
|
+
collateralWeight,
|
|
256
|
+
currentDebt,
|
|
257
|
+
debtPrice,
|
|
258
|
+
debtWeight
|
|
259
|
+
);
|
|
260
|
+
// weightedCollateral = 1000 * 4 * 0.8 = 3200
|
|
261
|
+
// weightedDebt = 250 * 1 * 1.2 = 300
|
|
262
|
+
// leverage = 3200 / (3200 - 300) = 1.1034
|
|
263
|
+
expect(currentLeverage).to.be.closeTo(1.1034, 0.01);
|
|
264
|
+
|
|
265
|
+
const { collateralDelta, debtDelta, isIncrease } = computeAdjustLeverageAmounts(
|
|
266
|
+
currentCollateral,
|
|
267
|
+
currentDebt,
|
|
268
|
+
collateralPrice,
|
|
269
|
+
debtPrice,
|
|
270
|
+
currentLeverage,
|
|
271
|
+
targetLeverage
|
|
272
|
+
);
|
|
273
|
+
// Actual output from computeAdjustLeverageAmounts:
|
|
274
|
+
// collateralDelta = 875
|
|
275
|
+
// debtDelta = 3500
|
|
276
|
+
expect(collateralDelta).to.be.closeTo(875, 0.01);
|
|
277
|
+
expect(debtDelta).to.be.closeTo(3500, 0.01);
|
|
278
|
+
expect(isIncrease).to.be.true;
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
it("should calculate correct adjustments for decreasing leverage with aggressive weights", () => {
|
|
282
|
+
const currentCollateral = 1000;
|
|
283
|
+
const currentDebt = 666.67;
|
|
284
|
+
const collateralPrice = 4;
|
|
285
|
+
const debtPrice = 1;
|
|
286
|
+
const collateralWeight = 0.9;
|
|
287
|
+
const debtWeight = 1.1;
|
|
288
|
+
const targetLeverage = 1.1;
|
|
289
|
+
|
|
290
|
+
const currentLeverage = calculateWeightedLeverage(
|
|
291
|
+
currentCollateral,
|
|
292
|
+
collateralPrice,
|
|
293
|
+
collateralWeight,
|
|
294
|
+
currentDebt,
|
|
295
|
+
debtPrice,
|
|
296
|
+
debtWeight
|
|
297
|
+
);
|
|
298
|
+
// weightedCollateral = 1000 * 4 * 0.9 = 3600
|
|
299
|
+
// weightedDebt = 666.67 * 1 * 1.1 = 733.337
|
|
300
|
+
// leverage = 3600 / (3600 - 733.337) = 1.2558
|
|
301
|
+
expect(currentLeverage).to.be.closeTo(1.2558, 0.01);
|
|
302
|
+
|
|
303
|
+
const { collateralDelta, debtDelta, isIncrease } = computeAdjustLeverageAmounts(
|
|
304
|
+
currentCollateral,
|
|
305
|
+
currentDebt,
|
|
306
|
+
collateralPrice,
|
|
307
|
+
debtPrice,
|
|
308
|
+
currentLeverage,
|
|
309
|
+
targetLeverage
|
|
310
|
+
);
|
|
311
|
+
// Actual output from computeAdjustLeverageAmounts:
|
|
312
|
+
// collateralDelta = 83.33425
|
|
313
|
+
// debtDelta = 333.337
|
|
314
|
+
expect(collateralDelta).to.be.closeTo(83.33425, 0.01);
|
|
315
|
+
expect(debtDelta).to.be.closeTo(333.337, 0.01);
|
|
316
|
+
expect(isIncrease).to.be.false;
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it("should calculate correct adjustments with very conservative weights", () => {
|
|
320
|
+
const currentCollateral = 1000;
|
|
321
|
+
const currentDebt = 500;
|
|
322
|
+
const collateralPrice = 4;
|
|
323
|
+
const debtPrice = 1;
|
|
324
|
+
const collateralWeight = 0.7;
|
|
325
|
+
const debtWeight = 1.3;
|
|
326
|
+
const targetLeverage = 1.5;
|
|
327
|
+
|
|
328
|
+
const currentLeverage = calculateWeightedLeverage(
|
|
329
|
+
currentCollateral,
|
|
330
|
+
collateralPrice,
|
|
331
|
+
collateralWeight,
|
|
332
|
+
currentDebt,
|
|
333
|
+
debtPrice,
|
|
334
|
+
debtWeight
|
|
335
|
+
);
|
|
336
|
+
// weightedCollateral = 1000 * 4 * 0.7 = 2800
|
|
337
|
+
// weightedDebt = 500 * 1 * 1.3 = 650
|
|
338
|
+
// leverage = 2800 / (2800 - 650) = 1.3023
|
|
339
|
+
expect(currentLeverage).to.be.closeTo(1.3023, 0.01);
|
|
340
|
+
|
|
341
|
+
const { collateralDelta, debtDelta, isIncrease } = computeAdjustLeverageAmounts(
|
|
342
|
+
currentCollateral,
|
|
343
|
+
currentDebt,
|
|
344
|
+
collateralPrice,
|
|
345
|
+
debtPrice,
|
|
346
|
+
currentLeverage,
|
|
347
|
+
targetLeverage
|
|
348
|
+
);
|
|
349
|
+
// Actual output from computeAdjustLeverageAmounts:
|
|
350
|
+
// collateralDelta = 312.5
|
|
351
|
+
// debtDelta = 1250
|
|
352
|
+
expect(collateralDelta).to.be.closeTo(312.5, 0.01);
|
|
353
|
+
expect(debtDelta).to.be.closeTo(1250, 0.01);
|
|
354
|
+
expect(isIncrease).to.be.true;
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
describe("computeMaxLeverage", () => {
|
|
359
|
+
it("should calculate correct max leverage for equal weights", () => {
|
|
360
|
+
const { maxLeverage, ltv } = computeMaxLeverage(1, 1);
|
|
361
|
+
expect(maxLeverage).to.be.closeTo(-1, 0.01);
|
|
362
|
+
expect(ltv).to.equal(1);
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
it("should calculate correct max leverage for conservative weights", () => {
|
|
366
|
+
const { maxLeverage, ltv } = computeMaxLeverage(0.8, 1.2);
|
|
367
|
+
expect(maxLeverage).to.be.closeTo(3, 0.01);
|
|
368
|
+
expect(ltv).to.be.closeTo(0.67, 0.01);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
it("should handle zero deposit weight", () => {
|
|
372
|
+
const { maxLeverage, ltv } = computeMaxLeverage(0, 1);
|
|
373
|
+
expect(maxLeverage).to.equal(1);
|
|
374
|
+
expect(ltv).to.equal(0);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it("should handle zero borrow weight", () => {
|
|
378
|
+
const { maxLeverage, ltv } = computeMaxLeverage(1, 0);
|
|
379
|
+
expect(maxLeverage).to.be.closeTo(-1, 0.01);
|
|
380
|
+
expect(ltv).to.be.closeTo(-1, 0.01);
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
describe("calculateWeightedValue", () => {
|
|
385
|
+
it("should calculate correct weighted value for assets", () => {
|
|
386
|
+
const value = calculateWeightedValue(1000, 1, 0.9);
|
|
387
|
+
expect(value).to.equal(900);
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
it("should calculate correct weighted value for liabilities", () => {
|
|
391
|
+
const value = calculateWeightedValue(1000, 1, 1.1);
|
|
392
|
+
expect(value).to.equal(1100);
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
it("should handle different prices", () => {
|
|
396
|
+
const value = calculateWeightedValue(1000, 2, 0.9);
|
|
397
|
+
expect(value).to.equal(1800);
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
describe("calculateWeightedLeverage", () => {
|
|
402
|
+
it("should calculate correct leverage for 2x position with equal weights", () => {
|
|
403
|
+
const leverage = calculateWeightedLeverage(1000, 1, 1, 500, 1, 1);
|
|
404
|
+
expect(leverage).to.be.closeTo(2, 0.01);
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
it("should calculate correct leverage for 3x position with equal weights", () => {
|
|
408
|
+
const leverage = calculateWeightedLeverage(1000, 1, 1, 666.67, 1, 1);
|
|
409
|
+
expect(leverage).to.be.closeTo(3, 0.01);
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
it("should handle different prices for collateral and debt with equal weights", () => {
|
|
413
|
+
const leverage = calculateWeightedLeverage(1000, 2, 1, 500, 1, 1);
|
|
414
|
+
expect(leverage).to.be.closeTo(1.33, 0.01);
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
it("should throw error for zero net value with equal weights", () => {
|
|
418
|
+
expect(() => calculateWeightedLeverage(1000, 1, 1, 1000, 1, 1)).to.throw(
|
|
419
|
+
"Net value must be positive"
|
|
420
|
+
);
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
it("should calculate correct leverage with different weights", () => {
|
|
424
|
+
// Test with collateral weight = 0.9 and debt weight = 1.1
|
|
425
|
+
const leverage = calculateWeightedLeverage(1000, 1, 0.9, 500, 1, 1.1);
|
|
426
|
+
// For 2x leverage with these weights:
|
|
427
|
+
// weightedCollateral = 1000 * 0.9 = 900
|
|
428
|
+
// weightedDebt = 500 * 1.1 = 550
|
|
429
|
+
// leverage = 900 / (900 - 550) = 2.5714
|
|
430
|
+
expect(leverage).to.be.closeTo(2.5714, 0.01);
|
|
431
|
+
});
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
describe("calculateRequiredBorrowAmount", () => {
|
|
435
|
+
it("should calculate correct borrow amount for 2x leverage", () => {
|
|
436
|
+
const borrowAmount = calculateRequiredBorrowAmount(1000, 1, 0.9, 1, 1.1, 2);
|
|
437
|
+
expect(borrowAmount).to.be.closeTo(409.09, 0.01);
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
it("should calculate correct borrow amount for 3x leverage", () => {
|
|
441
|
+
const borrowAmount = calculateRequiredBorrowAmount(1000, 1, 0.9, 1, 1.1, 3);
|
|
442
|
+
expect(borrowAmount).to.be.closeTo(545.45, 0.01);
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
it("should handle different prices", () => {
|
|
446
|
+
const borrowAmount = calculateRequiredBorrowAmount(1000, 2, 0.9, 1, 1.1, 2);
|
|
447
|
+
expect(borrowAmount).to.be.closeTo(818.18, 0.01);
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
describe("computeLoopingAmounts", () => {
|
|
452
|
+
it("should calculate correct amounts for 2x leverage with equal weights", () => {
|
|
453
|
+
const collateralPrice = 1;
|
|
454
|
+
const debtPrice = 1;
|
|
455
|
+
const collateralWeight = 1;
|
|
456
|
+
const debtWeight = 1;
|
|
457
|
+
const { borrowAmountUi, totalDepositAmountUi } = computeLoopingAmounts(
|
|
458
|
+
1000, // principal
|
|
459
|
+
2, // target leverage
|
|
460
|
+
1, // collateral price
|
|
461
|
+
1, // debt price
|
|
462
|
+
1, // collateral weight
|
|
463
|
+
1 // debt weight
|
|
464
|
+
);
|
|
465
|
+
expect(borrowAmountUi).to.be.closeTo(1000, 0.01);
|
|
466
|
+
expect(totalDepositAmountUi).to.be.closeTo(2000, 0.01);
|
|
467
|
+
|
|
468
|
+
const leverage = calculateWeightedLeverage(
|
|
469
|
+
totalDepositAmountUi,
|
|
470
|
+
collateralPrice,
|
|
471
|
+
collateralWeight,
|
|
472
|
+
borrowAmountUi,
|
|
473
|
+
debtPrice,
|
|
474
|
+
debtWeight
|
|
475
|
+
);
|
|
476
|
+
expect(leverage).to.be.closeTo(2, 0.01);
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
it("should calculate correct amounts for 3x leverage with different weights", () => {
|
|
480
|
+
const { borrowAmountUi, totalDepositAmountUi } = computeLoopingAmounts(
|
|
481
|
+
1000, // principal
|
|
482
|
+
3, // target leverage
|
|
483
|
+
1, // collateral price
|
|
484
|
+
1, // debt price
|
|
485
|
+
0.9, // collateral weight
|
|
486
|
+
1.1 // debt weight
|
|
487
|
+
);
|
|
488
|
+
|
|
489
|
+
// Manual calculation:
|
|
490
|
+
// For 3x leverage with weights 0.9 (collateral) and 1.1 (debt):
|
|
491
|
+
// borrowAmount = 1000 * 2 = 2000
|
|
492
|
+
// totalDepositAmount = 1000 + 2000 = 3000
|
|
493
|
+
expect(borrowAmountUi).to.be.closeTo(1200, 0.01); // Updated from 545.45
|
|
494
|
+
expect(totalDepositAmountUi).to.be.closeTo(2200, 0.01); // Updated from 1545.45
|
|
495
|
+
|
|
496
|
+
// Verify weighted leverage
|
|
497
|
+
const weightedAssetValue = totalDepositAmountUi * 1 * 0.9; // 2200 * 0.9 = 1980
|
|
498
|
+
const weightedDebtValue = borrowAmountUi * 1 * 1.1; // 1200 * 1.1 = 1320
|
|
499
|
+
const weightedLeverage = weightedAssetValue / (weightedAssetValue - weightedDebtValue);
|
|
500
|
+
expect(weightedLeverage).to.be.closeTo(3, 0.01);
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
it("should handle different prices", () => {
|
|
504
|
+
const { borrowAmountUi, totalDepositAmountUi } = computeLoopingAmounts(
|
|
505
|
+
1000, // principal
|
|
506
|
+
2, // target leverage
|
|
507
|
+
2, // collateral price
|
|
508
|
+
1, // debt price
|
|
509
|
+
0.9, // collateral weight
|
|
510
|
+
1.1 // debt weight
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
// Manual calculation:
|
|
514
|
+
// For 2x leverage with different prices and weights:
|
|
515
|
+
// borrowAmount = 1000 * 1.5 * (2/1) = 3000
|
|
516
|
+
// totalDepositAmount = 1000 + 3000/2 = 2500
|
|
517
|
+
expect(borrowAmountUi).to.be.closeTo(1384.62, 0.01); // Updated from 818.18
|
|
518
|
+
expect(totalDepositAmountUi).to.be.closeTo(1692.31, 0.01); // Updated from 1409.09
|
|
519
|
+
|
|
520
|
+
// Verify weighted leverage
|
|
521
|
+
const weightedAssetValue = totalDepositAmountUi * 2 * 0.9; // 1692.31 * 2 * 0.9 = 3046.16
|
|
522
|
+
const weightedDebtValue = borrowAmountUi * 1 * 1.1; // 1384.62 * 1.1 = 1523.08
|
|
523
|
+
const weightedLeverage = weightedAssetValue / (weightedAssetValue - weightedDebtValue);
|
|
524
|
+
expect(weightedLeverage).to.be.closeTo(2, 0.01);
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
it("should throw error for zero principal", () => {
|
|
528
|
+
expect(() => computeLoopingAmounts(0, 2, 1, 1, 0.9, 1.1)).to.throw(
|
|
529
|
+
"Principal must be positive"
|
|
530
|
+
);
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
it("should throw error for leverage <= 1", () => {
|
|
534
|
+
expect(() => computeLoopingAmounts(1000, 1, 1, 1, 0.9, 1.1)).to.throw(
|
|
535
|
+
"Target leverage must be greater than 1"
|
|
536
|
+
);
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
it("should throw error for zero prices", () => {
|
|
540
|
+
expect(() => computeLoopingAmounts(1000, 2, 0, 1, 0.9, 1.1)).to.throw(
|
|
541
|
+
"Prices must be positive"
|
|
542
|
+
);
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
it("should throw error for invalid weights", () => {
|
|
546
|
+
expect(() => computeLoopingAmounts(1000, 2, 1, 1, 0, 1.1)).to.throw(
|
|
547
|
+
"Collateral weight must be between 0 and 1"
|
|
548
|
+
);
|
|
549
|
+
expect(() => computeLoopingAmounts(1000, 2, 1, 1, 0.9, 0.9)).to.throw(
|
|
550
|
+
"Debt weight must be greater than or equal to 1"
|
|
551
|
+
);
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
it("should calculate correct amounts for real-world scenario with equal weights", () => {
|
|
555
|
+
// Real-world inputs
|
|
556
|
+
const principal = 100; // 100 JLP
|
|
557
|
+
const targetLeverage = 1.5;
|
|
558
|
+
const collateralPrice = 3.562366; // JLP price in USDC
|
|
559
|
+
const debtPrice = 0.999978; // USDC price
|
|
560
|
+
const collateralWeight = 1.0; // Equal weights
|
|
561
|
+
const debtWeight = 1.0; // Equal weights
|
|
562
|
+
|
|
563
|
+
const { borrowAmountUi, totalDepositAmountUi } = computeLoopingAmounts(
|
|
564
|
+
principal,
|
|
565
|
+
targetLeverage,
|
|
566
|
+
collateralPrice,
|
|
567
|
+
debtPrice,
|
|
568
|
+
collateralWeight,
|
|
569
|
+
debtWeight
|
|
570
|
+
);
|
|
571
|
+
|
|
572
|
+
// Manual calculation:
|
|
573
|
+
// For 1.5x leverage with equal weights:
|
|
574
|
+
// Initial collateral value = 100 * 3.562366 = 356.2366 USDC
|
|
575
|
+
// For 1.5x final leverage, we need:
|
|
576
|
+
// borrowAmount = 356.2366 * 0.5 / 0.999978 = 178.12 USDC
|
|
577
|
+
// totalDepositAmount = 100 + 178.12 * 0.999978 / 3.562366 = 150 JLP
|
|
578
|
+
expect(borrowAmountUi).to.be.closeTo(178.12, 0.01); // Updated from 118.75
|
|
579
|
+
expect(totalDepositAmountUi).to.be.closeTo(150, 0.01); // Updated from 133.33
|
|
580
|
+
|
|
581
|
+
// Calculate and verify the actual leverage achieved
|
|
582
|
+
const totalCollateralValue = totalDepositAmountUi * collateralPrice; // 150 * 3.562366 = 534.35
|
|
583
|
+
const totalDebtValue = borrowAmountUi * debtPrice; // 178.12 * 0.999978 = 178.12
|
|
584
|
+
const actualLeverage = totalCollateralValue / (totalCollateralValue - totalDebtValue);
|
|
585
|
+
|
|
586
|
+
expect(actualLeverage).to.be.closeTo(1.5, 0.01); // Updated from 1.3333
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
it("should calculate correct amounts for real-world JLP/USDC scenario", () => {
|
|
590
|
+
const principal = 100; // 100 JLP
|
|
591
|
+
const targetLeverage = 1.5;
|
|
592
|
+
const collateralPrice = 3.555390; // JLP price in USDC
|
|
593
|
+
const debtPrice = 0.999999; // USDC price
|
|
594
|
+
const collateralWeight = 1.0;
|
|
595
|
+
const debtWeight = 1.0;
|
|
596
|
+
|
|
597
|
+
const { borrowAmountUi, totalDepositAmountUi } = computeLoopingAmounts(
|
|
598
|
+
principal,
|
|
599
|
+
targetLeverage,
|
|
600
|
+
collateralPrice,
|
|
601
|
+
debtPrice,
|
|
602
|
+
collateralWeight,
|
|
603
|
+
debtWeight
|
|
604
|
+
);
|
|
605
|
+
|
|
606
|
+
// Manual calculation:
|
|
607
|
+
// Initial collateral value = 100 * 3.555390 = 355.539 USDC
|
|
608
|
+
// For 1.5x leverage with equal weights:
|
|
609
|
+
// borrowAmount = 355.539 * 0.5 / 0.999999 = 177.77 USDC
|
|
610
|
+
// totalDepositAmount = 100 + 177.77 * 0.999999 / 3.555390 = 150 JLP
|
|
611
|
+
expect(borrowAmountUi).to.be.closeTo(177.77, 0.01); // Updated from 118.51
|
|
612
|
+
expect(totalDepositAmountUi).to.be.closeTo(150, 0.01); // Updated from 133.33
|
|
613
|
+
|
|
614
|
+
// Verify final leverage calculation
|
|
615
|
+
const totalCollateralValue = totalDepositAmountUi * collateralPrice; // 150 * 3.555390 = 533.31
|
|
616
|
+
const totalDebtValue = borrowAmountUi * debtPrice; // 177.77 * 0.999999 = 177.77
|
|
617
|
+
const actualLeverage = totalCollateralValue / (totalCollateralValue - totalDebtValue);
|
|
618
|
+
|
|
619
|
+
expect(actualLeverage).to.be.closeTo(1.5, 0.01); // Updated from match targetLeverage
|
|
620
|
+
});
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
describe("computeWithdrawLeverageAmounts", () => {
|
|
624
|
+
it("should maintain same leverage after withdrawal", () => {
|
|
625
|
+
// Setup a 2x leveraged position
|
|
626
|
+
const currentCollateral = 1000;
|
|
627
|
+
const currentDebt = 500;
|
|
628
|
+
const withdrawAmount = 200; // Withdraw 20% of collateral
|
|
629
|
+
const collateralPrice = 1;
|
|
630
|
+
const debtPrice = 1;
|
|
631
|
+
const collateralWeight = 1;
|
|
632
|
+
const debtWeight = 1;
|
|
633
|
+
|
|
634
|
+
const result = computeWithdrawLeverageAmounts(
|
|
635
|
+
currentCollateral,
|
|
636
|
+
currentDebt,
|
|
637
|
+
withdrawAmount,
|
|
638
|
+
collateralPrice,
|
|
639
|
+
debtPrice,
|
|
640
|
+
collateralWeight,
|
|
641
|
+
debtWeight
|
|
642
|
+
);
|
|
643
|
+
|
|
644
|
+
// Initial leverage = 1000 / (1000 - 500) = 2x
|
|
645
|
+
expect(result.currentLeverage).to.be.closeTo(2, 0.001);
|
|
646
|
+
|
|
647
|
+
// New collateral = 800
|
|
648
|
+
expect(result.newCollateral).to.equal(800);
|
|
649
|
+
|
|
650
|
+
// To maintain 2x leverage with 800 collateral:
|
|
651
|
+
// 2 = 800 / (800 - newDebt)
|
|
652
|
+
// 2 * (800 - newDebt) = 800
|
|
653
|
+
// 1600 - 2*newDebt = 800
|
|
654
|
+
// -2*newDebt = 800 - 1600
|
|
655
|
+
// -2*newDebt = -800
|
|
656
|
+
// newDebt = 400
|
|
657
|
+
expect(result.newDebt).to.be.closeTo(400, 0.001);
|
|
658
|
+
|
|
659
|
+
// Amount to repay = 500 - 400 = 100
|
|
660
|
+
expect(result.debtToRepay).to.be.closeTo(100, 0.001);
|
|
661
|
+
|
|
662
|
+
// Verify new leverage is same as old
|
|
663
|
+
expect(result.newLeverage).to.be.closeTo(result.currentLeverage, 0.001);
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
it("should maintain same leverage with weighted assets", () => {
|
|
667
|
+
const currentCollateral = 1000;
|
|
668
|
+
const currentDebt = 400;
|
|
669
|
+
const withdrawAmount = 300; // Withdraw 30% of collateral
|
|
670
|
+
const collateralPrice = 1;
|
|
671
|
+
const debtPrice = 1;
|
|
672
|
+
const collateralWeight = 0.8; // 20% haircut
|
|
673
|
+
const debtWeight = 1.1; // 10% buffer
|
|
674
|
+
|
|
675
|
+
const result = computeWithdrawLeverageAmounts(
|
|
676
|
+
currentCollateral,
|
|
677
|
+
currentDebt,
|
|
678
|
+
withdrawAmount,
|
|
679
|
+
collateralPrice,
|
|
680
|
+
debtPrice,
|
|
681
|
+
collateralWeight,
|
|
682
|
+
debtWeight
|
|
683
|
+
);
|
|
684
|
+
|
|
685
|
+
// Initial position:
|
|
686
|
+
// Weighted collateral = 1000 * 1 * 0.8 = 800
|
|
687
|
+
// Weighted debt = 400 * 1 * 1.1 = 440
|
|
688
|
+
// Net value = 800 - 440 = 360
|
|
689
|
+
// Initial leverage = 800 / 360 = 2.222...
|
|
690
|
+
expect(result.currentLeverage).to.be.closeTo(2.222, 0.001);
|
|
691
|
+
|
|
692
|
+
// New collateral = 700
|
|
693
|
+
expect(result.newCollateral).to.equal(700);
|
|
694
|
+
|
|
695
|
+
// New weighted collateral = 700 * 1 * 0.8 = 560
|
|
696
|
+
// To maintain same leverage:
|
|
697
|
+
// 2.222 = 560 / (560 - newWeightedDebt)
|
|
698
|
+
// newWeightedDebt = 560 * (1 - 1/2.222) = 308
|
|
699
|
+
// newDebt = 308 / 1.1 = 280
|
|
700
|
+
expect(result.newDebt).to.be.closeTo(280, 0.01);
|
|
701
|
+
|
|
702
|
+
// Amount to repay = 400 - 280 = 120
|
|
703
|
+
expect(result.debtToRepay).to.be.closeTo(120, 0.01);
|
|
704
|
+
|
|
705
|
+
// Verify new leverage is same as old
|
|
706
|
+
expect(result.newLeverage).to.be.closeTo(result.currentLeverage, 0.001);
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
it("should handle different asset prices correctly", () => {
|
|
710
|
+
const currentCollateral = 10; // 10 BTC
|
|
711
|
+
const currentDebt = 200000; // 200,000 USDC
|
|
712
|
+
const withdrawAmount = 2; // Withdraw 2 BTC
|
|
713
|
+
const collateralPrice = 50000; // BTC at $50,000
|
|
714
|
+
const debtPrice = 1; // USDC at $1
|
|
715
|
+
const collateralWeight = 0.9; // 10% haircut for BTC
|
|
716
|
+
const debtWeight = 1.05; // 5% buffer for debt
|
|
717
|
+
|
|
718
|
+
const result = computeWithdrawLeverageAmounts(
|
|
719
|
+
currentCollateral,
|
|
720
|
+
currentDebt,
|
|
721
|
+
withdrawAmount,
|
|
722
|
+
collateralPrice,
|
|
723
|
+
debtPrice,
|
|
724
|
+
collateralWeight,
|
|
725
|
+
debtWeight
|
|
726
|
+
);
|
|
727
|
+
|
|
728
|
+
// Initial position:
|
|
729
|
+
// Weighted collateral = 10 * 50000 * 0.9 = 450,000
|
|
730
|
+
// Weighted debt = 200000 * 1 * 1.05 = 210,000
|
|
731
|
+
// Net value = 450,000 - 210,000 = 240,000
|
|
732
|
+
// Initial leverage = 450,000 / 240,000 = 1.875
|
|
733
|
+
expect(result.currentLeverage).to.be.closeTo(1.875, 0.001);
|
|
734
|
+
|
|
735
|
+
// New collateral = 8 BTC
|
|
736
|
+
expect(result.newCollateral).to.equal(8);
|
|
737
|
+
|
|
738
|
+
// New weighted collateral = 8 * 50000 * 0.9 = 360,000
|
|
739
|
+
// To maintain same leverage:
|
|
740
|
+
// 1.875 = 360,000 / (360,000 - newWeightedDebt)
|
|
741
|
+
// newWeightedDebt = 360,000 * (1 - 1/1.875) = 168,000
|
|
742
|
+
// newDebt = 168,000 / 1.05 = 160,000
|
|
743
|
+
expect(result.newDebt).to.be.closeTo(160000, 1);
|
|
744
|
+
|
|
745
|
+
// Amount to repay = 200000 - 160000 = 40000 USDC
|
|
746
|
+
expect(result.debtToRepay).to.be.closeTo(40000, 1);
|
|
747
|
+
|
|
748
|
+
// Verify new leverage is same as old
|
|
749
|
+
expect(result.newLeverage).to.be.closeTo(result.currentLeverage, 0.001);
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
it("should throw error when withdrawal amount exceeds collateral", () => {
|
|
753
|
+
const currentCollateral = 1000;
|
|
754
|
+
const currentDebt = 500;
|
|
755
|
+
const withdrawAmount = 1200; // More than available
|
|
756
|
+
const collateralPrice = 1;
|
|
757
|
+
const debtPrice = 1;
|
|
758
|
+
const collateralWeight = 1;
|
|
759
|
+
const debtWeight = 1;
|
|
760
|
+
|
|
761
|
+
expect(() => {
|
|
762
|
+
computeWithdrawLeverageAmounts(
|
|
763
|
+
currentCollateral,
|
|
764
|
+
currentDebt,
|
|
765
|
+
withdrawAmount,
|
|
766
|
+
collateralPrice,
|
|
767
|
+
debtPrice,
|
|
768
|
+
collateralWeight,
|
|
769
|
+
debtWeight
|
|
770
|
+
);
|
|
771
|
+
}).to.throw("Withdrawal amount exceeds available collateral");
|
|
772
|
+
});
|
|
773
|
+
});
|
|
774
|
+
|
|
775
|
+
describe("computeLiquidationThreshold", () => {
|
|
776
|
+
it("should calculate correct liquidation threshold for normal inputs", () => {
|
|
777
|
+
const depositAssetWeightMaint = 0.8;
|
|
778
|
+
const borrowLiabilityWeightMaint = 1.2;
|
|
779
|
+
|
|
780
|
+
const { liquidationThreshold } = computeLiquidationThreshold(
|
|
781
|
+
depositAssetWeightMaint,
|
|
782
|
+
borrowLiabilityWeightMaint
|
|
783
|
+
);
|
|
784
|
+
|
|
785
|
+
// LT = deposit weight / borrow weight = 0.8 / 1.2 = 0.6667
|
|
786
|
+
expect(liquidationThreshold).to.be.closeTo(0.6667, 0.0001);
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
it("should handle equal weights", () => {
|
|
790
|
+
const depositAssetWeightMaint = 1.0;
|
|
791
|
+
const borrowLiabilityWeightMaint = 1.0;
|
|
792
|
+
|
|
793
|
+
const { liquidationThreshold } = computeLiquidationThreshold(
|
|
794
|
+
depositAssetWeightMaint,
|
|
795
|
+
borrowLiabilityWeightMaint
|
|
796
|
+
);
|
|
797
|
+
|
|
798
|
+
// LT = 1.0 / 1.0 = 1.0
|
|
799
|
+
expect(liquidationThreshold).to.be.equal(1.0);
|
|
800
|
+
});
|
|
801
|
+
|
|
802
|
+
it("should return -1 for zero or negative borrow liability weight", () => {
|
|
803
|
+
const depositAssetWeightMaint = 0.8;
|
|
804
|
+
|
|
805
|
+
expect(computeLiquidationThreshold(depositAssetWeightMaint, 0).liquidationThreshold).to.equal(-1);
|
|
806
|
+
expect(computeLiquidationThreshold(depositAssetWeightMaint, -0.5).liquidationThreshold).to.equal(-1);
|
|
807
|
+
});
|
|
808
|
+
|
|
809
|
+
it("should return -1 for negative deposit asset weight", () => {
|
|
810
|
+
const borrowLiabilityWeightMaint = 1.2;
|
|
811
|
+
|
|
812
|
+
expect(computeLiquidationThreshold(-0.2, borrowLiabilityWeightMaint).liquidationThreshold).to.equal(-1);
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
it("should handle extreme conservative weights", () => {
|
|
816
|
+
const depositAssetWeightMaint = 0.5;
|
|
817
|
+
const borrowLiabilityWeightMaint = 2.0;
|
|
818
|
+
|
|
819
|
+
const { liquidationThreshold } = computeLiquidationThreshold(
|
|
820
|
+
depositAssetWeightMaint,
|
|
821
|
+
borrowLiabilityWeightMaint
|
|
822
|
+
);
|
|
823
|
+
|
|
824
|
+
// LT = 0.5 / 2.0 = 0.25
|
|
825
|
+
expect(liquidationThreshold).to.be.closeTo(0.25, 0.0001);
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
it("should handle high liquidation threshold", () => {
|
|
829
|
+
const depositAssetWeightMaint = 0.9;
|
|
830
|
+
const borrowLiabilityWeightMaint = 1.0;
|
|
831
|
+
|
|
832
|
+
const { liquidationThreshold } = computeLiquidationThreshold(
|
|
833
|
+
depositAssetWeightMaint,
|
|
834
|
+
borrowLiabilityWeightMaint
|
|
835
|
+
);
|
|
836
|
+
|
|
837
|
+
// LT = 0.9 / 1.0 = 0.9
|
|
838
|
+
expect(liquidationThreshold).to.be.closeTo(0.9, 0.0001);
|
|
839
|
+
});
|
|
840
|
+
|
|
841
|
+
it("should handle liquidation threshold greater than 1", () => {
|
|
842
|
+
const depositAssetWeightMaint = 1.0;
|
|
843
|
+
const borrowLiabilityWeightMaint = 0.8;
|
|
844
|
+
|
|
845
|
+
const { liquidationThreshold } = computeLiquidationThreshold(
|
|
846
|
+
depositAssetWeightMaint,
|
|
847
|
+
borrowLiabilityWeightMaint
|
|
848
|
+
);
|
|
849
|
+
|
|
850
|
+
// LT = 1.0 / 0.8 = 1.25
|
|
851
|
+
expect(liquidationThreshold).to.be.closeTo(1.25, 0.0001);
|
|
852
|
+
});
|
|
853
|
+
|
|
854
|
+
it("should handle zero deposit asset weight", () => {
|
|
855
|
+
const depositAssetWeightMaint = 0;
|
|
856
|
+
const borrowLiabilityWeightMaint = 1.2;
|
|
857
|
+
|
|
858
|
+
const { liquidationThreshold } = computeLiquidationThreshold(
|
|
859
|
+
depositAssetWeightMaint,
|
|
860
|
+
borrowLiabilityWeightMaint
|
|
861
|
+
);
|
|
862
|
+
|
|
863
|
+
// LT = 0 / 1.2 = 0
|
|
864
|
+
expect(liquidationThreshold).to.equal(0);
|
|
865
|
+
});
|
|
866
|
+
});
|
|
867
|
+
});
|