impermax-sdk 2.1.261 → 2.1.262

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.
@@ -1,4 +1,4 @@
1
- import Position from "../interface";
1
+ import GenericPosition from "../genericPosition";
2
2
  export interface UniswapV2PositionParams {
3
3
  liquidity: number;
4
4
  debtX: number;
@@ -11,121 +11,25 @@ export interface UniswapV2PositionParams {
11
11
  availableToBorrowY?: number;
12
12
  lockStateChange?: boolean;
13
13
  }
14
- export declare class UniswapV2Position implements Position {
15
- lockStateChange: boolean;
16
- state: number;
17
- /**
18
- * NOTICE all values inside this class are normalized (no decimals or mantissa to take into account)
19
- */
20
- liquidity: number;
21
- debtX: number;
22
- debtY: number;
23
- initialLiquidity: number;
24
- initialDebtX: number;
25
- initialDebtY: number;
26
- marketPrice: number;
27
- oraclePrice: number;
28
- safetyMargin: number;
29
- liquidationPenalty: number;
30
- availableToBorrowX: number;
31
- availableToBorrowY: number;
14
+ export declare class UniswapV2Position extends GenericPosition {
32
15
  constructor(params: UniswapV2PositionParams);
33
- private checkLock;
16
+ protected checkLock(): void;
34
17
  /**
35
- * PRIVATE SETTERS
18
+ * protected SETTERS
36
19
  */
37
- private setRealXRealY;
38
- private setRealX;
39
- private setRealY;
40
- private setDebtX;
41
- private setDebtY;
20
+ protected setLiquidity(liquidity: number): void;
42
21
  /**
43
- * PRIVATE GETTERS
22
+ * protected GETTERS
44
23
  */
45
- private getRealXGivenLiquidityAndPrice;
46
- private getRealYGivenLiquidityAndPrice;
47
- private getRealXGivenLiquidity;
48
- private getRealYGivenLiquidity;
49
- private getRealXGivenPrice;
50
- private getRealYGivenPrice;
51
- private getRealX;
52
- private getRealY;
53
- private getInitialRealX;
54
- private getInitialRealY;
55
- private getValueGivenPriceAndAmounts;
56
- private getValueGivenAmounts;
57
- private getAmountXGivenValue;
58
- private getAmountYGivenValue;
59
- private getInitialDebtValue;
60
- private getDebtValueGivenPrice;
61
- private getInitialCollateralValue;
62
- private getCollateralValueGivenPrice;
63
- private getCollateralValueGivenPriceAndDeltaLeverage;
64
- private getInitialEquityValue;
65
- private getEquityValueGivenPrice;
66
- private getDebtValue;
67
- private getCollateralValue;
68
- private getEquityValue;
69
- private getLiquidityPostLiquidationValueGivenPriceAndDebt;
70
- private getLiquidityPostLiquidationValueGivenPriceAndDeltaLeverage;
71
- private isLiquidatableGivenPriceAndDebt;
72
- private isLiquidatableGivenPriceAndDeltaLeverage;
73
- private isLiquidatableGivenDebt;
74
- private isLiquidatableGivenDeltaLeverage;
75
- private isLiquidatableGivenPrice;
76
- private isUnderwaterGivenPrice;
77
- private getLiquidationPriceInRange;
78
- private getMaxDeltaDebtInRange;
79
- private getMaxDeltaLeverageInRange;
80
- private getMinLeverageInRange;
81
- /**
82
- * PUBLIC SETTERS
83
- */
84
- depositX(amount: number): void;
85
- depositY(amount: number): void;
86
- withdrawX(amount: number): void;
87
- withdrawY(amount: number): void;
88
- borrowX(amount: number): void;
89
- borrowY(amount: number): void;
90
- repayX(amount: number): void;
91
- repayY(amount: number): void;
24
+ protected getRealXGivenLiquidityAndPrice(liquidity: number, price: number): number;
25
+ protected getRealYGivenLiquidityAndPrice(liquidity: number, price: number): number;
92
26
  /**
93
27
  * PUBLIC GETTERS
94
28
  */
95
- getInitialDepositedX(): number;
96
- getInitialDepositedY(): number;
97
- getDepositedX(): number;
98
- getDepositedY(): number;
99
- getNetX(): number;
100
- getNetY(): number;
101
- isLiquidatable(): boolean;
102
- isUnderwater(): boolean;
103
- getLiquidationRange(): {
104
- priceA: number;
105
- priceB: number;
106
- } | undefined;
107
- getInitialLeverage(): number;
108
- getLeverage(): number;
109
29
  getOptimalLiquidity(amountX: number, amountY: number): {
110
30
  liquidity: number;
111
31
  amountX: number;
112
32
  amountY: number;
113
33
  };
114
- getOptimalWithdraw(amountX: number, amountY: number, withdrawAtLeast?: boolean): {
115
- amountX: number;
116
- amountY: number;
117
- };
118
- getOptimalWithdrawForDeleverage(targetLeverage: number): {
119
- amountX: number;
120
- amountY: number;
121
- } | null;
122
- getMaxLeverage(): number;
123
- getMinLeverage(): number;
124
- getMaxWithdrawable(): {
125
- amountX: number;
126
- amountY: number;
127
- };
128
- getMaxBorrowableX(): number;
129
- getMaxBorrowableY(): number;
130
34
  }
131
35
  export default UniswapV2Position;
@@ -1,30 +1,13 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.UniswapV2Position = void 0;
4
- function getRealX(liquidity, price) {
5
- return liquidity / Math.sqrt(price);
6
- }
7
- function getRealY(liquidity, price) {
8
- return liquidity * Math.sqrt(price);
9
- }
10
- const LOWEST_PRICE = 1 / 1e18;
11
- const HIGHEST_PRICE = 1e18;
12
- class UniswapV2Position {
7
+ const genericPosition_1 = __importDefault(require("../genericPosition"));
8
+ class UniswapV2Position extends genericPosition_1.default {
13
9
  constructor(params) {
14
- this.liquidity = params.liquidity;
15
- this.debtX = params.debtX;
16
- this.debtY = params.debtY;
17
- this.initialLiquidity = params.liquidity;
18
- this.initialDebtX = params.debtX;
19
- this.initialDebtY = params.debtY;
20
- this.marketPrice = params.marketPrice;
21
- this.oraclePrice = params.oraclePrice;
22
- this.safetyMargin = params.safetyMargin;
23
- this.liquidationPenalty = params.liquidationPenalty;
24
- this.availableToBorrowX = params.availableToBorrowX ?? 0;
25
- this.availableToBorrowY = params.availableToBorrowY ?? 0;
26
- this.lockStateChange = params.lockStateChange ?? true;
27
- this.state = 0;
10
+ super(params);
28
11
  }
29
12
  checkLock() {
30
13
  if (this.lockStateChange)
@@ -33,297 +16,23 @@ class UniswapV2Position {
33
16
  this.state++;
34
17
  }
35
18
  /**
36
- * PRIVATE SETTERS
19
+ * protected SETTERS
37
20
  */
38
- setRealXRealY(amountX, amountY) {
39
- if (Number.isNaN(amountX))
40
- return;
41
- if (Number.isNaN(amountY))
42
- return;
43
- this.checkLock();
44
- const { liquidity } = this.getOptimalLiquidity(amountX, amountY);
45
- this.liquidity = liquidity;
46
- }
47
- setRealX(amountX) {
48
- if (Number.isNaN(amountX))
49
- return;
50
- this.checkLock();
51
- const { liquidity } = this.getOptimalLiquidity(amountX, Infinity);
52
- this.liquidity = liquidity;
53
- }
54
- setRealY(amountY) {
55
- if (Number.isNaN(amountY))
56
- return;
57
- this.checkLock();
58
- const { liquidity } = this.getOptimalLiquidity(Infinity, amountY);
21
+ setLiquidity(liquidity) {
59
22
  this.liquidity = liquidity;
60
23
  }
61
- setDebtX(_debtX) {
62
- if (Number.isNaN(_debtX))
63
- return;
64
- this.checkLock();
65
- this.debtX = _debtX;
66
- }
67
- setDebtY(_debtY) {
68
- if (Number.isNaN(_debtY))
69
- return;
70
- this.checkLock();
71
- this.debtY = _debtY;
72
- }
73
24
  /**
74
- * PRIVATE GETTERS
25
+ * protected GETTERS
75
26
  */
76
27
  getRealXGivenLiquidityAndPrice(liquidity, price) {
77
- return getRealX(liquidity, price);
28
+ return liquidity / Math.sqrt(price);
78
29
  }
79
30
  getRealYGivenLiquidityAndPrice(liquidity, price) {
80
- return getRealY(liquidity, price);
81
- }
82
- getRealXGivenLiquidity(liquidity) {
83
- return this.getRealXGivenLiquidityAndPrice(liquidity, this.marketPrice);
84
- }
85
- getRealYGivenLiquidity(liquidity) {
86
- return this.getRealYGivenLiquidityAndPrice(liquidity, this.marketPrice);
87
- }
88
- getRealXGivenPrice(price) {
89
- return this.getRealXGivenLiquidityAndPrice(this.liquidity, price);
90
- }
91
- getRealYGivenPrice(price) {
92
- return this.getRealYGivenLiquidityAndPrice(this.liquidity, price);
93
- }
94
- getRealX() {
95
- return this.getRealXGivenLiquidityAndPrice(this.liquidity, this.marketPrice);
96
- }
97
- getRealY() {
98
- return this.getRealYGivenLiquidityAndPrice(this.liquidity, this.marketPrice);
99
- }
100
- getInitialRealX() {
101
- return this.getRealXGivenLiquidityAndPrice(this.initialLiquidity, this.marketPrice);
102
- }
103
- getInitialRealY() {
104
- return this.getRealYGivenLiquidityAndPrice(this.initialLiquidity, this.marketPrice);
105
- }
106
- getValueGivenPriceAndAmounts(price, amountX, amountY) {
107
- return amountX * price + amountY;
108
- }
109
- getValueGivenAmounts(amountX, amountY) {
110
- return amountX * this.marketPrice + amountY;
111
- }
112
- getAmountXGivenValue(value) {
113
- return value / this.marketPrice;
114
- }
115
- getAmountYGivenValue(value) {
116
- return value;
117
- }
118
- getInitialDebtValue() {
119
- return this.getValueGivenAmounts(this.initialDebtX, this.initialDebtY);
120
- }
121
- getDebtValueGivenPrice(price) {
122
- return this.getValueGivenPriceAndAmounts(price, this.debtX, this.debtY);
123
- }
124
- getInitialCollateralValue() {
125
- return this.getValueGivenAmounts(this.getInitialRealX(), this.getInitialRealY());
126
- }
127
- getCollateralValueGivenPrice(price) {
128
- return this.getValueGivenPriceAndAmounts(price, this.getRealXGivenPrice(price), this.getRealYGivenPrice(price));
129
- }
130
- getCollateralValueGivenPriceAndDeltaLeverage(price, deltaX, deltaY) {
131
- const { liquidity } = this.getOptimalLiquidity(deltaX, deltaY);
132
- return this.getValueGivenPriceAndAmounts(price, this.getRealXGivenLiquidityAndPrice(this.liquidity + liquidity, price), this.getRealYGivenLiquidityAndPrice(this.liquidity + liquidity, price));
133
- }
134
- getInitialEquityValue() {
135
- return this.getInitialCollateralValue() - this.getInitialDebtValue();
136
- }
137
- getEquityValueGivenPrice(price) {
138
- return this.getCollateralValueGivenPrice(price) - this.getDebtValueGivenPrice(price);
139
- }
140
- getDebtValue() {
141
- return this.getDebtValueGivenPrice(this.marketPrice);
142
- }
143
- getCollateralValue() {
144
- return this.getCollateralValueGivenPrice(this.marketPrice);
145
- }
146
- getEquityValue() {
147
- return this.getEquityValueGivenPrice(this.marketPrice);
148
- }
149
- getLiquidityPostLiquidationValueGivenPriceAndDebt(price, debtX, debtY) {
150
- const debtValue = this.getValueGivenPriceAndAmounts(price, debtX, debtY);
151
- const collateralValue = this.getCollateralValueGivenPrice(price);
152
- const collateralNeeded = debtValue * this.liquidationPenalty;
153
- return collateralValue - collateralNeeded;
154
- }
155
- getLiquidityPostLiquidationValueGivenPriceAndDeltaLeverage(price, deltaX, deltaY) {
156
- const debtValue = this.getDebtValueGivenPrice(price) + this.getValueGivenPriceAndAmounts(price, deltaX, deltaY);
157
- const collateralValue = this.getCollateralValueGivenPriceAndDeltaLeverage(price, deltaX, deltaY);
158
- const collateralNeeded = debtValue * this.liquidationPenalty;
159
- return collateralValue - collateralNeeded;
160
- }
161
- isLiquidatableGivenPriceAndDebt(price, debtX, debtY) {
162
- return this.getLiquidityPostLiquidationValueGivenPriceAndDebt(price / this.safetyMargin, debtX, debtY) < 0
163
- || this.getLiquidityPostLiquidationValueGivenPriceAndDebt(price * this.safetyMargin, debtX, debtY) < 0;
164
- }
165
- isLiquidatableGivenPriceAndDeltaLeverage(price, deltaX, deltaY) {
166
- return this.getLiquidityPostLiquidationValueGivenPriceAndDeltaLeverage(price / this.safetyMargin, deltaX, deltaY) < 0
167
- || this.getLiquidityPostLiquidationValueGivenPriceAndDeltaLeverage(price * this.safetyMargin, deltaX, deltaY) < 0;
168
- }
169
- isLiquidatableGivenDebt(debtX, debtY) {
170
- return this.isLiquidatableGivenPriceAndDebt(this.marketPrice, debtX, debtY);
171
- }
172
- isLiquidatableGivenDeltaLeverage(deltaX, deltaY) {
173
- return this.isLiquidatableGivenPriceAndDeltaLeverage(this.marketPrice, deltaX, deltaY);
174
- }
175
- isLiquidatableGivenPrice(price) {
176
- return this.isLiquidatableGivenPriceAndDebt(price, this.debtX, this.debtY);
177
- }
178
- isUnderwaterGivenPrice(price) {
179
- return this.getLiquidityPostLiquidationValueGivenPriceAndDebt(price, this.debtX, this.debtY) < 0;
180
- }
181
- getLiquidationPriceInRange(lowPrice, highPrice, lowIsLiquidatable, highIsLiquidatable) {
182
- if (lowIsLiquidatable == highIsLiquidatable)
183
- return undefined;
184
- const avgPrice = Math.sqrt(lowPrice * highPrice);
185
- if (lowPrice / highPrice > 0.9999)
186
- return avgPrice;
187
- const avgIsLiquidatable = this.isLiquidatableGivenPrice(avgPrice);
188
- return this.getLiquidationPriceInRange(lowPrice, avgPrice, lowIsLiquidatable, avgIsLiquidatable)
189
- ?? this.getLiquidationPriceInRange(avgPrice, highPrice, avgIsLiquidatable, highIsLiquidatable);
190
- }
191
- getMaxDeltaDebtInRange(lowDeltaX, lowDeltaY, highDeltaX, highDeltaY) {
192
- if (Number.isNaN(lowDeltaX) || Number.isNaN(lowDeltaY) || Number.isNaN(highDeltaX) || Number.isNaN(highDeltaY))
193
- return [0, 0];
194
- if (highDeltaX == 0 && highDeltaY == 0)
195
- return [0, 0];
196
- if (Math.abs(highDeltaX / lowDeltaX) < 1.001 || Math.abs(highDeltaY / lowDeltaY) < 1.001)
197
- return [lowDeltaX, lowDeltaY];
198
- const avgDeltaX = (lowDeltaX + highDeltaX) / 2;
199
- const avgDeltaY = (lowDeltaY + highDeltaY) / 2;
200
- if (this.isLiquidatableGivenDebt(this.debtX + avgDeltaX, this.debtY + avgDeltaY))
201
- return this.getMaxDeltaDebtInRange(lowDeltaX, lowDeltaY, avgDeltaX, avgDeltaY);
202
- else
203
- return this.getMaxDeltaDebtInRange(avgDeltaX, avgDeltaY, highDeltaX, highDeltaY);
204
- }
205
- getMaxDeltaLeverageInRange(lowDeltaX, lowDeltaY, highDeltaX, highDeltaY) {
206
- if (Number.isNaN(lowDeltaX) || Number.isNaN(lowDeltaY) || Number.isNaN(highDeltaX) || Number.isNaN(highDeltaY))
207
- return [0, 0];
208
- if (highDeltaX == 0 && highDeltaY == 0)
209
- return [0, 0];
210
- if (Math.abs(highDeltaX / lowDeltaX) < 1.001 || Math.abs(highDeltaY / lowDeltaY) < 1.001)
211
- return [lowDeltaX, lowDeltaY];
212
- const avgDeltaX = (lowDeltaX + highDeltaX) / 2;
213
- const avgDeltaY = (lowDeltaY + highDeltaY) / 2;
214
- if (this.isLiquidatableGivenDeltaLeverage(avgDeltaX, avgDeltaY))
215
- return this.getMaxDeltaLeverageInRange(lowDeltaX, lowDeltaY, avgDeltaX, avgDeltaY);
216
- else
217
- return this.getMaxDeltaLeverageInRange(avgDeltaX, avgDeltaY, highDeltaX, highDeltaY);
218
- }
219
- getMinLeverageInRange(lowLeverage, highLeverage) {
220
- if (highLeverage / lowLeverage < 1.001)
221
- return highLeverage;
222
- const avgLeverage = (lowLeverage + highLeverage) / 2;
223
- if (this.getOptimalWithdrawForDeleverage(avgLeverage) !== null)
224
- return this.getMinLeverageInRange(lowLeverage, avgLeverage);
225
- else
226
- return this.getMinLeverageInRange(avgLeverage, highLeverage);
227
- }
228
- /**
229
- * PUBLIC SETTERS
230
- */
231
- depositX(amount) {
232
- this.setRealX(this.getInitialRealX() + amount);
233
- }
234
- depositY(amount) {
235
- this.setRealY(this.getInitialRealY() + amount);
236
- }
237
- withdrawX(amount) {
238
- this.setRealX(Math.max(this.getInitialRealX() - amount, 0));
239
- }
240
- withdrawY(amount) {
241
- this.setRealY(Math.max(this.getInitialRealY() - amount, 0));
242
- }
243
- borrowX(amount) {
244
- if (amount > this.availableToBorrowX) {
245
- throw new Error("Trying to borrow more than available liquidity");
246
- }
247
- else {
248
- this.setDebtX(this.initialDebtX + amount);
249
- }
250
- }
251
- borrowY(amount) {
252
- if (amount > this.availableToBorrowY) {
253
- throw new Error("Trying to borrow more than available liquidity");
254
- }
255
- else {
256
- this.setDebtY(this.initialDebtY + amount);
257
- }
258
- }
259
- repayX(amount) {
260
- this.setDebtX(Math.max(this.initialDebtX - amount, 0));
261
- }
262
- repayY(amount) {
263
- this.setDebtY(Math.max(this.initialDebtY - amount, 0));
31
+ return liquidity * Math.sqrt(price);
264
32
  }
265
33
  /**
266
34
  * PUBLIC GETTERS
267
35
  */
268
- getInitialDepositedX() {
269
- return this.getInitialRealX();
270
- }
271
- getInitialDepositedY() {
272
- return this.getInitialRealY();
273
- }
274
- getDepositedX() {
275
- return this.getRealX();
276
- }
277
- getDepositedY() {
278
- return this.getRealY();
279
- }
280
- getNetX() {
281
- return this.getDepositedX() - this.debtX;
282
- }
283
- getNetY() {
284
- return this.getDepositedY() - this.debtY;
285
- }
286
- isLiquidatable() {
287
- return this.isLiquidatableGivenPrice(this.oraclePrice);
288
- }
289
- isUnderwater() {
290
- return this.isUnderwaterGivenPrice(this.marketPrice);
291
- }
292
- getLiquidationRange() {
293
- const isLiquidatable = this.isLiquidatable();
294
- if (isLiquidatable)
295
- return undefined;
296
- if (this.marketPrice < LOWEST_PRICE || this.marketPrice > HIGHEST_PRICE)
297
- return undefined;
298
- const lowIsLiquidatable = this.isLiquidatableGivenPrice(LOWEST_PRICE);
299
- const highIsLiquidatable = this.isLiquidatableGivenPrice(HIGHEST_PRICE);
300
- const priceA = this.getLiquidationPriceInRange(LOWEST_PRICE, this.marketPrice, lowIsLiquidatable, isLiquidatable);
301
- const priceB = this.getLiquidationPriceInRange(this.marketPrice, HIGHEST_PRICE, isLiquidatable, highIsLiquidatable);
302
- return {
303
- priceA: priceA && priceA > LOWEST_PRICE ? priceA : 0,
304
- priceB: priceB && priceB < HIGHEST_PRICE ? priceB : Infinity,
305
- };
306
- }
307
- getInitialLeverage() {
308
- const leverage = this.getInitialCollateralValue() / this.getInitialEquityValue();
309
- if (!leverage)
310
- return 1;
311
- if (Number.isNaN(leverage))
312
- return 1;
313
- if (leverage < 1)
314
- return 1;
315
- return leverage;
316
- }
317
- getLeverage() {
318
- const leverage = this.getCollateralValue() / this.getEquityValue();
319
- if (!leverage)
320
- return 1;
321
- if (Number.isNaN(leverage))
322
- return 1;
323
- if (leverage < 1)
324
- return 1;
325
- return leverage;
326
- }
327
36
  // amountX and amountY are expected to have the same sign
328
37
  getOptimalLiquidity(amountX, amountY) {
329
38
  amountX = Number.isNaN(amountX) ? 0 : amountX ?? 0;
@@ -337,149 +46,6 @@ class UniswapV2Position {
337
46
  amountY: this.getRealYGivenLiquidity(liquidity),
338
47
  };
339
48
  }
340
- getOptimalWithdraw(amountX, amountY, withdrawAtLeast = true) {
341
- let percentageToRemove;
342
- const percentageToRemoveX = amountX / this.getInitialDepositedX();
343
- const percentageToRemoveY = amountY / this.getInitialDepositedY();
344
- // Withdraw at least amountX and amountY
345
- if (withdrawAtLeast)
346
- percentageToRemove = Math.min(Math.max(percentageToRemoveX, percentageToRemoveY), 1);
347
- // Withdraw at most amountX and amountY
348
- else
349
- percentageToRemove = Math.min(Math.min(percentageToRemoveX, percentageToRemoveY), 1);
350
- percentageToRemove = percentageToRemove && !Number.isNaN(percentageToRemove) ? percentageToRemove : 0;
351
- return {
352
- amountX: this.getInitialDepositedX() * percentageToRemove,
353
- amountY: this.getInitialDepositedY() * percentageToRemove,
354
- };
355
- }
356
- getOptimalWithdrawForDeleverage(targetLeverage) {
357
- // 1. If target leverage out of range
358
- if (!(targetLeverage >= 1 && targetLeverage < this.getInitialLeverage())) {
359
- return null;
360
- }
361
- // 2. If target leverage is achievable through a straight deleverage
362
- const maxStraightDeleverage = this.getOptimalWithdraw(this.initialDebtX, this.initialDebtY, false);
363
- const maxStraightDeleverageValue = this.getValueGivenAmounts(maxStraightDeleverage.amountX, maxStraightDeleverage.amountY);
364
- const minStraightLeverage = (this.getInitialCollateralValue() - maxStraightDeleverageValue) / this.getInitialEquityValue();
365
- if (targetLeverage >= minStraightLeverage) {
366
- const desiredCollateralValue = targetLeverage * this.getInitialEquityValue();
367
- const desiredValue = this.getInitialCollateralValue() - desiredCollateralValue;
368
- const ratio = desiredValue / maxStraightDeleverageValue;
369
- return {
370
- amountX: maxStraightDeleverage.amountX * ratio,
371
- amountY: maxStraightDeleverage.amountY * ratio,
372
- };
373
- }
374
- // 3. Deleveraging will result in withdrawing
375
- const debtValue = this.getInitialDebtValue() - maxStraightDeleverageValue;
376
- const collateralValue = this.getInitialCollateralValue() - maxStraightDeleverageValue;
377
- let repayRatio;
378
- if (this.initialDebtX == maxStraightDeleverage.amountX) {
379
- repayRatio = this.getValueGivenAmounts(0, this.getInitialDepositedY()) / this.getInitialCollateralValue();
380
- }
381
- else {
382
- repayRatio = this.getValueGivenAmounts(this.getInitialDepositedX(), 0) / this.getInitialCollateralValue();
383
- }
384
- const deltaValue = (collateralValue * (targetLeverage - 1) - debtValue * targetLeverage) / (targetLeverage * (1 - repayRatio) - 1);
385
- // Proof:
386
- // leverage = newCollateral / (newCollateral - newDebt)
387
- // newCollateral = collateral - delta
388
- // newDebt = debt - delta * repayRatio;
389
- // ((collateral - delta) - (debt - delta * repayRatio)) * leverage = (collateral - delta)
390
- // (collateral - delta - debt + delta * repayRatio) * leverage - collateral = - delta
391
- // collateral * leverage - delta * leverage - debt * leverage + delta * repayRatio * leverage - collateral = - delta
392
- // collateral * leverage - debt * leverage - collateral = - delta + delta * leverage - delta * repayRatio * leverage
393
- // collateral * (leverage-1) - debt * leverage = delta * (leverage - repayRatio * leverage - 1)
394
- // collateral * (leverage-1) - debt * leverage = delta * (leverage * (1-repayRatio) - 1)
395
- // (collateral * (leverage-1) - debt * leverage) / (leverage * (1-repayRatio) - 1) = delta
396
- // 4. Return amounts if the leverage is achievable
397
- if (deltaValue < 0 || deltaValue > collateralValue)
398
- return null;
399
- const percentageToRemove = (deltaValue + maxStraightDeleverageValue) / this.getInitialCollateralValue();
400
- return {
401
- amountX: this.getInitialDepositedX() * percentageToRemove,
402
- amountY: this.getInitialDepositedY() * percentageToRemove,
403
- };
404
- }
405
- getMaxLeverage() {
406
- const currentLeverage = this.getLeverage();
407
- if (this.isLiquidatable())
408
- return currentLeverage;
409
- const highLeverage = 100; // we assume the position is liquidatable with this leverage
410
- let setLiquidityToZero = false;
411
- if (this.liquidity === 0) {
412
- this.liquidity = 0.000001;
413
- setLiquidityToZero = true;
414
- }
415
- const realX = this.getRealX();
416
- const realY = this.getRealY();
417
- let maxDeltaX = realX * highLeverage / currentLeverage;
418
- let maxDeltaY = realY * highLeverage / currentLeverage;
419
- const actualAvailableToBorrowX = this.availableToBorrowX - (this.debtX - this.initialDebtX);
420
- const actualAvailableToBorrowY = this.availableToBorrowY - (this.debtY - this.initialDebtY);
421
- if (maxDeltaX > actualAvailableToBorrowX) {
422
- maxDeltaY *= actualAvailableToBorrowX / maxDeltaX;
423
- maxDeltaX = actualAvailableToBorrowX;
424
- }
425
- if (maxDeltaY > actualAvailableToBorrowY) {
426
- maxDeltaX *= actualAvailableToBorrowY / maxDeltaY;
427
- maxDeltaY = actualAvailableToBorrowY;
428
- }
429
- const [deltaX, deltaY] = this.getMaxDeltaLeverageInRange(0, 0, maxDeltaX, maxDeltaY);
430
- const collateralValue = this.getCollateralValue();
431
- const additionalValue = this.getValueGivenAmounts(deltaX, deltaY);
432
- if (setLiquidityToZero)
433
- this.liquidity = 0;
434
- return (collateralValue + additionalValue) / collateralValue * currentLeverage;
435
- }
436
- getMinLeverage() {
437
- const depositedX = this.getDepositedX();
438
- const depositedY = this.getDepositedY();
439
- const ratioX = this.debtX === 0 ? Infinity : depositedX / this.debtX;
440
- const ratioY = this.debtY === 0 ? Infinity : depositedY / this.debtY;
441
- if (ratioX >= 1 && ratioY >= 1)
442
- return 0;
443
- return this.getMinLeverageInRange(1, this.getInitialLeverage());
444
- }
445
- getMaxWithdrawable() {
446
- const depositedX = this.getDepositedX();
447
- const depositedY = this.getDepositedY();
448
- const additionalDepositX = this.getRealX() - this.getInitialRealX();
449
- const additionalDepositY = this.getRealY() - this.getInitialRealY();
450
- let percentage = 0;
451
- if (!this.isLiquidatable()) {
452
- if (this.debtX == 0 && this.debtY == 0) {
453
- percentage = 1;
454
- }
455
- else {
456
- const highRatio = this.getEquityValue() / this.getDebtValue();
457
- const [deltaDebtX, deltaDebtY] = this.getMaxDeltaDebtInRange(0, 0, this.debtX * highRatio, this.debtY * highRatio);
458
- const ratio = this.debtX > 0 ? deltaDebtX / this.debtX : deltaDebtY / this.debtY;
459
- percentage = 1 / (1 / ratio + 1);
460
- }
461
- }
462
- return {
463
- amountX: depositedX * percentage - additionalDepositX,
464
- amountY: depositedY * percentage - additionalDepositY,
465
- };
466
- }
467
- getMaxBorrowableX() {
468
- if (this.isLiquidatable())
469
- return 0;
470
- const equityValue = this.getEquityValue();
471
- const highDebtX = this.getAmountXGivenValue(equityValue);
472
- const [debtX,] = this.getMaxDeltaDebtInRange(0, 0, highDebtX, 0);
473
- return Math.min(debtX + this.debtX - this.initialDebtX, this.availableToBorrowX);
474
- }
475
- getMaxBorrowableY() {
476
- if (this.isLiquidatable())
477
- return 0;
478
- const equityValue = this.getEquityValue();
479
- const highDebtY = this.getAmountYGivenValue(equityValue);
480
- const [, debtY] = this.getMaxDeltaDebtInRange(0, 0, 0, highDebtY);
481
- return Math.min(debtY + this.debtY - this.initialDebtY, this.availableToBorrowY);
482
- }
483
49
  }
484
50
  exports.UniswapV2Position = UniswapV2Position;
485
51
  exports.default = UniswapV2Position;