@strkfarm/sdk 2.0.0-dev.1 → 2.0.0-dev.10

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.
@@ -13,7 +13,7 @@ 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 { EXTENDED_QTY_PRECISION, LIMIT_BALANCE, MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED, MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED, MINIMUM_EXTENDED_POSITION_SIZE, USDC_TOKEN_DECIMALS, WBTC_TOKEN_DECIMALS } from "./utils/constants";
16
+ import { BUFFER_USDC_IN_WITHDRAWAL, EXTENDED_QTY_PRECISION, LIMIT_BALANCE, LIMIT_BALANCE_VALUE, MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED, MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED, MINIMUM_EXTENDED_POSITION_SIZE, USDC_TOKEN_DECIMALS, WALLET_ADDRESS, WBTC_TOKEN_DECIMALS } from "./utils/constants";
17
17
  import { PricerBase } from "@/modules/pricerBase";
18
18
  import { ContractAddr, Web3Number } from "@/dataTypes";
19
19
  import { Global } from "@/global";
@@ -53,6 +53,7 @@ import {
53
53
  } from "./utils/helper";
54
54
  import { SingleTokenInfo } from "../base-strategy";
55
55
  import { Call } from "starknet";
56
+ import { PositionTypeAvnuExtended} from "../universal-strategy";
56
57
 
57
58
 
58
59
  export interface VesuExtendedStrategySettings
@@ -71,7 +72,6 @@ export class VesuExtendedMultiplierStrategy<
71
72
  >
72
73
  extends SVKStrategy<S>
73
74
  implements Operations {
74
-
75
75
  constructor(
76
76
  config: IConfig,
77
77
  pricer: PricerBase,
@@ -109,6 +109,26 @@ export class VesuExtendedMultiplierStrategy<
109
109
  };
110
110
  }
111
111
 
