@strkfarm/sdk 2.0.0-dev.22 → 2.0.0-dev.23

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.
@@ -8,12 +8,21 @@ import {
8
8
  UNIVERSAL_MANAGE_IDS,
9
9
  UniversalStrategySettings,
10
10
  } from "../universal-strategy";
11
- import { calculateExtendedLevergae } from "./utils/helper";
11
+ import { calculateDebtAmount, calculateDeltaDebtAmount, calculateExtendedLevergae } from "./utils/helper";
12
12
  import { logger } from "@/utils";
13
13
  import { AUDIT_URL } from "../universal-lst-muliplier-strategy";
14
14
  import { getNoRiskTags } from "@/interfaces";
15
15
  import { _riskFactor } from "../universal-lst-muliplier-strategy";
16
- import { BUFFER_USDC_IN_WITHDRAWAL, LIMIT_BALANCE, LIMIT_BALANCE_VALUE, MINIMUM_EXTENDED_POSITION_SIZE, USDC_TOKEN_DECIMALS, WALLET_ADDRESS, WBTC_TOKEN_DECIMALS } from "./utils/constants";
16
+ import {
17
+ BUFFER_USDC_IN_WITHDRAWAL,
18
+ LIMIT_BALANCE,
19
+ LIMIT_BALANCE_VALUE,
20
+ MAX_LTV_BTC_USDC,
21
+ MINIMUM_EXTENDED_POSITION_SIZE,
22
+ USDC_TOKEN_DECIMALS,
23
+ WALLET_ADDRESS,
24
+ WBTC_TOKEN_DECIMALS,
25
+ } from "./utils/constants";
17
26
  import { CycleType } from "./types/transaction-metadata";
18
27
  import { PricerBase } from "@/modules/pricerBase";
19
28
  import { ContractAddr, Web3Number } from "@/dataTypes";
@@ -22,7 +31,10 @@ import { ERC20 } from "@/modules";
22
31
  import { Balance, OrderSide } from "@/modules/ExtendedWrapperSDk";
23
32
  import { Protocols } from "@/interfaces";
24
33
  import { MINIMUM_WBTC_DIFFERENCE_FOR_AVNU_SWAP } from "./utils/constants";
25
- import { getInvestmentSteps, getFAQs } from "../universal-lst-muliplier-strategy";
34
+ import {
35
+ getInvestmentSteps,
36
+ getFAQs,
37
+ } from "../universal-lst-muliplier-strategy";
26
38
  import { getContractDetails } from "../universal-strategy";
27
39
  import { highlightTextWithLinks } from "@/interfaces";
28
40
  import { PositionInfo } from "../universal-adapters";
@@ -50,13 +62,15 @@ import {
50
62
  calculateAmountDistribution,
51
63
  calculateAmountDistributionForWithdrawal,
52
64
  calculateVesuLeverage,
53
- calculateVesUPositionSizeGivenExtended
65
+ calculateVesUPositionSizeGivenExtended,
54
66
  } from "./utils/helper";
55
67
  import { SingleTokenInfo } from "../base-strategy";
56
68
  import { Call } from "starknet";
57
69
  import { PositionTypeAvnuExtended } from "../universal-strategy";
58
- import { TransactionMetadata, TransactionResult } from "./types/transaction-metadata";
59
-
70
+ import {
71
+ TransactionMetadata,
72
+ TransactionResult,
73
+ } from "./types/transaction-metadata";
60
74
 
61
75
  export interface VesuExtendedStrategySettings
62
76
  extends UniversalStrategySettings {
@@ -71,10 +85,11 @@ export interface VesuExtendedStrategySettings
71
85
  }
72
86
 
73
87
  export class VesuExtendedMultiplierStrategy<
74
- S extends VesuExtendedStrategySettings
75
- >
88
+ S extends VesuExtendedStrategySettings
89
+ >
76
90
  extends SVKStrategy<S>
77
- implements Operations {
91
+ implements Operations
92
+ {
78
93
  constructor(
79
94
  config: IConfig,
80
95
  pricer: PricerBase,
@@ -122,8 +137,7 @@ export class VesuExtendedMultiplierStrategy<
122
137
  usdceToken.decimals
123
138
  );
124
139
  const price = await this.pricer.getPrice(usdceToken.symbol);
125
- const usdValue =
126
- Number(balance.toFixed(usdceToken.decimals)) * price.price;
140
+ const usdValue = Number(balance.toFixed(usdceToken.decimals)) * price.price;
127
141
  return {
128
142
  tokenInfo: usdceToken,
129
143
  amount: balance,
@@ -131,7 +145,6 @@ export class VesuExtendedMultiplierStrategy<
131
145
  };
132
146
  }
133
147
 
134
-
135
148
  async getUnusedBalanceWBTC(): Promise<SingleTokenInfo> {
136
149
  const collateralToken = this.metadata.additionalInfo.borrowable_assets[0]!;
137
150
  const balance = await new ERC20(this.config).balanceOf(
@@ -182,9 +195,12 @@ export class VesuExtendedMultiplierStrategy<
182
195
  return extendedAdapter.adapter as ExtendedAdapter;
183
196
  }
184
197
 
185
- async moveAssetsToVaultAllocator(amount: Web3Number, extendedAdapter: ExtendedAdapter): Promise<{
186
- calls: Call[],
187
- status: boolean,
198
+ async moveAssetsToVaultAllocator(
199
+ amount: Web3Number,
200
+ extendedAdapter: ExtendedAdapter
201
+ ): Promise<{
202
+ calls: Call[];
203
+ status: boolean;
188
204
  }> {
189
205
  try {
190
206
  const usdceToken = Global.getDefaultTokens().find(
@@ -195,12 +211,22 @@ export class VesuExtendedMultiplierStrategy<
195
211
  WALLET_ADDRESS,
196
212
  usdceToken.decimals
197
213
  );
198
- logger.info(`${VesuExtendedMultiplierStrategy.name}::moveAssetsToVaultAllocator walletBalance: ${walletBalance}`);
214
+ logger.info(
215
+ `${VesuExtendedMultiplierStrategy.name}::moveAssetsToVaultAllocator walletBalance: ${walletBalance}`
216
+ );
199
217
  const amountToBeTransferred = amount.minimum(walletBalance);
200
- logger.info(`${VesuExtendedMultiplierStrategy.name}::moveAssetsToVaultAllocator amountToBeTransferred: ${amountToBeTransferred.toNumber()}`);
201
-
218
+ logger.info(
219
+ `${
220
+ VesuExtendedMultiplierStrategy.name
221
+ }::moveAssetsToVaultAllocator amountToBeTransferred: ${amountToBeTransferred.toNumber()}`
222
+ );
223
+
202
224
  if (amountToBeTransferred.lessThan(0)) {
203
- logger.error(`${VesuExtendedMultiplierStrategy.name}::moveAssetsToVaultAllocator amountToBeTransferred is less than 0: ${amountToBeTransferred.toNumber()}`);
225
+ logger.error(
226
+ `${
227
+ VesuExtendedMultiplierStrategy.name
228
+ }::moveAssetsToVaultAllocator amountToBeTransferred is less than 0: ${amountToBeTransferred.toNumber()}`
229
+ );
204
230
  return {
205
231
  calls: [],
206
232
  status: false,
@@ -246,12 +272,19 @@ export class VesuExtendedMultiplierStrategy<
246
272
  collateralPrice: number;
247
273
  debtPrice: number;
248
274
  vesuLeverage: number;
275
+ debtAmountToBeRepaid: Web3Number;
249
276
  }> {
250
277
  try {
251
- logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest starting`);
278
+ logger.info(
279
+ `${VesuExtendedMultiplierStrategy.name}::shouldInvest starting`
280
+ );
252
281
  const vesuAdapter = await this.getVesuAdapter();
253
282
  const extendedAdapter = await this.getExtendedAdapter();
254
- logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest adapters fetched: vesuAdapter=${!!vesuAdapter}, extendedAdapter=${!!extendedAdapter}, extendedAdapter.client=${!!extendedAdapter?.client}`);
283
+ logger.info(
284
+ `${
285
+ VesuExtendedMultiplierStrategy.name
286
+ }::shouldInvest adapters fetched: vesuAdapter=${!!vesuAdapter}, extendedAdapter=${!!extendedAdapter}, extendedAdapter.client=${!!extendedAdapter?.client}`
287
+ );
255
288
 
256
289
  if (!vesuAdapter) {
257
290
  logger.error(
@@ -265,6 +298,7 @@ export class VesuExtendedMultiplierStrategy<
265
298
  collateralPrice: 0,
266
299
  debtPrice: 0,
267
300
  vesuLeverage: 0,
301
+ debtAmountToBeRepaid: new Web3Number(0, 0),
268
302
  };
269
303
  }
270
304
  if (!extendedAdapter) {
@@ -279,6 +313,7 @@ export class VesuExtendedMultiplierStrategy<
279
313
  collateralPrice: 0,
280
314
  debtPrice: 0,
281
315
  vesuLeverage: 0,
316
+ debtAmountToBeRepaid: new Web3Number(0, 0),
282
317
  };
283
318
  }
284
319
  if (!extendedAdapter.client) {
@@ -293,10 +328,13 @@ export class VesuExtendedMultiplierStrategy<
293
328
  collateralPrice: 0,
294
329
  debtPrice: 0,
295
330
  vesuLeverage: 0,
331
+ debtAmountToBeRepaid: new Web3Number(0, 0),
296
332
  };
297
333
  }
298
334
 
299
- logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest calling getUnusedBalance`);
335
+ logger.info(
336
+ `${VesuExtendedMultiplierStrategy.name}::shouldInvest calling getUnusedBalance`
337
+ );
300
338
  const balance = await this.getUnusedBalance();
301
339
 
302
340
  if (!Number.isFinite(balance.usdValue) || balance.usdValue < 0) {
@@ -311,14 +349,23 @@ export class VesuExtendedMultiplierStrategy<
311
349
  collateralPrice: 0,
312
350
  debtPrice: 0,
313
351
  vesuLeverage: 0,
352
+ debtAmountToBeRepaid: new Web3Number(0, 0),
314
353
  };
315
354
  }
316
- logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest balance: ${balance.usdValue}`);
317
- const usdcBalanceOnExtended = await extendedAdapter.getExtendedDepositAmount();
355
+ logger.info(
356
+ `${VesuExtendedMultiplierStrategy.name}::shouldInvest balance: ${balance.usdValue}`
357
+ );
358
+ const usdcBalanceOnExtended =
359
+ await extendedAdapter.getExtendedDepositAmount();
318
360
 
319
361
  if (usdcBalanceOnExtended) {
320
- const availableForWithdrawal = parseFloat(usdcBalanceOnExtended.availableForWithdrawal);
321
- if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
362
+ const availableForWithdrawal = parseFloat(
363
+ usdcBalanceOnExtended.availableForWithdrawal
364
+ );
365
+ if (
366
+ !Number.isFinite(availableForWithdrawal) ||
367
+ availableForWithdrawal < 0
368
+ ) {
322
369
  logger.error(
323
370
  `Invalid usdcBalanceOnExtended.availableForWithdrawal: ${usdcBalanceOnExtended.availableForWithdrawal}. Expected a finite, non-negative number.`
324
371
  );
@@ -330,13 +377,18 @@ export class VesuExtendedMultiplierStrategy<
330
377
  collateralPrice: 0,
331
378
  debtPrice: 0,
332
379
  vesuLeverage: 0,
380
+ debtAmountToBeRepaid: new Web3Number(0, 0),
333
381
  };
334
382
  }
335
383
  }
336
384
 
337
385
  /** The LIMIT_BALANCE is the bffer amount to keep in the investing Cycle */
338
- const amountToInvest = new Web3Number(balance.usdValue, USDC_TOKEN_DECIMALS).plus(usdcBalanceOnExtended?.availableForTrade ?? 0).multipliedBy(1 - LIMIT_BALANCE);
339
-
386
+ const amountToInvest = new Web3Number(
387
+ balance.usdValue,
388
+ USDC_TOKEN_DECIMALS
389
+ )
390
+ .plus(usdcBalanceOnExtended?.availableForTrade ?? 0)
391
+ .multipliedBy(1 - LIMIT_BALANCE);
340
392
 
341
393
  const amountToInvestNumber = amountToInvest.toNumber();
342
394
  if (!Number.isFinite(amountToInvestNumber)) {
@@ -351,10 +403,14 @@ export class VesuExtendedMultiplierStrategy<
351
403
  collateralPrice: 0,
352
404
  debtPrice: 0,
353
405
  vesuLeverage: 0,
406
+ debtAmountToBeRepaid: new Web3Number(0, 0),
354
407
  };
355
408
  }
356
409
 
357
- logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvestNumber}`);
410
+ logger.info(
411
+ `${VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvestNumber}`
412
+ );
413
+
358
414
  if (amountToInvest.lessThan(LIMIT_BALANCE_VALUE)) {
359
415
  return {
360
416
  shouldInvest: false,
@@ -364,6 +420,7 @@ export class VesuExtendedMultiplierStrategy<
364
420
  collateralPrice: 0,
365
421
  debtPrice: 0,
366
422
  vesuLeverage: 0,
423
+ debtAmountToBeRepaid: new Web3Number(0, 0),
367
424
  };
368
425
  }
369
426
 
@@ -378,18 +435,18 @@ export class VesuExtendedMultiplierStrategy<
378
435
  collateralPrice: 0,
379
436
  debtPrice: 0,
380
437
  vesuLeverage: 0,
438
+ debtAmountToBeRepaid: new Web3Number(0, 0),
381
439
  };
382
440
  }
383
- const { collateralTokenAmount } =
441
+ const { collateralTokenAmount, debtTokenAmount } =
384
442
  await vesuAdapter.vesuAdapter.getAssetPrices();
385
443
 
386
- const {
387
- collateralPrice,
388
- debtPrice
389
- } = await this.getAssetPrices();
390
-
444
+ const { collateralPrice, debtPrice } = await this.getAssetPrices();
391
445
 
392
- if (!Number.isFinite(collateralPrice.price) || collateralPrice.price <= 0) {
446
+ if (
447
+ !Number.isFinite(collateralPrice.price) ||
448
+ collateralPrice.price <= 0
449
+ ) {
393
450
  logger.error(
394
451
  `Invalid collateralPrice: ${collateralPrice.price}. Expected a finite, positive number.`
395
452
  );
@@ -401,6 +458,7 @@ export class VesuExtendedMultiplierStrategy<
401
458
  collateralPrice: 0,
402
459
  debtPrice: 0,
403
460
  vesuLeverage: 0,
461
+ debtAmountToBeRepaid: new Web3Number(0, 0),
404
462
  };
405
463
  }
406
464
  if (!Number.isFinite(debtPrice.price) || debtPrice.price <= 0) {
@@ -415,12 +473,35 @@ export class VesuExtendedMultiplierStrategy<
415
473
  collateralPrice: 0,
416
474
  debtPrice: 0,
417
475
  vesuLeverage: 0,
476
+ debtAmountToBeRepaid: new Web3Number(0, 0),
418
477
  };
419
478
  }
420
479
 
480
+ const debtAmountToBeRepaid = calculateDeltaDebtAmount(
481
+ MAX_LTV_BTC_USDC,
482
+ collateralTokenAmount,
483
+ debtTokenAmount,
484
+ collateralPrice.price,
485
+ debtPrice.price,
486
+ this.metadata.additionalInfo.targetHealthFactor
487
+ );
488
+ if (!debtAmountToBeRepaid) {
489
+ logger.error("error calculating debt amount to be repaid");
490
+ return {
491
+ shouldInvest: false,
492
+ vesuAmount: new Web3Number(0, 0),
493
+ extendedAmount: new Web3Number(0, 0),
494
+ extendedLeverage: 0,
495
+ collateralPrice: 0,
496
+ debtPrice: 0,
497
+ vesuLeverage: 0,
498
+ debtAmountToBeRepaid: new Web3Number(0, 0),
499
+ };
500
+ }
501
+ const amountToInvestAfterRepayingDebt = amountToInvest.minus(debtAmountToBeRepaid);
421
502
  const { vesu_amount, extended_amount, extended_leverage, vesu_leverage } =
422
503
  await calculateAmountDistribution(
423
- amountToInvest.toNumber(),
504
+ amountToInvestAfterRepayingDebt.toNumber(),
424
505
  extendedAdapter.client,
425
506
  extendedAdapter.config.extendedMarketName,
426
507
  collateralPrice.price,
@@ -445,9 +526,14 @@ export class VesuExtendedMultiplierStrategy<
445
526
  collateralPrice: 0,
446
527
  debtPrice: 0,
447
528
  vesuLeverage: 0,
529
+ debtAmountToBeRepaid: new Web3Number(0, 0),
448
530
  };
449
531
  }
450
- logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest vesu_amount: ${vesu_amount.toNumber()}, extended_amount: ${extended_amount.toNumber()}`);
532
+ logger.info(
533
+ `${
534
+ VesuExtendedMultiplierStrategy.name
535
+ }::shouldInvest vesu_amount: ${vesu_amount.toNumber()}, extended_amount: ${extended_amount.toNumber()}`
536
+ );
451
537
  return {
452
538
  shouldInvest: true,
453
539
  vesuAmount: vesu_amount,
@@ -456,6 +542,7 @@ export class VesuExtendedMultiplierStrategy<
456
542
  vesuLeverage: vesu_leverage,
457
543
  collateralPrice: collateralPrice.price,
458
544
  debtPrice: debtPrice.price,
545
+ debtAmountToBeRepaid: debtAmountToBeRepaid,
459
546
  };
