@strkfarm/sdk 2.0.0-dev.3 → 2.0.0-dev.30

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.
Files changed (75) hide show
  1. package/dist/cli.js +190 -36
  2. package/dist/cli.mjs +188 -34
  3. package/dist/index.browser.global.js +78478 -45620
  4. package/dist/index.browser.mjs +19583 -9901
  5. package/dist/index.d.ts +3763 -1424
  6. package/dist/index.js +20980 -11063
  7. package/dist/index.mjs +20948 -11087
  8. package/package.json +1 -1
  9. package/src/data/avnu.abi.json +840 -0
  10. package/src/data/ekubo-price-fethcer.abi.json +265 -0
  11. package/src/dataTypes/_bignumber.ts +13 -4
  12. package/src/dataTypes/bignumber.browser.ts +6 -1
  13. package/src/dataTypes/bignumber.node.ts +5 -1
  14. package/src/dataTypes/index.ts +3 -2
  15. package/src/dataTypes/mynumber.ts +141 -0
  16. package/src/global.ts +76 -41
  17. package/src/index.browser.ts +2 -1
  18. package/src/interfaces/common.tsx +175 -3
  19. package/src/modules/ExtendedWrapperSDk/types.ts +28 -5
  20. package/src/modules/ExtendedWrapperSDk/wrapper.ts +275 -59
  21. package/src/modules/apollo-client-config.ts +28 -0
  22. package/src/modules/avnu.ts +4 -4
  23. package/src/modules/ekubo-pricer.ts +79 -0
  24. package/src/modules/ekubo-quoter.ts +48 -30
  25. package/src/modules/erc20.ts +17 -0
  26. package/src/modules/harvests.ts +43 -29
  27. package/src/modules/pragma.ts +23 -8
  28. package/src/modules/pricer-from-api.ts +156 -15
  29. package/src/modules/pricer-lst.ts +1 -1
  30. package/src/modules/pricer.ts +40 -4
  31. package/src/modules/pricerBase.ts +2 -1
  32. package/src/node/deployer.ts +36 -1
  33. package/src/node/pricer-redis.ts +2 -1
  34. package/src/strategies/base-strategy.ts +78 -10
  35. package/src/strategies/ekubo-cl-vault.tsx +906 -347
  36. package/src/strategies/factory.ts +159 -0
  37. package/src/strategies/index.ts +7 -1
  38. package/src/strategies/registry.ts +239 -0
  39. package/src/strategies/sensei.ts +335 -7
  40. package/src/strategies/svk-strategy.ts +97 -27
  41. package/src/strategies/types.ts +4 -0
  42. package/src/strategies/universal-adapters/adapter-utils.ts +2 -1
  43. package/src/strategies/universal-adapters/avnu-adapter.ts +180 -265
  44. package/src/strategies/universal-adapters/baseAdapter.ts +263 -251
  45. package/src/strategies/universal-adapters/common-adapter.ts +206 -203
  46. package/src/strategies/universal-adapters/extended-adapter.ts +490 -316
  47. package/src/strategies/universal-adapters/index.ts +11 -8
  48. package/src/strategies/universal-adapters/svk-troves-adapter.ts +364 -0
  49. package/src/strategies/universal-adapters/token-transfer-adapter.ts +200 -0
  50. package/src/strategies/universal-adapters/usdc<>usdce-adapter.ts +200 -0
  51. package/src/strategies/universal-adapters/vesu-adapter.ts +120 -82
  52. package/src/strategies/universal-adapters/vesu-modify-position-adapter.ts +476 -0
  53. package/src/strategies/universal-adapters/vesu-multiply-adapter.ts +1067 -704
  54. package/src/strategies/universal-adapters/vesu-position-common.ts +251 -0
  55. package/src/strategies/universal-adapters/vesu-supply-only-adapter.ts +18 -3
  56. package/src/strategies/universal-lst-muliplier-strategy.tsx +397 -204
  57. package/src/strategies/universal-strategy.tsx +1426 -1173
  58. package/src/strategies/vesu-extended-strategy/services/executionService.ts +2233 -0
  59. package/src/strategies/vesu-extended-strategy/services/extended-vesu-state-manager.ts +4087 -0
  60. package/src/strategies/vesu-extended-strategy/services/ltv-imbalance-rebalance-math.ts +783 -0
  61. package/src/strategies/vesu-extended-strategy/services/operationService.ts +38 -16
  62. package/src/strategies/vesu-extended-strategy/types/transaction-metadata.ts +88 -0
  63. package/src/strategies/vesu-extended-strategy/utils/config.runtime.ts +1 -0
  64. package/src/strategies/vesu-extended-strategy/utils/constants.ts +5 -6
  65. package/src/strategies/vesu-extended-strategy/utils/helper.ts +259 -103
  66. package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +688 -817
  67. package/src/strategies/vesu-rebalance.tsx +255 -152
  68. package/src/utils/cacheClass.ts +11 -2
  69. package/src/utils/health-factor-math.ts +4 -1
  70. package/src/utils/index.ts +3 -1
  71. package/src/utils/logger.browser.ts +22 -4
  72. package/src/utils/logger.node.ts +259 -24
  73. package/src/utils/starknet-call-parser.ts +1036 -0
  74. package/src/utils/strategy-utils.ts +61 -0
  75. 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 Extend and Vesu
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 = async (
44
- amount: number,
45
- client: ExtendedWrapper,
46
- marketName: string,
47
- collateralPrice: number,
48
- debtPrice: number,
49
- collateralUnits: Web3Number,
50
- extendedPosition: Position[] | null
51
- ): Promise<{
52
- vesu_amount: Web3Number;
53
- extended_amount: Web3Number;
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
- const extended_leverage = calculateExtendedLevergae();
59
- const vesu_leverage = calculateVesuLeverage();
60
- if (extendedPosition === null) {
61
- logger.error("error getting extended positions");
62
- return {
63
- vesu_amount: new Web3Number(0, 0),
64
- extended_amount: new Web3Number(0, 0),
65
- extended_leverage: 0,
66
- vesu_leverage: 0,
67
- };
68
- }
69
- const extendedBTCExposure =
70
- extendedPosition.length > 0
71
- ? new Web3Number(extendedPosition[0].size, WBTC_TOKEN_DECIMALS)
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 = vesu_leverage * amount + vesuBTCExposureUSD.toNumber();
77
- const numerator2 = extendedExposureUSD.toNumber();
78
- const denominator = vesu_leverage + extended_leverage;
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
- amount.toFixed(2),
86
- USDC_TOKEN_DECIMALS
83
+ amountToInvest.toFixed(2),
84
+ USDC_TOKEN_DECIMALS,
87
85
  ).minus(ExtendedAmount);
