impermax-sdk 2.1.214 → 2.1.216
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/offchain/account/lendingPool/offchainAccountCollateralV2.js +1 -1
- package/lib/offchain/lendingPool/offchainCollateralV2.js +5 -0
- package/lib/onchain/account/lendingPool/onchainAccountCollateralV2.js +3 -3
- package/lib/onchain/account/onchainAccountPoolToken.d.ts +7 -3
- package/lib/onchain/account/onchainAccountPoolToken.js +19 -8
- package/lib/onchain/impermaxFactory/lendingPool/onchainCollateralV2.js +6 -2
- package/lib/utils/position/uniswapV3/index.d.ts +8 -1
- package/lib/utils/position/uniswapV3/index.js +51 -4
- package/package.json +1 -1
|
@@ -27,8 +27,8 @@ class OffchainAccountCollateralV2 extends offchainAccountPoolToken_1.default {
|
|
|
27
27
|
return parseFloat(collateralPosition.balance);
|
|
28
28
|
}
|
|
29
29
|
async getLiquidity() {
|
|
30
|
-
// todo check if growth factor works
|
|
31
30
|
console.log("Offchain `getAmount`: %s", await this.getAmount());
|
|
31
|
+
console.log("Offchain `getGrowthFactor`: %s", await this.getCollateral().getGrowthFactor());
|
|
32
32
|
return await this.getAmount() * await this.getCollateral().getGrowthFactor();
|
|
33
33
|
}
|
|
34
34
|
// Notice: createNewPositionObject is not needed for V2
|
|
@@ -45,6 +45,11 @@ class OffchainCollateralV2 extends offchainPoolToken_1.default {
|
|
|
45
45
|
const reserve1 = parseFloat(lendingPoolData.pair.reserve1);
|
|
46
46
|
const totalSupply = parseFloat(lendingPoolData.pair.totalSupply);
|
|
47
47
|
const exchangeRate = await this.getExchangeRate();
|
|
48
|
+
console.log("offchain exchangeRate", exchangeRate);
|
|
49
|
+
console.log("offchain reserve0", reserve0);
|
|
50
|
+
console.log("offchain reserve1", reserve1);
|
|
51
|
+
console.log("offchain totalSupply", totalSupply);
|
|
52
|
+
console.log("offchain k", Math.sqrt(reserve0 * reserve1) / totalSupply);
|
|
48
53
|
return Math.sqrt(reserve0 * reserve1) / totalSupply * exchangeRate;
|
|
49
54
|
}
|
|
50
55
|
//
|
|
@@ -31,9 +31,9 @@ class OnchainAccountCollateralV2 extends onchainAccountPoolToken_1.default {
|
|
|
31
31
|
this.collateralCache = {};
|
|
32
32
|
}
|
|
33
33
|
async getLiquidity() {
|
|
34
|
-
console.log("Onchain `
|
|
35
|
-
|
|
36
|
-
return await this.
|
|
34
|
+
console.log("Onchain `getTokens`: %s", await this.getTokens());
|
|
35
|
+
console.log("Offchain `getGrowthFactor`: %s", await this.getCollateral().getGrowthFactor());
|
|
36
|
+
return await this.getTokens() * await this.getCollateral().getGrowthFactor();
|
|
37
37
|
}
|
|
38
38
|
// Notice: createNewPositionObject is not needed for V2
|
|
39
39
|
async createPositionObject(lockStateChange = false) {
|
|
@@ -6,7 +6,8 @@ export default abstract class OnchainAccountPoolToken {
|
|
|
6
6
|
protected poolToken: OnchainPoolToken;
|
|
7
7
|
protected cache: {
|
|
8
8
|
availableBalance?: Promise<number>;
|
|
9
|
-
|
|
9
|
+
tokens?: Promise<number>;
|
|
10
|
+
amount?: Promise<number>;
|
|
10
11
|
};
|
|
11
12
|
getPoolToken: () => OnchainPoolToken;
|
|
12
13
|
abstract getAccount(): OnchainAccount;
|
|
@@ -23,8 +24,11 @@ export default abstract class OnchainAccountPoolToken {
|
|
|
23
24
|
private initializeAvailableBalance;
|
|
24
25
|
getAvailableBalance(): Promise<number>;
|
|
25
26
|
getAvailableBalanceUSD(): Promise<number>;
|
|
26
|
-
private
|
|
27
|
-
|
|
27
|
+
private initializeTokens;
|
|
28
|
+
getTokens(): Promise<number>;
|
|
29
|
+
private initializeAmount;
|
|
30
|
+
getAmount(): Promise<number>;
|
|
31
|
+
getDeposited: () => Promise<number>;
|
|
28
32
|
getDepositedUSD(): Promise<number>;
|
|
29
33
|
getMaxWithdrawable(): Promise<number>;
|
|
30
34
|
}
|
|
@@ -13,6 +13,7 @@ class OnchainAccountPoolToken {
|
|
|
13
13
|
this.getLiquidityBuffer = () => this.getAccount().getOnchain().liquidityBuffer;
|
|
14
14
|
this.getUiMargin = () => this.getAccount().getOnchain().uiMargin;
|
|
15
15
|
this.getTokenPriceAccurate = async () => (await this.poolToken.getOffchainPoolToken()).getTokenPriceAccurate();
|
|
16
|
+
this.getDeposited = this.getAmount;
|
|
16
17
|
}
|
|
17
18
|
cleanCache() {
|
|
18
19
|
this.cache = {};
|
|
@@ -36,17 +37,27 @@ class OnchainAccountPoolToken {
|
|
|
36
37
|
const tokenPrice = await this.getTokenPriceAccurate();
|
|
37
38
|
return availableBalance * tokenPrice;
|
|
38
39
|
}
|
|
39
|
-
//
|
|
40
|
-
async
|
|
40
|
+
// Tokens
|
|
41
|
+
async initializeTokens() {
|
|
41
42
|
const poolToken = await this.poolToken.getPoolToken();
|
|
42
|
-
const exchangeRate = await this.poolToken.getExchangeRate();
|
|
43
43
|
const balance = await poolToken.methods.balanceOf(this.getAccountAddress()).call();
|
|
44
|
-
return (await this.poolToken.normalize(balance))
|
|
44
|
+
return (await this.poolToken.normalize(balance));
|
|
45
|
+
}
|
|
46
|
+
async getTokens() {
|
|
47
|
+
if (!this.cache.tokens)
|
|
48
|
+
this.cache.tokens = this.initializeTokens();
|
|
49
|
+
return this.cache.tokens;
|
|
50
|
+
}
|
|
51
|
+
// Deposited
|
|
52
|
+
async initializeAmount() {
|
|
53
|
+
const exchangeRate = await this.poolToken.getExchangeRate();
|
|
54
|
+
const tokens = await this.getTokens();
|
|
55
|
+
return (await this.poolToken.normalize(tokens)) * exchangeRate;
|
|
45
56
|
}
|
|
46
|
-
async
|
|
47
|
-
if (!this.cache.
|
|
48
|
-
this.cache.
|
|
49
|
-
return this.cache.
|
|
57
|
+
async getAmount() {
|
|
58
|
+
if (!this.cache.amount)
|
|
59
|
+
this.cache.amount = this.initializeAmount();
|
|
60
|
+
return this.cache.amount;
|
|
50
61
|
}
|
|
51
62
|
async getDepositedUSD() {
|
|
52
63
|
const deposited = await this.getDeposited();
|
|
@@ -37,9 +37,13 @@ class OnchainCollateralV2 extends onchainPoolToken_1.default {
|
|
|
37
37
|
async getGrowthFactor() {
|
|
38
38
|
const [reserve0, reserve1] = await this.getLendingPool().getReserves();
|
|
39
39
|
const totalSupply = await this.getLendingPool().getLPTotalSupply();
|
|
40
|
-
const stakedLPExchangeRate = await this.getLendingPool().getStakedLPExchangeRate();
|
|
41
40
|
const exchangeRate = await this.getExchangeRate();
|
|
42
|
-
|
|
41
|
+
console.log("onchain exchangeRate", exchangeRate);
|
|
42
|
+
console.log("onchain reserve0", reserve0);
|
|
43
|
+
console.log("onchain reserve1", reserve1);
|
|
44
|
+
console.log("onchain totalSupply", totalSupply);
|
|
45
|
+
console.log("onchain k", Math.sqrt(reserve0 * reserve1) / totalSupply);
|
|
46
|
+
return Math.sqrt(reserve0 * reserve1) / totalSupply * exchangeRate;
|
|
43
47
|
}
|
|
44
48
|
}
|
|
45
49
|
exports.default = OnchainCollateralV2;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { Position } from "../interface";
|
|
2
|
+
/**
|
|
3
|
+
* TODO: Cache for initialRealX, intialCollateralValue, etc...
|
|
4
|
+
*/
|
|
2
5
|
export declare class UniswapV3Position implements Position {
|
|
3
6
|
lockStateChange: boolean;
|
|
4
7
|
state: number;
|
|
@@ -106,10 +109,14 @@ export declare class UniswapV3Position implements Position {
|
|
|
106
109
|
amountX: number;
|
|
107
110
|
amountY: number;
|
|
108
111
|
};
|
|
109
|
-
getOptimalWithdraw(
|
|
112
|
+
getOptimalWithdraw(amountX: number, amountY: number, withdrawAtLeast?: boolean): {
|
|
110
113
|
amountX: number;
|
|
111
114
|
amountY: number;
|
|
112
115
|
};
|
|
116
|
+
getOptimalWithdrawForDeleverage(targetLeverage: number): {
|
|
117
|
+
amountX: number;
|
|
118
|
+
amountY: number;
|
|
119
|
+
} | null;
|
|
113
120
|
getMaxLeverage(): number;
|
|
114
121
|
getMinLeverage(): number;
|
|
115
122
|
getMaxWithdrawable(): {
|
|
@@ -20,6 +20,9 @@ function getRealY(liquidity, price, priceA, priceB) {
|
|
|
20
20
|
const LOWEST_PRICE = 1 / 1e18;
|
|
21
21
|
const HIGHEST_PRICE = 1e18;
|
|
22
22
|
const FEE_COLLECTED_WEIGHT = 0.95;
|
|
23
|
+
/**
|
|
24
|
+
* TODO: Cache for initialRealX, intialCollateralValue, etc...
|
|
25
|
+
*/
|
|
23
26
|
class UniswapV3Position {
|
|
24
27
|
constructor(_liquidity, _unclaimedFeesX, _unclaimedFeesY, _debtX, _debtY, _marketPrice, _oraclePrice, _priceA, _priceB, _safetyMargin, _liquidationPenalty, _lockStateChange) {
|
|
25
28
|
this.liquidity = _liquidity;
|
|
@@ -361,16 +364,60 @@ class UniswapV3Position {
|
|
|
361
364
|
amountY: Number.isNaN(maxAmountY) ? 0 : maxAmountY ?? 0,
|
|
362
365
|
};
|
|
363
366
|
}
|
|
364
|
-
getOptimalWithdraw(
|
|
365
|
-
|
|
366
|
-
const
|
|
367
|
-
|
|
367
|
+
getOptimalWithdraw(amountX, amountY, withdrawAtLeast = true) {
|
|
368
|
+
let percentageToRemove;
|
|
369
|
+
const percentageToRemoveX = amountX / this.getInitialDepositedX();
|
|
370
|
+
const percentageToRemoveY = amountY / this.getInitialDepositedY();
|
|
371
|
+
// Withdraw at least amountX and amountY
|
|
372
|
+
if (withdrawAtLeast)
|
|
373
|
+
percentageToRemove = Math.min(Math.max(percentageToRemoveX, percentageToRemoveY), 1);
|
|
374
|
+
// Withdraw at most amountX and amountY
|
|
375
|
+
else
|
|
376
|
+
percentageToRemove = Math.min(Math.min(percentageToRemoveX, percentageToRemoveY), 1);
|
|
368
377
|
percentageToRemove = percentageToRemove && !Number.isNaN(percentageToRemove) ? percentageToRemove : 0;
|
|
369
378
|
return {
|
|
370
379
|
amountX: this.getInitialDepositedX() * percentageToRemove,
|
|
371
380
|
amountY: this.getInitialDepositedY() * percentageToRemove,
|
|
372
381
|
};
|
|
373
382
|
}
|
|
383
|
+
getOptimalWithdrawForDeleverage(targetLeverage) {
|
|
384
|
+
// 1. If target leverage out of range
|
|
385
|
+
if (!(targetLeverage >= 1 && targetLeverage < this.getInitialLeverage())) {
|
|
386
|
+
return null;
|
|
387
|
+
}
|
|
388
|
+
// 2. If target leverage is achievable through a straight deleverage
|
|
389
|
+
const maxStraightDeleverage = this.getOptimalWithdraw(this.initialDebtX, this.initialDebtY, false);
|
|
390
|
+
const maxStraightDeleverageValue = this.getValueGivenAmounts(maxStraightDeleverage.amountX, maxStraightDeleverage.amountY);
|
|
391
|
+
const minStraightLeverage = (this.getInitialCollateralValue() - maxStraightDeleverageValue) / this.getInitialEquityValue();
|
|
392
|
+
if (targetLeverage >= minStraightLeverage) {
|
|
393
|
+
const desiredCollateralValue = targetLeverage * this.getEquityValue();
|
|
394
|
+
const desiredValue = this.getInitialCollateralValue() - desiredCollateralValue;
|
|
395
|
+
const ratio = desiredValue / maxStraightDeleverageValue;
|
|
396
|
+
return {
|
|
397
|
+
amountX: maxStraightDeleverage.amountX * ratio,
|
|
398
|
+
amountY: maxStraightDeleverage.amountY * ratio,
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
// 3. Deleveraging will result in withdrawing
|
|
402
|
+
const debtValue = this.getInitialDebtValue() - maxStraightDeleverageValue;
|
|
403
|
+
const collateralValue = this.getInitialCollateralValue() - maxStraightDeleverageValue;
|
|
404
|
+
let repayRatio;
|
|
405
|
+
if (this.initialDebtX == maxStraightDeleverage.amountX) {
|
|
406
|
+
repayRatio = this.getValueGivenAmounts(0, this.getInitialDepositedY()) / this.getInitialCollateralValue();
|
|
407
|
+
}
|
|
408
|
+
else {
|
|
409
|
+
repayRatio = this.getValueGivenAmounts(this.getInitialDepositedX(), 0) / this.getInitialCollateralValue();
|
|
410
|
+
}
|
|
411
|
+
const deltaValue = (collateralValue * (targetLeverage - 1) - debtValue * targetLeverage) / (targetLeverage * (1 - repayRatio) - 1);
|
|
412
|
+
// 4. Return amounts if the leverage is achievable
|
|
413
|
+
if (deltaValue < 0 || deltaValue > collateralValue)
|
|
414
|
+
return null;
|
|
415
|
+
const percentageToRemove = (deltaValue + maxStraightDeleverageValue) / this.getInitialCollateralValue();
|
|
416
|
+
return {
|
|
417
|
+
amountX: this.getInitialDepositedX() * percentageToRemove,
|
|
418
|
+
amountY: this.getInitialDepositedY() * percentageToRemove,
|
|
419
|
+
};
|
|
420
|
+
}
|
|
374
421
|
getMaxLeverage() {
|
|
375
422
|
const currentLeverage = this.getLeverage();
|
|
376
423
|
if (this.isLiquidatable())
|