@strkfarm/sdk 2.0.0-dev.27 → 2.0.0-dev.28

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 (70) hide show
  1. package/dist/cli.js +190 -36
  2. package/dist/cli.mjs +188 -34
  3. package/dist/index.browser.global.js +79130 -49357
  4. package/dist/index.browser.mjs +18039 -11434
  5. package/dist/index.d.ts +2869 -898
  6. package/dist/index.js +19036 -12210
  7. package/dist/index.mjs +18942 -12161
  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/index.ts +3 -2
  13. package/src/dataTypes/mynumber.ts +141 -0
  14. package/src/global.ts +76 -41
  15. package/src/index.browser.ts +2 -1
  16. package/src/interfaces/common.tsx +167 -2
  17. package/src/modules/ExtendedWrapperSDk/types.ts +26 -4
  18. package/src/modules/ExtendedWrapperSDk/wrapper.ts +110 -67
  19. package/src/modules/apollo-client-config.ts +28 -0
  20. package/src/modules/avnu.ts +4 -4
  21. package/src/modules/ekubo-pricer.ts +79 -0
  22. package/src/modules/ekubo-quoter.ts +46 -30
  23. package/src/modules/erc20.ts +17 -0
  24. package/src/modules/harvests.ts +43 -29
  25. package/src/modules/pragma.ts +23 -8
  26. package/src/modules/pricer-from-api.ts +156 -15
  27. package/src/modules/pricer-lst.ts +1 -1
  28. package/src/modules/pricer.ts +40 -4
  29. package/src/modules/pricerBase.ts +2 -1
  30. package/src/node/deployer.ts +36 -1
  31. package/src/node/pricer-redis.ts +2 -1
  32. package/src/strategies/base-strategy.ts +78 -10
  33. package/src/strategies/ekubo-cl-vault.tsx +906 -347
  34. package/src/strategies/factory.ts +159 -0
  35. package/src/strategies/index.ts +6 -1
  36. package/src/strategies/registry.ts +239 -0
  37. package/src/strategies/sensei.ts +335 -7
  38. package/src/strategies/svk-strategy.ts +97 -27
  39. package/src/strategies/types.ts +4 -0
  40. package/src/strategies/universal-adapters/adapter-utils.ts +2 -1
  41. package/src/strategies/universal-adapters/avnu-adapter.ts +177 -268
  42. package/src/strategies/universal-adapters/baseAdapter.ts +263 -251
  43. package/src/strategies/universal-adapters/common-adapter.ts +206 -203
  44. package/src/strategies/universal-adapters/extended-adapter.ts +155 -336
  45. package/src/strategies/universal-adapters/index.ts +9 -8
  46. package/src/strategies/universal-adapters/token-transfer-adapter.ts +200 -0
  47. package/src/strategies/universal-adapters/usdc<>usdce-adapter.ts +200 -0
  48. package/src/strategies/universal-adapters/vesu-adapter.ts +110 -75
  49. package/src/strategies/universal-adapters/vesu-modify-position-adapter.ts +476 -0
  50. package/src/strategies/universal-adapters/vesu-multiply-adapter.ts +762 -844
  51. package/src/strategies/universal-adapters/vesu-position-common.ts +251 -0
  52. package/src/strategies/universal-adapters/vesu-supply-only-adapter.ts +18 -3
  53. package/src/strategies/universal-lst-muliplier-strategy.tsx +396 -204
  54. package/src/strategies/universal-strategy.tsx +1426 -1178
  55. package/src/strategies/vesu-extended-strategy/services/executionService.ts +2251 -0
  56. package/src/strategies/vesu-extended-strategy/services/extended-vesu-state-manager.ts +2941 -0
  57. package/src/strategies/vesu-extended-strategy/services/operationService.ts +12 -1
  58. package/src/strategies/vesu-extended-strategy/types/transaction-metadata.ts +52 -0
  59. package/src/strategies/vesu-extended-strategy/utils/config.runtime.ts +1 -0
  60. package/src/strategies/vesu-extended-strategy/utils/constants.ts +2 -0
  61. package/src/strategies/vesu-extended-strategy/utils/helper.ts +158 -124
  62. package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +377 -1788
  63. package/src/strategies/vesu-rebalance.tsx +255 -152
  64. package/src/utils/health-factor-math.ts +4 -1
  65. package/src/utils/index.ts +2 -1
  66. package/src/utils/logger.browser.ts +22 -4
  67. package/src/utils/logger.node.ts +259 -24
  68. package/src/utils/starknet-call-parser.ts +1036 -0
  69. package/src/utils/strategy-utils.ts +61 -0
  70. package/src/strategies/universal-adapters/unused-balance-adapter.ts +0 -109