460
547
  } catch (err) {
461
548
  logger.error(`error deciding invest: ${err}`);
@@ -467,11 +554,15 @@ export class VesuExtendedMultiplierStrategy<
467
554
  collateralPrice: 0,
468
555
  debtPrice: 0,
469
556
  vesuLeverage: 0,
557
+ debtAmountToBeRepaid: new Web3Number(0, 0),
470
558
  };
471
559
  }
472
560
  }
473
561
 
474
- async shouldMoveAssets(extendedAmount: Web3Number, vesuAmount: Web3Number): Promise<TransactionResult[]> {
562
+ async shouldMoveAssets(
563
+ extendedAmount: Web3Number,
564
+ vesuAmount: Web3Number
565
+ ): Promise<TransactionResult[]> {
475
566
  try {
476
567
  const vesuAdapter = await this.getVesuAdapter();
477
568
  const extendedAdapter = await this.getExtendedAdapter();
@@ -495,13 +586,24 @@ export class VesuExtendedMultiplierStrategy<
495
586
  extendedHoldings.availableForTrade
496
587
  );
497
588
 
498
- logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldMoveAssets calculating movements - Extended current: ${usdcAmountOnExtendedAvailableForTrade}, Wallet: ${usdcAmountInWallet.toNumber()}, Target Extended: ${extendedAmount.toNumber()}, Target Vesu: ${vesuAmount.toNumber()}`);
589
+ logger.info(
590
+ `${
591
+ VesuExtendedMultiplierStrategy.name
592
+ }::shouldMoveAssets calculating movements - Extended current: ${usdcAmountOnExtendedAvailableForTrade}, Wallet: ${usdcAmountInWallet.toNumber()}, Target Extended: ${extendedAmount.toNumber()}, Target Vesu: ${vesuAmount.toNumber()}`
593
+ );
499
594
 
500
595
  let totalExtendedWithdrawal = new Web3Number(0, USDC_TOKEN_DECIMALS);
501
596
  let totalExtendedDeposit = new Web3Number(0, USDC_TOKEN_DECIMALS);
502
597
 
503
- if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
504
- totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmount.abs());
598
+ if (
599
+ extendedAmount.isNegative() &&
600
+ extendedAmount
601
+ .abs()
602
+ .greaterThan(extendedAdapter.minimumExtendedMovementAmount)
603
+ ) {
604
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(
605
+ extendedAmount.abs()
606
+ );
505
607
  }
506
608
 
507
609
  // Calculate remaining Extended difference (target vs current)
@@ -511,17 +613,24 @@ export class VesuExtendedMultiplierStrategy<
511
613
  let projectedExtendedBalance = usdcAmountOnExtendedAvailableForTrade;
512
614
 
513
615
  if (extendedAmount.isNegative()) {
514
- projectedExtendedBalance = projectedExtendedBalance - extendedAmount.abs().toNumber();
616
+ projectedExtendedBalance =
617
+ projectedExtendedBalance - extendedAmount.abs().toNumber();
515
618
  }
516
619
 
517
- const extendedAmountDifference = extendedTargetAmount.minus(projectedExtendedBalance);
620
+ const extendedAmountDifference = extendedTargetAmount.minus(
621
+ projectedExtendedBalance
622
+ );
518
623
  const extendedAmountDifferenceAbs = extendedAmountDifference.abs();
519
624
 
520
625
  // Track additional Extended movements
521
626
  if (extendedAmountDifference.lessThan(0)) {
522
- totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmountDifferenceAbs);
627
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(
628
+ extendedAmountDifferenceAbs
629
+ );
523
630
  } else if (extendedAmountDifference.greaterThan(0)) {
524
- totalExtendedDeposit = totalExtendedDeposit.plus(extendedAmountDifference);
631
+ totalExtendedDeposit = totalExtendedDeposit.plus(
632
+ extendedAmountDifference
633
+ );
525
634
  }
526
635
 
527
636
  const vesuTargetAmount = vesuAmount.abs();
@@ -532,18 +641,31 @@ export class VesuExtendedMultiplierStrategy<
532
641
  let vesuAmountDifference = vesuTargetAmount.minus(projectedWalletBalance);
533
642
  const vesuAmountDifferenceAbs = vesuAmountDifference.abs();
534
643
 
535
- logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldMoveAssets calculated movements - Extended withdrawal: ${totalExtendedWithdrawal.toNumber()}, Extended deposit: ${totalExtendedDeposit.toNumber()}, Extended diff: ${extendedAmountDifference.toNumber()}, Projected wallet: ${projectedWalletBalance.toNumber()}, Vesu diff: ${vesuAmountDifference.toNumber()}`);
644
+ logger.info(
645
+ `${
646
+ VesuExtendedMultiplierStrategy.name
647
+ }::shouldMoveAssets calculated movements - Extended withdrawal: ${totalExtendedWithdrawal.toNumber()}, Extended deposit: ${totalExtendedDeposit.toNumber()}, Extended diff: ${extendedAmountDifference.toNumber()}, Projected wallet: ${projectedWalletBalance.toNumber()}, Vesu diff: ${vesuAmountDifference.toNumber()}`
648
+ );
536
649
  let transactionResults: TransactionResult[] = [];
537
650
 
538
651
  // Handle negative extendedAmount (initial withdrawal needed)
539
- if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
652
+ if (
653
+ extendedAmount.isNegative() &&
654
+ extendedAmount
655
+ .abs()
656
+ .greaterThan(extendedAdapter.minimumExtendedMovementAmount)
657
+ ) {
540
658
  try {
541
- const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
659
+ const {
660
+ calls: extendedCalls,
661
+ status: extendedStatus,
662
+ transactionMetadata: extendedTransactionMetadata,
663
+ } = await this.moveAssets(
542
664
  {
543
665
  to: Protocols.VAULT.name,
544
666
  from: Protocols.EXTENDED.name,
545
667
  amount: extendedAmount.abs(),
546
- cycleType: CycleType.INVESTMENT
668
+ cycleType: CycleType.INVESTMENT,
547
669
  },
548
670
  extendedAdapter,
549
671
  vesuAdapter
@@ -556,30 +678,73 @@ export class VesuExtendedMultiplierStrategy<
556
678
  ...extendedTransactionMetadata,
557
679
  transactionType: "DEPOSIT",
558
680
  },
559
- })
681
+ });
560
682
  } else {
561
- return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmount.abs() }, "NONE", CycleType.INVESTMENT)];
683
+ return [
684
+ this.createTransactionResult(
685
+ [],
686
+ false,
687
+ {
688
+ from: Protocols.EXTENDED.name,
689
+ to: Protocols.VAULT.name,
690
+ amount: extendedAmount.abs(),
691
+ },
692
+ "NONE",
693
+ CycleType.INVESTMENT
694
+ ),
695
+ ];
562
696
  }
563
697
  } catch (err) {
564
698
  logger.error(`Failed moving assets to vault: ${err}`);
565
- return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmount.abs() }, "NONE", CycleType.INVESTMENT)];
699
+ return [
700
+ this.createTransactionResult(
701
+ [],
702
+ false,
703
+ {
704
+ from: Protocols.EXTENDED.name,
705
+ to: Protocols.VAULT.name,
706
+ amount: extendedAmount.abs(),
707
+ },
708
+ "NONE",
709
+ CycleType.INVESTMENT
710
+ ),
711
+ ];
566
712
  }
567
713
  }
568
714
 
569
- if (vesuAmount.isNegative() && vesuAmount.abs().greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
715
+ if (
716
+ vesuAmount.isNegative() &&
717
+ vesuAmount.abs().greaterThan(vesuAdapter.minimumVesuMovementAmount)
718
+ ) {
570
719
  try {
571
- const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
720
+ const {
721
+ calls: vesuCalls,
722
+ status: vesuStatus,
723
+ transactionMetadata: vesuTransactionMetadata,
724
+ } = await this.moveAssets(
572
725
  {
573
726
  to: Protocols.EXTENDED.name,
574
727
  from: Protocols.VESU.name,
575
728
  amount: vesuAmount.abs(),
576
- cycleType: CycleType.INVESTMENT
729
+ cycleType: CycleType.INVESTMENT,
577
730
  },
578
731
  extendedAdapter,
579
732
  vesuAdapter
580
733
  );
581
734
  if (!vesuStatus) {
582
- return [this.createTransactionResult([], false, { from: Protocols.VESU.name, to: Protocols.EXTENDED.name, amount: vesuAmount.abs() }, "NONE", CycleType.INVESTMENT)];
735
+ return [
736
+ this.createTransactionResult(
737
+ [],
738
+ false,
739
+ {
740
+ from: Protocols.VESU.name,
741
+ to: Protocols.EXTENDED.name,
742
+ amount: vesuAmount.abs(),
743
+ },
744
+ "NONE",
745
+ CycleType.INVESTMENT
746
+ ),
747
+ ];
583
748
  }
584
749
  transactionResults.push({
585
750
  status: vesuStatus,
@@ -587,24 +752,46 @@ export class VesuExtendedMultiplierStrategy<
587
752
  transactionMetadata: {
588
753
  ...vesuTransactionMetadata,
589
754
  transactionType: "DEPOSIT",
590
- }
591
- })
755
+ },
756
+ });
592
757
  } catch (err) {
593
- logger.error(`Failed moving assets to extended via vault allocator: ${err}`);
594
- return [this.createTransactionResult([], false, { from: Protocols.VESU.name, to: Protocols.EXTENDED.name, amount: vesuAmount.abs() }, "NONE", CycleType.INVESTMENT)];
758
+ logger.error(
759
+ `Failed moving assets to extended via vault allocator: ${err}`
760
+ );
761
+ return [
762
+ this.createTransactionResult(
763
+ [],
764
+ false,
765
+ {
766
+ from: Protocols.VESU.name,
767
+ to: Protocols.EXTENDED.name,
768
+ amount: vesuAmount.abs(),
769
+ },
770
+ "NONE",
771
+ CycleType.INVESTMENT
772
+ ),
773
+ ];
595
774
  }
