@strkfarm/sdk 2.0.0-dev.3 → 2.0.0-dev.31
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/dist/cli.js +190 -36
- package/dist/cli.mjs +188 -34
- package/dist/index.browser.global.js +78475 -45620
- package/dist/index.browser.mjs +19580 -9901
- package/dist/index.d.ts +3763 -1424
- package/dist/index.js +20977 -11063
- package/dist/index.mjs +20945 -11087
- package/package.json +1 -1
- package/src/data/avnu.abi.json +840 -0
- package/src/data/ekubo-price-fethcer.abi.json +265 -0
- package/src/dataTypes/_bignumber.ts +13 -4
- package/src/dataTypes/bignumber.browser.ts +6 -1
- package/src/dataTypes/bignumber.node.ts +5 -1
- package/src/dataTypes/index.ts +3 -2
- package/src/dataTypes/mynumber.ts +141 -0
- package/src/global.ts +76 -41
- package/src/index.browser.ts +2 -1
- package/src/interfaces/common.tsx +175 -3
- package/src/modules/ExtendedWrapperSDk/types.ts +28 -5
- package/src/modules/ExtendedWrapperSDk/wrapper.ts +275 -59
- package/src/modules/apollo-client-config.ts +28 -0
- package/src/modules/avnu.ts +4 -4
- package/src/modules/ekubo-pricer.ts +79 -0
- package/src/modules/ekubo-quoter.ts +48 -30
- package/src/modules/erc20.ts +17 -0
- package/src/modules/harvests.ts +43 -29
- package/src/modules/pragma.ts +23 -8
- package/src/modules/pricer-from-api.ts +156 -15
- package/src/modules/pricer-lst.ts +1 -1
- package/src/modules/pricer.ts +40 -4
- package/src/modules/pricerBase.ts +2 -1
- package/src/node/deployer.ts +36 -1
- package/src/node/pricer-redis.ts +2 -1
- package/src/strategies/base-strategy.ts +78 -10
- package/src/strategies/ekubo-cl-vault.tsx +906 -347
- package/src/strategies/factory.ts +159 -0
- package/src/strategies/index.ts +7 -1
- package/src/strategies/registry.ts +239 -0
- package/src/strategies/sensei.ts +335 -7
- package/src/strategies/svk-strategy.ts +97 -27
- package/src/strategies/types.ts +4 -0
- package/src/strategies/universal-adapters/adapter-utils.ts +2 -1
- package/src/strategies/universal-adapters/avnu-adapter.ts +180 -265
- package/src/strategies/universal-adapters/baseAdapter.ts +263 -251
- package/src/strategies/universal-adapters/common-adapter.ts +206 -203
- package/src/strategies/universal-adapters/extended-adapter.ts +490 -316
- package/src/strategies/universal-adapters/index.ts +11 -8
- package/src/strategies/universal-adapters/svk-troves-adapter.ts +364 -0
- package/src/strategies/universal-adapters/token-transfer-adapter.ts +200 -0
- package/src/strategies/universal-adapters/usdc<>usdce-adapter.ts +200 -0
- package/src/strategies/universal-adapters/vesu-adapter.ts +120 -82
- package/src/strategies/universal-adapters/vesu-modify-position-adapter.ts +476 -0
- package/src/strategies/universal-adapters/vesu-multiply-adapter.ts +1067 -704
- package/src/strategies/universal-adapters/vesu-position-common.ts +251 -0
- package/src/strategies/universal-adapters/vesu-supply-only-adapter.ts +18 -3
- package/src/strategies/universal-lst-muliplier-strategy.tsx +397 -204
- package/src/strategies/universal-strategy.tsx +1426 -1173
- package/src/strategies/vesu-extended-strategy/services/executionService.ts +2233 -0
- package/src/strategies/vesu-extended-strategy/services/extended-vesu-state-manager.ts +4087 -0
- package/src/strategies/vesu-extended-strategy/services/ltv-imbalance-rebalance-math.ts +783 -0
- package/src/strategies/vesu-extended-strategy/services/operationService.ts +38 -16
- package/src/strategies/vesu-extended-strategy/types/transaction-metadata.ts +88 -0
- package/src/strategies/vesu-extended-strategy/utils/config.runtime.ts +1 -0
- package/src/strategies/vesu-extended-strategy/utils/constants.ts +5 -6
- package/src/strategies/vesu-extended-strategy/utils/helper.ts +259 -103
- package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +688 -817
- package/src/strategies/vesu-rebalance.tsx +255 -152
- package/src/utils/cacheClass.ts +11 -2
- package/src/utils/health-factor-math.ts +4 -1
- package/src/utils/index.ts +3 -1
- package/src/utils/logger.browser.ts +22 -4
- package/src/utils/logger.node.ts +259 -24
- package/src/utils/starknet-call-parser.ts +1036 -0
- package/src/utils/strategy-utils.ts +61 -0
- package/src/strategies/universal-adapters/unused-balance-adapter.ts +0 -109
|
@@ -9,11 +9,15 @@ import {
|
|
|
9
9
|
USDC_TOKEN_DECIMALS,
|
|
10
10
|
MAX_LIQUIDATION_RATIO,
|
|
11
11
|
} from "./constants";
|
|
12
|
+
import { VesuConfig } from "./config.runtime";
|
|
13
|
+
import { ExtendedAdapter } from "../../universal-adapters/extended-adapter";
|
|
14
|
+
import { Balance } from "@/modules/ExtendedWrapperSDk";
|
|
12
15
|
import { Web3Number } from "@/dataTypes";
|
|
13
16
|
import { Position } from "@/modules/ExtendedWrapperSDk";
|
|
14
17
|
// import { getAllOpenPositionsExtended } from "../services/extendedService";
|
|
15
18
|
import ExtendedWrapper from "@/modules/ExtendedWrapperSDk";
|
|
16
19
|
import { logger } from "@/utils";
|
|
20
|
+
import { HealthFactorMath } from "@/utils/health-factor-math";
|
|
17
21
|
// import {
|
|
18
22
|
// calculatePositionOnVesu,
|
|
19
23
|
// getAssetPrice,
|
|
@@ -27,7 +31,7 @@ import { logger } from "@/utils";
|
|
|
27
31
|
*/
|
|
28
32
|
export const returnFormattedAmount = (
|
|
29
33
|
amount: number,
|
|
30
|
-
toTokenDecimals: number
|
|
34
|
+
toTokenDecimals: number,
|
|
31
35
|
) => {
|
|
32
36
|
const formattedAmount =
|
|
33
37
|
"0x" + BigInt(Math.floor(amount * 10 ** toTokenDecimals)).toString(16);
|
|
@@ -35,69 +39,63 @@ export const returnFormattedAmount = (
|
|
|
35
39
|
};
|
|
36
40
|
|
|
37
41
|
/**
|
|
38
|
-
* calculates the amount to distribute to
|
|
42
|
+
* calculates the amount to distribute to Extended and Vesu
|
|
39
43
|
* Determines how much to allocate to each platform based on leverage calculations
|
|
40
44
|
* @param {number} amount - The total amount to distribute
|
|
41
45
|
* @returns {object} Object containing avnu_amount, extended_amount, and extended_leverage
|
|
42
46
|
*/
|
|
43
|
-
export const calculateAmountDistribution =
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
extended_leverage: number;
|
|
55
|
-
vesu_leverage: number;
|
|
56
|
-
}> => {
|
|
47
|
+
export const calculateAmountDistribution = (
|
|
48
|
+
amountToInvest: number,
|
|
49
|
+
collateralPrice: number, // in usd
|
|
50
|
+
collateralUnits: Web3Number, // existing collateral in vesu (e.g. BTC)
|
|
51
|
+
extendedExposureUsd: Web3Number,
|
|
52
|
+
): {
|
|
53
|
+
vesuAmount: Web3Number;
|
|
54
|
+
extendedAmount: Web3Number;
|
|
55
|
+
extendedLeverage: number;
|
|
56
|
+
vesuLeverage: number;
|
|
57
|
+
} => {
|
|
57
58
|
try {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
: new Web3Number(0, WBTC_TOKEN_DECIMALS);
|
|
73
|
-
const extendedExposureUSD =
|
|
74
|
-
extendedBTCExposure.multipliedBy(collateralPrice);
|
|
59
|
+
/**
|
|
60
|
+
* Logic: Match the newly created total exposure in USD on both sides
|
|
61
|
+
* New Vesu exposure = VesuAmount * vesuLeverage
|
|
62
|
+
* New Extended exposure = ExtendedAmount * extendedLeverage
|
|
63
|
+
* VesuAmount + ExtendedAmount = amountToInvest
|
|
64
|
+
* ExtendedAmount * extendedleverage = (amountToInvest - ExtendedAmount) * vesuLeverage
|
|
65
|
+
* ExtendedAmount * (extendedleverage + vesuLeverage) = amountToInvest * vesuLeverage
|
|
66
|
+
* ExtendedAmount = amountToInvest * vesuLeverage / (extendedleverage + vesuLeverage)
|
|
67
|
+
* VesuAmount = amountToInvest - ExtendedAmount
|
|
68
|
+
* @dev note: below cal includes existing exposures too
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
const extendedLeverage = calculateExtendedLevergae();
|
|
72
|
+
const vesuLeverage = calculateVesuLeverage();
|
|
75
73
|
const vesuBTCExposureUSD = collateralUnits.multipliedBy(collateralPrice);
|
|
76
|
-
const numerator1 =
|
|
77
|
-
const numerator2 =
|
|
78
|
-
const denominator =
|
|
74
|
+
const numerator1 = vesuLeverage * amountToInvest + vesuBTCExposureUSD.toNumber();
|
|
75
|
+
const numerator2 = extendedExposureUsd.toNumber();
|
|
76
|
+
const denominator = vesuLeverage + extendedLeverage;
|
|
79
77
|
const ExtendedAmount = new Web3Number(
|
|
80
78
|
((numerator1 - numerator2) / denominator).toFixed(2),
|
|
81
|
-
USDC_TOKEN_DECIMALS
|
|
79
|
+
USDC_TOKEN_DECIMALS,
|
|
82
80
|
);
|
|
83
81
|
|
|
84
82
|
const VesuAmount = new Web3Number(
|
|
85
|
-
|
|
86
|
-
USDC_TOKEN_DECIMALS
|
|
83
|
+
amountToInvest.toFixed(2),
|
|
84
|
+
USDC_TOKEN_DECIMALS,
|
|
87
85
|
).minus(ExtendedAmount);
|
|
88
86
|
|
|
89
87
|
return {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
vesuAmount: VesuAmount,
|
|
89
|
+
extendedAmount: ExtendedAmount,
|
|
90
|
+
extendedLeverage,
|
|
91
|
+
vesuLeverage,
|
|
94
92
|
};
|
|
95
93
|
} catch (err) {
|
|
96
94
|
return {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
vesuAmount: new Web3Number(0, 0),
|
|
96
|
+
extendedAmount: new Web3Number(0, 0),
|
|
97
|
+
extendedLeverage: 0,
|
|
98
|
+
vesuLeverage: 0,
|
|
101
99
|
};
|
|
102
100
|
}
|
|
103
101
|
};
|
|
@@ -113,7 +111,7 @@ export const calculateAmountDistributionForWithdrawal = async (
|
|
|
113
111
|
amountInUsdc: Web3Number,
|
|
114
112
|
collateralPrice: number,
|
|
115
113
|
collateralUnits: Web3Number,
|
|
116
|
-
extendedPosition: Position[] | null
|
|
114
|
+
extendedPosition: Position[] | null,
|
|
117
115
|
): Promise<{
|
|
118
116
|
vesu_amount: Web3Number;
|
|
119
117
|
extended_amount: Web3Number;
|
|
@@ -128,9 +126,9 @@ export const calculateAmountDistributionForWithdrawal = async (
|
|
|
128
126
|
return null;
|
|
129
127
|
}
|
|
130
128
|
const extendedExposureUSD =
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
extendedPosition.length > 0
|
|
130
|
+
? new Web3Number(extendedPosition[0].value, USDC_TOKEN_DECIMALS)
|
|
131
|
+
: new Web3Number(0, USDC_TOKEN_DECIMALS);
|
|
134
132
|
const vesuExposureUSD = collateralUnits.multipliedBy(collateralPrice);
|
|
135
133
|
if (vesuExposureUSD.lessThan(0)) {
|
|
136
134
|
return {
|
|
@@ -148,24 +146,20 @@ export const calculateAmountDistributionForWithdrawal = async (
|
|
|
148
146
|
vesu_leverage,
|
|
149
147
|
};
|
|
150
148
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
149
|
+
logger.debug(`calculateAmountDistributionForWithdrawal vesuExposureUsd=${vesuExposureUSD.toNumber()}`);
|
|
150
|
+
logger.debug(`calculateAmountDistributionForWithdrawal extendedExposureUsd=${extendedExposureUSD.toNumber()}`);
|
|
151
|
+
logger.debug(`calculateAmountDistributionForWithdrawal amountInUsdc=${amountInUsdc.toNumber()}`);
|
|
152
|
+
logger.debug(`calculateAmountDistributionForWithdrawal extendedLeverage=${extended_leverage}`);
|
|
153
|
+
logger.debug(`calculateAmountDistributionForWithdrawal vesuLeverage=${vesu_leverage}`);
|
|
156
154
|
const numerator1 = amountInUsdc.multipliedBy(extended_leverage);
|
|
157
155
|
const numerator2 = vesuExposureUSD;
|
|
158
|
-
const numerator3 = extendedExposureUSD
|
|
159
|
-
.multipliedBy(-1);
|
|
156
|
+
const numerator3 = extendedExposureUSD.multipliedBy(-1);
|
|
160
157
|
const finalNumerator = numerator1.plus(numerator2).plus(numerator3);
|
|
161
158
|
const denominator = extended_leverage + vesu_leverage;
|
|
162
159
|
const vesuAmountInUSDC = finalNumerator.dividedBy(denominator);
|
|
163
|
-
|
|
160
|
+
logger.debug(`calculateAmountDistributionForWithdrawal vesuAmountInUsdc=${vesuAmountInUSDC.toNumber()}`);
|
|
164
161
|
const extendedAmountInUSDC = amountInUsdc.minus(vesuAmountInUSDC);
|
|
165
|
-
|
|
166
|
-
"the extended amount in usdc is",
|
|
167
|
-
extendedAmountInUSDC.toNumber()
|
|
168
|
-
);
|
|
162
|
+
logger.debug(`calculateAmountDistributionForWithdrawal extendedAmountInUsdc=${extendedAmountInUSDC.toNumber()}`);
|
|
169
163
|
//console.log("the vesu amount in usdc is", vesuAmountInUSDC.toNumber());
|
|
170
164
|
//console.log("the extended amount in usdc is", extendedAmountInUSDC.toNumber());\
|
|
171
165
|
await new Promise((resolve) => setTimeout(resolve, 10000));
|
|
@@ -176,7 +170,9 @@ export const calculateAmountDistributionForWithdrawal = async (
|
|
|
176
170
|
vesu_leverage,
|
|
177
171
|
};
|
|
178
172
|
} catch (err) {
|
|
179
|
-
logger.error(
|
|
173
|
+
logger.error(
|
|
174
|
+
`error calculating amount distribution for withdrawal: ${err}`,
|
|
175
|
+
);
|
|
180
176
|
return null;
|
|
181
177
|
}
|
|
182
178
|
};
|
|
@@ -186,10 +182,10 @@ export const calculateAmountDistributionForWithdrawal = async (
|
|
|
186
182
|
* @returns {number} The calculated leverage value
|
|
187
183
|
*/
|
|
188
184
|
export const calculateVesuLeverage = () => {
|
|
189
|
-
const
|
|
190
|
-
const
|
|
191
|
-
const leverage =
|
|
192
|
-
return
|
|
185
|
+
const targetLtv = VesuConfig.targetLtv;
|
|
186
|
+
const debtBorrowed = targetLtv / (1 - targetLtv);
|
|
187
|
+
const leverage = (1 + debtBorrowed);
|
|
188
|
+
return leverage;
|
|
193
189
|
};
|
|
194
190
|
|
|
195
191
|
/**
|
|
@@ -216,32 +212,44 @@ export const calculateExtendedLevergae = () => {
|
|
|
216
212
|
* @returns {object} Object containing deltadebtAmountUnits and isIncrease flag
|
|
217
213
|
*/
|
|
218
214
|
// In case BTC_PRICE DROPS the added amount will be zero, and use this formula to calculated the debt that needs to be paid to maintain the ltv
|
|
215
|
+
|
|
219
216
|
export const calculateDebtAmount = (
|
|
220
217
|
collateralAmount: Web3Number,
|
|
221
218
|
debtAmount: Web3Number,
|
|
222
219
|
debtPrice: number,
|
|
223
|
-
maxLtv: number =
|
|
220
|
+
maxLtv: number = VesuConfig.maxLtv,
|
|
224
221
|
addedAmount: Web3Number, // this is in btc
|
|
225
222
|
collateralPrice: number,
|
|
226
|
-
isDeposit: boolean
|
|
223
|
+
isDeposit: boolean,
|
|
224
|
+
targetLtv: number = VesuConfig.targetLtv,
|
|
227
225
|
) => {
|
|
228
226
|
try {
|
|
229
227
|
// => X = (((collateral + legDepositAmount) * collateralPrice * ltv) - (debt * debtPrice * target hf)) / (target hf - ltv)
|
|
228
|
+
logger.debug(`calculateDebtAmount maxLtv=${maxLtv}, collateralAmount=${collateralAmount.toNumber()}`);
|
|
229
|
+
logger.debug(`calculateDebtAmount targetLtv=${targetLtv}, debtAmount=${debtAmount.toNumber()}`);
|
|
230
|
+
|
|
231
|
+
const targetHf = VesuConfig.maxLtv / targetLtv;
|
|
232
|
+
logger.debug(`calculateDebtAmount targetHf=${targetHf}`);
|
|
230
233
|
const addedCollateral = addedAmount.multipliedBy(isDeposit ? 1 : -1);
|
|
231
|
-
|
|
232
|
-
|
|
234
|
+
logger.debug(`calculateDebtAmount addedCollateral=${addedCollateral.toNumber()}, collateralPrice=${collateralPrice}`);
|
|
235
|
+
const numerator1 = collateralAmount
|
|
236
|
+
.plus(addedCollateral)
|
|
233
237
|
.multipliedBy(collateralPrice)
|
|
234
238
|
.multipliedBy(maxLtv);
|
|
239
|
+
logger.debug(`calculateDebtAmount numerator1=${numerator1.toNumber()}`);
|
|
235
240
|
const numerator2 = debtAmount
|
|
236
241
|
.multipliedBy(debtPrice)
|
|
237
|
-
.multipliedBy(
|
|
238
|
-
|
|
242
|
+
.multipliedBy(targetHf);
|
|
243
|
+
logger.debug(`calculateDebtAmount numerator2=${numerator2.toNumber()}`);
|
|
244
|
+
const denominator = targetHf - maxLtv;
|
|
245
|
+
logger.debug(`calculateDebtAmount denominator=${denominator}`);
|
|
239
246
|
const x_debt_usd = numerator1.minus(numerator2).dividedBy(denominator);
|
|
240
|
-
|
|
247
|
+
logger.debug(`calculateDebtAmount xDebtUsd=${x_debt_usd.toNumber()}`);
|
|
248
|
+
const deltadebtAmountUnits = new Web3Number(
|
|
241
249
|
x_debt_usd.dividedBy(debtPrice).toFixed(2),
|
|
242
|
-
2
|
|
250
|
+
2,
|
|
243
251
|
);
|
|
244
|
-
|
|
252
|
+
const isIncrease = x_debt_usd.greaterThan(0);
|
|
245
253
|
return { deltadebtAmountUnits, isIncrease };
|
|
246
254
|
} catch (err) {
|
|
247
255
|
return { deltadebtAmountUnits: null, isIncrease: null };
|
|
@@ -266,7 +274,7 @@ export const calculateDebtReductionAmountForWithdrawal = (
|
|
|
266
274
|
withdrawalAmount: Web3Number,
|
|
267
275
|
collateralPrice: number,
|
|
268
276
|
debtPrice: number,
|
|
269
|
-
usdcDecimals: number
|
|
277
|
+
usdcDecimals: number,
|
|
270
278
|
) => {
|
|
271
279
|
try {
|
|
272
280
|
const vesuLeverage = calculateVesuLeverage();
|
|
@@ -293,44 +301,99 @@ export const calculateDebtReductionAmountForWithdrawal = (
|
|
|
293
301
|
}
|
|
294
302
|
};
|
|
295
303
|
|
|
304
|
+
|
|
305
|
+
// ! required?
|
|
296
306
|
/**
|
|
297
307
|
* calculate the amount to deposit on extended when incurring losses
|
|
298
308
|
* @param client - The client
|
|
299
309
|
* @returns The amount to deposit on extended when incurring losses
|
|
300
310
|
*/
|
|
301
311
|
export const calculateAmountDepositOnExtendedWhenIncurringLosses = async (
|
|
302
|
-
client: ExtendedWrapper
|
|
312
|
+
client: ExtendedWrapper,
|
|
303
313
|
) => {
|
|
304
314
|
try {
|
|
305
315
|
const extendedHoldings = await client.getHoldings();
|
|
306
316
|
const extended_leverage = calculateExtendedLevergae();
|
|
307
317
|
const latestPosition = (await client.getPositions()).data.pop();
|
|
308
318
|
if (!extendedHoldings || !latestPosition) {
|
|
309
|
-
logger.error(
|
|
319
|
+
logger.error(
|
|
320
|
+
`error getting extended position: extendedHoldings=${extendedHoldings}, latestPosition=${latestPosition}`,
|
|
321
|
+
);
|
|
310
322
|
return null;
|
|
311
323
|
}
|
|
312
|
-
const positionValueInUSD =
|
|
324
|
+
const positionValueInUSD = new Web3Number(
|
|
325
|
+
latestPosition.value,
|
|
326
|
+
USDC_TOKEN_DECIMALS,
|
|
327
|
+
);
|
|
313
328
|
const equity = extendedHoldings.data.equity;
|
|
314
|
-
const deposit =
|
|
315
|
-
|
|
316
|
-
|
|
329
|
+
const deposit = positionValueInUSD
|
|
330
|
+
.dividedBy(extended_leverage)
|
|
331
|
+
.minus(equity)
|
|
332
|
+
.toFixed(2);
|
|
333
|
+
return new Web3Number(deposit, USDC_TOKEN_DECIMALS);
|
|
317
334
|
} catch (err) {
|
|
335
|
+
logger.error(
|
|
336
|
+
`error calculating amount deposit on extended when incurring losses: ${err}`,
|
|
337
|
+
);
|
|
318
338
|
return null;
|
|
319
339
|
}
|
|
320
340
|
};
|
|
321
341
|
|
|
342
|
+
/**
|
|
343
|
+
* calculate the amount of collateral to deposit to maintain the ltv
|
|
344
|
+
* The formula is:
|
|
345
|
+
* ((debt * debtPrice * targetHF) - (collateral * collateralPrice * ltv)) / ltv
|
|
346
|
+
* @param collateralAmount in collateral units
|
|
347
|
+
* @param debtAmount in debt units
|
|
348
|
+
* @param debtPrice in usd
|
|
349
|
+
* @param maxLtv
|
|
350
|
+
* @param collateralPrice in usd
|
|
351
|
+
* @param targetHF
|
|
352
|
+
* @returns deltaCollateralAmountUnits in collateral units
|
|
353
|
+
* null if there is an error
|
|
354
|
+
*/
|
|
355
|
+
export const calculateWBTCAmountToMaintainLTV = (
|
|
356
|
+
collateralAmount: Web3Number,
|
|
357
|
+
debtAmount: Web3Number,
|
|
358
|
+
debtPrice: number,
|
|
359
|
+
maxLtv: number = MAX_LIQUIDATION_RATIO,
|
|
360
|
+
collateralPrice: number,
|
|
361
|
+
) => {
|
|
362
|
+
try {
|
|
363
|
+
const targetHf = VesuConfig.maxLtv / VesuConfig.targetLtv;
|
|
364
|
+
const numerator1 = collateralAmount
|
|
365
|
+
.multipliedBy(collateralPrice)
|
|
366
|
+
.multipliedBy(maxLtv);
|
|
367
|
+
const numerator2 = debtAmount
|
|
368
|
+
.multipliedBy(debtPrice)
|
|
369
|
+
.multipliedBy(targetHf);
|
|
370
|
+
const denominator = maxLtv;
|
|
371
|
+
const collateralAmountToMaintainLTV = numerator2
|
|
372
|
+
.minus(numerator1)
|
|
373
|
+
.dividedBy(denominator);
|
|
374
|
+
let deltaCollateralAmountUnits = new Web3Number(
|
|
375
|
+
collateralAmountToMaintainLTV
|
|
376
|
+
.dividedBy(collateralPrice)
|
|
377
|
+
.toFixed(WBTC_TOKEN_DECIMALS),
|
|
378
|
+
WBTC_TOKEN_DECIMALS,
|
|
379
|
+
);
|
|
380
|
+
return { deltaCollateralAmountUnits };
|
|
381
|
+
} catch (err) {
|
|
382
|
+
return { deltaCollateralAmountUnits: null };
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
// ! required?
|
|
322
387
|
export const calculateExposureDelta = (
|
|
323
388
|
exposure_extended: number,
|
|
324
|
-
exposure_vesu: number
|
|
389
|
+
exposure_vesu: number,
|
|
325
390
|
) => {
|
|
326
391
|
const exposure_delta = new Web3Number(exposure_extended - exposure_vesu, 2);
|
|
327
392
|
return exposure_delta.absoluteValue().toNumber();
|
|
328
393
|
};
|
|
329
394
|
|
|
330
|
-
/// In case BTC PRICE DROPS
|
|
331
|
-
// 1. calculate the ltv on vesu
|
|
332
|
-
// 2. Find the debt that needs to be paid to maintain the ltv
|
|
333
395
|
|
|
396
|
+
// ! required?
|
|
334
397
|
/**
|
|
335
398
|
* calculate the delta percentage between the current btc price and the last btc price
|
|
336
399
|
* @param {number} btcPrice - The current btc price
|
|
@@ -339,34 +402,127 @@ export const calculateExposureDelta = (
|
|
|
339
402
|
*/
|
|
340
403
|
export const calculateBTCPriceDelta = (
|
|
341
404
|
btcPrice: number,
|
|
342
|
-
lastBtcPrice: number
|
|
405
|
+
lastBtcPrice: number,
|
|
343
406
|
) => {
|
|
344
407
|
return ((btcPrice - lastBtcPrice) / lastBtcPrice) * 100;
|
|
345
408
|
};
|
|
346
409
|
|
|
347
410
|
export const calculateVesUPositionSizeGivenExtended = (
|
|
348
|
-
|
|
411
|
+
extendedPositonSize: number,
|
|
349
412
|
extendedHoldingAmount: Web3Number,
|
|
350
413
|
collateralAmount: Web3Number,
|
|
351
|
-
|
|
414
|
+
extendedBtcPrice: number,
|
|
352
415
|
) => {
|
|
353
416
|
const extendedLeverage = calculateExtendedLevergae();
|
|
354
417
|
const vesuLeverage = calculateVesuLeverage();
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
418
|
+
logger.debug(`calculateVesUPositionSizeGivenExtended extendedLeverage=${extendedLeverage}`);
|
|
419
|
+
logger.debug(`calculateVesUPositionSizeGivenExtended vesuLeverage=${vesuLeverage}`);
|
|
420
|
+
const extendedAmountInBTC = new Web3Number(extendedHoldingAmount.dividedBy(extendedBtcPrice).toFixed(WBTC_TOKEN_DECIMALS), WBTC_TOKEN_DECIMALS);
|
|
421
|
+
logger.debug(`calculateVesUPositionSizeGivenExtended extendedAmountInBTC=${extendedAmountInBTC.toNumber()}`);
|
|
422
|
+
const numerator1 = extendedAmountInBTC
|
|
423
|
+
.multipliedBy(extendedLeverage)
|
|
424
|
+
.plus(extendedPositonSize);
|
|
425
|
+
logger.debug(`calculateVesUPositionSizeGivenExtended numerator1=${numerator1.toNumber()}`);
|
|
360
426
|
const numerator2 = collateralAmount
|
|
361
|
-
.multipliedBy(collateralPrice)
|
|
362
427
|
.multipliedBy(-1);
|
|
363
|
-
|
|
364
|
-
const vesuAmountInBTC =
|
|
365
|
-
|
|
366
|
-
.toFixed(WBTC_TOKEN_DECIMALS);
|
|
428
|
+
logger.debug(`calculateVesUPositionSizeGivenExtended numerator2=${numerator2.toNumber()}`);
|
|
429
|
+
const vesuAmountInBTC = new Web3Number(numerator1.plus(numerator2).dividedBy(vesuLeverage).toFixed(WBTC_TOKEN_DECIMALS), WBTC_TOKEN_DECIMALS);
|
|
430
|
+
logger.debug(`calculateVesUPositionSizeGivenExtended vesuAmountInBTC=${vesuAmountInBTC.toNumber()}`);
|
|
367
431
|
return {
|
|
368
|
-
|
|
369
|
-
vesuAmountInBTC: new Web3Number(vesuAmountInBTC, WBTC_TOKEN_DECIMALS),
|
|
432
|
+
vesuAmountInBTC: vesuAmountInBTC,
|
|
370
433
|
extendedAmountInBTC: extendedAmountInBTC,
|
|
371
434
|
};
|
|
372
435
|
};
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* calculate the debt amount to be repaid to maintain the ltv
|
|
439
|
+
* @param maxLtv - The maximum ltv
|
|
440
|
+
* @param existingVesuCollateral - The existing vesu collateral
|
|
441
|
+
* @param existingVesuDebt - The existing vesu debt
|
|
442
|
+
* @param collateralPrice - The collateral price
|
|
443
|
+
* @param debtPrice - The debt price
|
|
444
|
+
* @param targetHf - The target hf
|
|
445
|
+
* @@dev returns negative to represent debt to be repaid
|
|
446
|
+
* @returns The debt amount to be repaid
|
|
447
|
+
*/
|
|
448
|
+
export const calculateDeltaDebtAmount = (
|
|
449
|
+
existingVesuCollateral: Web3Number,
|
|
450
|
+
existingVesuDebt: Web3Number,
|
|
451
|
+
debtPrice: number,
|
|
452
|
+
collateralPrice: number,
|
|
453
|
+
) => {
|
|
454
|
+
const currentHf = HealthFactorMath.getHealthFactor(
|
|
455
|
+
existingVesuCollateral,
|
|
456
|
+
collateralPrice,
|
|
457
|
+
VesuConfig.maxLtv,
|
|
458
|
+
existingVesuDebt,
|
|
459
|
+
debtPrice
|
|
460
|
+
);
|
|
461
|
+
const targetHf = VesuConfig.maxLtv / VesuConfig.targetLtv;
|
|
462
|
+
logger.debug(`calculateDeltaDebtAmount currentHf=${currentHf} targetHf=${targetHf}`);
|
|
463
|
+
|
|
464
|
+
const term1 = existingVesuCollateral
|
|
465
|
+
.multipliedBy(collateralPrice)
|
|
466
|
+
.multipliedBy(VesuConfig.maxLtv);
|
|
467
|
+
|
|
468
|
+
const term2 = existingVesuDebt
|
|
469
|
+
.multipliedBy(debtPrice)
|
|
470
|
+
.multipliedBy(targetHf)
|
|
471
|
+
.multipliedBy(-1);
|
|
472
|
+
const debtAmountToBeRepaid = term1.plus(term2).dividedBy(targetHf);
|
|
473
|
+
return {
|
|
474
|
+
deltaDebt: new Web3Number(
|
|
475
|
+
debtAmountToBeRepaid.toFixed(USDC_TOKEN_DECIMALS),
|
|
476
|
+
USDC_TOKEN_DECIMALS,
|
|
477
|
+
),
|
|
478
|
+
shouldRebalance: currentHf < (targetHf - 0.05),
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
export const calculatePositionToCloseToWithdrawAmount = async (
|
|
483
|
+
extendedBalance: Balance,
|
|
484
|
+
extendedPositions: Position,
|
|
485
|
+
amountToWithdraw: Web3Number,
|
|
486
|
+
) => {
|
|
487
|
+
try {
|
|
488
|
+
const extendedLeverage = calculateExtendedLevergae();
|
|
489
|
+
const extendedPosition = extendedPositions.value;
|
|
490
|
+
const marginRequired = new Web3Number(
|
|
491
|
+
extendedBalance.initialMargin,
|
|
492
|
+
USDC_TOKEN_DECIMALS,
|
|
493
|
+
);
|
|
494
|
+
const unrealisedPnl = new Web3Number(
|
|
495
|
+
extendedBalance.unrealisedPnl,
|
|
496
|
+
USDC_TOKEN_DECIMALS,
|
|
497
|
+
);
|
|
498
|
+
const availableForWithdrawal = new Web3Number(
|
|
499
|
+
extendedBalance.availableForWithdrawal,
|
|
500
|
+
USDC_TOKEN_DECIMALS,
|
|
501
|
+
);
|
|
502
|
+
const upnlPercent = unrealisedPnl.dividedBy(extendedPosition);
|
|
503
|
+
/**
|
|
504
|
+
* New Formula
|
|
505
|
+
*/
|
|
506
|
+
const walletBalance = new Web3Number(
|
|
507
|
+
extendedBalance.balance,
|
|
508
|
+
USDC_TOKEN_DECIMALS,
|
|
509
|
+
);
|
|
510
|
+
const term1 = marginRequired
|
|
511
|
+
.minus(walletBalance)
|
|
512
|
+
.minus(availableForWithdrawal)
|
|
513
|
+
.plus(amountToWithdraw)
|
|
514
|
+
.multipliedBy(extendedLeverage);
|
|
515
|
+
const denominator = upnlPercent.multipliedBy(extendedLeverage).plus(1);
|
|
516
|
+
return new Web3Number(
|
|
517
|
+
Math.ceil(
|
|
518
|
+
term1.dividedBy(denominator).dividedBy(extendedLeverage).toNumber(),
|
|
519
|
+
),
|
|
520
|
+
USDC_TOKEN_DECIMALS,
|
|
521
|
+
);
|
|
522
|
+
} catch (err) {
|
|
523
|
+
logger.error(
|
|
524
|
+
`error calculating position to close to withdraw amount: ${err}`,
|
|
525
|
+
);
|
|
526
|
+
return new Web3Number(0, USDC_TOKEN_DECIMALS);
|
|
527
|
+
}
|
|
528
|
+
};
|