@strkfarm/sdk 2.0.0-dev.7 → 2.0.0-dev.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -30072,8 +30072,47 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30072
30072
  async withdrawFromExtended(amount) {
30073
30073
  try {
30074
30074
  if (!this.client) {
30075
- throw new Error("Client not initialized");
30075
+ logger.error("Client not initialized");
30076
+ return false;
30077
+ }
30078
+ if (amount.lessThanOrEqualTo(0)) {
30079
+ logger.error(
30080
+ `Invalid withdrawal amount: ${amount.toNumber()}. Amount must be positive.`
30081
+ );
30082
+ return false;
30083
+ }
30084
+ if (amount.lessThanOrEqualTo(this.minimumExtendedMovementAmount)) {
30085
+ logger.warn(
30086
+ `Withdrawal amount ${amount.toNumber()} is below minimum Extended movement amount ${this.minimumExtendedMovementAmount}. Skipping withdrawal.`
30087
+ );
30088
+ return false;
30089
+ }
30090
+ const holdings = await this.getExtendedDepositAmount();
30091
+ if (!holdings) {
30092
+ logger.error(
30093
+ "Cannot get holdings - unable to validate withdrawal amount"
30094
+ );
30095
+ return false;
30096
+ }
30097
+ const availableForWithdrawal = parseFloat(
30098
+ holdings.availableForWithdrawal
30099
+ );
30100
+ if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
30101
+ logger.error(
30102
+ `Invalid availableForWithdrawal: ${holdings.availableForWithdrawal}. Expected a finite, non-negative number.`
30103
+ );
30104
+ return false;
30105
+ }
30106
+ const withdrawalAmount = amount.toNumber();
30107
+ if (withdrawalAmount > availableForWithdrawal) {
30108
+ logger.error(
30109
+ `Withdrawal amount ${withdrawalAmount} exceeds available balance ${availableForWithdrawal}`
30110
+ );
30111
+ return false;
30076
30112
  }
30113
+ logger.info(
30114
+ `Withdrawing ${withdrawalAmount} from Extended. Available balance: ${availableForWithdrawal}`
30115
+ );
30077
30116
  const withdrawalRequest = await this.client.withdrawUSDC(
30078
30117
  amount.toFixed(2)
30079
30118
  );
@@ -30084,6 +30123,9 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30084
30123
  );
30085
30124
  return withdrawalStatus;
30086
30125
  }
30126
+ logger.error(
30127
+ `Withdrawal request failed with status: ${withdrawalRequest.status}`
30128
+ );
30087
30129
  return false;
30088
30130
  } catch (error) {
30089
30131
  logger.error(`Error creating Withdraw Call: ${error}`);
@@ -30094,21 +30136,44 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30094
30136
  return Promise.resolve(1);
30095
30137
  }