596
775
  }
597
776
 
598
777
  // Handle Extended adjustments based on calculated difference
599
- if (extendedAmountDifferenceAbs.greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
778
+ if (
779
+ extendedAmountDifferenceAbs.greaterThan(
780
+ extendedAdapter.minimumExtendedMovementAmount
781
+ )
782
+ ) {
600
783
  if (extendedAmountDifference.greaterThan(0)) {
601
784
  try {
602
- const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
785
+ const {
786
+ calls: extendedCalls,
787
+ status: extendedStatus,
788
+ transactionMetadata: extendedTransactionMetadata,
789
+ } = await this.moveAssets(
603
790
  {
604
791
  to: Protocols.EXTENDED.name,
605
792
  from: Protocols.VAULT.name,
606
793
  amount: extendedAmountDifference,
607
- cycleType: CycleType.INVESTMENT
794
+ cycleType: CycleType.INVESTMENT,
608
795
  },
609
796
  extendedAdapter,
610
797
  vesuAdapter
@@ -613,24 +800,54 @@ export class VesuExtendedMultiplierStrategy<
613
800
  transactionResults.push({
614
801
  status: extendedStatus,
615
802
  calls: extendedCalls,
616
- transactionMetadata: extendedTransactionMetadata
617
- })
803
+ transactionMetadata: extendedTransactionMetadata,
804
+ });
618
805
  } else {
619
- logger.error(`Failed to move assets to extended - operation returned false status`);
620
- return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.EXTENDED.name, amount: extendedAmountDifference }, "NONE", CycleType.INVESTMENT)];
806
+ logger.error(
807
+ `Failed to move assets to extended - operation returned false status`
808
+ );
809
+ return [
810
+ this.createTransactionResult(
811
+ [],
812
+ false,
813
+ {
814
+ from: Protocols.VAULT.name,
815
+ to: Protocols.EXTENDED.name,
816
+ amount: extendedAmountDifference,
817
+ },
818
+ "NONE",
819
+ CycleType.INVESTMENT
820
+ ),
821
+ ];
621
822
  }
622
823
  } catch (err) {
623
824
  logger.error(`Failed moving assets to extended: ${err}`);
624
- return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.EXTENDED.name, amount: extendedAmountDifference }, "NONE", CycleType.INVESTMENT)];
825
+ return [
826
+ this.createTransactionResult(
827
+ [],
828
+ false,
829
+ {
830
+ from: Protocols.VAULT.name,
831
+ to: Protocols.EXTENDED.name,
832
+ amount: extendedAmountDifference,
833
+ },
834
+ "NONE",
835
+ CycleType.INVESTMENT
836
+ ),
837
+ ];
625
838
  }
626
839
  } else if (extendedAmountDifference.lessThan(0)) {
627
840
  try {
628
- const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
841
+ const {
842
+ calls: extendedCalls,
843
+ status: extendedStatus,
844
+ transactionMetadata: extendedTransactionMetadata,
845
+ } = await this.moveAssets(
629
846
  {
630
847
  to: Protocols.VAULT.name,
631
848
  from: Protocols.EXTENDED.name,
632
849
  amount: extendedAmountDifferenceAbs,
633
- cycleType: CycleType.INVESTMENT
850
+ cycleType: CycleType.INVESTMENT,
634
851
  },
635
852
  extendedAdapter,
636
853
  vesuAdapter
@@ -642,21 +859,51 @@ export class VesuExtendedMultiplierStrategy<
642
859
  transactionMetadata: {
643
860
  ...extendedTransactionMetadata,
644
861
  transactionType: "DEPOSIT",
645
- }
646
- })
862
+ },
863
+ });
647
864
  } else {
648
- logger.error(`Failed to withdraw from extended - operation returned false status`);
649
- return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmountDifferenceAbs }, "NONE", CycleType.INVESTMENT)];
865
+ logger.error(
866
+ `Failed to withdraw from extended - operation returned false status`
867
+ );
868
+ return [
869
+ this.createTransactionResult(
870
+ [],
871
+ false,
872
+ {
873
+ from: Protocols.EXTENDED.name,
874
+ to: Protocols.VAULT.name,
875
+ amount: extendedAmountDifferenceAbs,
876
+ },
877
+ "NONE",
878
+ CycleType.INVESTMENT
879
+ ),
880
+ ];
650
881
  }
651
882
  } catch (err) {
652
883
  logger.error(`Failed moving assets from extended to vault: ${err}`);
653
- return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmountDifferenceAbs }, "NONE", CycleType.INVESTMENT)];
884
+ return [
885
+ this.createTransactionResult(
886
+ [],
887
+ false,
888
+ {
889
+ from: Protocols.EXTENDED.name,
890
+ to: Protocols.VAULT.name,
891
+ amount: extendedAmountDifferenceAbs,
892
+ },
893
+ "NONE",
894
+ CycleType.INVESTMENT
895
+ ),
896
+ ];
654
897
  }
655
898
  }
656
899
  }
657
900
 
658
901
  // Handle Vesu adjustments based on calculated difference (already adjusted for Extended movements)
659
- if (vesuAmountDifferenceAbs.greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
902
+ if (
903
+ vesuAmountDifferenceAbs.greaterThan(
904
+ vesuAdapter.minimumVesuMovementAmount
905
+ )
906
+ ) {
660
907
  if (vesuAmountDifference.lessThanOrEqualTo(0)) {
661
908
  logger.warn(
662
909
  `Vesu amount difference is negative or zero: ${vesuAmountDifference.toNumber()}. Skipping operation.`
@@ -664,19 +911,37 @@ export class VesuExtendedMultiplierStrategy<
664
911
  } else {
665
912
  // Move assets from Extended to Vault (which will then go to Vesu)
666
913
  try {
667
- const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
914
+ const {
915
+ calls: vesuCalls,
916
+ status: vesuStatus,
917
+ transactionMetadata: vesuTransactionMetadata,
918
+ } = await this.moveAssets(
668
919
  {
669
920
  to: Protocols.VAULT.name,
670
921
  from: Protocols.EXTENDED.name,
671
922
  amount: vesuAmountDifference,
672
- cycleType: CycleType.INVESTMENT
923
+ cycleType: CycleType.INVESTMENT,
673
924
  },
674
925
  extendedAdapter,
675
926
  vesuAdapter
676
927
  );
677
928
  if (!vesuStatus) {
678
- logger.error(`Failed to move assets to vesu - operation returned false status`);
679
- return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: vesuAmountDifference }, "NONE", CycleType.INVESTMENT)];
929
+ logger.error(
930
+ `Failed to move assets to vesu - operation returned false status`
931
+ );
932
+ return [
933
+ this.createTransactionResult(
934
+ [],
935
+ false,
936
+ {
937
+ from: Protocols.EXTENDED.name,
938
+ to: Protocols.VAULT.name,
939
+ amount: vesuAmountDifference,
940
+ },
941
+ "NONE",
942
+ CycleType.INVESTMENT
943
+ ),
944
+ ];
680
945
  }
681
946
  transactionResults.push({
682
947
  status: vesuStatus,
@@ -684,18 +949,42 @@ export class VesuExtendedMultiplierStrategy<
684
949
  transactionMetadata: {
685
950
  ...vesuTransactionMetadata,
686
951
  transactionType: "DEPOSIT",
687
- }
688
- })
952
+ },
953
+ });
689
954
  } catch (err) {
690
955
  logger.error(`Failed moving assets to vault: ${err}`);
691
- return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: vesuAmountDifference }, "NONE", CycleType.INVESTMENT)];
956
+ return [
957
+ this.createTransactionResult(
958
+ [],
959
+ false,
960
+ {
961
+ from: Protocols.EXTENDED.name,
962
+ to: Protocols.VAULT.name,
963
+ amount: vesuAmountDifference,
964
+ },
965
+ "NONE",
966
+ CycleType.INVESTMENT
967
+ ),
968
+ ];
692
969
  }
693
970
  }
694
971
  }
695
972
  return transactionResults;
696
973
  } catch (err) {
697
974
  logger.error(`Failed moving assets to vesu: ${err}`);
698
- return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: new Web3Number(0, USDC_TOKEN_DECIMALS) }, "NONE", CycleType.INVESTMENT)];
975
+ return [
976
+ this.createTransactionResult(
977
+ [],
978
+ false,
979
+ {
980
+ from: Protocols.EXTENDED.name,
981
+ to: Protocols.VAULT.name,
982
+ amount: new Web3Number(0, USDC_TOKEN_DECIMALS),
983
+ },
984
+ "NONE",
985
+ CycleType.INVESTMENT
986
+ ),
987
+ ];
699
988
  }
700
989
  }
701
990
 
@@ -706,7 +995,7 @@ export class VesuExtendedMultiplierStrategy<
706
995
  calls: Call[],
707
996
  status: boolean,
708
997
  params: { from: string; to: string; amount: Web3Number },
709
- transactionType: 'DEPOSIT' | 'WITHDRAWAL' | 'NONE',
998
+ transactionType: "DEPOSIT" | "WITHDRAWAL" | "NONE",
710
999
  cycleType: CycleType
711
1000
  ): TransactionResult {
712
1001
  if (status) {
@@ -718,12 +1007,23 @@ export class VesuExtendedMultiplierStrategy<
718
1007
  protocolTo: params.to,
719
1008
  transactionType: transactionType,
720
1009
  usdAmount: params.amount.abs().toFixed(),
721
- status: 'PENDING',
722
- cycleType: cycleType
723
- }
1010
+ status: "PENDING",
1011
+ cycleType: cycleType,
1012
+ },
724
1013
  };
725
1014
  }
726
- return { calls: [], status: false, transactionMetadata: { protocolFrom: '', protocolTo: '', transactionType: 'DEPOSIT', usdAmount: '0', status: 'FAILED', cycleType: cycleType } };
1015
+ return {
1016
+ calls: [],
1017
+ status: false,
1018
+ transactionMetadata: {
1019
+ protocolFrom: "",
1020
+ protocolTo: "",
1021
+ transactionType: "DEPOSIT",
1022
+ usdAmount: "0",
1023
+ status: "FAILED",
1024
+ cycleType: cycleType,
1025
+ },
1026
+ };
727
1027
  }
728
1028
 
729
1029
  /**
@@ -732,7 +1032,7 @@ export class VesuExtendedMultiplierStrategy<
732
1032
  * @param extendedAdapter - The extended adapter
733
1033
  * @param vesuAdapter - The vesu adapter
734
1034
  * @returns The transaction result
735
- * If Extended amount is greater than amount of withdrawal from extended, then we need to open a long position
1035
+ * If Extended amount is greater than amount of withdrawal from extended, then we need to open a long position
736
1036
  * so that the amount of withdrawal from extended is fullfilled
737
1037
  */
738
1038
  async moveAssets(
@@ -743,7 +1043,7 @@ export class VesuExtendedMultiplierStrategy<
743
1043
  cycleType: CycleType;
744
1044
  },
745
1045
  extendedAdapter: ExtendedAdapter,