88
86
 
89
87
  return {
90
- vesu_amount: VesuAmount,
91
- extended_amount: ExtendedAmount,
92
- extended_leverage,
93
- vesu_leverage,
88
+ vesuAmount: VesuAmount,
89
+ extendedAmount: ExtendedAmount,
90
+ extendedLeverage,
91
+ vesuLeverage,
94
92
  };
95
93
  } catch (err) {
96
94
  return {
97
- vesu_amount: new Web3Number(0, 0),
98
- extended_amount: new Web3Number(0, 0),
99
- extended_leverage: 0,
100
- vesu_leverage: 0,
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
- extendedPosition.length > 0
132
- ? new Web3Number(extendedPosition[0].value, USDC_TOKEN_DECIMALS)
133
- : new Web3Number(0, USDC_TOKEN_DECIMALS);
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
- console.log("the vesu exposure usd is", vesuExposureUSD.toNumber());
152
- console.log("the extended exposure usd is", extendedExposureUSD.toNumber());
153
- console.log("the amount in usdc is", amountInUsdc.toNumber());
154
- console.log("the extended leverage is", extended_leverage);
155
- console.log("the vesu leverage is", vesu_leverage);
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
- console.log("the vesu amount in usdc is", vesuAmountInUSDC.toNumber());
160
+ logger.debug(`calculateAmountDistributionForWithdrawal vesuAmountInUsdc=${vesuAmountInUSDC.toNumber()}`);
164
161
  const extendedAmountInUSDC = amountInUsdc.minus(vesuAmountInUSDC);
165
- console.log(
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(`error calculating amount distribution for withdrawal: ${err}`);
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 max_ltv_ratio = (1 - MAX_PRICE_DROP_PERCENTAGE) * MAX_LIQUIDATION_RATIO; //0.75
190
- const our_ltv_ratio = Math.floor(max_ltv_ratio * 100) - 5; //buffer of 5% to prevent liquidation
191
- const leverage = 1 / (1 - our_ltv_ratio / 100);
192
- return Math.ceil(leverage * 10) / 10;
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 = MAX_LIQUIDATION_RATIO,
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
- const numerator1 = (collateralAmount
232
- .plus(addedCollateral))
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(TARGET_HF);
238
- const denominator = TARGET_HF - maxLtv;
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
- let deltadebtAmountUnits = new Web3Number(
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
- let isIncrease = x_debt_usd.greaterThan(0);
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(`error getting extended position: extendedHoldings=${extendedHoldings}, latestPosition=${latestPosition}`);
319
+ logger.error(
320
+ `error getting extended position: extendedHoldings=${extendedHoldings}, latestPosition=${latestPosition}`,
321
+ );
310
322
  return null;
311
323
  }
312
- const positionValueInUSD = latestPosition.value;
324
+ const positionValueInUSD = new Web3Number(
325
+ latestPosition.value,
326
+ USDC_TOKEN_DECIMALS,
327
+ );
313
328
  const equity = extendedHoldings.data.equity;
314
- const deposit =
315
- Number(positionValueInUSD) / extended_leverage - Number(equity);
316
- return new Web3Number(Math.floor(deposit / 0.2) * 0.2, USDC_TOKEN_DECIMALS);
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
- extendedPositonValue: number,
411
+ extendedPositonSize: number,
349
412
  extendedHoldingAmount: Web3Number,
350
413
  collateralAmount: Web3Number,
351
- collateralPrice: number
414
+ extendedBtcPrice: number,
352
415
  ) => {
353
416
  const extendedLeverage = calculateExtendedLevergae();
354
417
  const vesuLeverage = calculateVesuLeverage();
355
- const extendedAmount = extendedHoldingAmount;
356
- const extendedAmountInBTC = extendedAmount
357
- .dividedBy(collateralPrice)
358
- const numerator1 = extendedAmount.multipliedBy(extendedLeverage)
359
- .plus(extendedPositonValue)
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
- const vesuAmountInUsd = numerator1.plus(numerator2).dividedBy(vesuLeverage);
364
- const vesuAmountInBTC = vesuAmountInUsd
365
- .dividedBy(collateralPrice)
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
- vesuAmountInUsd: vesuAmountInUsd.toFixed(2),
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
+ };