30096
30138
  async getExtendedDepositAmount() {
30097
- if (this.client === null) {
30098
- logger.error("error initializing client");
30099
- return void 0;
30100
- }
30101
- const result = await this.client.getHoldings();
30102
- if (!result) {
30103
- logger.error(`error getting holdings: ${result}`);
30104
- return void 0;
30105
- }
30106
- const holdings = result.data;
30107
- if (!holdings) {
30108
- logger.error(`error getting holdings: ${holdings}`);
30139
+ try {
30140
+ if (this.client === null) {
30141
+ logger.error("error initializing client - client is null");
30142
+ return void 0;
30143
+ }
30144
+ const result = await this.client.getHoldings();
30145
+ if (!result) {
30146
+ logger.error("error getting holdings - API returned null/undefined");
30147
+ return void 0;
30148
+ }
30149
+ if (result.status && result.status !== "OK") {
30150
+ logger.error(
30151
+ `error getting holdings - API returned status: ${result.status}`
30152
+ );
30153
+ return void 0;
30154
+ }
30155
+ const holdings = result.data;
30156
+ if (!holdings) {
30157
+ logger.warn(
30158
+ "holdings data is null/undefined - treating as zero balance"
30159
+ );
30160
+ return {
30161
+ collateral_name: "",
30162
+ balance: "0",
30163
+ equity: "0",
30164
+ availableForTrade: "0",
30165
+ availableForWithdrawal: "0",
30166
+ unrealisedPnl: "0",
30167
+ initialMargin: "0",
30168
+ marginRatio: "0",
30169
+ updatedTime: Date.now()
30170
+ };
30171
+ }
30172
+ return holdings;
30173
+ } catch (error) {
30174
+ logger.error(`error getting holdings - exception: ${error}`);
30109
30175
  return void 0;
30110
30176
  }
30111
- return holdings;
30112
30177
  }
30113
30178
  async setLeverage(leverage, marketName) {
30114
30179
  if (this.client === null) {
@@ -30150,38 +30215,24 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30150
30215
  return result.data;
30151
30216
  }
30152
30217
  async getOrderStatus(orderId, marketName) {
30153
- if (this.client === null) {
30154
- logger.error("error initializing client");
30155
- return null;
30156
- }
30157
- let orderhistory = await this.getOrderHistory(marketName);
30158
- if (!orderhistory || orderhistory.length === 0) {
30159
- logger.error(`error getting order history: ${orderId}`);
30160
- } else {
30161
- const order = orderhistory.slice(0, 10).find((order2) => order2.id.toString() === orderId);
30162
- if (order) {
30163
- return order;
30218
+ try {
30219
+ if (this.client === null) {
30220
+ logger.error("error initializing client");
30221
+ return null;
30164
30222
  }
30165
- }
30166
- for (let attempt = 1; attempt <= 5; attempt++) {
30167
- await new Promise((resolve) => setTimeout(resolve, this.retryDelayForOrderStatus));
30168
- orderhistory = await this.getOrderHistory(marketName);
30223
+ const orderhistory = await this.getOrderHistory(marketName);
30169
30224
  if (!orderhistory || orderhistory.length === 0) {
30170
- logger.error(
30171
- `error getting order history on retry ${attempt}: ${orderId}`
30172
- );
30173
- continue;
30225
+ return null;
30174
30226
  }
30175
- const order = orderhistory.slice(0, 5).find((order2) => order2.id.toString() === orderId);
30176
- if (order && order.status === "FILLED" /* FILLED */) {
30227
+ const order = orderhistory.slice(0, 20).find((order2) => order2.id.toString() === orderId);
30228
+ if (order) {
30177
30229
  return order;
30178
30230
  }
30179
- logger.error(
30180
- `order not found in top 15 entries on retry ${attempt}: ${orderId}`
30181
- );
30231
+ return null;
30232
+ } catch (error) {
30233
+ logger.error(`error getting order status: ${error}`);
30234
+ return null;
30182
30235
  }
30183
- logger.error(`error getting order after all retries: ${orderId}`);
30184
- return null;
30185
30236
  }
30186
30237
  async fetchOrderBookBTCUSDC() {
30187
30238
  try {
@@ -30232,14 +30283,40 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30232
30283
  logger.error("error depositing or setting leverage");
30233
30284
  return null;
30234
30285
  }
30235
- const positions = await this.getAllOpenPositions();
30236
- if (positions === null) {
30286
+ const { ask, bid } = await this.fetchOrderBookBTCUSDC();
30287
+ if (!ask || !bid || ask.lessThanOrEqualTo(0) || bid.lessThanOrEqualTo(0)) {
30288
+ logger.error(
30289
+ `Invalid orderbook prices: ask=${ask?.toNumber()}, bid=${bid?.toNumber()}`
30290
+ );
30237
30291
  return null;
30238
30292
  }
30239
- const { ask, bid } = await this.fetchOrderBookBTCUSDC();
30240
30293
  const spread = ask.minus(bid);
30241
- let price = ask.plus(bid).div(2);
30242
- side === "SELL" /* SELL */ ? price = price.minus(spread.times(0.2 * attempt)) : price = price.plus(spread.times(0.2 * attempt));
30294
+ const midPrice = ask.plus(bid).div(2);
30295
+ const MAX_PRICE_DEVIATION_MULTIPLIER = 0.5;
30296
+ const priceAdjustmentMultiplier = Math.min(
30297
+ 0.2 * attempt,
30298
+ MAX_PRICE_DEVIATION_MULTIPLIER
30299
+ );
30300
+ const priceAdjustment = spread.times(priceAdjustmentMultiplier);
30301
+ let price = midPrice;
30302
+ if (side === "SELL" /* SELL */) {
30303
+ price = midPrice.minus(priceAdjustment);
30304
+ } else {
30305
+ price = midPrice.plus(priceAdjustment);
30306
+ }
30307
+ const maxDeviation = midPrice.times(0.5);
30308
+ if (price.minus(midPrice).abs().greaterThan(maxDeviation)) {
30309
+ logger.error(
30310
+ `Price deviation too large on attempt ${attempt}: price=${price.toNumber()}, midPrice=${midPrice.toNumber()}, deviation=${price.minus(midPrice).abs().toNumber()}`
30311
+ );
30312
+ if (attempt >= maxAttempts) {
30313
+ return null;
30314
+ }
30315
+ price = side === "SELL" /* SELL */ ? midPrice.minus(maxDeviation) : midPrice.plus(maxDeviation);
30316
+ }
30317
+ logger.info(
30318
+ `createOrder attempt ${attempt}/${maxAttempts}: side=${side}, midPrice=${midPrice.toNumber()}, adjustedPrice=${price.toNumber()}, adjustment=${priceAdjustmentMultiplier * 100}%`
30319
+ );
30243
30320
  const amount_in_token = (btcAmount * parseInt(leverage)).toFixed(
30244
30321
  this.config.extendedPrecision
30245
30322
  );
@@ -30250,17 +30327,57 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30250
30327
  price.toFixed(0),
30251
30328
  side
30252
30329
  );
30253
- if (!result) {
30330
+ if (!result || !result.position_id) {
30331
+ logger.error("Failed to create order - no position_id returned");
30254
30332
  return null;
30255
30333
  }
30256
- await new Promise((resolve) => setTimeout(resolve, 5e3));
30257
- const openOrder = await this.getOrderStatus(
30258
- result.position_id,
30334
+ const positionId = result.position_id;
30335
+ logger.info(
30336
+ `Order created with position_id: ${positionId}. Waiting for API to update...`
30337
+ );
30338
+ let openOrder = await this.getOrderStatus(
30339
+ positionId,
30259
30340
  this.config.extendedMarketName
30260
30341
  );
30342
+ const maxStatusRetries = 3;
30343
+ const statusRetryDelay = 5e3;
30261
30344
  if (!openOrder) {
30345
+ logger.warn(
30346
+ `Order ${positionId} not found in API yet. Retrying status fetch (max ${maxStatusRetries} times)...`
30347
+ );
30348
+ for (let statusRetry = 1; statusRetry <= maxStatusRetries; statusRetry++) {
30349
+ await new Promise((resolve) => setTimeout(resolve, statusRetryDelay));
30350
+ openOrder = await this.getOrderStatus(
30351
+ positionId,
30352
+ this.config.extendedMarketName
30353
+ );
30354
+ if (openOrder) {
30355
+ logger.info(
30356
+ `Order ${positionId} found after ${statusRetry} status retry(ies)`
30357
+ );
30358
+ break;
30359
+ }
30360
+ logger.warn(
30361
+ `Order ${positionId} still not found after ${statusRetry}/${maxStatusRetries} status retries`
30362
+ );
30363
+ }
30364
+ }
30365
+ if (openOrder && openOrder.status === "FILLED" /* FILLED */) {
30366
+ logger.info(
30367
+ `Order ${positionId} successfully filled with quantity ${openOrder.qty}`
30368
+ );
30369
+ return {
30370
+ position_id: positionId,
30371
+ btc_exposure: openOrder.qty
30372
+ };
30373
+ } else if (openOrder && openOrder.status !== "FILLED" /* FILLED */) {
30374
+ logger.warn(
30375
+ `Order ${positionId} found but status is ${openOrder.status}, not FILLED. Retrying order creation...`
30376
+ );
30262
30377
  if (attempt >= maxAttempts) {
30263
- logger.error("Max retries reached \u2014 could not verify open position");
30378
+ logger.error(
30379
+ `Max retries reached \u2014 order ${positionId} status is ${openOrder.status}, not FILLED`
30380
+ );
30264
30381
  return null;
30265
30382
  } else {
30266
30383
  const backoff = 2e3 * attempt;
@@ -30274,9 +30391,12 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30274
30391
  );
30275
30392
  }
30276
30393
  } else {
30394
+ logger.warn(
30395
+ `Order ${positionId} not found in API after ${maxStatusRetries} status retries (API update delayed ~30s). We got position_id from creation, so order exists. Returning position_id - status will be checked in next loop iteration.`
30396
+ );
30277
30397
  return {
30278
- position_id: result.position_id,
30279
- btc_exposure: openOrder.qty
30398
+ position_id: positionId,
30399
+ btc_exposure: amount_in_token
30280
30400
  };
30281
30401
  }
30282
30402
  } catch (err) {
@@ -34296,11 +34416,27 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34296
34416
  }
34297
34417
  async shouldInvest() {
34298
34418
  try {
34419
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest starting`);
34299
34420
  const vesuAdapter = await this.getVesuAdapter();
34300
34421
  const extendedAdapter = await this.getExtendedAdapter();
34301
- if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
34422
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest adapters fetched: vesuAdapter=${!!vesuAdapter}, extendedAdapter=${!!extendedAdapter}, extendedAdapter.client=${!!extendedAdapter?.client}`);
34423
+ if (!vesuAdapter) {
34302
34424
  logger.error(
34303
- `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
34425
+ `Vesu adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
34426
+ );
34427
+ return {
34428
+ shouldInvest: false,
34429
+ vesuAmount: new Web3Number(0, 0),
34430
+ extendedAmount: new Web3Number(0, 0),
34431
+ extendedLeverage: 0,
34432
+ collateralPrice: 0,
34433
+ debtPrice: 0,
34434
+ vesuLeverage: 0
34435
+ };
34436
+ }
34437
+ if (!extendedAdapter) {
34438
+ logger.error(
34439
+ `Extended adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
34304
34440
  );
34305
34441
  return {
34306
34442
  shouldInvest: false,
@@ -34312,10 +34448,72 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34312
34448
  vesuLeverage: 0
34313
34449
  };
34314
34450
  }
34451
+ if (!extendedAdapter.client) {
34452
+ logger.error(
34453
+ `Extended adapter client not initialized. This may be a temporary initialization failure - check network connectivity and API availability.`
34454
+ );
34455
+ return {
34456
+ shouldInvest: false,
34457
+ vesuAmount: new Web3Number(0, 0),
34458
+ extendedAmount: new Web3Number(0, 0),
34459
+ extendedLeverage: 0,
34460
+ collateralPrice: 0,
34461
+ debtPrice: 0,
34462
+ vesuLeverage: 0
34463
+ };
34464
+ }
34465
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest calling getUnusedBalance`);
34315
34466
  const balance = await this.getUnusedBalance();
34467
+ if (!Number.isFinite(balance.usdValue) || balance.usdValue < 0) {
34468
+ logger.error(
34469
+ `Invalid balance.usdValue: ${balance.usdValue}. Expected a finite, non-negative number.`
34470
+ );
34471
+ return {
34472
+ shouldInvest: false,
34473
+ vesuAmount: new Web3Number(0, 0),
34474
+ extendedAmount: new Web3Number(0, 0),
34475
+ extendedLeverage: 0,
34476
+ collateralPrice: 0,
34477
+ debtPrice: 0,
34478
+ vesuLeverage: 0
34479
+ };
34480
+ }
34481
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest balance: ${balance.usdValue}`);
34316
34482
  const usdcBalanceOnExtended = await extendedAdapter.getExtendedDepositAmount();
34483
+ if (usdcBalanceOnExtended) {
34484
+ const availableForWithdrawal = parseFloat(usdcBalanceOnExtended.availableForWithdrawal);
34485
+ if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
34486
+ logger.error(
34487
+ `Invalid usdcBalanceOnExtended.availableForWithdrawal: ${usdcBalanceOnExtended.availableForWithdrawal}. Expected a finite, non-negative number.`
34488
+ );
34489
+ return {
34490
+ shouldInvest: false,
34491
+ vesuAmount: new Web3Number(0, 0),
34492
+ extendedAmount: new Web3Number(0, 0),
34493
+ extendedLeverage: 0,
34494
+ collateralPrice: 0,
34495
+ debtPrice: 0,
34496
+ vesuLeverage: 0
34497
+ };
34498
+ }
34499
+ }
34317
34500
  const amountToInvest = new Web3Number(balance.usdValue, USDC_TOKEN_DECIMALS).plus(usdcBalanceOnExtended?.availableForWithdrawal ?? 0).multipliedBy(1 - LIMIT_BALANCE);
34318
- logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvest.toNumber()}`);
34501
+ const amountToInvestNumber = amountToInvest.toNumber();
34502
+ if (!Number.isFinite(amountToInvestNumber)) {
34503
+ logger.error(
34504
+ `Invalid amountToInvest calculation result: ${amountToInvestNumber}. Calculation may have produced NaN or Infinity.`
34505
+ );
34506
+ return {
34507
+ shouldInvest: false,
34508
+ vesuAmount: new Web3Number(0, 0),
34509
+ extendedAmount: new Web3Number(0, 0),
34510
+ extendedLeverage: 0,
34511
+ collateralPrice: 0,
34512
+ debtPrice: 0,
34513
+ vesuLeverage: 0
34514
+ };
34515
+ }
34516
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvestNumber}`);
34319
34517
  if (amountToInvest.lessThan(0)) {
34320
34518
  return {
34321
34519
  shouldInvest: false,
@@ -34345,6 +34543,34 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34345
34543
  collateralPrice,
34346
34544
  debtPrice
34347
34545
  } = await this.getAssetPrices();
34546
+ if (!Number.isFinite(collateralPrice.price) || collateralPrice.price <= 0) {
34547
+ logger.error(
34548
+ `Invalid collateralPrice: ${collateralPrice.price}. Expected a finite, positive number.`
34549
+ );
34550
+ return {
34551
+ shouldInvest: false,
34552
+ vesuAmount: new Web3Number(0, 0),
34553
+ extendedAmount: new Web3Number(0, 0),
34554
+ extendedLeverage: 0,
34555
+ collateralPrice: 0,
34556
+ debtPrice: 0,
34557
+ vesuLeverage: 0
34558
+ };
34559
+ }
34560
+ if (!Number.isFinite(debtPrice.price) || debtPrice.price <= 0) {
34561
+ logger.error(
34562
+ `Invalid debtPrice: ${debtPrice.price}. Expected a finite, positive number.`
34563
+ );
34564
+ return {
34565
+ shouldInvest: false,
34566
+ vesuAmount: new Web3Number(0, 0),
34567
+ extendedAmount: new Web3Number(0, 0),
34568
+ extendedLeverage: 0,
34569
+ collateralPrice: 0,
34570
+ debtPrice: 0,
34571
+ vesuLeverage: 0
34572
+ };
34573
+ }
34348
34574
  const { vesu_amount, extended_amount, extended_leverage, vesu_leverage } = await calculateAmountDistribution(
34349
34575
  amountToInvest.toNumber(),
34350
34576
  extendedAdapter.client,
@@ -34395,13 +34621,45 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34395
34621
  try {
34396
34622
  const vesuAdapter = await this.getVesuAdapter();
34397
34623
  const extendedAdapter = await this.getExtendedAdapter();
34398
- let calls = [];
34399
34624
  if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
34400
34625
  logger.error(
34401
34626
  `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
34402
34627
  );
34403
- return calls;
34628
+ return [];
34629
+ }
34630
+ const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
34631
+ if (!extendedHoldings) {
34632
+ logger.error(`error getting extended holdings: ${extendedHoldings}`);
34633
+ return [];
34404
34634
  }
34635
+ const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
34636
+ const usdcAmountOnExtendedAvailableForWithdrawal = parseFloat(
34637
+ extendedHoldings.availableForWithdrawal
34638
+ );
34639
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldMoveAssets calculating movements - Extended current: ${usdcAmountOnExtendedAvailableForWithdrawal}, Wallet: ${usdcAmountInWallet.toNumber()}, Target Extended: ${extendedAmount.toNumber()}, Target Vesu: ${vesuAmount.toNumber()}`);
34640
+ let totalExtendedWithdrawal = new Web3Number(0, USDC_TOKEN_DECIMALS);
34641
+ let totalExtendedDeposit = new Web3Number(0, USDC_TOKEN_DECIMALS);
34642
+ if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34643
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmount.abs());
34644
+ }
34645
+ const extendedTargetAmount = extendedAmount.abs();
34646
+ let projectedExtendedBalance = usdcAmountOnExtendedAvailableForWithdrawal;
34647
+ if (extendedAmount.isNegative()) {
34648
+ projectedExtendedBalance = projectedExtendedBalance - extendedAmount.abs().toNumber();
34649
+ }
34650
+ const extendedAmountDifference = extendedTargetAmount.minus(projectedExtendedBalance);
34651
+ const extendedAmountDifferenceAbs = extendedAmountDifference.abs();
34652
+ if (extendedAmountDifference.lessThan(0)) {
34653
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmountDifferenceAbs);
34654
+ } else if (extendedAmountDifference.greaterThan(0)) {
34655
+ totalExtendedDeposit = totalExtendedDeposit.plus(extendedAmountDifference);
34656
+ }
34657
+ const vesuTargetAmount = vesuAmount.abs();
34658
+ const projectedWalletBalance = usdcAmountInWallet.plus(totalExtendedWithdrawal).minus(totalExtendedDeposit);
34659
+ let vesuAmountDifference = vesuTargetAmount.minus(projectedWalletBalance);
34660
+ const vesuAmountDifferenceAbs = vesuAmountDifference.abs();
34661
+ 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()}`);
34662
+ let calls = [];
34405
34663
  if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34406
34664
  try {
34407
34665
  const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
@@ -34422,7 +34680,7 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34422
34680
  logger.error(`Failed moving assets to vault: ${err}`);
34423
34681
  }
34424
34682
  }
34425
- if (vesuAmount.isNegative() && vesuAmount.lessThan(vesuAdapter.minimumVesuMovementAmount)) {
34683
+ if (vesuAmount.isNegative() && vesuAmount.abs().greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
34426
34684
  try {
34427
34685
  const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
34428
34686
  {
@@ -34441,48 +34699,76 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34441
34699
  logger.error(`Failed moving assets to vault: ${err}`);
34442
34700
  }
34443
34701
  }
34444
- const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
34445
- if (!extendedHoldings) {
34446
- logger.error(`error getting extended holdings: ${extendedHoldings}`);
34447
- return calls;
34448
- }
34449
- const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
34450
- const usdcAmountOnExtended = parseFloat(
34451
- extendedHoldings.availableForWithdrawal
34452
- );
34453
- if (extendedAmount.minus(usdcAmountOnExtended).greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34454
- try {
34455
- const { calls: extendedCalls } = await this.moveAssets(
34456
- {
34457
- to: Protocols.EXTENDED.name,
34458
- from: Protocols.VAULT.name,
34459
- amount: extendedAmount.minus(usdcAmountOnExtended)
34460
- },
34461
- extendedAdapter,
34462
- vesuAdapter
34463
- );
34464
- calls.push(...extendedCalls);
34465
- } catch (err) {
34466
- logger.error(`Failed moving assets to extended: ${err}`);
34702
+ if (extendedAmountDifferenceAbs.greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34703
+ if (extendedAmountDifference.greaterThan(0)) {
34704
+ try {
34705
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
34706
+ {
34707
+ to: Protocols.EXTENDED.name,
34708
+ from: Protocols.VAULT.name,
34709
+ amount: extendedAmountDifference
34710
+ },
34711
+ extendedAdapter,
34712
+ vesuAdapter
34713
+ );
34714
+ if (extendedStatus) {
34715
+ calls.push(...extendedCalls);
34716
+ } else {
34717
+ logger.error(`Failed to move assets to extended - operation returned false status`);
34718
+ return [];
34719
+ }
34720
+ } catch (err) {
34721
+ logger.error(`Failed moving assets to extended: ${err}`);
34722
+ return [];
34723
+ }
34724
+ } else if (extendedAmountDifference.lessThan(0)) {
34725
+ try {
34726
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
34727
+ {
34728
+ to: Protocols.VAULT.name,
34729
+ from: Protocols.EXTENDED.name,
34730
+ amount: extendedAmountDifferenceAbs
34731
+ },
34732
+ extendedAdapter,
34733
+ vesuAdapter
34734
+ );
34735
+ if (extendedStatus) {
34736
+ calls.push(...extendedCalls);
34737
+ } else {
34738
+ logger.error(`Failed to withdraw from extended - operation returned false status`);
34739
+ return [];
34740
+ }
34741
+ } catch (err) {
34742
+ logger.error(`Failed moving assets from extended to vault: ${err}`);
34743
+ return [];
34744
+ }
34467
34745
  }
34468
34746
  }
34469
- if (vesuAmount.minus(usdcAmountInWallet).greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
34470
- try {
34471
- const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
34472
- {
34473
- to: Protocols.VAULT.name,
34474
- from: Protocols.EXTENDED.name,
34475
- amount: vesuAmount.minus(usdcAmountInWallet)
34476
- },
34477
- extendedAdapter,
34478
- vesuAdapter
34747
+ if (vesuAmountDifferenceAbs.greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
34748
+ if (vesuAmountDifference.lessThanOrEqualTo(0)) {
34749
+ logger.warn(
34750
+ `Vesu amount difference is negative or zero: ${vesuAmountDifference.toNumber()}. Skipping operation.`
34479
34751
  );
34480
- if (!vesuStatus) {
34752
+ } else {
34753
+ try {
34754
+ const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
34755
+ {
34756
+ to: Protocols.VAULT.name,
34757
+ from: Protocols.EXTENDED.name,
34758
+ amount: vesuAmountDifference
34759
+ },
34760
+ extendedAdapter,
34761
+ vesuAdapter
34762
+ );
34763
+ if (!vesuStatus) {
34764
+ logger.error(`Failed to move assets to vesu - operation returned false status`);
34765
+ return [];
34766
+ }
34767
+ calls.push(...vesuCalls);
34768
+ } catch (err) {
34769
+ logger.error(`Failed moving assets to vault: ${err}`);
34481
34770
  return [];
34482
34771
  }
34483
- calls.push(...vesuCalls);
34484
- } catch (err) {
34485
- logger.error(`Failed moving assets to vault: ${err}`);
34486
34772
  }
34487
34773
  }
34488
34774
  return calls;
@@ -34493,6 +34779,38 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34493
34779
  }
34494
34780
  async moveAssets(params, extendedAdapter, vesuAdapter) {
34495
34781
  try {
34782
+ if (params.amount.lessThanOrEqualTo(0)) {
34783
+ logger.error(
34784
+ `Invalid amount for moveAssets: ${params.amount.toNumber()}. Amount must be positive.`
34785
+ );
34786
+ return {
34787
+ calls: [],
34788
+ status: false
34789
+ };
34790
+ }
34791
+ const amountAbs = params.amount.abs();
34792
+ if (params.from === Protocols.EXTENDED.name || params.to === Protocols.EXTENDED.name) {
34793
+ if (amountAbs.lessThanOrEqualTo(extendedAdapter.minimumExtendedMovementAmount)) {
34794
+ logger.warn(
34795
+ `Amount ${amountAbs.toNumber()} is below minimum Extended movement amount ${extendedAdapter.minimumExtendedMovementAmount}. Skipping operation.`
34796
+ );
34797
+ return {
34798
+ calls: [],
34799
+ status: false
34800
+ };
34801
+ }
34802
+ }
34803
+ if (params.from === Protocols.VESU.name || params.to === Protocols.VESU.name) {
34804
+ if (amountAbs.lessThanOrEqualTo(vesuAdapter.minimumVesuMovementAmount)) {
34805
+ logger.warn(
34806
+ `Amount ${amountAbs.toNumber()} is below minimum Vesu movement amount ${vesuAdapter.minimumVesuMovementAmount}. Skipping operation.`
34807
+ );
34808
+ return {
34809
+ calls: [],
34810
+ status: false
34811
+ };
34812
+ }
34813
+ }
34496
34814
  const avnuAdapter = await this.getAvnuAdapter();
34497
34815
  if (!avnuAdapter) {
34498
34816
  logger.error(`avnu adapter not found: ${avnuAdapter}`);
@@ -34553,12 +34871,13 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34553
34871
  );
34554
34872
  if (!openLongPosition) {
34555
34873
  logger.error(`error opening long position: ${openLongPosition}`);
34556
- return {
34557
- calls: [],
34558
- status: false
34559
- };
34560
34874
  }
34561
34875
  await new Promise((resolve) => setTimeout(resolve, 5e3));
34876
+ const updatedHoldings = await extendedAdapter.getExtendedDepositAmount();
34877
+ if (!updatedHoldings || new Web3Number(updatedHoldings.availableForWithdrawal, USDC_TOKEN_DECIMALS).lessThan(params.amount.abs())) {
34878
+ logger.error(`Insufficient balance after opening position. Available: ${updatedHoldings?.availableForWithdrawal}, Needed: ${params.amount.abs()}`);
34879
+ return { calls: [], status: false };
34880
+ }
34562
34881
  }
34563
34882
  const withdrawalFromExtended = await extendedAdapter.withdrawFromExtended(params.amount);
34564
34883
  if (withdrawalFromExtended) {