746
- vesuAdapter: VesuMultiplyAdapter,
1046
+ vesuAdapter: VesuMultiplyAdapter
747
1047
  ): Promise<TransactionResult> {
748
1048
  try {
749
1049
  // Validate amount is positive before starting operations
@@ -751,7 +1051,13 @@ export class VesuExtendedMultiplierStrategy<
751
1051
  logger.error(
752
1052
  `Invalid amount for moveAssets: ${params.amount.toNumber()}. Amount must be positive.`
753
1053
  );
754
- return this.createTransactionResult([], false, params, "NONE", params.cycleType);
1054
+ return this.createTransactionResult(
1055
+ [],
1056
+ false,
1057
+ params,
1058
+ "NONE",
1059
+ params.cycleType
1060
+ );
755
1061
  }
756
1062
 
757
1063
  // Check minimum movement amounts before starting operations
@@ -776,15 +1082,22 @@ export class VesuExtendedMultiplierStrategy<
776
1082
  const avnuAdapter = await this.getAvnuAdapter();
777
1083
  if (!avnuAdapter) {
778
1084
  logger.error(`avnu adapter not found: ${avnuAdapter}`);
779
- return this.createTransactionResult([], false, params, "NONE", params.cycleType);
1085
+ return this.createTransactionResult(
1086
+ [],
1087
+ false,
1088
+ params,
1089
+ "NONE",
1090
+ params.cycleType
1091
+ );
780
1092
  }
781
1093
  logger.info(`moveAssets params, ${JSON.stringify(params)}`);
782
1094
  const collateralToken = vesuAdapter.config.supportedPositions[0].asset;
783
- const {
784
- collateralPrice,
785
- } = await this.getAssetPrices();
1095
+ const { collateralPrice } = await this.getAssetPrices();
786
1096
 
787
- if (params.to === Protocols.EXTENDED.name && params.from === Protocols.VAULT.name) {
1097
+ if (
1098
+ params.to === Protocols.EXTENDED.name &&
1099
+ params.from === Protocols.VAULT.name
1100
+ ) {
788
1101
  const proofsInfo = extendedAdapter.getProofs(
789
1102
  true,
790
1103
  this.getMerkleTree()
@@ -796,29 +1109,54 @@ export class VesuExtendedMultiplierStrategy<
796
1109
  await proofsInfo.callConstructor({ amount: params.amount })
797
1110
  );
798
1111
  calls.push(call);
799
- return this.createTransactionResult(calls, true, params, "DEPOSIT", params.cycleType);
800
- }
801
- else if (params.to === Protocols.VAULT.name && params.from === Protocols.EXTENDED.name) {
1112
+ return this.createTransactionResult(
1113
+ calls,
1114
+ true,
1115
+ params,
1116
+ "DEPOSIT",
1117
+ params.cycleType
1118
+ );
1119
+ } else if (
1120
+ params.to === Protocols.VAULT.name &&
1121
+ params.from === Protocols.EXTENDED.name
1122
+ ) {
802
1123
  const extendedLeverage = calculateExtendedLevergae();
803
- const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
1124
+ const extendedHoldings =
1125
+ await extendedAdapter.getExtendedDepositAmount();
804
1126
  if (!extendedHoldings) {
805
1127
  logger.error(`error getting extended holdings: ${extendedHoldings}`);
806
- return this.createTransactionResult([], false, params, "NONE", params.cycleType);
1128
+ return this.createTransactionResult(
1129
+ [],
1130
+ false,
1131
+ params,
1132
+ "NONE",
1133
+ params.cycleType
1134
+ );
807
1135
  }
808
1136
  const extendedHoldingAmount = new Web3Number(
809
1137
  extendedHoldings.availableForWithdrawal,
810
1138
  USDC_TOKEN_DECIMALS
811
1139
  );
812
- logger.info(`${VesuExtendedMultiplierStrategy.name}::moveAssets extendedHoldingAmount: ${extendedHoldingAmount.toNumber()}`);
1140
+ logger.info(
1141
+ `${
1142
+ VesuExtendedMultiplierStrategy.name
1143
+ }::moveAssets extendedHoldingAmount: ${extendedHoldingAmount.toNumber()}`
1144
+ );
813
1145
  if (params.amount.abs().greaterThan(extendedHoldingAmount)) {
814
- const leftAmountAfterWithdrawalAmountInAccount = new Web3Number(Math.ceil(params.amount.abs().minus(extendedHoldingAmount).toNumber()), USDC_TOKEN_DECIMALS);
815
- logger.info(`${VesuExtendedMultiplierStrategy.name}::moveAssets leftAmountAfterWithdrawalAmountInAccount: ${leftAmountAfterWithdrawalAmountInAccount.toNumber()}`);
1146
+ const leftAmountAfterWithdrawalAmountInAccount = new Web3Number(
1147
+ Math.ceil(
1148
+ params.amount.abs().minus(extendedHoldingAmount).toNumber()
1149
+ ),
1150
+ USDC_TOKEN_DECIMALS
1151
+ );
1152
+ logger.info(
1153
+ `${
1154
+ VesuExtendedMultiplierStrategy.name
1155
+ }::moveAssets leftAmountAfterWithdrawalAmountInAccount: ${leftAmountAfterWithdrawalAmountInAccount.toNumber()}`
1156
+ );
816
1157
  let priceOfBTC;
817
- const {
818
- ask,
819
- bid,
820
- status
821
- } = await extendedAdapter.fetchOrderBookBTCUSDC();
1158
+ const { ask, bid, status } =
1159
+ await extendedAdapter.fetchOrderBookBTCUSDC();
822
1160
  const price = ask.plus(bid).dividedBy(2);
823
1161
  if (status) {
824
1162
  priceOfBTC = price;
@@ -826,73 +1164,149 @@ export class VesuExtendedMultiplierStrategy<
826
1164
  logger.error(`error fetching order book btc usdc: ${status}`);
827
1165
  priceOfBTC = collateralPrice.price;
828
1166
  }
829
- const btcAmount = leftAmountAfterWithdrawalAmountInAccount.dividedBy(priceOfBTC);
1167
+ const btcAmount =
1168
+ leftAmountAfterWithdrawalAmountInAccount.dividedBy(priceOfBTC);
830
1169
  /**
831
1170
  * If amount for withdrawal is greater than the amount in extended available for withdrawal,
832
1171
  * then we need to open a long position depending on the difference between the two
833
1172
  */
834
- const openLongPosition = btcAmount.multipliedBy(3).greaterThan(MINIMUM_EXTENDED_POSITION_SIZE) ? await extendedAdapter.createOrder(
835
- extendedLeverage.toString(),
836
- btcAmount.toNumber(),
837
- OrderSide.BUY
838
- ) : await extendedAdapter.createOrder(
839
- extendedLeverage.toString(),
840
- 0.000034, // just in case amount falls short then we need to create a withdrawal
841
- OrderSide.BUY
842
- )
1173
+ const openLongPosition = btcAmount
1174
+ .multipliedBy(3)
1175
+ .greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)
1176
+ ? await extendedAdapter.createOrder(
1177
+ extendedLeverage.toString(),
1178
+ btcAmount.toNumber(),
1179
+ OrderSide.BUY
1180
+ )
1181
+ : await extendedAdapter.createOrder(
1182
+ extendedLeverage.toString(),
1183
+ 0.000034, // just in case amount falls short then we need to create a withdrawal
1184
+ OrderSide.BUY
1185
+ );
843
1186
  if (!openLongPosition) {
844
1187
  logger.error(`error opening long position: ${openLongPosition}`);
845
1188
  }
846
- const updatedHoldings = await extendedAdapter.getExtendedDepositAmount();
847
- if (!updatedHoldings || new Web3Number(updatedHoldings.availableForWithdrawal, USDC_TOKEN_DECIMALS).lessThan(params.amount.abs())) {
848
- logger.error(`Insufficient balance after opening position. Available: ${updatedHoldings?.availableForWithdrawal}, Needed: ${params.amount.abs()}`);
849
- return this.createTransactionResult([], false, params, "NONE", params.cycleType);
1189
+ const updatedHoldings =
1190
+ await extendedAdapter.getExtendedDepositAmount();
1191
+ if (
1192
+ !updatedHoldings ||
1193
+ new Web3Number(
1194
+ updatedHoldings.availableForWithdrawal,
1195
+ USDC_TOKEN_DECIMALS
1196
+ ).lessThan(params.amount.abs())
1197
+ ) {
1198
+ logger.error(
1199
+ `Insufficient balance after opening position. Available: ${
1200
+ updatedHoldings?.availableForWithdrawal
1201
+ }, Needed: ${params.amount.abs()}`
1202
+ );
1203
+ return this.createTransactionResult(
1204
+ [],
1205
+ false,
1206
+ params,
1207
+ "NONE",
1208
+ params.cycleType
1209
+ );
850
1210
  }
851
1211
  }
852
1212
  const {
853
1213
  status: withdrawalFromExtendedStatus,
854
1214
  receivedTxnHash: withdrawalFromExtendedTxnHash,
855
- } =
856
- await extendedAdapter.withdrawFromExtended(params.amount);
1215
+ } = await extendedAdapter.withdrawFromExtended(params.amount);
857
1216
  /**
858
1217
  * This logic needs fixing
859
1218
  */
860
- logger.info(`withdrawalFromExtendedStatus: ${withdrawalFromExtendedStatus}, withdrawalFromExtendedTxnHash: ${withdrawalFromExtendedTxnHash}`);
1219
+ logger.info(
1220
+ `withdrawalFromExtendedStatus: ${withdrawalFromExtendedStatus}, withdrawalFromExtendedTxnHash: ${withdrawalFromExtendedTxnHash}`
1221
+ );
861
1222
  if (withdrawalFromExtendedStatus && withdrawalFromExtendedTxnHash) {
862
1223
  /**
863
- * We need to move assets from my wallet back to vault contract
864
- */
865
- const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
866
- logger.info(`extendedHoldings after withdrawal ${extendedHoldings?.availableForWithdrawal}`);
867
- await new Promise(resolve => setTimeout(resolve, 5000));
868
- const { calls, status } = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
1224
+ * We need to move assets from my wallet back to vault contract
1225
+ */
1226
+ const extendedHoldings =
1227
+ await extendedAdapter.getExtendedDepositAmount();
1228
+ logger.info(
1229
+ `extendedHoldings after withdrawal ${extendedHoldings?.availableForWithdrawal}`
1230
+ );
1231
+ await new Promise((resolve) => setTimeout(resolve, 5000));
1232
+ const { calls, status } = await this.moveAssetsToVaultAllocator(
1233
+ params.amount,
1234
+ extendedAdapter
1235
+ );
869
1236
  if (calls.length > 0 && status) {
870
- return this.createTransactionResult(calls, true, params, "WITHDRAWAL", params.cycleType);
1237
+ return this.createTransactionResult(
1238
+ calls,
1239
+ true,
1240
+ params,
1241
+ "WITHDRAWAL",
1242
+ params.cycleType
1243
+ );
871
1244
  } else {
872
1245
  /**
873
1246
  * This is a fallback scenario, where the funds were withdrawn from extended, but didn't get transferred to the wallet
874
1247
  * We need to return a successful transaction result, but with no calls
875
1248
  * Db update will be handled by the risk engine for this specific case
876
1249
  */
877
- return this.createTransactionResult([], true, params, "WITHDRAWAL", params.cycleType);
1250
+ return this.createTransactionResult(
1251
+ [],
1252
+ true,
1253
+ params,
1254
+ "WITHDRAWAL",
1255
+ params.cycleType
1256
+ );
878
1257
  }
879
- } else if (withdrawalFromExtendedStatus && !withdrawalFromExtendedTxnHash) {
880
- logger.error("withdrawal from extended successful, but funds didn't get transferred to the wallet");
881
- return this.createTransactionResult([], true, params, "WITHDRAWAL", params.cycleType);
1258
+ } else if (
1259
+ withdrawalFromExtendedStatus &&
1260
+ !withdrawalFromExtendedTxnHash
1261
+ ) {
1262
+ logger.error(
1263
+ "withdrawal from extended successful, but funds didn't get transferred to the wallet"
1264
+ );
1265
+ return this.createTransactionResult(
1266
+ [],
1267
+ true,
1268
+ params,
1269
+ "WITHDRAWAL",
1270
+ params.cycleType
1271
+ );
882
1272
  } else {
883
1273
  logger.error("withdrawal from extended failed");
884
- return this.createTransactionResult([], false, params, "NONE", params.cycleType);
1274
+ return this.createTransactionResult(
1275
+ [],
1276
+ false,
1277
+ params,
1278
+ "NONE",
1279
+ params.cycleType
1280
+ );
885
1281
  }
886
- } else if (params.to === Protocols.VAULT.name && params.from === Protocols.VESU.name) {
887
-
888
- const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, PositionTypeAvnuExtended.CLOSE);
1282
+ } else if (
1283
+ params.to === Protocols.VAULT.name &&
1284
+ params.from === Protocols.VESU.name
1285
+ ) {
1286
+ const isPriceDifferenceBetweenAvnuAndExtended =
1287
+ await this.checkPriceDifferenceBetweenAvnuAndExtended(
1288
+ extendedAdapter,
1289
+ vesuAdapter,
1290
+ avnuAdapter,
1291
+ PositionTypeAvnuExtended.CLOSE
1292
+ );
889
1293
  if (!isPriceDifferenceBetweenAvnuAndExtended) {
890
- logger.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
891
- return this.createTransactionResult([], false, params, "NONE", params.cycleType);
1294
+ logger.warn(
1295
+ `price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`
1296
+ );
1297
+ return this.createTransactionResult(
1298
+ [],
1299
+ false,
1300
+ params,
1301
+ "NONE",
1302
+ params.cycleType
1303
+ );
892
1304
  }
893
- //withdraw from vesu
1305
+ //withdraw from vesu
894
1306
  const vesuAmountInBTC = new Web3Number(
895
- params.amount.dividedBy(collateralPrice.price).toFixed(WBTC_TOKEN_DECIMALS),
1307
+ params.amount
1308
+ .dividedBy(collateralPrice.price)
1309
+ .toFixed(WBTC_TOKEN_DECIMALS),
896
1310
  collateralToken.decimals
897
1311
  );
898
1312
  const proofsInfo = vesuAdapter.getProofs(false, this.getMerkleTree());
@@ -903,22 +1317,45 @@ export class VesuExtendedMultiplierStrategy<
903
1317
  await proofsInfo.callConstructor({ amount: vesuAmountInBTC })
904
1318
  );
905
1319
  calls.push(call);
906
- const swapProofsInfo = avnuAdapter.getProofs(false, this.getMerkleTree());
1320
+ const swapProofsInfo = avnuAdapter.getProofs(
1321
+ false,
1322
+ this.getMerkleTree()
1323
+ );
907
1324
  const swapProofGroups = swapProofsInfo.proofs;
908
1325
  const swapCall = this.getManageCall(
909
1326
  swapProofGroups,
910
1327
  await swapProofsInfo.callConstructor({ amount: vesuAmountInBTC })
911
1328
  );
912
1329
  calls.push(swapCall);