@@ -2,9 +2,19 @@ import { Web3Number } from "@/dataTypes";
2
2
  import { ExtendedAdapter } from "@/strategies/universal-adapters/extended-adapter";
3
3
  import { VesuMultiplyAdapter } from "../../universal-adapters/vesu-multiply-adapter";
4
4
  import { CycleType, TransactionResult } from "../types/transaction-metadata";
5
-
5
+ import { UsdcToUsdceAdapter } from "@/strategies/universal-adapters/usdc<>usdce-adapter";
6
+ import { AssetMovementPlan } from "../vesu-extended-strategy";
6
7
  export abstract class Operations {
7
8
 
9
+ abstract computeAssetMovements(
10
+ extendedAmount: Web3Number,
11
+ vesuAmount: Web3Number
12
+ ): Promise<AssetMovementPlan | null>;
13
+
14
+ abstract executeAssetMovements(
15
+ plan: AssetMovementPlan
16
+ ): Promise<TransactionResult[]>;
17
+
8
18
  abstract shouldMoveAssets(
9
19
  extendedAmount: Web3Number,
10
20
  vesuAmount: Web3Number
@@ -28,6 +38,7 @@ export abstract class Operations {
28
38
  params: { from: string; to: string; amount: Web3Number, cycleType: CycleType },
29
39
  extendedAdapter: ExtendedAdapter,
30
40
  vesuAdapter: VesuMultiplyAdapter,
41
+ usdcToUsdceAdapter: UsdcToUsdceAdapter,
31
42
  ): Promise<TransactionResult>;
32
43
  /**
33
44
  * Handle deposit operation.
@@ -32,5 +32,57 @@ export interface TransactionResult<T = any> {
32
32
  transactionMetadata: TransactionMetadata;
33
33
  }
34
34
 
35
+ // ─── Execution Lifecycle Events ─────────────────────────────────────────────
35
36
 
37
+ /**
38
+ * Key lifecycle event types emitted during execution.
39
+ * Used by callers (e.g. risk engine) to hook into the execution pipeline
40
+ * and persist state to DB, send alerts, etc.
41
+ */
42
+ export enum ExecutionEventType {
43
+ /** Execution started — tx sent on-chain or order placed on exchange */
44
+ INITIATED = 'INITIATED',
45
+ /** Execution completed successfully — tx confirmed / order filled */
46
+ SUCCESS = 'SUCCESS',
47
+ /** Execution failed — tx reverted / order rejected / timeout */
48
+ FAILURE = 'FAILURE',
49
+ }
50
+
51
+ /**
52
+ * Metadata payload accompanying each execution lifecycle event.
53
+ * Contains relevant identifiers, prices, and contextual information.
54
+ */
55
+ export interface ExecutionEventMetadata {
56
+ /** Route type string (e.g. RouteType value) */
57
+ routeType?: string;
58
+ /** Human-readable route summary */
59
+ routeSummary?: string;
60
+ /** On-chain transaction hash (when available) */
61
+ txHash?: string;
62
+ /** Exchange order ID (for off-chain orders) */
63
+ orderId?: string;
64
+ /** Amount involved in the operation */
65
+ amount?: string;
66
+ /** Protocol name */
67
+ protocol?: string;
68
+ /** Actual execution price (for exchange orders) */
69
+ executionPrice?: number;
70
+ /** Limit price that was set */
71
+ limitPrice?: number;
72
+ /** Error message on failure */
73
+ error?: string;
74
+ /** On-chain calls that were built */
75
+ calls?: Call[];
76
+ /** Extensible: any extra metadata */
77
+ [key: string]: any;
78
+ }
79
+
80
+ /**
81
+ * Callback invoked on key execution lifecycle events.
82
+ * Callers can use this to save to DB, send notifications, log, etc.
83
+ */
84
+ export type ExecutionCallback = (
85
+ eventType: ExecutionEventType,
86
+ metadata: ExecutionEventMetadata,
87
+ ) => void | Promise<void>;
36
88
 
@@ -62,6 +62,7 @@ export const VesuConfig = {
62
62
  avnu: {
63
63
  api: AVNU_API,
64
64
  },
65
+ targetLtv : 0.61,
65
66
  minDebtForVesuRebalacing:MINIMUM_DEBT_AMOUNT_VESU_FOR_REBALANCING
66
67
  } as const;
67
68
 
@@ -18,6 +18,8 @@ export const STRK_API_RPC = process.env.STRK_API_RPC ?? "https://mainnet.starkne
18
18
  export const MAX_RETRIES = Number(process.env.MAX_RETRIES ?? 3);
19
19
  export const MAX_DELAY = Number(process.env.MAX_DELAY ?? 100);
20
20
  export const EXTEND_MARKET_NAME = "BTC-USD";
21
+
22
+ // factor of balance to keep as buffer (0.05 = 5%)
21
23
  export const LIMIT_BALANCE = Number(process.env.LIMIT_BALANCE ?? 0.05);
22
24
  export const LIMIT_BALANCE_VALUE=20;
23
25
  export const REBALANCER_INTERVAL = Number(process.env.REBALANCER_INTERVAL ?? 180000); //3 mins
@@ -9,6 +9,7 @@ import {
9
9
  USDC_TOKEN_DECIMALS,
10
10
  MAX_LIQUIDATION_RATIO,
11
11
  } from "./constants";
12
+ import { VesuConfig } from "./config.runtime";
12
13
  import { ExtendedAdapter } from "../../universal-adapters/extended-adapter";
13
14
  import { Balance } from "@/modules/ExtendedWrapperSDk";
14
15
  import { Web3Number } from "@/dataTypes";
@@ -16,6 +17,7 @@ import { Position } from "@/modules/ExtendedWrapperSDk";
16
17
  // import { getAllOpenPositionsExtended } from "../services/extendedService";
17
18
  import ExtendedWrapper from "@/modules/ExtendedWrapperSDk";
18
19
  import { logger } from "@/utils";
20
+ import { HealthFactorMath } from "@/utils/health-factor-math";
19
21
  // import {
20
22
  // calculatePositionOnVesu,
21
23
  // getAssetPrice,
@@ -29,7 +31,7 @@ import { logger } from "@/utils";
29
31
  */
30
32
  export const returnFormattedAmount = (
31
33
  amount: number,
32
- toTokenDecimals: number
34
+ toTokenDecimals: number,
33
35
  ) => {
34
36
  const formattedAmount =
35
37
  "0x" + BigInt(Math.floor(amount * 10 ** toTokenDecimals)).toString(16);
@@ -37,67 +39,63 @@ export const returnFormattedAmount = (
37
39
  };
38
40
 
39
41
  /**
40
- * calculates the amount to distribute to Extend and Vesu
42
+ * calculates the amount to distribute to Extended and Vesu
41
43
  * Determines how much to allocate to each platform based on leverage calculations
42
44
  * @param {number} amount - The total amount to distribute
43
45
  * @returns {object} Object containing avnu_amount, extended_amount, and extended_leverage
44
46
  */
45
- export const calculateAmountDistribution = async (
46
- amount: number,
47
- client: ExtendedWrapper,
48
- marketName: string,
49
- collateralPrice: number,
50
- debtPrice: number,
51
- collateralUnits: Web3Number,
52
- extendedPosition: Position[] | null
53
- ): Promise<{
54
- vesu_amount: Web3Number;
55
- extended_amount: Web3Number;
56
- extended_leverage: number;
57
- vesu_leverage: number;
58
- }> => {
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
+ } => {
59
58
  try {
60
- const extended_leverage = calculateExtendedLevergae();
61
- const vesu_leverage = calculateVesuLeverage();
62
- if (extendedPosition === null) {
63
- logger.error("error getting extended positions");
64
- return {
65
- vesu_amount: new Web3Number(0, 0),
66
- extended_amount: new Web3Number(0, 0),
67
- extended_leverage: 0,
68
- vesu_leverage: 0,
69
- };
70
- }
71
- const extendedExposureUSD =
72
- extendedPosition.length > 0
73
- ? new Web3Number(extendedPosition[0].value, WBTC_TOKEN_DECIMALS)
74
- : new Web3Number(0, WBTC_TOKEN_DECIMALS);
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;
@@ -148,23 +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
156
  const numerator3 = extendedExposureUSD.multipliedBy(-1);
159
157
  const finalNumerator = numerator1.plus(numerator2).plus(numerator3);
160
158
  const denominator = extended_leverage + vesu_leverage;
161
159
  const vesuAmountInUSDC = finalNumerator.dividedBy(denominator);
162
- console.log("the vesu amount in usdc is", vesuAmountInUSDC.toNumber());
160
+ logger.debug(`calculateAmountDistributionForWithdrawal vesuAmountInUsdc=${vesuAmountInUSDC.toNumber()}`);
163
161
  const extendedAmountInUSDC = amountInUsdc.minus(vesuAmountInUSDC);
164
- console.log(
165
- "the extended amount in usdc is",
166
- extendedAmountInUSDC.toNumber()
167
- );
162
+ logger.debug(`calculateAmountDistributionForWithdrawal extendedAmountInUsdc=${extendedAmountInUSDC.toNumber()}`);
168
163
  //console.log("the vesu amount in usdc is", vesuAmountInUSDC.toNumber());
169
164
  //console.log("the extended amount in usdc is", extendedAmountInUSDC.toNumber());\
170
165
  await new Promise((resolve) => setTimeout(resolve, 10000));
@@ -176,7 +171,7 @@ export const calculateAmountDistributionForWithdrawal = async (
176
171
  };
177
172
  } catch (err) {
178
173
  logger.error(
179
- `error calculating amount distribution for withdrawal: ${err}`
174
+ `error calculating amount distribution for withdrawal: ${err}`,
180
175
  );
181
176
  return null;
182
177
  }
@@ -187,10 +182,10 @@ export const calculateAmountDistributionForWithdrawal = async (
187
182
  * @returns {number} The calculated leverage value
188
183
  */
189
184
  export const calculateVesuLeverage = () => {
190
- const max_ltv_ratio = (1 - MAX_PRICE_DROP_PERCENTAGE) * MAX_LIQUIDATION_RATIO; //0.75
191
- const our_ltv_ratio = Math.floor(max_ltv_ratio * 100) - 5; //buffer of 5% to prevent liquidation
192
- const leverage = 1 / (1 - our_ltv_ratio / 100);
193
- 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;
194
189
  };
195
190
 
196
191
  /**
@@ -217,32 +212,44 @@ export const calculateExtendedLevergae = () => {
217
212
  * @returns {object} Object containing deltadebtAmountUnits and isIncrease flag
218
213
  */
219
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
+
220
216
  export const calculateDebtAmount = (
221
217
  collateralAmount: Web3Number,
222
218
  debtAmount: Web3Number,
223
219
  debtPrice: number,
224
- maxLtv: number = MAX_LIQUIDATION_RATIO,
220
+ maxLtv: number = VesuConfig.maxLtv,
225
221
  addedAmount: Web3Number, // this is in btc
226
222
  collateralPrice: number,
227
- isDeposit: boolean
223
+ isDeposit: boolean,
224
+ targetLtv: number = VesuConfig.targetLtv,
228
225
  ) => {
229
226
  try {
230
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}`);
231
233
  const addedCollateral = addedAmount.multipliedBy(isDeposit ? 1 : -1);
234
+ logger.debug(`calculateDebtAmount addedCollateral=${addedCollateral.toNumber()}, collateralPrice=${collateralPrice}`);
232
235
  const numerator1 = collateralAmount
233
236
  .plus(addedCollateral)
234
237
  .multipliedBy(collateralPrice)
235
238
  .multipliedBy(maxLtv);
239
+ logger.debug(`calculateDebtAmount numerator1=${numerator1.toNumber()}`);
236
240
  const numerator2 = debtAmount
237
241
  .multipliedBy(debtPrice)
238
- .multipliedBy(TARGET_HF);
239
- 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}`);
240
246
  const x_debt_usd = numerator1.minus(numerator2).dividedBy(denominator);
241
- let deltadebtAmountUnits = new Web3Number(
247
+ logger.debug(`calculateDebtAmount xDebtUsd=${x_debt_usd.toNumber()}`);
248
+ const deltadebtAmountUnits = new Web3Number(
242
249
  x_debt_usd.dividedBy(debtPrice).toFixed(2),
243
- 2
250
+ 2,
244
251
  );
245
- let isIncrease = x_debt_usd.greaterThan(0);
252
+ const isIncrease = x_debt_usd.greaterThan(0);
246
253
  return { deltadebtAmountUnits, isIncrease };
247
254
  } catch (err) {
248
255
  return { deltadebtAmountUnits: null, isIncrease: null };
@@ -267,7 +274,7 @@ export const calculateDebtReductionAmountForWithdrawal = (
267
274
  withdrawalAmount: Web3Number,
268
275
  collateralPrice: number,
269
276
  debtPrice: number,
270
- usdcDecimals: number
277
+ usdcDecimals: number,
271
278
  ) => {
272
279
  try {
273
280
  const vesuLeverage = calculateVesuLeverage();
@@ -294,13 +301,15 @@ export const calculateDebtReductionAmountForWithdrawal = (
294
301
  }
295
302
  };
296
303
 
304
+
305
+ // ! required?
297
306
  /**
298
307
  * calculate the amount to deposit on extended when incurring losses
299
308
  * @param client - The client
300
309
  * @returns The amount to deposit on extended when incurring losses
301
310
  */
302
311
  export const calculateAmountDepositOnExtendedWhenIncurringLosses = async (
303
- client: ExtendedWrapper
312
+ client: ExtendedWrapper,
304
313
  ) => {
305
314
  try {
306
315
  const extendedHoldings = await client.getHoldings();
@@ -308,13 +317,13 @@ export const calculateAmountDepositOnExtendedWhenIncurringLosses = async (
308
317
  const latestPosition = (await client.getPositions()).data.pop();
309
318
  if (!extendedHoldings || !latestPosition) {
310
319
  logger.error(
311
- `error getting extended position: extendedHoldings=${extendedHoldings}, latestPosition=${latestPosition}`
320
+ `error getting extended position: extendedHoldings=${extendedHoldings}, latestPosition=${latestPosition}`,
312
321
  );
313
322
  return null;
314
323
  }
315
324
  const positionValueInUSD = new Web3Number(
316
325
  latestPosition.value,
317
- USDC_TOKEN_DECIMALS
326
+ USDC_TOKEN_DECIMALS,
318
327
  );
319
328
  const equity = extendedHoldings.data.equity;
320
329
  const deposit = positionValueInUSD
@@ -324,7 +333,7 @@ export const calculateAmountDepositOnExtendedWhenIncurringLosses = async (
324
333
  return new Web3Number(deposit, USDC_TOKEN_DECIMALS);
325
334
  } catch (err) {
326
335
  logger.error(
327
- `error calculating amount deposit on extended when incurring losses: ${err}`
336
+ `error calculating amount deposit on extended when incurring losses: ${err}`,
328
337
  );
329
338
  return null;
330
339
  }
@@ -349,15 +358,15 @@ export const calculateWBTCAmountToMaintainLTV = (
349
358
  debtPrice: number,
350
359
  maxLtv: number = MAX_LIQUIDATION_RATIO,
351
360
  collateralPrice: number,
352
- targetHF: number = TARGET_HF
353
361
  ) => {
354
362
  try {
363
+ const targetHf = VesuConfig.maxLtv / VesuConfig.targetLtv;
355
364
  const numerator1 = collateralAmount
356
365
  .multipliedBy(collateralPrice)
357
366
  .multipliedBy(maxLtv);
358
367
  const numerator2 = debtAmount
359
368
  .multipliedBy(debtPrice)
360
- .multipliedBy(targetHF);
369
+ .multipliedBy(targetHf);
361
370
  const denominator = maxLtv;
362
371
  const collateralAmountToMaintainLTV = numerator2
363
372
  .minus(numerator1)
@@ -366,7 +375,7 @@ export const calculateWBTCAmountToMaintainLTV = (
366
375
  collateralAmountToMaintainLTV
367
376
  .dividedBy(collateralPrice)
368
377
  .toFixed(WBTC_TOKEN_DECIMALS),
369
- WBTC_TOKEN_DECIMALS
378
+ WBTC_TOKEN_DECIMALS,
370
379
  );
371
380
  return { deltaCollateralAmountUnits };
372
381
  } catch (err) {
@@ -374,18 +383,17 @@ export const calculateWBTCAmountToMaintainLTV = (
374
383
  }
375
384
  };
376
385
 
386
+ // ! required?
377
387
  export const calculateExposureDelta = (
378
388
  exposure_extended: number,
379
- exposure_vesu: number
389
+ exposure_vesu: number,
380
390
  ) => {
381
391
  const exposure_delta = new Web3Number(exposure_extended - exposure_vesu, 2);
382
392
  return exposure_delta.absoluteValue().toNumber();
383
393
  };
384
394
 
385
- /// In case BTC PRICE DROPS
386
- // 1. calculate the ltv on vesu
387
- // 2. Find the debt that needs to be paid to maintain the ltv
388
395
 
396
+ // ! required?
389
397
  /**
390
398
  * calculate the delta percentage between the current btc price and the last btc price
391
399
  * @param {number} btcPrice - The current btc price
@@ -394,36 +402,34 @@ export const calculateExposureDelta = (
394
402
  */
395
403
  export const calculateBTCPriceDelta = (
396
404
  btcPrice: number,
397
- lastBtcPrice: number
405
+ lastBtcPrice: number,
398
406
  ) => {
399
407
  return ((btcPrice - lastBtcPrice) / lastBtcPrice) * 100;
400
408
  };
401
409
 
402
410
  export const calculateVesUPositionSizeGivenExtended = (
403
- extendedPositonValue: number,
411
+ extendedPositonSize: number,
404
412
  extendedHoldingAmount: Web3Number,
405
413
  collateralAmount: Web3Number,
406
- collateralPrice: number
414
+ extendedBtcPrice: number,
407
415
  ) => {
408
416
  const extendedLeverage = calculateExtendedLevergae();
409
417
  const vesuLeverage = calculateVesuLeverage();
410
- const extendedAmount = extendedHoldingAmount;
411
- const extendedAmountInBTC = extendedAmount.dividedBy(collateralPrice);
412
- const numerator1 = extendedAmount
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
413
423
  .multipliedBy(extendedLeverage)
414
- .plus(extendedPositonValue);
424
+ .plus(extendedPositonSize);
425
+ logger.debug(`calculateVesUPositionSizeGivenExtended numerator1=${numerator1.toNumber()}`);
415
426
  const numerator2 = collateralAmount
416
- .multipliedBy(collateralPrice)
417
427
  .multipliedBy(-1);
418
- const vesuAmountInUsd = numerator1
419
- .plus(numerator2)
420
- .dividedBy(vesuLeverage)
421
- const vesuAmountInBTC = vesuAmountInUsd
422
- .dividedBy(collateralPrice)
423
- .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()}`);
424
431
  return {
425
- vesuAmountInUsd: vesuAmountInUsd.toFixed(2),
426
- vesuAmountInBTC: new Web3Number(vesuAmountInBTC, WBTC_TOKEN_DECIMALS),
432
+ vesuAmountInBTC: vesuAmountInBTC,
427
433
  extendedAmountInBTC: extendedAmountInBTC,
428
434
  };
429
435
  };
@@ -436,58 +442,86 @@ export const calculateVesUPositionSizeGivenExtended = (
436
442
  * @param collateralPrice - The collateral price
437
443
  * @param debtPrice - The debt price
438
444
  * @param targetHf - The target hf
445
+ * @@dev returns negative to represent debt to be repaid
439
446
  * @returns The debt amount to be repaid
440
447
  */
441
448
  export const calculateDeltaDebtAmount = (
442
- maxLtv: number = MAX_LTV_BTC_USDC,
443
449
  existingVesuCollateral: Web3Number,
444
450
  existingVesuDebt: Web3Number,
445
- collateralPrice: number,
446
451
  debtPrice: number,
447
- targetHf: number = TARGET_HF
452
+ collateralPrice: number,
448
453
  ) => {
449
- try {
450
- const term1 = existingVesuCollateral
451
- .multipliedBy(collateralPrice)
452
- .multipliedBy(maxLtv);
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}`);
453
463
 
454
- logger.info(`term1: ${term1.toNumber()}`);
455
- const term2 = existingVesuDebt
456
- .multipliedBy(debtPrice)
457
- .multipliedBy(targetHf)
458
- .multipliedBy(-1);
459
- logger.info(`term2: ${term2.toNumber()}`);
460
- const debtAmountToBeRepaid = term1.plus(term2).dividedBy(targetHf);
461
- logger.info(`debtAmountToBeRepaid: ${debtAmountToBeRepaid.toNumber()}`);
462
- return new Web3Number(debtAmountToBeRepaid.toFixed(USDC_TOKEN_DECIMALS), USDC_TOKEN_DECIMALS);
463
- } catch (err) {
464
- logger.error(`error calculating delta position: ${err}`);
465
- return null;
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),
466
479
  }
467
480
  };
468
481
 
469
482
  export const calculatePositionToCloseToWithdrawAmount = async (
470
483
  extendedBalance: Balance,
471
484
  extendedPositions: Position,
472
- amountToWithdraw: Web3Number
485
+ amountToWithdraw: Web3Number,
473
486
  ) => {
474
487
  try {
475
488
  const extendedLeverage = calculateExtendedLevergae();
476
489
  const extendedPosition = extendedPositions.value;
477
- const marginRequired = new Web3Number(extendedBalance.initialMargin , USDC_TOKEN_DECIMALS);
478
- const unrealisedPnl = new Web3Number(extendedBalance.unrealisedPnl, USDC_TOKEN_DECIMALS);
479
- const availableForWithdrawal = new Web3Number(extendedBalance.availableForWithdrawal, USDC_TOKEN_DECIMALS);
480
- const upnlPercent = unrealisedPnl.dividedBy(extendedPosition)
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);
481
503
  /**
482
504
  * New Formula
483
505
  */
484
- const walletBalance = new Web3Number(extendedBalance.balance, USDC_TOKEN_DECIMALS);
485
- const term1 = marginRequired.minus(walletBalance).minus(availableForWithdrawal).plus(amountToWithdraw).multipliedBy(extendedLeverage);
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);
486
515
  const denominator = upnlPercent.multipliedBy(extendedLeverage).plus(1);
487
- return new Web3Number(Math.ceil(term1.dividedBy(denominator).dividedBy(extendedLeverage).toNumber()), USDC_TOKEN_DECIMALS);
516
+ return new Web3Number(
517
+ Math.ceil(
518
+ term1.dividedBy(denominator).dividedBy(extendedLeverage).toNumber(),
519
+ ),
520
+ USDC_TOKEN_DECIMALS,
521
+ );
488
522
  } catch (err) {
489
523
  logger.error(
490
- `error calculating position to close to withdraw amount: ${err}`
524
+ `error calculating position to close to withdraw amount: ${err}`,
491
525
  );
492
526
  return new Web3Number(0, USDC_TOKEN_DECIMALS);
493
527
  }