112
+ async getUnusedBalanceUSDCE(): Promise<SingleTokenInfo> {
113
+ const usdceToken = Global.getDefaultTokens().find(
114
+ (token) => token.symbol === "USDCe"
115
+ )!;
116
+ const balance = await new ERC20(this.config).balanceOf(
117
+ usdceToken.address,
118
+ WALLET_ADDRESS,
119
+ usdceToken.decimals
120
+ );
121
+ const price = await this.pricer.getPrice(usdceToken.symbol);
122
+ const usdValue =
123
+ Number(balance.toFixed(usdceToken.decimals)) * price.price;
124
+ return {
125
+ tokenInfo: usdceToken,
126
+ amount: balance,
127
+ usdValue,
128
+ };
129
+ }
130
+
131
+
112
132
  async getUnusedBalanceWBTC(): Promise<SingleTokenInfo> {
113
133
  const collateralToken = this.metadata.additionalInfo.borrowable_assets[0]!;
114
134
  const balance = await new ERC20(this.config).balanceOf(
@@ -159,23 +179,31 @@ export class VesuExtendedMultiplierStrategy<
159
179
  return extendedAdapter.adapter as ExtendedAdapter;
160
180
  }
161
181
 
162
- async moveAssetsToVaultAllocator(amount: Web3Number): Promise<Call[]> {
163
- try{
164
- const usdcToken = Global.getDefaultTokens().find(
165
- (token) => token.symbol === "USDC"
182
+ async moveAssetsToVaultAllocator(amount: Web3Number, extendedAdapter: ExtendedAdapter): Promise<Call[]> {
183
+ try {
184
+ const usdceToken = Global.getDefaultTokens().find(
185
+ (token) => token.symbol === "USDCe"
166
186
  )!;
167
187
  const approveCall = new ERC20(this.config).approve(
168
- usdcToken.address,
188
+ usdceToken.address,
169
189
  this.metadata.additionalInfo.vaultAllocator,
170
190
  amount
171
191
  );
172
192
  const transferCall = new ERC20(this.config).transfer(
173
- usdcToken.address,
193
+ usdceToken.address,
174
194
  this.metadata.additionalInfo.vaultAllocator,
175
195
  amount
176
196
  );
177
- return [approveCall, transferCall];
178
- }catch(err){
197
+ const proofsInfo = extendedAdapter.getProofsForFromLegacySwap(
198
+ this.getMerkleTree()
199
+ );
200
+ const proofGroups = proofsInfo.proofs;
201
+ const call = this.getManageCall(
202
+ proofGroups,
203
+ await proofsInfo.callConstructor({ amount: amount })
204
+ );
205
+ return [approveCall, transferCall, call];
206
+ } catch (err) {
179
207
  logger.error(`error moving assets to vault allocator: ${err}`);
180
208
  return [];
181
209
  }
@@ -191,11 +219,14 @@ export class VesuExtendedMultiplierStrategy<
191
219
  vesuLeverage: number;
192
220
  }> {
193
221
  try {
222
+ logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest starting`);
194
223
  const vesuAdapter = await this.getVesuAdapter();
195
224
  const extendedAdapter = await this.getExtendedAdapter();
196
- if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
225
+ logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest adapters fetched: vesuAdapter=${!!vesuAdapter}, extendedAdapter=${!!extendedAdapter}, extendedAdapter.client=${!!extendedAdapter?.client}`);
226
+
227
+ if (!vesuAdapter) {
197
228
  logger.error(
198
- `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
229
+ `Vesu adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
199
230
  );
200
231
  return {
201
232
  shouldInvest: false,
@@ -207,12 +238,95 @@ export class VesuExtendedMultiplierStrategy<
207
238
  vesuLeverage: 0,
208
239
  };
209
240
  }
241
+ if (!extendedAdapter) {
242
+ logger.error(
243
+ `Extended adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
244
+ );
245
+ return {
246
+ shouldInvest: false,
247
+ vesuAmount: new Web3Number(0, 0),
248
+ extendedAmount: new Web3Number(0, 0),
249
+ extendedLeverage: 0,
250
+ collateralPrice: 0,
251
+ debtPrice: 0,
252
+ vesuLeverage: 0,
253
+ };
254
+ }
255
+ if (!extendedAdapter.client) {
256
+ logger.error(
257
+ `Extended adapter client not initialized. This may be a temporary initialization failure - check network connectivity and API availability.`
258
+ );
259
+ return {
260
+ shouldInvest: false,
261
+ vesuAmount: new Web3Number(0, 0),
262
+ extendedAmount: new Web3Number(0, 0),
263
+ extendedLeverage: 0,
264
+ collateralPrice: 0,
265
+ debtPrice: 0,
266
+ vesuLeverage: 0,
267
+ };
268
+ }
269
+
270
+ logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest calling getUnusedBalance`);
210
271
  const balance = await this.getUnusedBalance();
272
+
273
+ if (!Number.isFinite(balance.usdValue) || balance.usdValue < 0) {
274
+ logger.error(
275
+ `Invalid balance.usdValue: ${balance.usdValue}. Expected a finite, non-negative number.`
276
+ );
277
+ return {
278
+ shouldInvest: false,
279
+ vesuAmount: new Web3Number(0, 0),
280
+ extendedAmount: new Web3Number(0, 0),
281
+ extendedLeverage: 0,
282
+ collateralPrice: 0,
283
+ debtPrice: 0,
284
+ vesuLeverage: 0,
285
+ };
286
+ }
287
+ logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest balance: ${balance.usdValue}`);
211
288
  const usdcBalanceOnExtended = await extendedAdapter.getExtendedDepositAmount();
289
+
290
+ if (usdcBalanceOnExtended) {
291
+ const availableForWithdrawal = parseFloat(usdcBalanceOnExtended.availableForWithdrawal);
292
+ if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
293
+ logger.error(
294
+ `Invalid usdcBalanceOnExtended.availableForWithdrawal: ${usdcBalanceOnExtended.availableForWithdrawal}. Expected a finite, non-negative number.`
295
+ );
296
+ return {
297
+ shouldInvest: false,
298
+ vesuAmount: new Web3Number(0, 0),
299
+ extendedAmount: new Web3Number(0, 0),
300
+ extendedLeverage: 0,
301
+ collateralPrice: 0,
302
+ debtPrice: 0,
303
+ vesuLeverage: 0,
304
+ };
305
+ }
306
+ }
307
+
212
308
  /** The LIMIT_BALANCE is the bffer amount to keep in the investing Cycle */
213
- const amountToInvest = balance.amount.plus(usdcBalanceOnExtended?.availableForWithdrawal ?? 0).minus(LIMIT_BALANCE);
309
+ const amountToInvest = new Web3Number(balance.usdValue, USDC_TOKEN_DECIMALS).plus(usdcBalanceOnExtended?.availableForWithdrawal ?? 0).multipliedBy(1 - LIMIT_BALANCE);
214
310
 
215
- if (amountToInvest.lessThan(0)) {
311
+
312
+ const amountToInvestNumber = amountToInvest.toNumber();
313
+ if (!Number.isFinite(amountToInvestNumber)) {
314
+ logger.error(
315
+ `Invalid amountToInvest calculation result: ${amountToInvestNumber}. Calculation may have produced NaN or Infinity.`
316
+ );
317
+ return {
318
+ shouldInvest: false,
319
+ vesuAmount: new Web3Number(0, 0),
320
+ extendedAmount: new Web3Number(0, 0),
321
+ extendedLeverage: 0,
322
+ collateralPrice: 0,
323
+ debtPrice: 0,
324
+ vesuLeverage: 0,
325
+ };
326
+ }
327
+
328
+ logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvestNumber}`);
329
+ if (amountToInvest.lessThan(LIMIT_BALANCE_VALUE)) {
216
330
  return {
217
331
  shouldInvest: false,
218
332
  vesuAmount: new Web3Number(0, 0),
@@ -244,6 +358,37 @@ export class VesuExtendedMultiplierStrategy<
244
358
  collateralPrice,
245
359
  debtPrice
246
360
  } = await this.getAssetPrices();
361
+
362
+
363
+ if (!Number.isFinite(collateralPrice.price) || collateralPrice.price <= 0) {
364
+ logger.error(
365
+ `Invalid collateralPrice: ${collateralPrice.price}. Expected a finite, positive number.`
366
+ );
367
+ return {
368
+ shouldInvest: false,
369
+ vesuAmount: new Web3Number(0, 0),
370
+ extendedAmount: new Web3Number(0, 0),
371
+ extendedLeverage: 0,
372
+ collateralPrice: 0,
373
+ debtPrice: 0,
374
+ vesuLeverage: 0,
375
+ };
376
+ }
377
+ if (!Number.isFinite(debtPrice.price) || debtPrice.price <= 0) {
378
+ logger.error(
379
+ `Invalid debtPrice: ${debtPrice.price}. Expected a finite, positive number.`
380
+ );
381
+ return {
382
+ shouldInvest: false,
383
+ vesuAmount: new Web3Number(0, 0),
384
+ extendedAmount: new Web3Number(0, 0),
385
+ extendedLeverage: 0,
386
+ collateralPrice: 0,
387
+ debtPrice: 0,
388
+ vesuLeverage: 0,
389
+ };
390
+ }
391
+
247
392
  const { vesu_amount, extended_amount, extended_leverage, vesu_leverage } =
248
393
  await calculateAmountDistribution(
249
394
  amountToInvest.toNumber(),
@@ -273,6 +418,7 @@ export class VesuExtendedMultiplierStrategy<
273
418
  vesuLeverage: 0,
274
419
  };
275
420
  }
421
+ logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest vesu_amount: ${vesu_amount.toNumber()}, extended_amount: ${extended_amount.toNumber()}`);
276
422
  return {
277
423
  shouldInvest: true,
278
424
  vesuAmount: vesu_amount,
@@ -300,18 +446,67 @@ export class VesuExtendedMultiplierStrategy<
300
446
  try {
301
447
  const vesuAdapter = await this.getVesuAdapter();
302
448
  const extendedAdapter = await this.getExtendedAdapter();
303
- let calls: Call[] = [];
304
449
  if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
305
450
  logger.error(
306
451
  `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
307
452
  );
308
- return calls;
453
+ return [];
454
+ }
455
+
456
+ const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
457
+ if (!extendedHoldings) {
458
+ logger.error(`error getting extended holdings: ${extendedHoldings}`);
459
+ return [];
460
+ }
461
+ const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
462
+ const usdcAmountOnExtendedAvailableForWithdrawal = parseFloat(
463
+ extendedHoldings.availableForWithdrawal
464
+ );
465
+
466
+ logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldMoveAssets calculating movements - Extended current: ${usdcAmountOnExtendedAvailableForWithdrawal}, Wallet: ${usdcAmountInWallet.toNumber()}, Target Extended: ${extendedAmount.toNumber()}, Target Vesu: ${vesuAmount.toNumber()}`);
467
+
468
+ let totalExtendedWithdrawal = new Web3Number(0, USDC_TOKEN_DECIMALS);
469
+ let totalExtendedDeposit = new Web3Number(0, USDC_TOKEN_DECIMALS);
470
+
471
+ if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
472
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmount.abs());
473
+ }
474
+
475
+ // Calculate remaining Extended difference (target vs current)
476
+ // If extendedAmount was negative, we've already accounted for that withdrawal
477
+ // So we calculate based on what Extended will be after that withdrawal
478
+ const extendedTargetAmount = extendedAmount.abs(); // Use absolute value as target
479
+ let projectedExtendedBalance = usdcAmountOnExtendedAvailableForWithdrawal;
480
+
481
+ if (extendedAmount.isNegative()) {
482
+ projectedExtendedBalance = projectedExtendedBalance - extendedAmount.abs().toNumber();
309
483
  }
310
- console.log("extendedAmount", extendedAmount);
311
- console.log("vesuAmount", vesuAmount);
312
- if (extendedAmount.lessThan(0)) {
484
+
485
+ const extendedAmountDifference = extendedTargetAmount.minus(projectedExtendedBalance);
486
+ const extendedAmountDifferenceAbs = extendedAmountDifference.abs();
487
+
488
+ // Track additional Extended movements
489
+ if (extendedAmountDifference.lessThan(0)) {
490
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmountDifferenceAbs);
491
+ } else if (extendedAmountDifference.greaterThan(0)) {
492
+ totalExtendedDeposit = totalExtendedDeposit.plus(extendedAmountDifference);
493
+ }
494
+
495
+ const vesuTargetAmount = vesuAmount.abs();
496
+ const projectedWalletBalance = usdcAmountInWallet
497
+ .plus(totalExtendedWithdrawal)
498
+ .minus(totalExtendedDeposit);
499
+
500
+ let vesuAmountDifference = vesuTargetAmount.minus(projectedWalletBalance);
501
+ const vesuAmountDifferenceAbs = vesuAmountDifference.abs();
502
+
503
+ 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()}`);
504
+ let calls: Call[] = [];
505
+
506
+ // Handle negative extendedAmount (initial withdrawal needed)
507
+ if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
313
508
  try {
314
- const extendedCalls = await this.moveAssets(
509
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
315
510
  {
316
511
  to: Protocols.VAULT.name,
317
512
  from: Protocols.EXTENDED.name,
@@ -320,15 +515,19 @@ export class VesuExtendedMultiplierStrategy<
320
515
  extendedAdapter,
321
516
  vesuAdapter
322
517
  );
323
- calls.push(...extendedCalls);
518
+ if (extendedStatus) {
519
+ calls.push(...extendedCalls);
520
+ } else {
521
+ return [];
522
+ }
324
523
  } catch (err) {
325
524
  logger.error(`Failed moving assets to vault: ${err}`);
326
525
  }
327
526
  }
328
527
 
329
- if (vesuAmount.lessThan(0)) {
528
+ if (vesuAmount.isNegative() && vesuAmount.abs().greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
330
529
  try {
331
- const vesuCalls = await this.moveAssets(
530
+ const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
332
531
  {
333
532
  to: Protocols.EXTENDED.name,
334
533
  from: Protocols.VESU.name,
@@ -338,54 +537,91 @@ export class VesuExtendedMultiplierStrategy<
338
537
  vesuAdapter
339
538
  );
340
539
  calls.push(...vesuCalls);
540
+ if (!vesuStatus) {
541
+ return [];
542
+ }
341
543
  } catch (err) {
342
544
  logger.error(`Failed moving assets to vault: ${err}`);
343
545
  }
344
546
  }
345
547
 
346
- const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
347
- if (!extendedHoldings) {
348
- logger.error(`error getting extended holdings: ${extendedHoldings}`);
349
- return calls;
350
- }
351
- const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
352
- const usdcAmountOnExtended = parseFloat(
353
- extendedHoldings.availableForWithdrawal
354
- );
355
- if (extendedAmount.minus(usdcAmountOnExtended).greaterThan(0)) {
356
- //move assets to extended
357
- try {
358
- const extendedCalls = await this.moveAssets(
359
- {
360
- to: Protocols.EXTENDED.name,
361
- from: Protocols.VAULT.name,
362
- amount: extendedAmount.minus(usdcAmountOnExtended),
363
- },
364
- extendedAdapter,
365
- vesuAdapter
366
- );
367
- calls.push(...extendedCalls);
368
- } catch (err) {
369
- logger.error(`Failed moving assets to extended: ${err}`);
548
+ // Handle Extended adjustments based on calculated difference
549
+ if (extendedAmountDifferenceAbs.greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
550
+ if (extendedAmountDifference.greaterThan(0)) {
551
+ try {
552
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
553
+ {
554
+ to: Protocols.EXTENDED.name,
555
+ from: Protocols.VAULT.name,
556
+ amount: extendedAmountDifference,
557
+ },
558
+ extendedAdapter,
559
+ vesuAdapter
560
+ );
561
+ if (extendedStatus) {
562
+ calls.push(...extendedCalls);
563
+ } else {
564
+ logger.error(`Failed to move assets to extended - operation returned false status`);
565
+ return [];
566
+ }
567
+ } catch (err) {
568
+ logger.error(`Failed moving assets to extended: ${err}`);
569
+ return [];
570
+ }
571
+ } else if (extendedAmountDifference.lessThan(0)) {
572
+ try {
573
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
574
+ {
575
+ to: Protocols.VAULT.name,
576
+ from: Protocols.EXTENDED.name,
577
+ amount: extendedAmountDifferenceAbs,
578
+ },
579
+ extendedAdapter,
580
+ vesuAdapter
581
+ );
582
+ if (extendedStatus) {
583
+ calls.push(...extendedCalls);
584
+ } else {
585
+ logger.error(`Failed to withdraw from extended - operation returned false status`);
586
+ return [];
587
+ }
588
+ } catch (err) {
589
+ logger.error(`Failed moving assets from extended to vault: ${err}`);
590
+ return [];
591
+ }
370
592
  }
371
593
  }
372
- if (vesuAmount.minus(usdcAmountInWallet).greaterThan(0)) {
373
- //move assets to vesu
374
- try {
375
- const vesuCalls = await this.moveAssets(
376
- {
377
- to: Protocols.VESU.name,
378
- from: Protocols.EXTENDED.name,
379
- amount: vesuAmount.minus(usdcAmountInWallet),
380
- },
381
- extendedAdapter,
382
- vesuAdapter
594
+
595
+ // Handle Vesu adjustments based on calculated difference (already adjusted for Extended movements)
596
+ if (vesuAmountDifferenceAbs.greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
597
+ if (vesuAmountDifference.lessThanOrEqualTo(0)) {
598
+ logger.warn(
599
+ `Vesu amount difference is negative or zero: ${vesuAmountDifference.toNumber()}. Skipping operation.`
383
600
  );
384
- calls.push(...vesuCalls);
385
- } catch (err) {
386
- logger.error(`Failed moving assets to vault: ${err}`);
601
+ } else {
602
+ // Move assets from Extended to Vault (which will then go to Vesu)
603
+ try {
604
+ const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
605
+ {
606
+ to: Protocols.VAULT.name,
607
+ from: Protocols.EXTENDED.name,
608
+ amount: vesuAmountDifference,
609
+ },
610
+ extendedAdapter,
611
+ vesuAdapter
612
+ );
613
+ if (!vesuStatus) {
614
+ logger.error(`Failed to move assets to vesu - operation returned false status`);
615
+ return [];
616
+ }
617
+ calls.push(...vesuCalls);
618
+ } catch (err) {
619
+ logger.error(`Failed moving assets to vault: ${err}`);
620
+ return [];
621
+ }
387
622
  }
388
623
  }
624
+
389
625
  return calls;
390
626
  } catch (err) {
391
627
  logger.error(`Failed moving assets to vesu: ${err}`);
@@ -401,18 +637,61 @@ export class VesuExtendedMultiplierStrategy<
401
637
  },
402
638
  extendedAdapter: ExtendedAdapter,
403
639
  vesuAdapter: VesuMultiplyAdapter
404
- ): Promise<Call[]> {
640
+ ): Promise<{
641
+ calls: Call[];
642
+ status: boolean;
643
+ }> {
405
644
  try {
645
+ // Validate amount is positive before starting operations
646
+ if (params.amount.lessThanOrEqualTo(0)) {
647
+ logger.error(
648
+ `Invalid amount for moveAssets: ${params.amount.toNumber()}. Amount must be positive.`
649
+ );
650
+ return {
651
+ calls: [],
652
+ status: false
653
+ };
654
+ }
655
+
656
+ // Check minimum movement amounts before starting operations
657
+ const amountAbs = params.amount.abs();
658
+ if (params.from === Protocols.EXTENDED.name || params.to === Protocols.EXTENDED.name) {
659
+ if (amountAbs.lessThanOrEqualTo(extendedAdapter.minimumExtendedMovementAmount)) {
660
+ logger.warn(
661
+ `Amount ${amountAbs.toNumber()} is below minimum Extended movement amount ${extendedAdapter.minimumExtendedMovementAmount}. Skipping operation.`
662
+ );
663
+ return {
664
+ calls: [],
665
+ status: false
666
+ };
667
+ }
668
+ }
669
+ if (params.from === Protocols.VESU.name || params.to === Protocols.VESU.name) {
670
+ if (amountAbs.lessThanOrEqualTo(vesuAdapter.minimumVesuMovementAmount)) {
671
+ logger.warn(
672
+ `Amount ${amountAbs.toNumber()} is below minimum Vesu movement amount ${vesuAdapter.minimumVesuMovementAmount}. Skipping operation.`
673
+ );
674
+ return {
675
+ calls: [],
676
+ status: false
677
+ };
678
+ }
679
+ }
680
+
406
681
  const avnuAdapter = await this.getAvnuAdapter();
407
682
  if (!avnuAdapter) {
408
683
  logger.error(`avnu adapter not found: ${avnuAdapter}`);
409
- return [];
684
+ return {
685
+ calls: [],
686
+ status: false
687
+ };
410
688
  }
411
- logger.info("moveAssets params", params);
689
+ logger.info(`moveAssets params, ${JSON.stringify(params)}`);
412
690
  const collateralToken = vesuAdapter.config.supportedPositions[0].asset;
413
691
  const {
414
692
  collateralPrice,
415
693
  } = await this.getAssetPrices();
694
+
416
695
  if (params.to === Protocols.EXTENDED.name && params.from === Protocols.VAULT.name) {
417
696
  const proofsInfo = extendedAdapter.getProofs(
418
697
  true,
@@ -425,23 +704,79 @@ export class VesuExtendedMultiplierStrategy<
425
704
  await proofsInfo.callConstructor({ amount: params.amount })
426
705
  );
427
706
  calls.push(call);
428
- return calls;
707
+ return {
708
+ calls: [call],
709
+ status: true
710
+ };
429
711
  } else if (params.to === Protocols.VAULT.name && params.from === Protocols.EXTENDED.name) {
712
+ const extendedLeverage = calculateExtendedLevergae();
713
+ const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
714
+ if (!extendedHoldings) {
715
+ logger.error(`error getting extended holdings: ${extendedHoldings}`);
716
+ return {
717
+ calls: [],
718
+ status: false
719
+ };
720
+ }
721
+ const extendedHoldingAmount = new Web3Number(
722
+ extendedHoldings.availableForWithdrawal,
723
+ USDC_TOKEN_DECIMALS
724
+ );
725
+ logger.info(`${VesuExtendedMultiplierStrategy.name}::moveAssets extendedHoldingAmount: ${extendedHoldingAmount.toNumber()}`);
726
+ if (params.amount.abs().greaterThan(extendedHoldingAmount)) {
727
+ const leftAmountAfterWithdrawalAmountInAccount = params.amount.abs().minus(extendedHoldingAmount);
728
+ logger.info(`${VesuExtendedMultiplierStrategy.name}::moveAssets leftAmountAfterWithdrawalAmountInAccount: ${leftAmountAfterWithdrawalAmountInAccount.toNumber()}`);
729
+ const btcAmount = leftAmountAfterWithdrawalAmountInAccount.dividedBy(collateralPrice.price);
730
+ const openLongPosition = btcAmount.multipliedBy(3).greaterThan(MINIMUM_EXTENDED_POSITION_SIZE) ? await extendedAdapter.createOrder(
731
+ extendedLeverage.toString(),
732
+ btcAmount.toNumber(),
733
+ OrderSide.BUY
734
+ ) : await extendedAdapter.createOrder(
735
+ extendedLeverage.toString(),
736
+ 0.000035, // just in case amount falls short then we need to create a withdrawal
737
+ OrderSide.BUY
738
+ )
739
+ if (!openLongPosition) {
740
+ logger.error(`error opening long position: ${openLongPosition}`);
741
+ }
742
+ const updatedHoldings = await extendedAdapter.getExtendedDepositAmount();
743
+ if (!updatedHoldings || new Web3Number(updatedHoldings.availableForWithdrawal, USDC_TOKEN_DECIMALS).lessThan(params.amount.abs())) {
744
+ logger.error(`Insufficient balance after opening position. Available: ${updatedHoldings?.availableForWithdrawal}, Needed: ${params.amount.abs()}`);
745
+ return { calls: [], status: false };
746
+ }
747
+ }
430
748
  const withdrawalFromExtended =
431
749
  await extendedAdapter.withdrawFromExtended(params.amount);
432
750
  if (withdrawalFromExtended) {
433
- /**
434
- * We need to move assets from my wallet back to vault contract
435
- */
436
- const calls = await this.moveAssetsToVaultAllocator(params.amount);
751
+ /**
752
+ * We need to move assets from my wallet back to vault contract
753
+ */
754
+ const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
755
+ logger.info(`extendedHoldings after withdrawal ${extendedHoldings?.availableForWithdrawal}`);
756
+ await new Promise(resolve => setTimeout(resolve, 5000));
757
+ const calls = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
437
758
  if (calls.length > 0) {
438
- return calls;
759
+ return {
760
+ calls: calls,
761
+ status: true
762
+ };
439
763
  }
440
764
  } else {
441
765
  logger.error("withdrawal from extended failed");
766
+ return {
767
+ calls: [],
768
+ status: false
769
+ };
442
770
  }
443
- return [];
444
771
  } else if (params.to === Protocols.VAULT.name && params.from === Protocols.VESU.name) {
772
+ const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, PositionTypeAvnuExtended.CLOSE);
773
+ if (!isPriceDifferenceBetweenAvnuAndExtended) {
774
+ logger.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
775
+ return {
776
+ calls: [],
777
+ status: false
778
+ };
779
+ }
445
780
  //withdraw from vesu
446
781
  const vesuAmountInBTC = new Web3Number(
447
782
  params.amount.dividedBy(collateralPrice.price).toNumber(),
@@ -462,8 +797,19 @@ export class VesuExtendedMultiplierStrategy<
462
797
  await swapProofsInfo.callConstructor({ amount: vesuAmountInBTC })
463
798
  );
464
799
  calls.push(swapCall);
465
- return calls;
800
+ return {
801
+ calls: calls,
802
+ status: true
803
+ };
466
804
  } else if (params.to === Protocols.EXTENDED.name && params.from === Protocols.VESU.name) {
805
+ const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, PositionTypeAvnuExtended.CLOSE);
806
+ if (!isPriceDifferenceBetweenAvnuAndExtended) {
807
+ logger.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
808
+ return {
809
+ calls: [],
810
+ status: false
811
+ };
812
+ }
467
813
  const vesuAmountInBTC = new Web3Number(
468
814
  params.amount.dividedBy(collateralPrice.price).toNumber(),
469
815
  collateralToken.decimals
@@ -494,19 +840,28 @@ export class VesuExtendedMultiplierStrategy<
494
840
  await proofsInfoDeposit.callConstructor({ amount: params.amount })
495
841
  );
496
842
  calls.push(callDeposit);
497
- return calls;
843
+ return {
844
+ calls: calls,
845
+ status: true
846
+ };
498
847
  }
499
- console.warn("moveAssets received unsupported route:", params);
500
- return [];
848
+ return {
849
+ calls: [],
850
+ status: false
851
+ };
501
852
  } catch (err) {
502
853
  logger.error(`error moving assets: ${err}`);
503
- return [];
854
+ return {
855
+ calls: [],
856
+ status: false
857
+ };
504
858
  }
505
859
  }
506
860
 
507
861
  async handleDeposit(): Promise<{
508
- extendedAmountInBTC : Web3Number,
509
- calls:Call[]}> {
862
+ extendedAmountInBTC: Web3Number,
863
+ calls: Call[]
864
+ }> {
510
865
  try {
511
866
  const vesuAdapter = await this.getVesuAdapter();
512
867
  const extendedAdapter = await this.getExtendedAdapter();
@@ -528,7 +883,7 @@ export class VesuExtendedMultiplierStrategy<
528
883
  };
529
884
  }
530
885
  const extendedLeverage = calculateExtendedLevergae();
531
- const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter);
886
+ const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, PositionTypeAvnuExtended.OPEN);
532
887
  if (!isPriceDifferenceBetweenAvnuAndExtended) {
533
888
  logger.error("price difference between avnu and extended doesn't fit the range");
534
889
  return {
@@ -545,6 +900,7 @@ export class VesuExtendedMultiplierStrategy<
545
900
  };
546
901
  }
