@curvefi/llamalend-api 2.0.8 → 2.0.10
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 +39 -4
- package/lib/constants/abis/ControllerV2.json +0 -25
- package/lib/lendMarkets/interfaces/v1/loanV1.d.ts +23 -5
- package/lib/lendMarkets/interfaces/v2/loanV2.d.ts +26 -5
- package/lib/lendMarkets/modules/common/leverageZapV2Base.js +4 -4
- package/lib/lendMarkets/modules/common/loanBase.d.ts +50 -14
- package/lib/lendMarkets/modules/common/loanBase.js +16 -134
- package/lib/lendMarkets/modules/v1/loanV1.d.ts +37 -1
- package/lib/lendMarkets/modules/v1/loanV1.js +137 -3
- package/lib/lendMarkets/modules/v2/loanV2.d.ts +36 -1
- package/lib/lendMarkets/modules/v2/loanV2.js +117 -3
- package/package.json +1 -1
- package/src/constants/abis/ControllerV2.json +0 -25
- package/src/lendMarkets/interfaces/v1/loanV1.ts +5 -5
- package/src/lendMarkets/interfaces/v2/loanV2.ts +5 -5
- package/src/lendMarkets/modules/common/index.ts +2 -2
- package/src/lendMarkets/modules/common/leverageZapV2Base.ts +4 -4
- package/src/lendMarkets/modules/common/loanBase.ts +46 -149
- package/src/lendMarkets/modules/v1/loanV1.ts +165 -2
- package/src/lendMarkets/modules/v2/loanV2.ts +164 -2
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
import {Llamalend} from "../../../llamalend";
|
|
17
17
|
import BigNumber from "bignumber.js";
|
|
18
18
|
import {_getUserCollateral} from "../../../external-api";
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
export abstract class LoanBaseModule {
|
|
20
21
|
protected market: LendMarketTemplate;
|
|
21
22
|
protected llamalend: Llamalend;
|
|
22
23
|
|
|
@@ -25,18 +26,45 @@ export class LoanBaseModule {
|
|
|
25
26
|
this.llamalend = market.getLlamalend();
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
protected abstract _calcN1(_collateral: bigint, _debt: bigint, range: number): Promise<bigint>;
|
|
30
|
+
|
|
31
|
+
protected abstract _calcN1AllRanges(_collateral: bigint, _debt: bigint, maxN: number): Promise<bigint[]>;
|
|
32
|
+
|
|
33
|
+
protected abstract _maxBorrowable(collateralAmount: TAmount, range?: number): Promise<bigint>;
|
|
34
|
+
|
|
35
|
+
protected abstract _getMaxBorrowableCall(_collateral: bigint, N: number): any;
|
|
36
|
+
|
|
37
|
+
protected abstract _createLoanContractCall(_collateral: bigint, _debt: bigint, range: number, estimateGas: boolean): Promise<string | TGas>;
|
|
38
|
+
|
|
39
|
+
protected abstract _borrowMoreContractCall(_collateral: bigint, _debt: bigint, estimateGas: boolean): Promise<string | TGas>;
|
|
40
|
+
|
|
41
|
+
protected abstract _repayContractCall(params: { _debt: bigint, address: string, n: number | bigint, estimateGas: boolean, shrink?: boolean }): Promise<string | TGas>;
|
|
42
|
+
|
|
43
|
+
protected abstract _partialLiquidateContractCall(address: string, _minAmount: bigint, frac: string, estimateGas: boolean): Promise<string | TGas>;
|
|
44
|
+
|
|
45
|
+
protected abstract _repayBands(params: { debt: number | string, address: string, shrink?: boolean }): Promise<[bigint, bigint]>;
|
|
46
|
+
|
|
47
|
+
public abstract repayBands(params: { debt: number | string; address?: string; shrink?: boolean }): Promise<[number, number]>;
|
|
48
|
+
|
|
49
|
+
public abstract repayPrices(params: { debt: number | string; address?: string; shrink?: boolean }): Promise<string[]>;
|
|
50
|
+
|
|
51
|
+
public abstract createLoanHealth(collateral: number | string, debt: number | string, range: number, full?: boolean): Promise<string>;
|
|
52
|
+
|
|
53
|
+
public abstract borrowMoreHealth(collateral: number | string, debt: number | string, full?: boolean, address?: string): Promise<string>;
|
|
54
|
+
|
|
55
|
+
public abstract addCollateralHealth(collateral: number | string, full?: boolean, address?: string): Promise<string>;
|
|
56
|
+
|
|
57
|
+
public abstract removeCollateralHealth(collateral: number | string, full?: boolean, address?: string): Promise<string>;
|
|
58
|
+
|
|
28
59
|
public _checkRange(range: number): void {
|
|
29
60
|
if (range < this.market.minBands) throw Error(`range must be >= ${this.market.minBands}`);
|
|
30
61
|
if (range > this.market.maxBands) throw Error(`range must be <= ${this.market.maxBands}`);
|
|
31
62
|
}
|
|
32
63
|
|
|
33
|
-
public async createLoanMaxRecv(collateral:
|
|
64
|
+
public async createLoanMaxRecv(collateral: TAmount, range: number): Promise<string> {
|
|
34
65
|
this._checkRange(range);
|
|
35
|
-
const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
|
|
36
|
-
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
37
66
|
|
|
38
|
-
|
|
39
|
-
return formatUnits(await contract.max_borrowable(_collateral, range, 0, this.llamalend.constantOptions), this.market.borrowed_token.decimals);
|
|
67
|
+
return formatUnits(await this._maxBorrowable(collateral, range), this.market.borrowed_token.decimals);
|
|
40
68
|
}
|
|
41
69
|
|
|
42
70
|
public createLoanMaxRecvAllRanges = memoize(async (collateral: number | string): Promise<{ [index: number]: string }> => {
|
|
@@ -44,8 +72,7 @@ export class LoanBaseModule {
|
|
|
44
72
|
|
|
45
73
|
const calls = [];
|
|
46
74
|
for (let N = this.market.minBands; N <= this.market.maxBands; N++) {
|
|
47
|
-
|
|
48
|
-
calls.push(this.llamalend.contracts[this.market.addresses.controller].multicallContract.max_borrowable(_collateral, N, 0));
|
|
75
|
+
calls.push(this._getMaxBorrowableCall(_collateral, N));
|
|
49
76
|
}
|
|
50
77
|
const _amounts = await this.llamalend.multicallProvider.all(calls) as bigint[];
|
|
51
78
|
|
|
@@ -70,21 +97,6 @@ export class LoanBaseModule {
|
|
|
70
97
|
return this.market.maxBands;
|
|
71
98
|
}
|
|
72
99
|
|
|
73
|
-
private async _calcN1(_collateral: bigint, _debt: bigint, range: number): Promise<bigint> {
|
|
74
|
-
this._checkRange(range);
|
|
75
|
-
// TODO: add 4th parameter - user address in calculate_debt_n1
|
|
76
|
-
return await this.llamalend.contracts[this.market.addresses.controller].contract.calculate_debt_n1(_collateral, _debt, range, this.llamalend.constantOptions);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
private async _calcN1AllRanges(_collateral: bigint, _debt: bigint, maxN: number): Promise<bigint[]> {
|
|
80
|
-
const calls = [];
|
|
81
|
-
// TODO: add 4th parameter - user address in calculate_debt_n1
|
|
82
|
-
for (let N = this.market.minBands; N <= maxN; N++) {
|
|
83
|
-
calls.push(this.llamalend.contracts[this.market.addresses.controller].multicallContract.calculate_debt_n1(_collateral, _debt, N));
|
|
84
|
-
}
|
|
85
|
-
return await this.llamalend.multicallProvider.all(calls) as bigint[];
|
|
86
|
-
}
|
|
87
|
-
|
|
88
100
|
private async _createLoanBands(collateral: number | string, debt: number | string, range: number): Promise<[bigint, bigint]> {
|
|
89
101
|
const _n1 = await this._calcN1(parseUnits(collateral, this.market.collateral_token.decimals), parseUnits(debt, this.market.borrowed_token.decimals), range);
|
|
90
102
|
const _n2 = _n1 + BigInt(range - 1);
|
|
@@ -150,17 +162,6 @@ export class LoanBaseModule {
|
|
|
150
162
|
return pricesAllRanges;
|
|
151
163
|
}
|
|
152
164
|
|
|
153
|
-
public async createLoanHealth(collateral: number | string, debt: number | string, range: number, full = true): Promise<string> {
|
|
154
|
-
const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
|
|
155
|
-
const _debt = parseUnits(debt, this.market.borrowed_token.decimals);
|
|
156
|
-
|
|
157
|
-
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
158
|
-
|
|
159
|
-
const _health = await contract.health_calculator(this.llamalend.constants.ZERO_ADDRESS, _collateral, _debt, full, range, this.llamalend.constantOptions) as bigint;
|
|
160
|
-
|
|
161
|
-
return formatUnits(_health * BigInt(100));
|
|
162
|
-
}
|
|
163
|
-
|
|
164
165
|
public async createLoanIsApproved(collateral: number | string): Promise<boolean> {
|
|
165
166
|
return await hasAllowance.call(this.llamalend, [this.market.collateral_token.address], [collateral], this.llamalend.signerAddress, this.market.addresses.controller);
|
|
166
167
|
}
|
|
@@ -179,14 +180,7 @@ export class LoanBaseModule {
|
|
|
179
180
|
|
|
180
181
|
const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
|
|
181
182
|
const _debt = parseUnits(debt, this.market.borrowed_token.decimals);
|
|
182
|
-
|
|
183
|
-
const gas = await contract.create_loan.estimateGas(_collateral, _debt, range, { ...this.llamalend.constantOptions });
|
|
184
|
-
if (estimateGas) return smartNumber(gas);
|
|
185
|
-
|
|
186
|
-
await this.llamalend.updateFeeData();
|
|
187
|
-
const gasLimit = _mulBy1_3(DIGas(gas));
|
|
188
|
-
// TODO: ABI has changed (see docs)
|
|
189
|
-
return (await contract.create_loan(_collateral, _debt, range, { ...this.llamalend.options, gasLimit })).hash
|
|
183
|
+
return this._createLoanContractCall(_collateral, _debt, range, estimateGas);
|
|
190
184
|
}
|
|
191
185
|
|
|
192
186
|
public async createLoanEstimateGas(collateral: number | string, debt: number | string, range: number): Promise<TGas> {
|
|
@@ -202,13 +196,7 @@ export class LoanBaseModule {
|
|
|
202
196
|
// ---------------- BORROW MORE ----------------
|
|
203
197
|
|
|
204
198
|
public async borrowMoreMaxRecv(collateralAmount: number | string): Promise<string> {
|
|
205
|
-
|
|
206
|
-
const _collateral = _currentCollateral + parseUnits(collateralAmount, this.market.collateral_token.decimals);
|
|
207
|
-
|
|
208
|
-
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
209
|
-
const _debt: bigint = await contract.max_borrowable(_collateral, _N, _currentDebt, this.llamalend.constantOptions);
|
|
210
|
-
// TODO: max_borrowable(deltaCollateral, _N, user) - debt is now calculated under the hood, return as is
|
|
211
|
-
return formatUnits(_debt - _currentDebt, this.market.borrowed_token.decimals);
|
|
199
|
+
return formatUnits(await this._maxBorrowable(collateralAmount), this.market.borrowed_token.decimals);
|
|
212
200
|
}
|
|
213
201
|
|
|
214
202
|
private async _borrowMoreBands(collateral: number | string, debt: number | string): Promise<[bigint, bigint]> {
|
|
@@ -236,17 +224,6 @@ export class LoanBaseModule {
|
|
|
236
224
|
return await this.market.prices.getPrices(_n2, _n1);
|
|
237
225
|
}
|
|
238
226
|
|
|
239
|
-
public async borrowMoreHealth(collateral: number | string, debt: number | string, full = true, address = ""): Promise<string> {
|
|
240
|
-
address = _getAddress.call(this.llamalend, address);
|
|
241
|
-
const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
|
|
242
|
-
const _debt = parseUnits(debt, this.market.borrowed_token.decimals);
|
|
243
|
-
|
|
244
|
-
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
245
|
-
const _health = await contract.health_calculator(address, _collateral, _debt, full, 0, this.llamalend.constantOptions) as bigint;
|
|
246
|
-
|
|
247
|
-
return formatUnits(_health * BigInt(100));
|
|
248
|
-
}
|
|
249
|
-
|
|
250
227
|
public async borrowMoreIsApproved(collateral: number | string): Promise<boolean> {
|
|
251
228
|
return await hasAllowance.call(this.llamalend, [this.market.addresses.collateral_token], [collateral], this.llamalend.signerAddress, this.market.addresses.controller);
|
|
252
229
|
}
|
|
@@ -266,13 +243,7 @@ export class LoanBaseModule {
|
|
|
266
243
|
|
|
267
244
|
const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
|
|
268
245
|
const _debt = parseUnits(debt, this.market.borrowed_token.decimals);
|
|
269
|
-
|
|
270
|
-
const gas = await contract.borrow_more.estimateGas(_collateral, _debt, { ...this.llamalend.constantOptions });
|
|
271
|
-
if (estimateGas) return smartNumber(gas);
|
|
272
|
-
|
|
273
|
-
await this.llamalend.updateFeeData();
|
|
274
|
-
const gasLimit = _mulBy1_3(DIGas(gas));
|
|
275
|
-
return (await contract.borrow_more(_collateral, _debt, { ...this.llamalend.options, gasLimit })).hash
|
|
246
|
+
return this._borrowMoreContractCall(_collateral, _debt, estimateGas);
|
|
276
247
|
}
|
|
277
248
|
|
|
278
249
|
public async borrowMoreEstimateGas(collateral: number | string, debt: number | string): Promise<TGas> {
|
|
@@ -323,16 +294,6 @@ export class LoanBaseModule {
|
|
|
323
294
|
return await this.market.prices.getPrices(_n2, _n1);
|
|
324
295
|
}
|
|
325
296
|
|
|
326
|
-
public async addCollateralHealth(collateral: number | string, full = true, address = ""): Promise<string> {
|
|
327
|
-
address = _getAddress.call(this.llamalend, address);
|
|
328
|
-
const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
|
|
329
|
-
|
|
330
|
-
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
331
|
-
const _health = await contract.health_calculator(address, _collateral, 0, full, 0, this.llamalend.constantOptions) as bigint;
|
|
332
|
-
|
|
333
|
-
return formatUnits(_health * BigInt(100));
|
|
334
|
-
}
|
|
335
|
-
|
|
336
297
|
public async addCollateralIsApproved(collateral: number | string): Promise<boolean> {
|
|
337
298
|
return await hasAllowance.call(this.llamalend, [this.market.addresses.collateral_token], [collateral], this.llamalend.signerAddress, this.market.addresses.controller);
|
|
338
299
|
}
|
|
@@ -416,16 +377,6 @@ export class LoanBaseModule {
|
|
|
416
377
|
return await this.market.prices.getPrices(_n2, _n1);
|
|
417
378
|
}
|
|
418
379
|
|
|
419
|
-
public async removeCollateralHealth(collateral: number | string, full = true, address = ""): Promise<string> {
|
|
420
|
-
address = _getAddress.call(this.llamalend, address);
|
|
421
|
-
const _collateral = parseUnits(collateral, this.market.collateral_token.decimals) * BigInt(-1);
|
|
422
|
-
|
|
423
|
-
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
424
|
-
const _health = await contract.health_calculator(address, _collateral, 0, full, 0, this.llamalend.constantOptions) as bigint;
|
|
425
|
-
|
|
426
|
-
return formatUnits(_health * BigInt(100));
|
|
427
|
-
}
|
|
428
|
-
|
|
429
380
|
private async _removeCollateral(collateral: number | string, estimateGas: boolean): Promise<string | TGas> {
|
|
430
381
|
const { borrowed, debt: currentDebt } = await this.market.userPosition.userState();
|
|
431
382
|
if (Number(currentDebt) === 0) throw Error(`Loan for ${this.llamalend.signerAddress} does not exist`);
|
|
@@ -462,32 +413,6 @@ export class LoanBaseModule {
|
|
|
462
413
|
}
|
|
463
414
|
|
|
464
415
|
// ---------------- REPAY ----------------
|
|
465
|
-
// TODO: add shrink: bool parameter
|
|
466
|
-
// If bool is true, _N = n2 - n1 + 1 -> _N = n2 - activeBand
|
|
467
|
-
private async _repayBands(debt: number | string, address: string): Promise<[bigint, bigint]> {
|
|
468
|
-
const { _collateral: _currentCollateral, _borrowed, _debt: _currentDebt, _N } = await this.market.userPosition.userStateBigInt(address);
|
|
469
|
-
if (_currentDebt === BigInt(0)) throw Error(`Loan for ${address} does not exist`);
|
|
470
|
-
// && shrink === false
|
|
471
|
-
if (_borrowed > BigInt(0)) return await this.market.userPosition.userBandsBigInt(address) as [bigint, bigint];
|
|
472
|
-
// If shrink == true, then _debt = _currentDebt - parseUnits(debt, this.market.borrowed_token.decimals) - _borrowed
|
|
473
|
-
const _debt = _currentDebt - parseUnits(debt, this.market.borrowed_token.decimals);
|
|
474
|
-
const _n1 = await this._calcN1(_currentCollateral, _debt, Number(_N));
|
|
475
|
-
const _n2 = _n1 + _N - BigInt(1);
|
|
476
|
-
|
|
477
|
-
return [_n2, _n1];
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
public async repayBands(debt: number | string, address = ""): Promise<[number, number]> {
|
|
481
|
-
const [_n2, _n1] = await this._repayBands(debt, address);
|
|
482
|
-
|
|
483
|
-
return [Number(_n2), Number(_n1)];
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
public async repayPrices(debt: number | string, address = ""): Promise<string[]> {
|
|
487
|
-
const [_n2, _n1] = await this._repayBands(debt, address);
|
|
488
|
-
|
|
489
|
-
return await this.market.prices.getPrices(_n2, _n1);
|
|
490
|
-
}
|
|
491
416
|
|
|
492
417
|
public async repayIsApproved(debt: number | string): Promise<boolean> {
|
|
493
418
|
return await hasAllowance.call(this.llamalend, [this.market.borrowed_token.address], [debt], this.llamalend.signerAddress, this.market.addresses.controller);
|
|
@@ -501,33 +426,26 @@ export class LoanBaseModule {
|
|
|
501
426
|
return await ensureAllowance.call(this.llamalend, [this.market.borrowed_token.address], [debt], this.market.addresses.controller);
|
|
502
427
|
}
|
|
503
428
|
|
|
504
|
-
private async _repay(debt: number | string, address: string, estimateGas: boolean): Promise<string | TGas> {
|
|
429
|
+
private async _repay(debt: number | string, address: string, estimateGas: boolean, shrink = false): Promise<string | TGas> {
|
|
505
430
|
address = _getAddress.call(this.llamalend, address);
|
|
506
431
|
const { debt: currentDebt } = await this.market.userPosition.userState(address);
|
|
507
432
|
if (Number(currentDebt) === 0) throw Error(`Loan for ${address} does not exist`);
|
|
508
433
|
|
|
509
434
|
const _debt = parseUnits(debt);
|
|
510
|
-
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
511
435
|
const [, n1] = await this.market.userPosition.userBands(address);
|
|
512
436
|
const { borrowed } = await this.market.userPosition.userState(address);
|
|
513
|
-
const n = (BN(borrowed).gt(0)) ? MAX_ACTIVE_BAND : n1 - 1;
|
|
514
|
-
|
|
515
|
-
if (estimateGas) return smartNumber(gas);
|
|
516
|
-
|
|
517
|
-
await this.llamalend.updateFeeData();
|
|
518
|
-
const gasLimit = _mulBy1_3(DIGas(gas));
|
|
519
|
-
// TODO: shrink parameter is added, which changes bands calculation
|
|
520
|
-
return (await contract.repay(_debt, address, n, { ...this.llamalend.options, gasLimit })).hash
|
|
437
|
+
const n = (BN(borrowed).gt(0)) ? MAX_ACTIVE_BAND : n1 - 1;
|
|
438
|
+
return this._repayContractCall({ _debt, address, n, estimateGas, shrink });
|
|
521
439
|
}
|
|
522
440
|
|
|
523
|
-
public async repayEstimateGas(debt: number | string
|
|
441
|
+
public async repayEstimateGas({ debt, address = "", shrink = false }: { debt: number | string; address?: string; shrink?: boolean }): Promise<TGas> {
|
|
524
442
|
if (!(await this.repayIsApproved(debt))) throw Error("Approval is needed for gas estimation");
|
|
525
|
-
return await this._repay(debt, address, true) as TGas;
|
|
443
|
+
return await this._repay(debt, address, true, shrink) as TGas;
|
|
526
444
|
}
|
|
527
445
|
|
|
528
|
-
public async repay(debt: number | string
|
|
446
|
+
public async repay({ debt, address = "", shrink = false }: { debt: number | string; address?: string; shrink?: boolean }): Promise<string> {
|
|
529
447
|
await this.repayApprove(debt);
|
|
530
|
-
return await this._repay(debt, address, false) as string;
|
|
448
|
+
return await this._repay(debt, address, false, shrink) as string;
|
|
531
449
|
}
|
|
532
450
|
|
|
533
451
|
public async repayFutureLeverage(debt: number | string, userAddress = ''): Promise<string> {
|
|
@@ -661,28 +579,7 @@ export class LoanBaseModule {
|
|
|
661
579
|
const minAmountBN = expectedBorrowedBN.times(100 - slippage).div(100);
|
|
662
580
|
const _minAmount = fromBN(minAmountBN);
|
|
663
581
|
|
|
664
|
-
|
|
665
|
-
const gas = (await contract.liquidate_extended.estimateGas(
|
|
666
|
-
address,
|
|
667
|
-
_minAmount,
|
|
668
|
-
frac,
|
|
669
|
-
this.llamalend.constants.ZERO_ADDRESS,
|
|
670
|
-
[],
|
|
671
|
-
this.llamalend.constantOptions
|
|
672
|
-
));
|
|
673
|
-
|
|
674
|
-
if (estimateGas) return smartNumber(gas);
|
|
675
|
-
|
|
676
|
-
await this.llamalend.updateFeeData();
|
|
677
|
-
const gasLimit = _mulBy1_3(DIGas(gas));
|
|
678
|
-
return (await contract.liquidate_extended(
|
|
679
|
-
address,
|
|
680
|
-
_minAmount,
|
|
681
|
-
frac,
|
|
682
|
-
this.llamalend.constants.ZERO_ADDRESS,
|
|
683
|
-
[],
|
|
684
|
-
{ ...this.llamalend.options, gasLimit }
|
|
685
|
-
)).hash;
|
|
582
|
+
return this._partialLiquidateContractCall(address, _minAmount, frac, estimateGas);
|
|
686
583
|
}
|
|
687
584
|
|
|
688
585
|
public async liquidateEstimateGas(address: string, slippage = 0.1): Promise<TGas> {
|
|
@@ -1,9 +1,172 @@
|
|
|
1
1
|
import { LoanBaseModule } from "../common/loanBase.js";
|
|
2
2
|
import { ILoanV1 } from "../../interfaces/v1/loanV1";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
_getAddress,
|
|
5
|
+
formatUnits,
|
|
6
|
+
parseUnits,
|
|
7
|
+
smartNumber,
|
|
8
|
+
_mulBy1_3,
|
|
9
|
+
DIGas,
|
|
10
|
+
} from "../../../utils";
|
|
11
|
+
import { TGas, TAmount } from "../../../interfaces";
|
|
4
12
|
|
|
5
13
|
export class LoanV1Module extends LoanBaseModule implements ILoanV1 {
|
|
6
|
-
|
|
14
|
+
protected _maxBorrowable = async (collateralAmount: TAmount, range?: number): Promise<bigint> => {
|
|
15
|
+
const { _collateral: _currentCollateral, _debt: _currentDebt, _N } = await this.market.userPosition.userStateBigInt();
|
|
16
|
+
const _collateral = _currentCollateral + parseUnits(collateralAmount, this.market.collateral_token.decimals);
|
|
17
|
+
const N = range ? BigInt(range) : _N;
|
|
18
|
+
|
|
19
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
20
|
+
return (await contract.max_borrowable(_collateral, N, _currentDebt, this.llamalend.constantOptions) - _currentDebt);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
protected _getMaxBorrowableCall(_collateral: bigint, N: number): any {
|
|
24
|
+
return this.llamalend.contracts[this.market.addresses.controller].multicallContract.max_borrowable(_collateral, N, 0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
protected async _calcN1(_collateral: bigint, _debt: bigint, range: number): Promise<bigint> {
|
|
28
|
+
this._checkRange(range);
|
|
29
|
+
|
|
30
|
+
return await this.llamalend.contracts[this.market.addresses.controller].contract.calculate_debt_n1(_collateral, _debt, range, this.llamalend.constantOptions);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
protected async _calcN1AllRanges(_collateral: bigint, _debt: bigint, maxN: number): Promise<bigint[]> {
|
|
34
|
+
const calls = [];
|
|
35
|
+
|
|
36
|
+
for (let N = this.market.minBands; N <= maxN; N++) {
|
|
37
|
+
calls.push(this.llamalend.contracts[this.market.addresses.controller].multicallContract.calculate_debt_n1(_collateral, _debt, N));
|
|
38
|
+
}
|
|
39
|
+
return await this.llamalend.multicallProvider.all(calls) as bigint[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public async createLoanHealth(collateral: number | string, debt: number | string, range: number, full = true): Promise<string> {
|
|
43
|
+
const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
|
|
44
|
+
const _debt = parseUnits(debt, this.market.borrowed_token.decimals);
|
|
45
|
+
|
|
46
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
47
|
+
const _health = await contract.health_calculator(this.llamalend.constants.ZERO_ADDRESS, _collateral, _debt, full, range, this.llamalend.constantOptions) as bigint;
|
|
48
|
+
|
|
49
|
+
return formatUnits(_health * BigInt(100));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public async borrowMoreHealth(collateral: number | string, debt: number | string, full = true, address = ""): Promise<string> {
|
|
53
|
+
address = _getAddress.call(this.llamalend, address);
|
|
54
|
+
const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
|
|
55
|
+
const _debt = parseUnits(debt, this.market.borrowed_token.decimals);
|
|
56
|
+
|
|
57
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
58
|
+
const _health = await contract.health_calculator(address, _collateral, _debt, full, 0, this.llamalend.constantOptions) as bigint;
|
|
59
|
+
|
|
60
|
+
return formatUnits(_health * BigInt(100));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public async addCollateralHealth(collateral: number | string, full = true, address = ""): Promise<string> {
|
|
64
|
+
address = _getAddress.call(this.llamalend, address);
|
|
65
|
+
const _collateral = parseUnits(collateral, this.market.collateral_token.decimals);
|
|
66
|
+
|
|
67
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
68
|
+
const _health = await contract.health_calculator(address, _collateral, 0, full, 0, this.llamalend.constantOptions) as bigint;
|
|
69
|
+
|
|
70
|
+
return formatUnits(_health * BigInt(100));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public async removeCollateralHealth(collateral: number | string, full = true, address = ""): Promise<string> {
|
|
74
|
+
address = _getAddress.call(this.llamalend, address);
|
|
75
|
+
const _collateral = parseUnits(collateral, this.market.collateral_token.decimals) * BigInt(-1);
|
|
76
|
+
|
|
77
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
78
|
+
const _health = await contract.health_calculator(address, _collateral, 0, full, 0, this.llamalend.constantOptions) as bigint;
|
|
79
|
+
|
|
80
|
+
return formatUnits(_health * BigInt(100));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
protected async _repayBands({ debt, address }: { debt: number | string, address: string, shrink?: boolean }): Promise<[bigint, bigint]> {
|
|
84
|
+
const { _collateral: _currentCollateral, _borrowed, _debt: _currentDebt, _N } = await this.market.userPosition.userStateBigInt(address);
|
|
85
|
+
if (_currentDebt === BigInt(0)) throw Error(`Loan for ${address} does not exist`);
|
|
86
|
+
if (_borrowed > BigInt(0)) return await this.market.userPosition.userBandsBigInt(address) as [bigint, bigint];
|
|
87
|
+
const _debt = _currentDebt - parseUnits(debt, this.market.borrowed_token.decimals);
|
|
88
|
+
const _n1 = await this._calcN1(_currentCollateral, _debt, Number(_N));
|
|
89
|
+
const _n2 = _n1 + _N - BigInt(1);
|
|
90
|
+
|
|
91
|
+
return [_n2, _n1];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public async repayBands({ debt, address = "" }: { debt: number | string; address?: string }): Promise<[number, number]> {
|
|
95
|
+
const [_n2, _n1] = await this._repayBands({ debt, address });
|
|
96
|
+
|
|
97
|
+
return [Number(_n2), Number(_n1)];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public async repayPrices({ debt, address = "" }: { debt: number | string; address?: string }): Promise<string[]> {
|
|
101
|
+
const [_n2, _n1] = await this._repayBands({ debt, address });
|
|
102
|
+
|
|
103
|
+
return await this.market.prices.getPrices(_n2, _n1);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
protected async _repayContractCall(
|
|
107
|
+
{ _debt, address, n, estimateGas }: { _debt: bigint, address: string, n: number | bigint, estimateGas: boolean, shrink?: boolean }
|
|
108
|
+
): Promise<string | TGas> {
|
|
109
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
110
|
+
const gas = await contract.repay.estimateGas(_debt, address, n, this.llamalend.constantOptions);
|
|
111
|
+
if (estimateGas) return smartNumber(gas);
|
|
112
|
+
|
|
113
|
+
await this.llamalend.updateFeeData();
|
|
114
|
+
const gasLimit = _mulBy1_3(DIGas(gas));
|
|
115
|
+
return (await contract.repay(_debt, address, n, { ...this.llamalend.options, gasLimit })).hash;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
protected async _createLoanContractCall(
|
|
119
|
+
_collateral: bigint, _debt: bigint, range: number, estimateGas: boolean
|
|
120
|
+
): Promise<string | TGas> {
|
|
121
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
122
|
+
const gas = await contract.create_loan.estimateGas(_collateral, _debt, range, { ...this.llamalend.constantOptions });
|
|
123
|
+
if (estimateGas) return smartNumber(gas);
|
|
124
|
+
|
|
125
|
+
await this.llamalend.updateFeeData();
|
|
126
|
+
const gasLimit = _mulBy1_3(DIGas(gas));
|
|
127
|
+
return (await contract.create_loan(_collateral, _debt, range, { ...this.llamalend.options, gasLimit })).hash;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
protected async _borrowMoreContractCall(
|
|
131
|
+
_collateral: bigint, _debt: bigint, estimateGas: boolean
|
|
132
|
+
): Promise<string | TGas> {
|
|
133
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
134
|
+
const gas = await contract.borrow_more.estimateGas(_collateral, _debt, { ...this.llamalend.constantOptions });
|
|
135
|
+
if (estimateGas) return smartNumber(gas);
|
|
136
|
+
|
|
137
|
+
await this.llamalend.updateFeeData();
|
|
138
|
+
const gasLimit = _mulBy1_3(DIGas(gas));
|
|
139
|
+
return (await contract.borrow_more(_collateral, _debt, { ...this.llamalend.options, gasLimit })).hash;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
protected async _partialLiquidateContractCall(
|
|
143
|
+
address: string, _minAmount: bigint, frac: string, estimateGas: boolean
|
|
144
|
+
): Promise<string | TGas> {
|
|
145
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
146
|
+
const gas = (await contract.liquidate_extended.estimateGas(
|
|
147
|
+
address,
|
|
148
|
+
_minAmount,
|
|
149
|
+
frac,
|
|
150
|
+
this.llamalend.constants.ZERO_ADDRESS,
|
|
151
|
+
[],
|
|
152
|
+
this.llamalend.constantOptions
|
|
153
|
+
));
|
|
154
|
+
|
|
155
|
+
if (estimateGas) return smartNumber(gas);
|
|
156
|
+
|
|
157
|
+
await this.llamalend.updateFeeData();
|
|
158
|
+
const gasLimit = _mulBy1_3(DIGas(gas));
|
|
159
|
+
return (await contract.liquidate_extended(
|
|
160
|
+
address,
|
|
161
|
+
_minAmount,
|
|
162
|
+
frac,
|
|
163
|
+
this.llamalend.constants.ZERO_ADDRESS,
|
|
164
|
+
[],
|
|
165
|
+
{ ...this.llamalend.options, gasLimit }
|
|
166
|
+
)).hash;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public async repayHealth({ debt, full = true, address = "" }: { debt: number | string; full?: boolean; address?: string }): Promise<string> {
|
|
7
170
|
address = _getAddress.call(this.llamalend, address);
|
|
8
171
|
const _debt = parseUnits(debt) * BigInt(-1);
|
|
9
172
|
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { LoanBaseModule } from "../common/loanBase.js";
|
|
2
2
|
import { ILoanV2 } from "../../interfaces/v2";
|
|
3
|
-
import {
|
|
3
|
+
import { TGas, TAmount } from "../../../interfaces";
|
|
4
|
+
import {
|
|
5
|
+
_getAddress,
|
|
6
|
+
formatUnits,
|
|
7
|
+
parseUnits,
|
|
8
|
+
smartNumber,
|
|
9
|
+
_mulBy1_3,
|
|
10
|
+
DIGas,
|
|
11
|
+
} from "../../../utils";
|
|
4
12
|
|
|
5
13
|
export class LoanV2Module extends LoanBaseModule implements ILoanV2 {
|
|
6
14
|
public async createLoanHealth(collateral: number | string, debt: number | string, range: number, full = true): Promise<string> {
|
|
@@ -46,7 +54,7 @@ export class LoanV2Module extends LoanBaseModule implements ILoanV2 {
|
|
|
46
54
|
return formatUnits(_health * BigInt(100));
|
|
47
55
|
}
|
|
48
56
|
|
|
49
|
-
public async repayHealth(debt
|
|
57
|
+
public async repayHealth({ debt, shrink = false, full = true, address = "" }: { debt: number | string; shrink?: boolean; full?: boolean; address?: string }): Promise<string> {
|
|
50
58
|
address = _getAddress.call(this.llamalend, address);
|
|
51
59
|
const _debt = parseUnits(debt);
|
|
52
60
|
|
|
@@ -55,4 +63,158 @@ export class LoanV2Module extends LoanBaseModule implements ILoanV2 {
|
|
|
55
63
|
|
|
56
64
|
return formatUnits(_health * BigInt(100));
|
|
57
65
|
}
|
|
66
|
+
|
|
67
|
+
protected _maxBorrowable = async (collateralAmount: TAmount, range?: number): Promise<bigint> => {
|
|
68
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
69
|
+
const collateral = parseUnits(collateralAmount, this.market.collateral_token.decimals)
|
|
70
|
+
const address = _getAddress.call(this.llamalend, '');
|
|
71
|
+
const N = range ? BigInt(range) : null;
|
|
72
|
+
|
|
73
|
+
return contract.max_borrowable(collateral, N, address, this.llamalend.constantOptions);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
protected async _calcN1(_collateral: bigint, _debt: bigint, range: number): Promise<bigint> {
|
|
77
|
+
this._checkRange(range);
|
|
78
|
+
const address = _getAddress.call(this.llamalend, '');
|
|
79
|
+
|
|
80
|
+
return await this.llamalend.contracts[this.market.addresses.controller].contract.calculate_debt_n1(_collateral, _debt, range, address, this.llamalend.constantOptions);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
protected async _calcN1AllRanges(_collateral: bigint, _debt: bigint, maxN: number): Promise<bigint[]> {
|
|
84
|
+
const calls = [];
|
|
85
|
+
const address = _getAddress.call(this.llamalend, '');
|
|
86
|
+
|
|
87
|
+
for (let N = this.market.minBands; N <= maxN; N++) {
|
|
88
|
+
calls.push(this.llamalend.contracts[this.market.addresses.controller].multicallContract.calculate_debt_n1(_collateral, _debt, N, address));
|
|
89
|
+
}
|
|
90
|
+
return await this.llamalend.multicallProvider.all(calls) as bigint[];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
protected _getMaxBorrowableCall(_collateral: bigint, N: number): any {
|
|
94
|
+
const address = _getAddress.call(this.llamalend, '');
|
|
95
|
+
return this.llamalend.contracts[this.market.addresses.controller].multicallContract.max_borrowable(_collateral, N, address);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
protected async _repayBands({ debt, address, shrink = false }: { debt: number | string, address: string, shrink?: boolean }): Promise<[bigint, bigint]> {
|
|
99
|
+
const { _collateral: _currentCollateral, _borrowed, _debt: _currentDebt, _N } = await this.market.userPosition.userStateBigInt(address);
|
|
100
|
+
if (_currentDebt === BigInt(0)) throw Error(`Loan for ${address} does not exist`);
|
|
101
|
+
|
|
102
|
+
if (_borrowed > BigInt(0) && !shrink) {
|
|
103
|
+
return await this.market.userPosition.userBandsBigInt(address) as [bigint, bigint];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const _debtRepaid = parseUnits(debt, this.market.borrowed_token.decimals);
|
|
107
|
+
|
|
108
|
+
let newN = _N;
|
|
109
|
+
let _debt: bigint;
|
|
110
|
+
|
|
111
|
+
if (shrink) {
|
|
112
|
+
_debt = _currentDebt - _debtRepaid - _borrowed;
|
|
113
|
+
const [n2] = await this.market.userPosition.userBandsBigInt(address) as [bigint, bigint];
|
|
114
|
+
const { activeBand } = await this.market.stats.bandsInfo();
|
|
115
|
+
newN = n2 - BigInt(activeBand);
|
|
116
|
+
} else {
|
|
117
|
+
_debt = _currentDebt - _debtRepaid;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const _n1 = await this._calcN1(_currentCollateral, _debt, Number(newN));
|
|
121
|
+
const _n2 = _n1 + newN - BigInt(1);
|
|
122
|
+
|
|
123
|
+
return [_n2, _n1];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public async repayBands({ debt, address = "", shrink = false }: { debt: number | string; address?: string; shrink?: boolean }): Promise<[number, number]> {
|
|
127
|
+
const [_n2, _n1] = await this._repayBands({ debt, address, shrink });
|
|
128
|
+
|
|
129
|
+
return [Number(_n2), Number(_n1)];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
public async repayPrices({ debt, address = "", shrink = false }: { debt: number | string; address?: string; shrink?: boolean }): Promise<string[]> {
|
|
133
|
+
const [_n2, _n1] = await this._repayBands({ debt, address, shrink });
|
|
134
|
+
|
|
135
|
+
return await this.market.prices.getPrices(_n2, _n1);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
protected async _createLoanContractCall(
|
|
139
|
+
_collateral: bigint, _debt: bigint, range: number, estimateGas: boolean
|
|
140
|
+
): Promise<string | TGas> {
|
|
141
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
142
|
+
const _for = _getAddress.call(this.llamalend, '');
|
|
143
|
+
const gas = await contract.create_loan.estimateGas(
|
|
144
|
+
_collateral, _debt, range, _for,
|
|
145
|
+
this.llamalend.constants.ZERO_ADDRESS, "0x",
|
|
146
|
+
{ ...this.llamalend.constantOptions }
|
|
147
|
+
);
|
|
148
|
+
if (estimateGas) return smartNumber(gas);
|
|
149
|
+
|
|
150
|
+
await this.llamalend.updateFeeData();
|
|
151
|
+
const gasLimit = _mulBy1_3(DIGas(gas));
|
|
152
|
+
return (await contract.create_loan(
|
|
153
|
+
_collateral, _debt, range, _for,
|
|
154
|
+
this.llamalend.constants.ZERO_ADDRESS, "0x",
|
|
155
|
+
{ ...this.llamalend.options, gasLimit }
|
|
156
|
+
)).hash;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
protected async _borrowMoreContractCall(
|
|
160
|
+
_collateral: bigint, _debt: bigint, estimateGas: boolean
|
|
161
|
+
): Promise<string | TGas> {
|
|
162
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
163
|
+
const _for = _getAddress.call(this.llamalend, '');
|
|
164
|
+
const gas = await contract.borrow_more.estimateGas(
|
|
165
|
+
_collateral, _debt, _for,
|
|
166
|
+
this.llamalend.constants.ZERO_ADDRESS, "0x",
|
|
167
|
+
{ ...this.llamalend.constantOptions }
|
|
168
|
+
);
|
|
169
|
+
if (estimateGas) return smartNumber(gas);
|
|
170
|
+
|
|
171
|
+
await this.llamalend.updateFeeData();
|
|
172
|
+
const gasLimit = _mulBy1_3(DIGas(gas));
|
|
173
|
+
return (await contract.borrow_more(
|
|
174
|
+
_collateral, _debt, _for,
|
|
175
|
+
this.llamalend.constants.ZERO_ADDRESS, "0x",
|
|
176
|
+
{ ...this.llamalend.options, gasLimit }
|
|
177
|
+
)).hash;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
protected async _repayContractCall(
|
|
181
|
+
{ _debt, address, n, estimateGas, shrink = false }: { _debt: bigint, address: string, n: number | bigint, estimateGas: boolean, shrink?: boolean }
|
|
182
|
+
): Promise<string | TGas> {
|
|
183
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
184
|
+
const gas = await contract.repay.estimateGas(
|
|
185
|
+
_debt, address, n,
|
|
186
|
+
this.llamalend.constants.ZERO_ADDRESS, "0x", shrink,
|
|
187
|
+
{ ...this.llamalend.constantOptions }
|
|
188
|
+
);
|
|
189
|
+
if (estimateGas) return smartNumber(gas);
|
|
190
|
+
|
|
191
|
+
await this.llamalend.updateFeeData();
|
|
192
|
+
const gasLimit = _mulBy1_3(DIGas(gas));
|
|
193
|
+
return (await contract.repay(
|
|
194
|
+
_debt, address, n,
|
|
195
|
+
this.llamalend.constants.ZERO_ADDRESS, "0x", shrink,
|
|
196
|
+
{ ...this.llamalend.options, gasLimit }
|
|
197
|
+
)).hash;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
protected async _partialLiquidateContractCall(
|
|
201
|
+
address: string, _minAmount: bigint, frac: string, estimateGas: boolean
|
|
202
|
+
): Promise<string | TGas> {
|
|
203
|
+
const contract = this.llamalend.contracts[this.market.addresses.controller].contract;
|
|
204
|
+
const gas = await contract.liquidate.estimateGas(
|
|
205
|
+
address, _minAmount, frac,
|
|
206
|
+
this.llamalend.constants.ZERO_ADDRESS, "0x",
|
|
207
|
+
this.llamalend.constantOptions
|
|
208
|
+
);
|
|
209
|
+
if (estimateGas) return smartNumber(gas);
|
|
210
|
+
|
|
211
|
+
await this.llamalend.updateFeeData();
|
|
212
|
+
const gasLimit = _mulBy1_3(DIGas(gas));
|
|
213
|
+
return (await contract.liquidate(
|
|
214
|
+
address, _minAmount, frac,
|
|
215
|
+
this.llamalend.constants.ZERO_ADDRESS, "0x",
|
|
216
|
+
{ ...this.llamalend.options, gasLimit }
|
|
217
|
+
)).hash;
|
|
218
|
+
}
|
|
219
|
+
|
|
58
220
|
}
|