913
- return this.createTransactionResult(calls, true, params, "WITHDRAWAL", params.cycleType);
914
-
915
- }
916
- else if (params.to === Protocols.EXTENDED.name && params.from === Protocols.VESU.name) {
917
-
918
- const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, PositionTypeAvnuExtended.CLOSE);
1330
+ return this.createTransactionResult(
1331
+ calls,
1332
+ true,
1333
+ params,
1334
+ "WITHDRAWAL",
1335
+ params.cycleType
1336
+ );
1337
+ } else if (
1338
+ params.to === Protocols.EXTENDED.name &&
1339
+ params.from === Protocols.VESU.name
1340
+ ) {
1341
+ const isPriceDifferenceBetweenAvnuAndExtended =
1342
+ await this.checkPriceDifferenceBetweenAvnuAndExtended(
1343
+ extendedAdapter,
1344
+ vesuAdapter,
1345
+ avnuAdapter,
1346
+ PositionTypeAvnuExtended.CLOSE
1347
+ );
919
1348
  if (!isPriceDifferenceBetweenAvnuAndExtended) {
920
- logger.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
921
- return this.createTransactionResult([], false, params, "NONE", params.cycleType);
1349
+ logger.warn(
1350
+ `price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`
1351
+ );
1352
+ return this.createTransactionResult(
1353
+ [],
1354
+ false,
1355
+ params,
1356
+ "NONE",
1357
+ params.cycleType
1358
+ );
922
1359
  }
923
1360
  const vesuAmountInBTC = new Web3Number(
924
1361
  params.amount.dividedBy(collateralPrice.price).toNumber(),
@@ -932,7 +1369,10 @@ export class VesuExtendedMultiplierStrategy<
932
1369
  await proofsInfo.callConstructor({ amount: vesuAmountInBTC })
933
1370
  );
934
1371
  calls.push(call);
935
- const swapProofsInfo = avnuAdapter.getProofs(false, this.getMerkleTree());
1372
+ const swapProofsInfo = avnuAdapter.getProofs(
1373
+ false,
1374
+ this.getMerkleTree()
1375
+ );
936
1376
  const swapProofGroups = swapProofsInfo.proofs;
937
1377
  const swapCall = this.getManageCall(
938
1378
  swapProofGroups,
@@ -950,14 +1390,33 @@ export class VesuExtendedMultiplierStrategy<
950
1390
  await proofsInfoDeposit.callConstructor({ amount: params.amount })
951
1391
  );
952
1392
  calls.push(callDeposit);
953
- return this.createTransactionResult(calls, true, params, "DEPOSIT", params.cycleType);
1393
+ return this.createTransactionResult(
1394
+ calls,
1395
+ true,
1396
+ params,
1397
+ "DEPOSIT",
1398
+ params.cycleType
1399
+ );
954
1400
  }
955
- logger.error(`Unsupported assets movement: ${params.from} to ${params.to}`);
956
- return this.createTransactionResult([], false, params, "NONE", params.cycleType);
957
-
1401
+ logger.error(
1402
+ `Unsupported assets movement: ${params.from} to ${params.to}`
1403
+ );
1404
+ return this.createTransactionResult(
1405
+ [],
1406
+ false,
1407
+ params,
1408
+ "NONE",
1409
+ params.cycleType
1410
+ );
958
1411
  } catch (err) {
959
1412
  logger.error(`error moving assets: ${err}`);
960
- return this.createTransactionResult([], false, params, "NONE", params.cycleType);
1413
+ return this.createTransactionResult(
1414
+ [],
1415
+ false,
1416
+ params,
1417
+ "NONE",
1418
+ params.cycleType
1419
+ );
961
1420
  }
962
1421
  }
963
1422
 
@@ -966,14 +1425,33 @@ export class VesuExtendedMultiplierStrategy<
966
1425
  /**
967
1426
  * Just a demo function, not used in the risk engine
968
1427
  */
969
- return this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.VAULT.name, amount: new Web3Number(0, 0) }, "NONE", CycleType.INVESTMENT);
1428
+ return this.createTransactionResult(
1429
+ [],
1430
+ false,
1431
+ {
1432
+ from: Protocols.VAULT.name,
1433
+ to: Protocols.VAULT.name,
1434
+ amount: new Web3Number(0, 0),
1435
+ },
1436
+ "NONE",
1437
+ CycleType.INVESTMENT
1438
+ );
970
1439
  } catch (err) {
971
1440
  logger.error(`error handling deposit: ${err}`);
972
- return this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.VAULT.name, amount: new Web3Number(0, 0) }, "NONE", CycleType.INVESTMENT);
1441
+ return this.createTransactionResult(
1442
+ [],
1443
+ false,
1444
+ {
1445
+ from: Protocols.VAULT.name,
1446
+ to: Protocols.VAULT.name,
1447
+ amount: new Web3Number(0, 0),
1448
+ },
1449
+ "NONE",
1450
+ CycleType.INVESTMENT
1451
+ );
973
1452
  }
974
1453
  }
975
1454
 
976
-
977
1455
  /**
978
1456
  * Check if the price difference between avnu and extended is within the acceptable range to enhance the position size or close the position
979
1457
  * @param extendedAdapter - the extended adapter
@@ -982,13 +1460,18 @@ export class VesuExtendedMultiplierStrategy<
982
1460
  * @param positionType - the position type (open or close)
983
1461
  * @returns true if the price difference is within the acceptable range, false otherwise
984
1462
  */
985
- async checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter: ExtendedAdapter, vesuAdapter: VesuMultiplyAdapter, avnuAdapter: AvnuAdapter, positionType: PositionTypeAvnuExtended): Promise<boolean> {
986
- const {
987
- ask, bid
988
- } = await extendedAdapter.fetchOrderBookBTCUSDC();
1463
+ async checkPriceDifferenceBetweenAvnuAndExtended(
1464
+ extendedAdapter: ExtendedAdapter,
1465
+ vesuAdapter: VesuMultiplyAdapter,
1466
+ avnuAdapter: AvnuAdapter,
1467
+ positionType: PositionTypeAvnuExtended
1468
+ ): Promise<boolean> {
1469
+ const { ask, bid } = await extendedAdapter.fetchOrderBookBTCUSDC();
989
1470
  const price = ask.plus(bid).dividedBy(2);
990
1471
  const btcToken = vesuAdapter.config.supportedPositions[0].asset;
991
- const btcPriceAvnu = await avnuAdapter.getPriceOfToken(btcToken.address.toString());
1472
+ const btcPriceAvnu = await avnuAdapter.getPriceOfToken(
1473
+ btcToken.address.toString()
1474
+ );
992
1475
 
993
1476
  if (!btcPriceAvnu) {
994
1477
  logger.error(`error getting btc price avnu: ${btcPriceAvnu}`);
@@ -996,19 +1479,34 @@ export class VesuExtendedMultiplierStrategy<
996
1479
  }
997
1480
  logger.info(`price: ${price}`);
998
1481
  logger.info(`btcPriceAvnu: ${btcPriceAvnu}`);
999
- const priceDifference = new Web3Number(price.minus(btcPriceAvnu).toFixed(2), 0);
1482
+ const priceDifference = new Web3Number(
1483
+ price.minus(btcPriceAvnu).toFixed(2),
1484
+ 0
1485
+ );
1000
1486
  logger.info(`priceDifference: ${priceDifference}`);
1001
1487
  if (priceDifference.isNegative()) {
1002
1488
  return false;
1003
1489
  }
1004
1490
  if (positionType === PositionTypeAvnuExtended.OPEN) {
1005
- logger.info(`price difference between avnu and extended for open position: ${priceDifference.toNumber()}, minimumExtendedPriceDifferenceForSwapOpen: ${avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen}`);
1006
- const result = priceDifference.greaterThanOrEqualTo(avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen); // 500 for now
1491
+ logger.info(
1492
+ `price difference between avnu and extended for open position: ${priceDifference.toNumber()}, minimumExtendedPriceDifferenceForSwapOpen: ${
1493
+ avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen
1494
+ }`
1495
+ );
1496
+ const result = priceDifference.greaterThanOrEqualTo(
1497
+ avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen
1498
+ ); // 500 for now
1007
1499
  logger.info(`result: ${result}`);
1008
1500
  return result;
1009
1501
  } else {
1010
- logger.info(`price difference between avnu and extended for close position: ${priceDifference.toNumber()}, maximumExtendedPriceDifferenceForSwapClosing: ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
1011
- const result = priceDifference.lessThanOrEqualTo(avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing); // 1000 for now
1502
+ logger.info(
1503
+ `price difference between avnu and extended for close position: ${priceDifference.toNumber()}, maximumExtendedPriceDifferenceForSwapClosing: ${
1504
+ avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing
1505
+ }`
1506
+ );
1507
+ const result = priceDifference.lessThanOrEqualTo(
1508
+ avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing
1509
+ ); // 1000 for now
1012
1510
  logger.info(`result: ${result}`);
1013
1511
  return result;
1014
1512
  }
@@ -1022,16 +1520,30 @@ export class VesuExtendedMultiplierStrategy<
1022
1520
  async handleWithdraw(amount: Web3Number): Promise<TransactionResult[]> {
1023
1521
  try {
1024
1522
  const usdcBalanceVaultAllocator = await this.getUnusedBalance();
1025
- const usdcBalanceDifference = amount.plus(BUFFER_USDC_IN_WITHDRAWAL).minus(usdcBalanceVaultAllocator.usdValue);
1523
+ const usdcBalanceDifference = amount
1524
+ .plus(BUFFER_USDC_IN_WITHDRAWAL)
1525
+ .minus(usdcBalanceVaultAllocator.usdValue);
1026
1526
  logger.info(`usdcBalanceDifference, ${usdcBalanceDifference.toNumber()}`);
1027
1527
  let calls: Call[] = [];
1028
1528
  let status: boolean = true;
1029
1529
  if (usdcBalanceDifference.lessThan(0)) {
1030
1530
  const withdrawCall = await this.getBringLiquidityCall({
1031
- amount: usdcBalanceVaultAllocator.amount
1032
- })
1531
+ amount: usdcBalanceVaultAllocator.amount,
1532
+ });
1033
1533
  calls.push(withdrawCall);
1034
- return [this.createTransactionResult(calls, true, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount: amount }, "WITHDRAWAL", CycleType.WITHDRAWAL)];
1534
+ return [
1535
+ this.createTransactionResult(
1536
+ calls,
1537
+ true,
1538
+ {
1539
+ from: Protocols.VAULT.name,
1540
+ to: Protocols.NONE.name,
1541
+ amount: amount,
1542
+ },
1543
+ "WITHDRAWAL",
1544
+ CycleType.WITHDRAWAL
1545
+ ),
1546
+ ];
1035
1547
  }
1036
1548
  const vesuAdapter = await this.getVesuAdapter();
1037
1549
  const extendedAdapter = await this.getExtendedAdapter();
@@ -1040,19 +1552,41 @@ export class VesuExtendedMultiplierStrategy<
1040
1552
  logger.error(
1041
1553
  `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
1042
1554
  );
1043
- return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount: amount }, "NONE", CycleType.WITHDRAWAL)];
1555
+ return [
1556
+ this.createTransactionResult(
1557
+ calls,
1558
+ status,
1559
+ {
1560
+ from: Protocols.VAULT.name,
1561
+ to: Protocols.NONE.name,
1562
+ amount: amount,
1563
+ },
1564
+ "NONE",
1565
+ CycleType.WITHDRAWAL
1566
+ ),
1567
+ ];
1044
1568
  }
1045
1569
  let transactionResults: TransactionResult[] = [];
1046
1570
  const { collateralTokenAmount } =
1047
1571
  await vesuAdapter.vesuAdapter.getAssetPrices();
1048
- const {
1049
- collateralPrice
1050
- } = await this.getAssetPrices();
1572
+ const { collateralPrice } = await this.getAssetPrices();
1051
1573
  const extendedPositon = await extendedAdapter.getAllOpenPositions();
1052
1574
  if (!extendedPositon) {
1053
1575
  status = false;
1054
1576
  logger.error("error getting extended position", extendedPositon);
1055
- return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount: amount }, "NONE", CycleType.WITHDRAWAL)];
1577
+ return [
1578
+ this.createTransactionResult(
1579
+ calls,
1580
+ status,
1581
+ {
1582
+ from: Protocols.VAULT.name,
1583
+ to: Protocols.NONE.name,
1584
+ amount: amount,
1585
+ },
1586
+ "NONE",
1587
+ CycleType.WITHDRAWAL
1588
+ ),
1589
+ ];
1056
1590
  }
1057
1591
  const amountDistributionForWithdrawal =
1058
1592
  await calculateAmountDistributionForWithdrawal(
@@ -1066,17 +1600,33 @@ export class VesuExtendedMultiplierStrategy<
1066
1600
  logger.error(
1067
1601
  `error calculating amount distribution for withdrawal: ${amountDistributionForWithdrawal}`
1068
1602
  );
1069
- return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount: amount }, "NONE", CycleType.WITHDRAWAL)];
1603
+ return [
1604
+ this.createTransactionResult(
1605
+ calls,
1606
+ status,
1607
+ {
1608
+ from: Protocols.VAULT.name,
1609
+ to: Protocols.NONE.name,
1610
+ amount: amount,
1611
+ },
1612
+ "NONE",
1613
+ CycleType.WITHDRAWAL
1614
+ ),
1615
+ ];
1070
1616
  }
1071
1617
  const { vesu_amount, extended_amount } = amountDistributionForWithdrawal;
1072
1618
 
1073
1619
  if (status && vesu_amount.greaterThan(0)) {
1074
- const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
1620
+ const {
1621
+ calls: vesuCalls,
1622
+ status: vesuStatus,
1623
+ transactionMetadata: vesuTransactionMetadata,
1624
+ } = await this.moveAssets(
1075
1625
  {
1076
1626
  amount: vesu_amount,
1077
1627
  from: Protocols.VESU.name,
1078
1628
  to: Protocols.VAULT.name,
1079
- cycleType: CycleType.WITHDRAWAL
1629
+ cycleType: CycleType.WITHDRAWAL,
1080
1630
  },
1081
1631
  extendedAdapter,
1082
1632
  vesuAdapter
@@ -1085,16 +1635,20 @@ export class VesuExtendedMultiplierStrategy<
1085
1635
  transactionResults.push({
1086
1636
  status: vesuStatus,
1087
1637
  calls: vesuCalls,
1088
- transactionMetadata: vesuTransactionMetadata
1089
- })
1638
+ transactionMetadata: vesuTransactionMetadata,
1639
+ });
1090
1640
  }