547
902
  const extendedPositionValue = position.length > 0 ? parseFloat(position[0].value) : 0;
903
+ const BUFFER_AMOUNT_IN_AVAILABLE_FOR_TRADE = BUFFER_USDC_IN_WITHDRAWAL;
548
904
  const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
549
905
  if (!extendedHoldings) {
550
906
  logger.error(`error getting extended holdings: ${extendedHoldings}`);
@@ -563,14 +919,14 @@ export class VesuExtendedMultiplierStrategy<
563
919
  const { collateralPrice } = await this.getAssetPrices();
564
920
  const { vesuAmountInBTC, extendedAmountInBTC } = calculateVesUPositionSizeGivenExtended(
565
921
  extendedPositionValue,
566
- extendedHoldingAmount,
922
+ extendedHoldingAmount.minus(BUFFER_AMOUNT_IN_AVAILABLE_FOR_TRADE),
567
923
  collateralTokenAmount,
568
924
  collateralPrice.price
569
925
  );
570
- console.log("vesuAmountInBTC", vesuAmountInBTC);
571
- console.log("extendedAmountInBTC", extendedAmountInBTC);
926
+ logger.info(`vesuAmountInBTC ${vesuAmountInBTC}, extendedAmountInBTC ${extendedAmountInBTC}`);
927
+
572
928
  let calls: Call[] = [];
573
- if(vesuAmountInBTC.greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)){
929
+ if (vesuAmountInBTC.greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)) {
574
930
  const proofsInfo = vesuAdapter.getProofs(true, this.getMerkleTree());
575
931
  const proofGroups = proofsInfo.proofs;
576
932
  const call = this.getManageCall(
@@ -581,7 +937,6 @@ export class VesuExtendedMultiplierStrategy<
581
937
  );
582
938
  const { amount: wbtcAmountInVaultAllocator } = await this.getUnusedBalanceWBTC();
583
939
  if (wbtcAmountInVaultAllocator.lessThan(vesuAmountInBTC)) {
584
- console.log("error wbtc amount in vault allocator is less than vesu amount in btc", wbtcAmountInVaultAllocator, vesuAmountInBTC);
585
940
  const swapProofsInfo = avnuAdapter.getProofs(true, this.getMerkleTree());
586
941
  const swapProofGroups = swapProofsInfo.proofs;
587
942
  const swapCall = this.getManageCall(
@@ -594,7 +949,6 @@ export class VesuExtendedMultiplierStrategy<
594
949
  }
595
950
  calls.push(call);
596
951
  }
597
-
598
952
  const shortPosition = extendedAmountInBTC.multipliedBy(3).abs().greaterThan(MINIMUM_EXTENDED_POSITION_SIZE) ? await extendedAdapter.createOrder(
599
953
  extendedLeverage.toString(),
600
954
  extendedAmountInBTC.toNumber(),
@@ -616,48 +970,67 @@ export class VesuExtendedMultiplierStrategy<
616
970
  return {
617
971
  extendedAmountInBTC: new Web3Number(0, 0),
618
972
  calls: [],
619
- };;
973
+ };
620
974
  }