1091
1641
  if (status && extended_amount.greaterThan(0)) {
1092
- const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
1642
+ const {
1643
+ calls: extendedCalls,
1644
+ status: extendedStatus,
1645
+ transactionMetadata: extendedTransactionMetadata,
1646
+ } = await this.moveAssets(
1093
1647
  {
1094
1648
  amount: extended_amount,
1095
1649
  from: Protocols.EXTENDED.name,
1096
1650
  to: Protocols.VAULT.name,
1097
- cycleType: CycleType.WITHDRAWAL
1651
+ cycleType: CycleType.WITHDRAWAL,
1098
1652
  },
1099
1653
  extendedAdapter,
1100
1654
  vesuAdapter
@@ -1104,16 +1658,30 @@ export class VesuExtendedMultiplierStrategy<
1104
1658
  transactionResults.push({
1105
1659
  status: extendedStatus,
1106
1660
  calls: extendedCalls,
1107
- transactionMetadata: extendedTransactionMetadata
1108
- })
1661
+ transactionMetadata: extendedTransactionMetadata,
1662
+ });
1109
1663
  } else {
1110
- logger.error("error moving assets to vault: extendedStatus: ${extendedStatus}");
1111
- return [this.createTransactionResult([], status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount: amount }, "NONE", CycleType.WITHDRAWAL)];
1664
+ logger.error(
1665
+ "error moving assets to vault: extendedStatus: ${extendedStatus}"
1666
+ );
1667
+ return [
1668
+ this.createTransactionResult(
1669
+ [],
1670
+ status,
1671
+ {
1672
+ from: Protocols.VAULT.name,
1673
+ to: Protocols.NONE.name,
1674
+ amount: amount,
1675
+ },
1676
+ "NONE",
1677
+ CycleType.WITHDRAWAL
1678
+ ),
1679
+ ];
1112
1680
  }
1113
1681
  }
1114
1682
  const withdrawCall = await this.getBringLiquidityCall({
1115
- amount: amount
1116
- })
1683
+ amount: amount,
1684
+ });
1117
1685
  logger.info("withdraw call", withdrawCall);
1118
1686
  transactionResults.push({
1119
1687
  status: status,
@@ -1123,18 +1691,34 @@ export class VesuExtendedMultiplierStrategy<
1123
1691
  protocolTo: Protocols.NONE.name,
1124
1692
  transactionType: "WITHDRAWAL",
1125
1693
  usdAmount: amount.toFixed(),
1126
- status: 'PENDING',
1127
- cycleType: CycleType.WITHDRAWAL
1128
- }
1129
- })
1694
+ status: "PENDING",
1695
+ cycleType: CycleType.WITHDRAWAL,
1696
+ },
1697
+ });
1130
1698
  return transactionResults;
1131
1699
  } catch (err) {
1132
1700
  logger.error(`error handling withdrawal: ${err}`);
1133
- return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount: amount }, "NONE", CycleType.WITHDRAWAL)];
1701
+ return [
1702
+ this.createTransactionResult(
1703
+ [],
1704
+ false,
1705
+ {
1706
+ from: Protocols.VAULT.name,
1707
+ to: Protocols.NONE.name,
1708
+ amount: amount,
1709
+ },
1710
+ "NONE",
1711
+ CycleType.WITHDRAWAL
1712
+ ),
1713
+ ];
1134
1714
  }
1135
1715
  }
1136
1716
 
1137
- async getAUM(): Promise<{ net: SingleTokenInfo, prevAum: Web3Number, splits: PositionInfo[] }> {
1717
+ async getAUM(): Promise<{
1718
+ net: SingleTokenInfo;
1719
+ prevAum: Web3Number;
1720
+ splits: PositionInfo[];
1721
+ }> {
1138
1722
  const allPositions: PositionInfo[] = [];
1139
1723
  for (let adapter of this.metadata.additionalInfo.adapters) {
1140
1724
  const positions = await adapter.adapter.getPositions();
@@ -1158,34 +1742,49 @@ export class VesuExtendedMultiplierStrategy<
1158
1742
  usdValue: netAUM.toNumber() * assetPrice.price,
1159
1743
  apy: { apy: netAUM.toNumber() * assetPrice.price, type: APYType.BASE },
1160
1744
  remarks: AUMTypes.FINALISED,
1161
- protocol: Protocols.NONE // just placeholder
1745
+ protocol: Protocols.NONE, // just placeholder
1162
1746
  };
1163
1747
 
1164
1748
  const estimatedAUMDelta: PositionInfo = {
1165
1749
  tokenInfo: this.asset(),
1166
- amount: Web3Number.fromWei('0', this.asset().decimals),
1750
+ amount: Web3Number.fromWei("0", this.asset().decimals),
1167
1751
  usdValue: 0,
1168
1752
  apy: { apy: 0, type: APYType.BASE },
1169
1753
  remarks: AUMTypes.DEFISPRING,
1170
- protocol: Protocols.NONE // just placeholder
1754
+ protocol: Protocols.NONE, // just placeholder
1171
1755
  };
1172
1756
 
1173
1757
  return {
1174
1758
  net: {
1175
1759
  tokenInfo: this.asset(),
1176
1760
  amount: netAUM,
1177
- usdValue: netAUM.toNumber() * assetPrice.price
1178
- }, prevAum: prevAum, splits: [realAUM, estimatedAUMDelta]
1761
+ usdValue: netAUM.toNumber() * assetPrice.price,
1762
+ },
1763
+ prevAum: prevAum,
1764
+ splits: [realAUM, estimatedAUMDelta],
1179
1765
  };
1180
1766
  }
1181
1767
 
1182
- async processTransactionDataFromSDK(txnData: TransactionResult<any>[]): Promise<{ callsToBeExecutedFinal: Call[], txnMetadata: TransactionMetadata[] } | null> {
1768
+ async processTransactionDataFromSDK(
1769
+ txnData: TransactionResult<any>[]
1770
+ ): Promise<{
1771
+ callsToBeExecutedFinal: Call[];
1772
+ txnMetadata: TransactionMetadata[];
1773
+ } | null> {
1183
1774
  try {
1184
- const txnsToBeExecuted = txnData.filter(txn => {
1185
- return txn.transactionMetadata.transactionType !== 'NONE' && txn.transactionMetadata.protocolFrom !== "" && txn.transactionMetadata.protocolTo !== "";
1186
- })
1187
- const callsToBeExecutedFinal = txnsToBeExecuted.flatMap(txn => txn.calls);
1188
- const txnMetadata = txnsToBeExecuted.map(txn => txn.transactionMetadata);
1775
+ const txnsToBeExecuted = txnData.filter((txn) => {
1776
+ return (
1777
+ txn.transactionMetadata.transactionType !== "NONE" &&
1778
+ txn.transactionMetadata.protocolFrom !== "" &&
1779
+ txn.transactionMetadata.protocolTo !== ""
1780
+ );
1781
+ });
1782
+ const callsToBeExecutedFinal = txnsToBeExecuted.flatMap(
1783
+ (txn) => txn.calls
1784
+ );
1785
+ const txnMetadata = txnsToBeExecuted.map(
1786
+ (txn) => txn.transactionMetadata
1787
+ );
1189
1788
  return { callsToBeExecutedFinal, txnMetadata };
1190
1789
  } catch (err) {
1191
1790
  logger.error(`error processing transaction data from SDK: ${err}`);
@@ -1193,18 +1792,23 @@ export class VesuExtendedMultiplierStrategy<
1193
1792
  }
1194
1793
  }
1195
1794
 
1196
- async processTransactionMetadata(txnMetadata: TransactionMetadata[], extendedIntentFulfilled: boolean): Promise<TransactionMetadata[] | null> {
1795
+ async processTransactionMetadata(
1796
+ txnMetadata: TransactionMetadata[],
1797
+ extendedIntentFulfilled: boolean
1798
+ ): Promise<TransactionMetadata[] | null> {
1197
1799
  try {
1198
- const txnMetadataNew = txnMetadata.map(txn => {
1199
- const isExtendedProtocol = txn.protocolFrom === Protocols.EXTENDED.name || txn.protocolTo === Protocols.EXTENDED.name;
1800
+ const txnMetadataNew = txnMetadata.map((txn) => {
1801
+ const isExtendedProtocol =
1802
+ txn.protocolFrom === Protocols.EXTENDED.name ||
1803
+ txn.protocolTo === Protocols.EXTENDED.name;
1200
1804
  // Only update status for extended protocol transactions since thsoe only cause delays
1201
1805
  if (isExtendedProtocol) {
1202
- txn.status = extendedIntentFulfilled ? 'COMPLETED' : 'PENDING';
1806
+ txn.status = extendedIntentFulfilled ? "COMPLETED" : "PENDING";
1203
1807
  } else {
1204
- txn.status = 'COMPLETED';
1808
+ txn.status = "COMPLETED";
1205
1809
  }
1206
1810
  return txn;
1207
- })
1811
+ });
1208
1812
  return txnMetadataNew;
1209
1813
  } catch (err) {
1210
1814
  logger.error(`error processing transaction data from SDK: ${err}`);
@@ -1218,23 +1822,43 @@ export class VesuExtendedMultiplierStrategy<
1218
1822
  if (!vesuAdapter || !extendedAdapter) {
1219
1823
  return new Web3Number(0, 0);
1220
1824
  }
1221
- const extendedFundingRate = new Web3Number((await extendedAdapter.getNetAPY()).toFixed(4), 0);
1825
+ const extendedFundingRate = new Web3Number(
1826
+ (await extendedAdapter.getNetAPY()).toFixed(4),
1827
+ 0
1828
+ );
1222
1829
  const extendedPositions = await extendedAdapter.getAllOpenPositions();
1223
1830
  if (!extendedPositions || extendedPositions.length === 0) {
1224
1831
  logger.info(`no extended positions found`);
1225
1832
  return new Web3Number(0, 0);
1226
1833
  }
1227
- const extendePositionSizeUSD = new Web3Number(extendedPositions[0].value || 0, 0);
1834
+ const extendePositionSizeUSD = new Web3Number(
1835
+ extendedPositions[0].value || 0,
1836
+ 0
1837
+ );
1228
1838
  const vesuPositions = await vesuAdapter.getPositions();
1229
1839
  const vesuSupplyApy = vesuPositions[0].apy.apy;
1230
- const vesuCollateralSizeUSD = new Web3Number(vesuPositions[0].usdValue.toFixed(USDC_TOKEN_DECIMALS), USDC_TOKEN_DECIMALS);
1231
- const vesuDebtSizeUSD = new Web3Number(vesuPositions[1].usdValue.toFixed(USDC_TOKEN_DECIMALS), USDC_TOKEN_DECIMALS)
1232
- const num1 = extendePositionSizeUSD.multipliedBy(extendedFundingRate);
1840
+ const vesuCollateralSizeUSD = new Web3Number(
1841
+ vesuPositions[0].usdValue.toFixed(USDC_TOKEN_DECIMALS),
1842
+ USDC_TOKEN_DECIMALS
1843
+ );
1844
+ const vesuDebtSizeUSD = new Web3Number(
1845
+ vesuPositions[1].usdValue.toFixed(USDC_TOKEN_DECIMALS),
1846
+ USDC_TOKEN_DECIMALS
1847
+ );
1848
+ const num1 = extendePositionSizeUSD.multipliedBy(extendedFundingRate);
1233
1849
  const num2 = vesuCollateralSizeUSD.multipliedBy(vesuSupplyApy);
1234
- const num3 = vesuDebtSizeUSD.abs()
1850
+ const num3 = vesuDebtSizeUSD.abs();
1235
1851
  const maxBorrowApy = num1.plus(num2).minus(0.1).dividedBy(num3);
1236
- const vesuMaxBorrowableAmount = await vesuAdapter.vesuAdapter.getMaxBorrowableByInterestRate(this.config, vesuAdapter.config.debt, maxBorrowApy.toNumber());
1237
- return new Web3Number(vesuMaxBorrowableAmount.toFixed(USDC_TOKEN_DECIMALS), USDC_TOKEN_DECIMALS);
1852
+ const vesuMaxBorrowableAmount =
1853
+ await vesuAdapter.vesuAdapter.getMaxBorrowableByInterestRate(
1854
+ this.config,
1855
+ vesuAdapter.config.debt,
1856
+ maxBorrowApy.toNumber()
1857
+ );
1858
+ return new Web3Number(
1859
+ vesuMaxBorrowableAmount.toFixed(USDC_TOKEN_DECIMALS),
1860
+ USDC_TOKEN_DECIMALS
1861
+ );
1238
1862
  }
1239
1863
 
1240
1864
  async getVesuHealthFactors(): Promise<number[]> {
@@ -1244,83 +1868,124 @@ export class VesuExtendedMultiplierStrategy<
1244
1868
  return [0, 0];
1245
1869
  }
1246
1870
  const vesuPositions = await vesuAdapter.getPositions();
1247
- const vesuCollateralSizeUSD = new Web3Number(vesuPositions[0].usdValue.toFixed(USDC_TOKEN_DECIMALS), 0);
1248
- const vesuDebtSizeUSD = new Web3Number(vesuPositions[1].usdValue.toFixed(USDC_TOKEN_DECIMALS), 0);
1871
+ const vesuCollateralSizeUSD = new Web3Number(
1872
+ vesuPositions[0].usdValue.toFixed(USDC_TOKEN_DECIMALS),
1873
+ 0
1874
+ );
1875
+ const vesuDebtSizeUSD = new Web3Number(
1876
+ vesuPositions[1].usdValue.toFixed(USDC_TOKEN_DECIMALS),
1877
+ 0
1878
+ );
1249
1879
  const actualLtv = vesuDebtSizeUSD.dividedBy(vesuCollateralSizeUSD).abs();
1250
1880
  logger.info(`actualLtv: ${actualLtv.toNumber()}`);
1251
- const maxLtv = new Web3Number(await vesuAdapter.vesuAdapter.getLTVConfig(this.config), 4);
1252
- const healthFactor = new Web3Number(maxLtv.dividedBy(actualLtv).toFixed(4), 4);
1881
+ const maxLtv = new Web3Number(
1882
+ await vesuAdapter.vesuAdapter.getLTVConfig(this.config),
1883
+ 4
1884
+ );
1885
+ const healthFactor = new Web3Number(
1886
+ maxLtv.dividedBy(actualLtv).toFixed(4),
1887
+ 4
1888
+ );
1253
1889
  logger.info(`healthFactor: ${healthFactor.toNumber()}`);
1254
1890
  const extendedBalance = await extendedAdapter.getExtendedDepositAmount();
1255
1891
  if (!extendedBalance) {
1256
1892
  return [0, 0];
1257
1893
  }
1258
- const extendedLeverage = new Web3Number((Number(extendedBalance.marginRatio) * 100).toFixed(4), 4);
1894
+ const extendedLeverage = new Web3Number(
1895
+ (Number(extendedBalance.marginRatio) * 100).toFixed(4),
1896
+ 4
1897
+ );
1259
1898
  logger.info(`extendedLeverage: ${extendedLeverage.toNumber()}`);
1260
1899
  return [healthFactor.toNumber(), extendedLeverage.toNumber()];
1261
1900
  }
1262
1901
 
1263
- async netAPY(): Promise<{ net: number; splits: { apy: number; id: string; }[]; }> {
1902
+ async netAPY(): Promise<{
1903
+ net: number;
1904
+ splits: { apy: number; id: string }[];
1905
+ }> {
1264
1906
  const allPositions: PositionInfo[] = [];
1265
1907
  for (let adapter of this.metadata.additionalInfo.adapters) {
1266
- if(adapter.adapter.name !== ExtendedAdapter.name){
1267
- let positions = await adapter.adapter.getPositions();
1268
- if(positions.length > 0){
1269
- allPositions.push(...positions);
1270
- }
1908
+ if (adapter.adapter.name !== ExtendedAdapter.name) {
1909
+ let positions = await adapter.adapter.getPositions();
1910
+ if (positions.length > 0) {
1911
+ allPositions.push(...positions);
1271
1912
  }
1272
1913
  }
1273
- const extendedAdapter =await this.getExtendedAdapter()
1274
- if(!extendedAdapter){
1914
+ }
1915
+ const extendedAdapter = await this.getExtendedAdapter();
1916
+ if (!extendedAdapter) {
1275
1917
  return {
1276
1918
  net: 0,
1277
- splits: []
1278
- }
1919
+ splits: [],
1920
+ };
1279
1921
  }
1280
- let vesuPositions = allPositions.filter((item) => item.protocol === Protocols.VESU);
1281
- vesuPositions.map((item) =>{
1922
+ let vesuPositions = allPositions.filter(
1923
+ (item) => item.protocol === Protocols.VESU
1924
+ );
1925
+ vesuPositions.map((item) => {
1282
1926
  item.apy.apy = item.apy.apy * 0.1;
1283
- })
1927
+ });
1284
1928
  const extendedPositions = await extendedAdapter.getAllOpenPositions();
1285
- const usdcToken = Global.getDefaultTokens().find(token => token.symbol === "USDC");
1286
- if(!extendedPositions || !usdcToken){
1929
+ const usdcToken = Global.getDefaultTokens().find(
1930
+ (token) => token.symbol === "USDC"
1931
+ );
1932
+ if (!extendedPositions || !usdcToken) {
1287
1933
  return {
1288
1934
  net: 0,
1289
- splits: []
1290
- }
1935
+ splits: [],
1936
+ };
1291
1937
  }
1292
1938
  const extendedPosition = extendedPositions[0] || 0;
1293
- const extendedEquity = (await extendedAdapter.getExtendedDepositAmount())?.equity || 0;
1939
+ const extendedEquity =
1940
+ (await extendedAdapter.getExtendedDepositAmount())?.equity || 0;
1294
1941
  const extendedApy = await extendedAdapter.getNetAPY();
1295
- const totalHoldingsUSDValue = allPositions.reduce((acc, curr) => acc + curr.usdValue, 0) + Number(extendedEquity);
1296
- console.log(totalHoldingsUSDValue)
1297
- const extendedPositionSizeMultipliedByApy = Number(extendedPosition.value) * extendedApy;
1298
- let weightedAPYs = allPositions.reduce((acc, curr) => acc + curr.apy.apy * curr.usdValue, 0) + extendedPositionSizeMultipliedByApy;
1299
- console.log(weightedAPYs)
1942
+ const totalHoldingsUSDValue =
1943
+ allPositions.reduce((acc, curr) => acc + curr.usdValue, 0) +
1944
+ Number(extendedEquity);
1945
+ console.log(totalHoldingsUSDValue);
1946
+ const extendedPositionSizeMultipliedByApy =
1947
+ Number(extendedPosition.value) * extendedApy;
1948
+ let weightedAPYs =
1949
+ allPositions.reduce(
1950
+ (acc, curr) => acc + curr.apy.apy * curr.usdValue,
1951
+ 0
1952
+ ) + extendedPositionSizeMultipliedByApy;
1953
+ console.log(weightedAPYs);
1300
1954
  const netAPY = weightedAPYs / totalHoldingsUSDValue;
1301
- console.log(netAPY)
1955
+ console.log(netAPY);
1302
1956
  allPositions.push({
1303
1957
  tokenInfo: usdcToken,
1304
1958
  amount: new Web3Number(extendedPosition.size, 0),
1305
1959
  usdValue: Number(extendedEquity),
1306
1960
  apy: { apy: extendedApy, type: APYType.BASE },
1307
1961
  remarks: AUMTypes.FINALISED,
1308
- protocol: Protocols.EXTENDED
1309
- })
1962
+ protocol: Protocols.EXTENDED,
1963
+ });
1310
1964
  return {
1311
1965
  net: netAPY,
1312
- splits: allPositions.map(p => ({apy: p.apy.apy, id: p.remarks ?? ''}))
1966
+ splits: allPositions.map((p) => ({
1967
+ apy: p.apy.apy,
1968
+ id: p.remarks ?? "",
1969
+ })),
1313
1970
  };
1314
1971
  }
1315
1972
 
1316
- async getWalletHoldings(): Promise<{
1317
- tokenInfo: TokenInfo,
1318
- amount: Web3Number,
1319
- usdValue: number
1320
- }[]> {
1321
- const usdceToken = Global.getDefaultTokens().find(token => token.symbol === "USDCe");
1322
- const wbtcToken = Global.getDefaultTokens().find(token => token.symbol === "WBTC");
1323
- const usdcToken = Global.getDefaultTokens().find(token => token.symbol === "USDC");
1973
+ async getWalletHoldings(): Promise<
1974
+ {
1975
+ tokenInfo: TokenInfo;
1976
+ amount: Web3Number;
1977
+ usdValue: number;
1978
+ }[]
1979
+ > {
1980
+ const usdceToken = Global.getDefaultTokens().find(
1981
+ (token) => token.symbol === "USDCe"
1982
+ );
1983
+ const wbtcToken = Global.getDefaultTokens().find(
1984
+ (token) => token.symbol === "WBTC"
1985
+ );
1986
+ const usdcToken = Global.getDefaultTokens().find(
1987
+ (token) => token.symbol === "USDC"
1988
+ );
1324
1989
  if (!usdceToken || !wbtcToken || !usdcToken) {
1325
1990
  return [];
1326
1991
  }
@@ -1342,23 +2007,29 @@ export class VesuExtendedMultiplierStrategy<
1342
2007
  );
1343
2008
  const price = await this.pricer.getPrice(usdceToken.symbol);
1344
2009
  const wbtcPrice = await this.pricer.getPrice(wbtcToken.symbol);
1345
- const usdceUsdValue = Number(usdceWalletBalance.toFixed(usdceToken.decimals)) * price.price;
1346
- const usdcUsdValue = Number(usdcWalletBalance.toFixed(usdcToken.decimals)) * price.price;
1347
- const wbtcUsdValue = Number(wbtcWalletBalance.toFixed(wbtcToken.decimals)) * wbtcPrice.price;
1348
- return [{
1349
- tokenInfo: usdceToken,
1350
- amount: usdceWalletBalance,
1351
- usdValue: usdceUsdValue
1352
- },
1353
- {
1354
- tokenInfo: usdcToken,
1355
- amount: usdcWalletBalance,
1356
- usdValue: usdcUsdValue
1357
- }, {
1358
- tokenInfo: wbtcToken,
1359
- amount: wbtcWalletBalance,
1360
- usdValue: wbtcUsdValue
1361
- }];
2010
+ const usdceUsdValue =
2011
+ Number(usdceWalletBalance.toFixed(usdceToken.decimals)) * price.price;
2012
+ const usdcUsdValue =
2013
+ Number(usdcWalletBalance.toFixed(usdcToken.decimals)) * price.price;
2014
+ const wbtcUsdValue =
2015
+ Number(wbtcWalletBalance.toFixed(wbtcToken.decimals)) * wbtcPrice.price;
2016
+ return [
2017
+ {
2018
+ tokenInfo: usdceToken,
2019
+ amount: usdceWalletBalance,
2020
+ usdValue: usdceUsdValue,
2021
+ },
2022
+ {
2023
+ tokenInfo: usdcToken,
2024
+ amount: usdcWalletBalance,
2025
+ usdValue: usdcUsdValue,
2026
+ },
2027
+ {
2028
+ tokenInfo: wbtcToken,
2029
+ amount: wbtcWalletBalance,
2030
+ usdValue: wbtcUsdValue,
2031
+ },
2032
+ ];
1362
2033
  }
1363
2034
  }
1364
2035
 
@@ -1374,7 +2045,7 @@ function getLooperSettings(
1374
2045
  minimumVesuMovementAmount: number,
1375
2046
  minimumExtendedRetriesDelayForOrderStatus: number,
1376
2047
  minimumExtendedPriceDifferenceForSwapOpen: number,
1377
- maximumExtendedPriceDifferenceForSwapClosing: number,
2048
+ maximumExtendedPriceDifferenceForSwapClosing: number
1378
2049
  ) {
1379
2050
  vaultSettings.leafAdapters = [];
1380
2051
 
@@ -1403,15 +2074,15 @@ function getLooperSettings(
1403
2074
  avnuContract: AVNU_MIDDLEWARE,
1404
2075
  slippage: 0.01,
1405
2076
  baseUrl: AVNU_QUOTE_URL,
1406
- minimumExtendedPriceDifferenceForSwapOpen: minimumExtendedPriceDifferenceForSwapOpen,
1407
- maximumExtendedPriceDifferenceForSwapClosing: maximumExtendedPriceDifferenceForSwapClosing,
2077
+ minimumExtendedPriceDifferenceForSwapOpen:
2078
+ minimumExtendedPriceDifferenceForSwapOpen,
2079
+ maximumExtendedPriceDifferenceForSwapClosing:
2080
+ maximumExtendedPriceDifferenceForSwapClosing,
1408
2081
  });
1409
2082
 
1410
2083
  const extendedAdapter = new ExtendedAdapter({
1411
2084
  ...baseAdapterConfig,
1412
- supportedPositions: [
1413
- { asset: usdcToken, isDebt: true },
1414
- ],
2085
+ supportedPositions: [{ asset: usdcToken, isDebt: true }],
1415
2086
  vaultIdExtended: vaultIdExtended,
1416
2087
  extendedContract: EXTENDED_CONTRACT,
1417
2088
  extendedBackendWriteUrl: extendedBackendWriteUrl,
@@ -1474,11 +2145,11 @@ function getLooperSettings(
1474
2145
  });
1475
2146
 
1476
2147
  vaultSettings.leafAdapters.push(() => vesuMultiplyAdapter.getDepositLeaf());
2148
+ vaultSettings.leafAdapters.push(() => vesuMultiplyAdapter.getWithdrawLeaf());
2149
+ vaultSettings.leafAdapters.push(() => extendedAdapter.getDepositLeaf());
1477
2150
  vaultSettings.leafAdapters.push(() =>
1478
- vesuMultiplyAdapter.getWithdrawLeaf()
2151
+ extendedAdapter.getSwapFromLegacyLeaf()
1479
2152
  );
1480
- vaultSettings.leafAdapters.push(() => extendedAdapter.getDepositLeaf());
1481
- vaultSettings.leafAdapters.push(() => extendedAdapter.getSwapFromLegacyLeaf());
1482
2153
  vaultSettings.leafAdapters.push(() => avnuAdapter.getDepositLeaf());
1483
2154
  vaultSettings.leafAdapters.push(() => avnuAdapter.getWithdrawLeaf());
1484
2155
  vaultSettings.leafAdapters.push(
@@ -1499,7 +2170,6 @@ function getLooperSettings(
1499
2170
  return vaultSettings;
1500
2171
  }
1501
2172
 
1502
-
1503
2173
  function getDescription(tokenSymbol: string, underlyingSymbol: string) {
1504
2174
  return VaultDescription(tokenSymbol, underlyingSymbol);
1505
2175
  }
@@ -1519,26 +2189,64 @@ export default function VaultDescription(
1519
2189
 
1520
2190
  return (
1521
2191
  <div style={containerStyle}>
1522
- <h1 style={{ fontSize: "18px", marginBottom: "10px" }}>Liquidation risk managed leverged {lstSymbol} Vault</h1>
2192
+ <h1 style={{ fontSize: "18px", marginBottom: "10px" }}>
2193
+ Liquidation risk managed leverged {lstSymbol} Vault
2194
+ </h1>
1523
2195
  <p style={{ fontSize: "14px", lineHeight: "1.5", marginBottom: "16px" }}>
1524
- This Levered Endur {lstSymbol} vault is a tokenized leveraged Vault, auto-compounding strategy that takes upto 5x leverage on {lstSymbol} by borrow {underlyingSymbol}. Borrowed amount
1525
- is swapped to {lstSymbol} to create leverage. Depositors receive vault shares that
1526
- represent a proportional claim on the underlying assets and accrued yield.
2196
+ This Levered Endur {lstSymbol} vault is a tokenized leveraged Vault,
2197
+ auto-compounding strategy that takes upto 5x leverage on {lstSymbol} by
2198
+ borrow {underlyingSymbol}. Borrowed amount is swapped to {lstSymbol} to
2199
+ create leverage. Depositors receive vault shares that represent a
2200
+ proportional claim on the underlying assets and accrued yield.
1527
2201
  </p>
1528
2202
 
1529
2203
  <p style={{ fontSize: "14px", lineHeight: "1.5", marginBottom: "16px" }}>
1530
- This vault uses Vesu for lending and borrowing. The oracle used by this pool is a {highlightTextWithLinks("conversion rate oracle", [{ highlight: "conversion rate oracle", link: "https://docs.pragma.build/starknet/development#conversion-rate" }])}
1531
- {" "}which is resilient to liquidity issues and price volatility, hence reducing the risk of liquidation. However, overtime, if left un-monitored, debt can increase enough to trigger a liquidation. But no worries, our continuous monitoring systems look for situations with reduced health factor and balance collateral/debt to bring it back to safe levels. With Troves, you can have a peaceful sleep.
2204
+ This vault uses Vesu for lending and borrowing. The oracle used by this
2205
+ pool is a{" "}
2206
+ {highlightTextWithLinks("conversion rate oracle", [
2207
+ {
2208
+ highlight: "conversion rate oracle",
2209
+ link: "https://docs.pragma.build/starknet/development#conversion-rate",
2210
+ },
2211
+ ])}{" "}
2212
+ which is resilient to liquidity issues and price volatility, hence
2213
+ reducing the risk of liquidation. However, overtime, if left
2214
+ un-monitored, debt can increase enough to trigger a liquidation. But no
2215
+ worries, our continuous monitoring systems look for situations with
2216
+ reduced health factor and balance collateral/debt to bring it back to
2217
+ safe levels. With Troves, you can have a peaceful sleep.
1532
2218
  </p>
1533
2219
 
1534
- <div style={{ backgroundColor: "#222", padding: "10px", borderRadius: "8px", marginBottom: "20px", border: "1px solid #444" }}>
2220
+ <div
2221
+ style={{
2222
+ backgroundColor: "#222",
2223
+ padding: "10px",
2224
+ borderRadius: "8px",
2225
+ marginBottom: "20px",
2226
+ border: "1px solid #444",
2227
+ }}
2228
+ >
1535
2229
  <p style={{ fontSize: "13px", color: "#ccc" }}>
1536
- <strong>Withdrawals:</strong> Requests can take up to <strong>1-2 hours</strong> to process as the vault unwinds and settles routing.
2230
+ <strong>Withdrawals:</strong> Requests can take up to{" "}
2231
+ <strong>1-2 hours</strong> to process as the vault unwinds and settles
2232
+ routing.
1537
2233
  </p>
1538
2234
  </div>
1539
- <div style={{ backgroundColor: "#222", padding: "10px", borderRadius: "8px", marginBottom: "20px", border: "1px solid #444" }}>
2235
+ <div
2236
+ style={{
2237
+ backgroundColor: "#222",
2238
+ padding: "10px",
2239
+ borderRadius: "8px",
2240
+ marginBottom: "20px",
2241
+ border: "1px solid #444",
2242
+ }}
2243
+ >
1540
2244
  <p style={{ fontSize: "13px", color: "#ccc" }}>
1541
- <strong>Debt limits:</strong> Pools on Vesu have debt caps that are gradually increased over time. Until caps are raised, deposited Tokens remain in the vault, generating a shared net return for all depositors. There is no additional fee taken by Troves on Yield token's APY, its only on added gain.
2245
+ <strong>Debt limits:</strong> Pools on Vesu have debt caps that are
2246
+ gradually increased over time. Until caps are raised, deposited Tokens
2247
+ remain in the vault, generating a shared net return for all
2248
+ depositors. There is no additional fee taken by Troves on Yield
2249
+ token's APY, its only on added gain.
1542
2250
  </p>
1543
2251
  </div>
1544
2252
  {/* <div style={{ backgroundColor: "#222", padding: "10px", borderRadius: "8px", marginBottom: "20px", border: "1px solid #444" }}>
@@ -1551,11 +2259,21 @@ export default function VaultDescription(
1551
2259
  }
1552
2260
 
1553
2261
  const re7UsdcPrimeDevansh: VesuExtendedStrategySettings = {
1554
- vaultAddress: ContractAddr.from("0x058905be22d6a81792df79425dc9641cf3e1b77f36748631b7d7e5d713a32b55"),
1555
- manager: ContractAddr.from("0x02648d703783feb2d967cf0520314cb5aa800d69a9426f3e3b317395af44de16"),
1556
- vaultAllocator: ContractAddr.from("0x07d533c838eab6a4d854dd3aea96a55993fccd35821921970d00bde946b63b6f"),
1557
- redeemRequestNFT: ContractAddr.from("0x01ef91f08fb99729c00f82fc6e0ece37917bcc43952596c19996259dc8adbbba"),
1558
- aumOracle: ContractAddr.from("0x030b6acfec162f5d6e72b8a4d2798aedce78fb39de78a8f549f7cd277ae8bc8d"),
2262
+ vaultAddress: ContractAddr.from(
2263
+ "0x058905be22d6a81792df79425dc9641cf3e1b77f36748631b7d7e5d713a32b55"
2264
+ ),
2265
+ manager: ContractAddr.from(
2266
+ "0x02648d703783feb2d967cf0520314cb5aa800d69a9426f3e3b317395af44de16"
2267
+ ),
2268
+ vaultAllocator: ContractAddr.from(
2269
+ "0x07d533c838eab6a4d854dd3aea96a55993fccd35821921970d00bde946b63b6f"
2270
+ ),
2271
+ redeemRequestNFT: ContractAddr.from(
2272
+ "0x01ef91f08fb99729c00f82fc6e0ece37917bcc43952596c19996259dc8adbbba"
2273
+ ),
2274
+ aumOracle: ContractAddr.from(
2275
+ "0x030b6acfec162f5d6e72b8a4d2798aedce78fb39de78a8f549f7cd277ae8bc8d"
2276
+ ),
1559
2277
  leafAdapters: [],
1560
2278
  adapters: [],
1561
2279
  targetHealthFactor: 1.4,
@@ -1567,34 +2285,88 @@ const re7UsdcPrimeDevansh: VesuExtendedStrategySettings = {
1567
2285
  "0.001",
1568
2286
  Global.getDefaultTokens().find((token) => token.symbol === "WBTC")!.decimals
1569
2287
  ),
1570
- borrowable_assets: [Global.getDefaultTokens().find(token => token.symbol === "WBTC")!],
2288
+ borrowable_assets: [
2289
+ Global.getDefaultTokens().find((token) => token.symbol === "WBTC")!,
2290
+ ],
1571
2291
  minimumWBTCDifferenceForAvnuSwap: MINIMUM_WBTC_DIFFERENCE_FOR_AVNU_SWAP,
1572
2292
  walletAddress: WALLET_ADDRESS,
1573
- }
2293
+ };
1574
2294
 
1575
- export const VesuExtendedTestStrategies = (extendedBackendReadUrl: string, extendedBackendWriteUrl: string, vaultIdExtended: number, minimumExtendedMovementAmount: number, minimumVesuMovementAmount: number, minimumExtendedRetriesDelayForOrderStatus: number, minimumExtendedPriceDifferenceForSwapOpen: number, maximumExtendedPriceDifferenceForSwapClosing: number): IStrategyMetadata<VesuExtendedStrategySettings>[] => {
2295
+ export const VesuExtendedTestStrategies = (
2296
+ extendedBackendReadUrl: string,
2297
+ extendedBackendWriteUrl: string,
2298
+ vaultIdExtended: number,
2299
+ minimumExtendedMovementAmount: number,
2300
+ minimumVesuMovementAmount: number,
2301
+ minimumExtendedRetriesDelayForOrderStatus: number,
2302
+ minimumExtendedPriceDifferenceForSwapOpen: number,
2303
+ maximumExtendedPriceDifferenceForSwapClosing: number
2304
+ ): IStrategyMetadata<VesuExtendedStrategySettings>[] => {
1576
2305
  return [
1577
- getStrategySettingsVesuExtended('WBTC', 'USDC', re7UsdcPrimeDevansh, false, false, extendedBackendReadUrl, extendedBackendWriteUrl, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing),
1578
- ]
1579
- }
1580
-
1581
-
1582
-
1583
- function getStrategySettingsVesuExtended(lstSymbol: string, underlyingSymbol: string, addresses: VesuExtendedStrategySettings, isPreview: boolean = false, isLST: boolean, extendedBackendReadUrl: string, extendedBackendWriteUrl: string, vaultIdExtended: number, minimumExtendedMovementAmount: number, minimumVesuMovementAmount: number, minimumExtendedRetriesDelayForOrderStatus: number, minimumExtendedPriceDifferenceForSwapOpen: number, maximumExtendedPriceDifferenceForSwapClosing: number): IStrategyMetadata<VesuExtendedStrategySettings> {
2306
+ getStrategySettingsVesuExtended(
2307
+ "WBTC",
2308
+ "USDC",
2309
+ re7UsdcPrimeDevansh,
2310
+ false,
2311
+ false,
2312
+ extendedBackendReadUrl,
2313
+ extendedBackendWriteUrl,
2314
+ vaultIdExtended,
2315
+ minimumExtendedMovementAmount,
2316
+ minimumVesuMovementAmount,
2317
+ minimumExtendedRetriesDelayForOrderStatus,
2318
+ minimumExtendedPriceDifferenceForSwapOpen,
2319
+ maximumExtendedPriceDifferenceForSwapClosing
2320
+ ),
2321
+ ];
2322
+ };
2323
+
2324
+ function getStrategySettingsVesuExtended(
2325
+ lstSymbol: string,
2326
+ underlyingSymbol: string,
2327
+ addresses: VesuExtendedStrategySettings,
2328
+ isPreview: boolean = false,
2329
+ isLST: boolean,
2330
+ extendedBackendReadUrl: string,
2331
+ extendedBackendWriteUrl: string,
2332
+ vaultIdExtended: number,
2333
+ minimumExtendedMovementAmount: number,
2334
+ minimumVesuMovementAmount: number,
2335
+ minimumExtendedRetriesDelayForOrderStatus: number,
2336
+ minimumExtendedPriceDifferenceForSwapOpen: number,
2337
+ maximumExtendedPriceDifferenceForSwapClosing: number
2338
+ ): IStrategyMetadata<VesuExtendedStrategySettings> {
1584
2339
  return {
1585
2340
  name: `Extended Test ${underlyingSymbol}`,
1586
2341
  description: getDescription(lstSymbol, underlyingSymbol),
1587
2342
  address: addresses.vaultAddress,
1588
2343
  launchBlock: 0,
1589
- type: 'Other',
1590
- depositTokens: [Global.getDefaultTokens().find(token => token.symbol === underlyingSymbol)!],
1591
- additionalInfo: getLooperSettings(lstSymbol, underlyingSymbol, addresses, VesuPools.Re7USDCPrime, extendedBackendReadUrl, extendedBackendWriteUrl, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing),
2344
+ type: "Other",
2345
+ depositTokens: [
2346
+ Global.getDefaultTokens().find(
2347
+ (token) => token.symbol === underlyingSymbol
2348
+ )!,
2349
+ ],
2350
+ additionalInfo: getLooperSettings(
2351
+ lstSymbol,
2352
+ underlyingSymbol,
2353
+ addresses,
2354
+ VesuPools.Re7USDCPrime,
2355
+ extendedBackendReadUrl,
2356
+ extendedBackendWriteUrl,
2357
+ vaultIdExtended,
2358
+ minimumExtendedMovementAmount,
2359
+ minimumVesuMovementAmount,
2360
+ minimumExtendedRetriesDelayForOrderStatus,
2361
+ minimumExtendedPriceDifferenceForSwapOpen,
2362
+ maximumExtendedPriceDifferenceForSwapClosing
2363
+ ),
1592
2364
  risk: {
1593
2365
  riskFactor: _riskFactor,
1594
2366
  netRisk:
1595
2367
  _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) /
1596
2368
  _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
1597
- notARisks: getNoRiskTags(_riskFactor)
2369
+ notARisks: getNoRiskTags(_riskFactor),
1598
2370
  },
1599
2371
  auditUrl: AUDIT_URL,
1600
2372
  protocols: [Protocols.ENDUR, Protocols.VESU],
@@ -1603,6 +2375,8 @@ function getStrategySettingsVesuExtended(lstSymbol: string, underlyingSymbol: st
1603
2375
  faqs: getFAQs(lstSymbol, underlyingSymbol, isLST),
1604
2376
  investmentSteps: getInvestmentSteps(lstSymbol, underlyingSymbol),
1605
2377
  isPreview: isPreview,
1606
- apyMethodology: isLST ? 'Current annualized APY in terms of base asset of the LST. There is no additional fee taken by Troves on LST APY. We charge a 10% performance fee on the additional gain which is already accounted in the APY shown.' : 'Current annualized APY in terms of base asset of the Yield Token. There is no additional fee taken by Troves on yield token APY. We charge a 10% performance fee on the additional gain which is already accounted in the APY shown.'
1607
- }
1608
- }
2378
+ apyMethodology: isLST
2379
+ ? "Current annualized APY in terms of base asset of the LST. There is no additional fee taken by Troves on LST APY. We charge a 10% performance fee on the additional gain which is already accounted in the APY shown."
2380
+ : "Current annualized APY in terms of base asset of the Yield Token. There is no additional fee taken by Troves on yield token APY. We charge a 10% performance fee on the additional gain which is already accounted in the APY shown.",
2381
+ };
2382
+ }