621
975
  }
622
976
 
623
- async checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter:ExtendedAdapter, vesuAdapter:VesuMultiplyAdapter, avnuAdapter:AvnuAdapter): Promise<boolean> {
977
+ async checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter: ExtendedAdapter, vesuAdapter: VesuMultiplyAdapter, avnuAdapter: AvnuAdapter, positionType: PositionTypeAvnuExtended): Promise<boolean> {
624
978
  const {
625
979
  ask, bid
626
- }= await extendedAdapter.fetchOrderBookBTCUSDC();
980
+ } = await extendedAdapter.fetchOrderBookBTCUSDC();
627
981
  const price = ask.plus(bid).dividedBy(2);
628
- const btcToken = vesuAdapter.config.supportedPositions[1].asset;
982
+ const btcToken = vesuAdapter.config.supportedPositions[0].asset;
629
983
  const btcPriceAvnu = await avnuAdapter.getPriceOfToken(btcToken.address.toString());
630
984
  if (!btcPriceAvnu) {
631
985
  logger.error(`error getting btc price avnu: ${btcPriceAvnu}`);
632
986
  return false;
633
987
  }
634
- const priceDifference = price.minus(btcPriceAvnu).toNumber();
635
- if(priceDifference < MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED && priceDifference > MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED){
636
- return true;
988
+ const priceDifference = new Web3Number(price.minus(btcPriceAvnu).toFixed(2), 0);
989
+ if(priceDifference.isNegative()){
990
+ return false;
991
+ }
992
+ if(positionType === PositionTypeAvnuExtended.OPEN){
993
+ logger.info(`price difference between avnu and extended for open position: ${priceDifference.toNumber()}, minimumExtendedPriceDifferenceForSwapOpen: ${avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen}`);
994
+ const result = priceDifference.greaterThanOrEqualTo(avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen); // 500 for now
995
+ logger.info(`result: ${result}`);
996
+ return result;
997
+ }else{
998
+ logger.info(`price difference between avnu and extended for close position: ${priceDifference.toNumber()}, maximumExtendedPriceDifferenceForSwapClosing: ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
999
+ const result = priceDifference.lessThanOrEqualTo(avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing); // 1000 for now
1000
+ logger.info(`result: ${result}`);
1001
+ return result;
637
1002
  }
638
- logger.error(`price difference between avnu and extended doesn't fit the range, priceDifference: ${priceDifference}`);
639
- return false;
640
1003
  }
641
1004
 
642
- async handleWithdraw(amount: Web3Number): Promise<Call[]> {
1005
+ async handleWithdraw(amount: Web3Number): Promise<{ calls: Call[], status: boolean }> {
643
1006
  try {
644
- const usdcBalanceVaultAllocator = await this.getUnusedBalance()
645
- const usdcBalanceDifference = amount.minus(usdcBalanceVaultAllocator.usdValue);
1007
+ const usdcBalanceVaultAllocator = await this.getUnusedBalance();
1008
+ const usdcBalanceDifference = amount.plus(BUFFER_USDC_IN_WITHDRAWAL).minus(usdcBalanceVaultAllocator.usdValue);
646
1009
  logger.info(`usdcBalanceDifference, ${usdcBalanceDifference.toNumber()}`);
1010
+ let calls: Call[] = [];
1011
+ let status: boolean = true;
647
1012
  if (usdcBalanceDifference.lessThan(0)) {
648
1013
  const withdrawCall = await this.getBringLiquidityCall({
649
- amount: amount
1014
+ amount: usdcBalanceVaultAllocator.amount
650
1015
  })
651
1016
  logger.info("withdraw call", withdrawCall);
652
- return [withdrawCall];
1017
+ calls.push(withdrawCall);
1018
+ return {
1019
+ calls: calls,
1020
+ status: true
1021
+ };
653
1022
  }
654
1023
  const vesuAdapter = await this.getVesuAdapter();
655
1024
  const extendedAdapter = await this.getExtendedAdapter();
656
1025
  if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
1026
+ status = false;
657
1027
  logger.error(
658
1028
  `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
659
1029
  );
660
- return [];
1030
+ return {
1031
+ calls: calls,
1032
+ status: status
1033
+ };
661
1034
  }
662
1035
  const { collateralTokenAmount } =
663
1036
  await vesuAdapter.vesuAdapter.getAssetPrices();
@@ -665,22 +1038,35 @@ export class VesuExtendedMultiplierStrategy<
665
1038
  collateralPrice
666
1039
  } = await this.getAssetPrices();
667
1040
  const extendedPositon = await extendedAdapter.getAllOpenPositions();
1041
+ if (!extendedPositon) {
1042
+ status = false;
1043
+ logger.error("error getting extended position", extendedPositon);
1044
+ return {
1045
+ calls: calls,
1046
+ status: status
1047
+ }
1048
+ }
668
1049
  const amountDistributionForWithdrawal =
669
1050
  await calculateAmountDistributionForWithdrawal(
670
- amount,
1051
+ usdcBalanceDifference,
671
1052
  collateralPrice.price,
672
1053
  collateralTokenAmount,
673
1054
  extendedPositon
674
1055
  );
675
1056
  if (!amountDistributionForWithdrawal) {
1057
+ status = false;
676
1058
  logger.error(
677
1059
  `error calculating amount distribution for withdrawal: ${amountDistributionForWithdrawal}`
678
1060
  );
679
- return [];
1061
+ return {
1062
+ calls: calls,
1063
+ status: status
1064
+ };
680
1065
  }
681
1066
  const { vesu_amount, extended_amount } = amountDistributionForWithdrawal;
682
- if (vesu_amount.greaterThan(0)) {
683
- const result = await this.moveAssets(
1067
+
1068
+ if (status && vesu_amount.greaterThan(0)) {
1069
+ const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
684
1070
  {
685
1071
  amount: vesu_amount,
686
1072
  from: Protocols.VESU.name,
@@ -689,10 +1075,11 @@ export class VesuExtendedMultiplierStrategy<
689
1075
  extendedAdapter,
690
1076
  vesuAdapter
691
1077
  );
692
- return result;
1078
+ status = vesuStatus;
1079
+ calls.push(...vesuCalls);
693
1080
  }
694
- if (extended_amount.greaterThan(0)) {
695
- const result = await this.moveAssets(
1081
+ if (status && extended_amount.greaterThan(0)) {
1082
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
696
1083
  {
697
1084
  amount: extended_amount,
698
1085
  from: Protocols.EXTENDED.name,
@@ -701,12 +1088,32 @@ export class VesuExtendedMultiplierStrategy<
701
1088
  extendedAdapter,
702
1089
  vesuAdapter
703
1090
  );
704
- return result;
1091
+ status = extendedStatus;
1092
+ if (status) {
1093
+ calls.push(...extendedCalls);
1094
+ } else {
1095
+ logger.error("error moving assets to vault: extendedStatus: ${extendedStatus}");
1096
+ return {
1097
+ calls: [],
1098
+ status: status
1099
+ };
1100
+ }
705
1101
  }
706
- return [];
1102
+ const withdrawCall = await this.getBringLiquidityCall({
1103
+ amount: amount
1104
+ })
1105
+ logger.info("withdraw call", withdrawCall);
1106
+ calls.push(withdrawCall);
1107
+ return {
1108
+ calls: calls,
1109
+ status: status
1110
+ };
707
1111
  } catch (err) {
708
1112
  logger.error(`error handling withdrawal: ${err}`);
709
- return [];
1113
+ return {
1114
+ calls: [],
1115
+ status: false
1116
+ };
710
1117
  }
711
1118
  }
712
1119
 
@@ -714,7 +1121,7 @@ export class VesuExtendedMultiplierStrategy<
714
1121
  const allPositions: PositionInfo[] = [];
715
1122
  for (let adapter of this.metadata.additionalInfo.adapters) {
716
1123
  const positions = await adapter.adapter.getPositions();
717
- allPositions.push(...positions);
1124
+ allPositions.push(...positions);
718
1125
  }
719
1126
 
720
1127
  const assetPrice = await this.pricer.getPrice(this.asset().symbol);
@@ -765,6 +1172,11 @@ function getLooperSettings(
765
1172
  extendedBackendUrl: string,
766
1173
  extendedApiKey: string,
767
1174
  vaultIdExtended: number,
1175
+ minimumExtendedMovementAmount: number,
1176
+ minimumVesuMovementAmount: number,
1177
+ minimumExtendedRetriesDelayForOrderStatus: number,
1178
+ minimumExtendedPriceDifferenceForSwapOpen: number,
1179
+ maximumExtendedPriceDifferenceForSwapClosing: number,
768
1180
  ) {
769
1181
  vaultSettings.leafAdapters = [];
770
1182
 
@@ -793,6 +1205,8 @@ function getLooperSettings(
793
1205
  avnuContract: AVNU_MIDDLEWARE,
794
1206
  slippage: 0.01,
795
1207
  baseUrl: AVNU_QUOTE_URL,
1208
+ minimumExtendedPriceDifferenceForSwapOpen: minimumExtendedPriceDifferenceForSwapOpen,
1209
+ maximumExtendedPriceDifferenceForSwapClosing: maximumExtendedPriceDifferenceForSwapClosing,
796
1210
  });
797
1211
 
798
1212
  const extendedAdapter = new ExtendedAdapter({
@@ -810,6 +1224,8 @@ function getLooperSettings(
810
1224
  extendedMarketName: "BTC-USD",
811
1225
  extendedPrecision: 5,
812
1226
  avnuAdapter: avnuAdapter,
1227
+ retryDelayForOrderStatus: minimumExtendedRetriesDelayForOrderStatus ?? 3000,
1228
+ minimumExtendedMovementAmount: minimumExtendedMovementAmount ?? 5, //5 usdcs
813
1229
  });
814
1230
 
815
1231
  const vesuMultiplyAdapter = new VesuMultiplyAdapter({
@@ -824,6 +1240,7 @@ function getLooperSettings(
824
1240
  { asset: wbtcToken, isDebt: false },
825
1241
  { asset: usdcToken, isDebt: true },
826
1242
  ],
1243
+ minimumVesuMovementAmount: minimumVesuMovementAmount ?? 5, //5 usdc
827
1244
  });
828
1245
 
829
1246
  const unusedBalanceAdapter = new UnusedBalanceAdapter({
@@ -863,6 +1280,7 @@ function getLooperSettings(
863
1280
  vesuMultiplyAdapter.getWithdrawLeaf()
864
1281
  );
865
1282
  vaultSettings.leafAdapters.push(() => extendedAdapter.getDepositLeaf());
1283
+ vaultSettings.leafAdapters.push(() => extendedAdapter.getSwapFromLegacyLeaf());
866
1284
  vaultSettings.leafAdapters.push(() => avnuAdapter.getDepositLeaf());
867
1285
  vaultSettings.leafAdapters.push(() => avnuAdapter.getWithdrawLeaf());
868
1286
  // Doubt here, should this be usdcToken.address, or wbtcToken.address?
@@ -956,15 +1374,15 @@ const re7UsdcPrimeDevansh: VesuExtendedStrategySettings = {
956
1374
  minimumWBTCDifferenceForAvnuSwap: MINIMUM_WBTC_DIFFERENCE_FOR_AVNU_SWAP,
957
1375
  }
958
1376
 
959
- export const VesuExtendedTestStrategies = (extendedBackendUrl: string, extendedApiKey: string, vaultIdExtended: number): IStrategyMetadata<VesuExtendedStrategySettings>[] => {
1377
+ export const VesuExtendedTestStrategies = (extendedBackendUrl: string, extendedApiKey: string, vaultIdExtended: number, minimumExtendedMovementAmount: number, minimumVesuMovementAmount: number, minimumExtendedRetriesDelayForOrderStatus: number, minimumExtendedPriceDifferenceForSwapOpen: number, maximumExtendedPriceDifferenceForSwapClosing: number): IStrategyMetadata<VesuExtendedStrategySettings>[] => {
960
1378
  return [
961
- getStrategySettingsVesuExtended('WBTC', 'USDC', re7UsdcPrimeDevansh, false, false, extendedBackendUrl, extendedApiKey, vaultIdExtended),
1379
+ getStrategySettingsVesuExtended('WBTC', 'USDC', re7UsdcPrimeDevansh, false, false, extendedBackendUrl, extendedApiKey, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing),
962
1380
  ]
963
1381
  }
964
1382
 
965
1383
 
966
1384
 
967
- function getStrategySettingsVesuExtended(lstSymbol: string, underlyingSymbol: string, addresses: VesuExtendedStrategySettings, isPreview: boolean = false, isLST: boolean, extendedBackendUrl: string, extendedApiKey: string, vaultIdExtended: number): IStrategyMetadata<VesuExtendedStrategySettings> {
1385
+ function getStrategySettingsVesuExtended(lstSymbol: string, underlyingSymbol: string, addresses: VesuExtendedStrategySettings, isPreview: boolean = false, isLST: boolean, extendedBackendUrl: string, extendedApiKey: string, vaultIdExtended: number, minimumExtendedMovementAmount: number, minimumVesuMovementAmount: number, minimumExtendedRetriesDelayForOrderStatus: number, minimumExtendedPriceDifferenceForSwapOpen: number, maximumExtendedPriceDifferenceForSwapClosing: number): IStrategyMetadata<VesuExtendedStrategySettings> {
968
1386
  return {
969
1387
  name: `Extended Test ${underlyingSymbol}`,
970
1388
  description: getDescription(lstSymbol, underlyingSymbol),
@@ -972,7 +1390,7 @@ function getStrategySettingsVesuExtended(lstSymbol: string, underlyingSymbol: st
972
1390
  launchBlock: 0,
973
1391
  type: 'Other',
974
1392
  depositTokens: [Global.getDefaultTokens().find(token => token.symbol === underlyingSymbol)!],
975
- additionalInfo: getLooperSettings(lstSymbol, underlyingSymbol, addresses, VesuPools.Re7USDCPrime, extendedBackendUrl, extendedApiKey, vaultIdExtended),
1393
+ additionalInfo: getLooperSettings(lstSymbol, underlyingSymbol, addresses, VesuPools.Re7USDCPrime, extendedBackendUrl, extendedApiKey, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing),
976
1394
  risk: {
977
1395
  riskFactor: _riskFactor,
978
1396
  netRisk: