@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.
@@ -93946,8 +93946,47 @@ spurious results.`);
93946
93946
  async withdrawFromExtended(amount) {
93947
93947
  try {
93948
93948
  if (!this.client) {
93949
- throw new Error("Client not initialized");
93949
+ logger2.error("Client not initialized");
93950
+ return false;
93951
+ }
93952
+ if (amount.lessThanOrEqualTo(0)) {
93953
+ logger2.error(
93954
+ `Invalid withdrawal amount: ${amount.toNumber()}. Amount must be positive.`
93955
+ );
93956
+ return false;
93957
+ }
93958
+ if (amount.lessThanOrEqualTo(this.minimumExtendedMovementAmount)) {
93959
+ logger2.warn(
93960
+ `Withdrawal amount ${amount.toNumber()} is below minimum Extended movement amount ${this.minimumExtendedMovementAmount}. Skipping withdrawal.`
93961
+ );
93962
+ return false;
93963
+ }
93964
+ const holdings = await this.getExtendedDepositAmount();
93965
+ if (!holdings) {
93966
+ logger2.error(
93967
+ "Cannot get holdings - unable to validate withdrawal amount"
93968
+ );
93969
+ return false;
93950
93970
  }
93971
+ const availableForWithdrawal = parseFloat(
93972
+ holdings.availableForWithdrawal
93973
+ );
93974
+ if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
93975
+ logger2.error(
93976
+ `Invalid availableForWithdrawal: ${holdings.availableForWithdrawal}. Expected a finite, non-negative number.`
93977
+ );
93978
+ return false;
93979
+ }
93980
+ const withdrawalAmount = amount.toNumber();
93981
+ if (withdrawalAmount > availableForWithdrawal) {
93982
+ logger2.error(
93983
+ `Withdrawal amount ${withdrawalAmount} exceeds available balance ${availableForWithdrawal}`
93984
+ );
93985
+ return false;
93986
+ }
93987
+ logger2.info(
93988
+ `Withdrawing ${withdrawalAmount} from Extended. Available balance: ${availableForWithdrawal}`
93989
+ );
93951
93990
  const withdrawalRequest = await this.client.withdrawUSDC(
93952
93991
  amount.toFixed(2)
93953
93992
  );
@@ -93958,6 +93997,9 @@ spurious results.`);
93958
93997
  );
93959
93998
  return withdrawalStatus;
93960
93999
  }
94000
+ logger2.error(
94001
+ `Withdrawal request failed with status: ${withdrawalRequest.status}`
94002
+ );
93961
94003
  return false;
93962
94004
  } catch (error2) {
93963
94005
  logger2.error(`Error creating Withdraw Call: ${error2}`);
@@ -93968,21 +94010,44 @@ spurious results.`);
93968
94010
  return Promise.resolve(1);
93969
94011
  }
93970
94012
  async getExtendedDepositAmount() {
93971
- if (this.client === null) {
93972
- logger2.error("error initializing client");
93973
- return void 0;
93974
- }
93975
- const result2 = await this.client.getHoldings();
93976
- if (!result2) {
93977
- logger2.error(`error getting holdings: ${result2}`);
93978
- return void 0;
93979
- }
93980
- const holdings = result2.data;
93981
- if (!holdings) {
93982
- logger2.error(`error getting holdings: ${holdings}`);
94013
+ try {
94014
+ if (this.client === null) {
94015
+ logger2.error("error initializing client - client is null");
94016
+ return void 0;
94017
+ }
94018
+ const result2 = await this.client.getHoldings();
94019
+ if (!result2) {
94020
+ logger2.error("error getting holdings - API returned null/undefined");
94021
+ return void 0;
94022
+ }
94023
+ if (result2.status && result2.status !== "OK") {
94024
+ logger2.error(
94025
+ `error getting holdings - API returned status: ${result2.status}`
94026
+ );
94027
+ return void 0;
94028
+ }
94029
+ const holdings = result2.data;
94030
+ if (!holdings) {
94031
+ logger2.warn(
94032
+ "holdings data is null/undefined - treating as zero balance"
94033
+ );
94034
+ return {
94035
+ collateral_name: "",
94036
+ balance: "0",
94037
+ equity: "0",
94038
+ availableForTrade: "0",
94039
+ availableForWithdrawal: "0",
94040
+ unrealisedPnl: "0",
94041
+ initialMargin: "0",
94042
+ marginRatio: "0",
94043
+ updatedTime: Date.now()
94044
+ };
94045
+ }
94046
+ return holdings;
94047
+ } catch (error2) {
94048
+ logger2.error(`error getting holdings - exception: ${error2}`);
93983
94049
  return void 0;
93984
94050
  }
93985
- return holdings;
93986
94051
  }
93987
94052
  async setLeverage(leverage, marketName) {
93988
94053
  if (this.client === null) {
@@ -94024,38 +94089,24 @@ spurious results.`);
94024
94089
  return result2.data;
94025
94090
  }
94026
94091
  async getOrderStatus(orderId, marketName) {
94027
- if (this.client === null) {
94028
- logger2.error("error initializing client");
94029
- return null;
94030
- }
94031
- let orderhistory = await this.getOrderHistory(marketName);
94032
- if (!orderhistory || orderhistory.length === 0) {
94033
- logger2.error(`error getting order history: ${orderId}`);
94034
- } else {
94035
- const order = orderhistory.slice(0, 10).find((order2) => order2.id.toString() === orderId);
94036
- if (order) {
94037
- return order;
94092
+ try {
94093
+ if (this.client === null) {
94094
+ logger2.error("error initializing client");
94095
+ return null;
94038
94096
  }
94039
- }
94040
- for (let attempt = 1; attempt <= 5; attempt++) {
94041
- await new Promise((resolve) => setTimeout(resolve, this.retryDelayForOrderStatus));
94042
- orderhistory = await this.getOrderHistory(marketName);
94097
+ const orderhistory = await this.getOrderHistory(marketName);
94043
94098
  if (!orderhistory || orderhistory.length === 0) {
94044
- logger2.error(
94045
- `error getting order history on retry ${attempt}: ${orderId}`
94046
- );
94047
- continue;
94099
+ return null;
94048
94100
  }
94049
- const order = orderhistory.slice(0, 5).find((order2) => order2.id.toString() === orderId);
94050
- if (order && order.status === "FILLED" /* FILLED */) {
94101
+ const order = orderhistory.slice(0, 20).find((order2) => order2.id.toString() === orderId);
94102
+ if (order) {
94051
94103
  return order;
94052
94104
  }
94053
- logger2.error(
94054
- `order not found in top 15 entries on retry ${attempt}: ${orderId}`
94055
- );
94105
+ return null;
94106
+ } catch (error2) {
94107
+ logger2.error(`error getting order status: ${error2}`);
94108
+ return null;
94056
94109
  }
94057
- logger2.error(`error getting order after all retries: ${orderId}`);
94058
- return null;
94059
94110
  }
94060
94111
  async fetchOrderBookBTCUSDC() {
94061
94112
  try {
@@ -94106,14 +94157,40 @@ spurious results.`);
94106
94157
  logger2.error("error depositing or setting leverage");
94107
94158
  return null;
94108
94159
  }
94109
- const positions = await this.getAllOpenPositions();
94110
- if (positions === null) {
94160
+ const { ask, bid } = await this.fetchOrderBookBTCUSDC();
94161
+ if (!ask || !bid || ask.lessThanOrEqualTo(0) || bid.lessThanOrEqualTo(0)) {
94162
+ logger2.error(
94163
+ `Invalid orderbook prices: ask=${ask?.toNumber()}, bid=${bid?.toNumber()}`
94164
+ );
94111
94165
  return null;
94112
94166
  }
94113
- const { ask, bid } = await this.fetchOrderBookBTCUSDC();
94114
94167
  const spread3 = ask.minus(bid);
94115
- let price = ask.plus(bid).div(2);
94116
- side === "SELL" /* SELL */ ? price = price.minus(spread3.times(0.2 * attempt)) : price = price.plus(spread3.times(0.2 * attempt));
94168
+ const midPrice = ask.plus(bid).div(2);
94169
+ const MAX_PRICE_DEVIATION_MULTIPLIER = 0.5;
94170
+ const priceAdjustmentMultiplier = Math.min(
94171
+ 0.2 * attempt,
94172
+ MAX_PRICE_DEVIATION_MULTIPLIER
94173
+ );
94174
+ const priceAdjustment = spread3.times(priceAdjustmentMultiplier);
94175
+ let price = midPrice;
94176
+ if (side === "SELL" /* SELL */) {
94177
+ price = midPrice.minus(priceAdjustment);
94178
+ } else {
94179
+ price = midPrice.plus(priceAdjustment);
94180
+ }
94181
+ const maxDeviation = midPrice.times(0.5);
94182
+ if (price.minus(midPrice).abs().greaterThan(maxDeviation)) {
94183
+ logger2.error(
94184
+ `Price deviation too large on attempt ${attempt}: price=${price.toNumber()}, midPrice=${midPrice.toNumber()}, deviation=${price.minus(midPrice).abs().toNumber()}`
94185
+ );
94186
+ if (attempt >= maxAttempts) {
94187
+ return null;
94188
+ }
94189
+ price = side === "SELL" /* SELL */ ? midPrice.minus(maxDeviation) : midPrice.plus(maxDeviation);
94190
+ }
94191
+ logger2.info(
94192
+ `createOrder attempt ${attempt}/${maxAttempts}: side=${side}, midPrice=${midPrice.toNumber()}, adjustedPrice=${price.toNumber()}, adjustment=${priceAdjustmentMultiplier * 100}%`
94193
+ );
94117
94194
  const amount_in_token = (btcAmount * parseInt(leverage)).toFixed(
94118
94195
  this.config.extendedPrecision
94119
94196
  );
@@ -94124,17 +94201,57 @@ spurious results.`);
94124
94201
  price.toFixed(0),
94125
94202
  side
94126
94203
  );
94127
- if (!result2) {
94204
+ if (!result2 || !result2.position_id) {
94205
+ logger2.error("Failed to create order - no position_id returned");
94128
94206
  return null;
94129
94207
  }
94130
- await new Promise((resolve) => setTimeout(resolve, 5e3));
94131
- const openOrder = await this.getOrderStatus(
94132
- result2.position_id,
94208
+ const positionId = result2.position_id;
94209
+ logger2.info(
94210
+ `Order created with position_id: ${positionId}. Waiting for API to update...`
94211
+ );
94212
+ let openOrder = await this.getOrderStatus(
94213
+ positionId,
94133
94214
  this.config.extendedMarketName
94134
94215
  );
94216
+ const maxStatusRetries = 3;
94217
+ const statusRetryDelay = 5e3;
94135
94218
  if (!openOrder) {
94219
+ logger2.warn(
94220
+ `Order ${positionId} not found in API yet. Retrying status fetch (max ${maxStatusRetries} times)...`
94221
+ );
94222
+ for (let statusRetry = 1; statusRetry <= maxStatusRetries; statusRetry++) {
94223
+ await new Promise((resolve) => setTimeout(resolve, statusRetryDelay));
94224
+ openOrder = await this.getOrderStatus(
94225
+ positionId,
94226
+ this.config.extendedMarketName
94227
+ );
94228
+ if (openOrder) {
94229
+ logger2.info(
94230
+ `Order ${positionId} found after ${statusRetry} status retry(ies)`
94231
+ );
94232
+ break;
94233
+ }
94234
+ logger2.warn(
94235
+ `Order ${positionId} still not found after ${statusRetry}/${maxStatusRetries} status retries`
94236
+ );
94237
+ }
94238
+ }
94239
+ if (openOrder && openOrder.status === "FILLED" /* FILLED */) {
94240
+ logger2.info(
94241
+ `Order ${positionId} successfully filled with quantity ${openOrder.qty}`
94242
+ );
94243
+ return {
94244
+ position_id: positionId,
94245
+ btc_exposure: openOrder.qty
94246
+ };
94247
+ } else if (openOrder && openOrder.status !== "FILLED" /* FILLED */) {
94248
+ logger2.warn(
94249
+ `Order ${positionId} found but status is ${openOrder.status}, not FILLED. Retrying order creation...`
94250
+ );
94136
94251
  if (attempt >= maxAttempts) {
94137
- logger2.error("Max retries reached \u2014 could not verify open position");
94252
+ logger2.error(
94253
+ `Max retries reached \u2014 order ${positionId} status is ${openOrder.status}, not FILLED`
94254
+ );
94138
94255
  return null;
94139
94256
  } else {
94140
94257
  const backoff = 2e3 * attempt;
@@ -94148,9 +94265,12 @@ spurious results.`);
94148
94265
  );
94149
94266
  }
94150
94267
  } else {
94268
+ logger2.warn(
94269
+ `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.`
94270
+ );
94151
94271
  return {
94152
- position_id: result2.position_id,
94153
- btc_exposure: openOrder.qty
94272
+ position_id: positionId,
94273
+ btc_exposure: amount_in_token
94154
94274
  };
94155
94275
  }
94156
94276
  } catch (err2) {
@@ -98165,11 +98285,27 @@ spurious results.`);
98165
98285
  }
98166
98286
  async shouldInvest() {
98167
98287
  try {
98288
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest starting`);
98168
98289
  const vesuAdapter = await this.getVesuAdapter();
98169
98290
  const extendedAdapter = await this.getExtendedAdapter();
98170
- if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
98291
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest adapters fetched: vesuAdapter=${!!vesuAdapter}, extendedAdapter=${!!extendedAdapter}, extendedAdapter.client=${!!extendedAdapter?.client}`);
98292
+ if (!vesuAdapter) {
98171
98293
  logger2.error(
98172
- `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
98294
+ `Vesu adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
98295
+ );
98296
+ return {
98297
+ shouldInvest: false,
98298
+ vesuAmount: new Web3Number(0, 0),
98299
+ extendedAmount: new Web3Number(0, 0),
98300
+ extendedLeverage: 0,
98301
+ collateralPrice: 0,
98302
+ debtPrice: 0,
98303
+ vesuLeverage: 0
98304
+ };
98305
+ }
98306
+ if (!extendedAdapter) {
98307
+ logger2.error(
98308
+ `Extended adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
98173
98309
  );
98174
98310
  return {
98175
98311
  shouldInvest: false,
@@ -98181,10 +98317,72 @@ spurious results.`);
98181
98317
  vesuLeverage: 0
98182
98318
  };
98183
98319
  }
98320
+ if (!extendedAdapter.client) {
98321
+ logger2.error(
98322
+ `Extended adapter client not initialized. This may be a temporary initialization failure - check network connectivity and API availability.`
98323
+ );
98324
+ return {
98325
+ shouldInvest: false,
98326
+ vesuAmount: new Web3Number(0, 0),
98327
+ extendedAmount: new Web3Number(0, 0),
98328
+ extendedLeverage: 0,
98329
+ collateralPrice: 0,
98330
+ debtPrice: 0,
98331
+ vesuLeverage: 0
98332
+ };
98333
+ }
98334
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest calling getUnusedBalance`);
98184
98335
  const balance = await this.getUnusedBalance();
98336
+ if (!Number.isFinite(balance.usdValue) || balance.usdValue < 0) {
98337
+ logger2.error(
98338
+ `Invalid balance.usdValue: ${balance.usdValue}. Expected a finite, non-negative number.`
98339
+ );
98340
+ return {
98341
+ shouldInvest: false,
98342
+ vesuAmount: new Web3Number(0, 0),
98343
+ extendedAmount: new Web3Number(0, 0),
98344
+ extendedLeverage: 0,
98345
+ collateralPrice: 0,
98346
+ debtPrice: 0,
98347
+ vesuLeverage: 0
98348
+ };
98349
+ }
98350
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest balance: ${balance.usdValue}`);
98185
98351
  const usdcBalanceOnExtended = await extendedAdapter.getExtendedDepositAmount();
98352
+ if (usdcBalanceOnExtended) {
98353
+ const availableForWithdrawal = parseFloat(usdcBalanceOnExtended.availableForWithdrawal);
98354
+ if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
98355
+ logger2.error(
98356
+ `Invalid usdcBalanceOnExtended.availableForWithdrawal: ${usdcBalanceOnExtended.availableForWithdrawal}. Expected a finite, non-negative number.`
98357
+ );
98358
+ return {
98359
+ shouldInvest: false,
98360
+ vesuAmount: new Web3Number(0, 0),
98361
+ extendedAmount: new Web3Number(0, 0),
98362
+ extendedLeverage: 0,
98363
+ collateralPrice: 0,
98364
+ debtPrice: 0,
98365
+ vesuLeverage: 0
98366
+ };
98367
+ }
98368
+ }
98186
98369
  const amountToInvest = new Web3Number(balance.usdValue, USDC_TOKEN_DECIMALS).plus(usdcBalanceOnExtended?.availableForWithdrawal ?? 0).multipliedBy(1 - LIMIT_BALANCE);
98187
- logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvest.toNumber()}`);
98370
+ const amountToInvestNumber = amountToInvest.toNumber();
98371
+ if (!Number.isFinite(amountToInvestNumber)) {
98372
+ logger2.error(
98373
+ `Invalid amountToInvest calculation result: ${amountToInvestNumber}. Calculation may have produced NaN or Infinity.`
98374
+ );
98375
+ return {
98376
+ shouldInvest: false,
98377
+ vesuAmount: new Web3Number(0, 0),
98378
+ extendedAmount: new Web3Number(0, 0),
98379
+ extendedLeverage: 0,
98380
+ collateralPrice: 0,
98381
+ debtPrice: 0,
98382
+ vesuLeverage: 0
98383
+ };
98384
+ }
98385
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvestNumber}`);
98188
98386
  if (amountToInvest.lessThan(0)) {
98189
98387
  return {
98190
98388
  shouldInvest: false,
@@ -98214,6 +98412,34 @@ spurious results.`);
98214
98412
  collateralPrice,
98215
98413
  debtPrice
98216
98414
  } = await this.getAssetPrices();
98415
+ if (!Number.isFinite(collateralPrice.price) || collateralPrice.price <= 0) {
98416
+ logger2.error(
98417
+ `Invalid collateralPrice: ${collateralPrice.price}. Expected a finite, positive number.`
98418
+ );
98419
+ return {
98420
+ shouldInvest: false,
98421
+ vesuAmount: new Web3Number(0, 0),
98422
+ extendedAmount: new Web3Number(0, 0),
98423
+ extendedLeverage: 0,
98424
+ collateralPrice: 0,
98425
+ debtPrice: 0,
98426
+ vesuLeverage: 0
98427
+ };
98428
+ }
98429
+ if (!Number.isFinite(debtPrice.price) || debtPrice.price <= 0) {
98430
+ logger2.error(
98431
+ `Invalid debtPrice: ${debtPrice.price}. Expected a finite, positive number.`
98432
+ );
98433
+ return {
98434
+ shouldInvest: false,
98435
+ vesuAmount: new Web3Number(0, 0),
98436
+ extendedAmount: new Web3Number(0, 0),
98437
+ extendedLeverage: 0,
98438
+ collateralPrice: 0,
98439
+ debtPrice: 0,
98440
+ vesuLeverage: 0
98441
+ };
98442
+ }
98217
98443
  const { vesu_amount, extended_amount, extended_leverage, vesu_leverage } = await calculateAmountDistribution(
98218
98444
  amountToInvest.toNumber(),
98219
98445
  extendedAdapter.client,
@@ -98264,13 +98490,45 @@ spurious results.`);
98264
98490
  try {
98265
98491
  const vesuAdapter = await this.getVesuAdapter();
98266
98492
  const extendedAdapter = await this.getExtendedAdapter();
98267
- let calls = [];
98268
98493
  if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
98269
98494
  logger2.error(
98270
98495
  `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
98271
98496
  );
98272
- return calls;
98497
+ return [];
98273
98498
  }
98499
+ const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
98500
+ if (!extendedHoldings) {
98501
+ logger2.error(`error getting extended holdings: ${extendedHoldings}`);
98502
+ return [];
98503
+ }
98504
+ const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
98505
+ const usdcAmountOnExtendedAvailableForWithdrawal = parseFloat(
98506
+ extendedHoldings.availableForWithdrawal
98507
+ );
98508
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldMoveAssets calculating movements - Extended current: ${usdcAmountOnExtendedAvailableForWithdrawal}, Wallet: ${usdcAmountInWallet.toNumber()}, Target Extended: ${extendedAmount.toNumber()}, Target Vesu: ${vesuAmount.toNumber()}`);
98509
+ let totalExtendedWithdrawal = new Web3Number(0, USDC_TOKEN_DECIMALS);
98510
+ let totalExtendedDeposit = new Web3Number(0, USDC_TOKEN_DECIMALS);
98511
+ if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
98512
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmount.abs());
98513
+ }
98514
+ const extendedTargetAmount = extendedAmount.abs();
98515
+ let projectedExtendedBalance = usdcAmountOnExtendedAvailableForWithdrawal;
98516
+ if (extendedAmount.isNegative()) {
98517
+ projectedExtendedBalance = projectedExtendedBalance - extendedAmount.abs().toNumber();
98518
+ }
98519
+ const extendedAmountDifference = extendedTargetAmount.minus(projectedExtendedBalance);
98520
+ const extendedAmountDifferenceAbs = extendedAmountDifference.abs();
98521
+ if (extendedAmountDifference.lessThan(0)) {
98522
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmountDifferenceAbs);
98523
+ } else if (extendedAmountDifference.greaterThan(0)) {
98524
+ totalExtendedDeposit = totalExtendedDeposit.plus(extendedAmountDifference);
98525
+ }
98526
+ const vesuTargetAmount = vesuAmount.abs();
98527
+ const projectedWalletBalance = usdcAmountInWallet.plus(totalExtendedWithdrawal).minus(totalExtendedDeposit);
98528
+ let vesuAmountDifference = vesuTargetAmount.minus(projectedWalletBalance);
98529
+ const vesuAmountDifferenceAbs = vesuAmountDifference.abs();
98530
+ logger2.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()}`);
98531
+ let calls = [];
98274
98532
  if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
98275
98533
  try {
98276
98534
  const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
@@ -98291,7 +98549,7 @@ spurious results.`);
98291
98549
  logger2.error(`Failed moving assets to vault: ${err2}`);
98292
98550
  }
98293
98551
  }
98294
- if (vesuAmount.isNegative() && vesuAmount.lessThan(vesuAdapter.minimumVesuMovementAmount)) {
98552
+ if (vesuAmount.isNegative() && vesuAmount.abs().greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
98295
98553
  try {
98296
98554
  const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
98297
98555
  {
@@ -98310,48 +98568,76 @@ spurious results.`);
98310
98568
  logger2.error(`Failed moving assets to vault: ${err2}`);
98311
98569
  }
98312
98570
  }
98313
- const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
98314
- if (!extendedHoldings) {
98315
- logger2.error(`error getting extended holdings: ${extendedHoldings}`);
98316
- return calls;
98317
- }
98318
- const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
98319
- const usdcAmountOnExtended = parseFloat(
98320
- extendedHoldings.availableForWithdrawal
98321
- );
98322
- if (extendedAmount.minus(usdcAmountOnExtended).greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
98323
- try {
98324
- const { calls: extendedCalls } = await this.moveAssets(
98325
- {
98326
- to: Protocols.EXTENDED.name,
98327
- from: Protocols.VAULT.name,
98328
- amount: extendedAmount.minus(usdcAmountOnExtended)
98329
- },
98330
- extendedAdapter,
98331
- vesuAdapter
98332
- );
98333
- calls.push(...extendedCalls);
98334
- } catch (err2) {
98335
- logger2.error(`Failed moving assets to extended: ${err2}`);
98571
+ if (extendedAmountDifferenceAbs.greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
98572
+ if (extendedAmountDifference.greaterThan(0)) {
98573
+ try {
98574
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
98575
+ {
98576
+ to: Protocols.EXTENDED.name,
98577
+ from: Protocols.VAULT.name,
98578
+ amount: extendedAmountDifference
98579
+ },
98580
+ extendedAdapter,
98581
+ vesuAdapter
98582
+ );
98583
+ if (extendedStatus) {
98584
+ calls.push(...extendedCalls);
98585
+ } else {
98586
+ logger2.error(`Failed to move assets to extended - operation returned false status`);
98587
+ return [];
98588
+ }
98589
+ } catch (err2) {
98590
+ logger2.error(`Failed moving assets to extended: ${err2}`);
98591
+ return [];
98592
+ }
98593
+ } else if (extendedAmountDifference.lessThan(0)) {
98594
+ try {
98595
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
98596
+ {
98597
+ to: Protocols.VAULT.name,
98598
+ from: Protocols.EXTENDED.name,
98599
+ amount: extendedAmountDifferenceAbs
98600
+ },
98601
+ extendedAdapter,
98602
+ vesuAdapter
98603
+ );
98604
+ if (extendedStatus) {
98605
+ calls.push(...extendedCalls);
98606
+ } else {
98607
+ logger2.error(`Failed to withdraw from extended - operation returned false status`);
98608
+ return [];
98609
+ }
98610
+ } catch (err2) {
98611
+ logger2.error(`Failed moving assets from extended to vault: ${err2}`);
98612
+ return [];
98613
+ }
98336
98614
  }
98337
98615
  }
98338
- if (vesuAmount.minus(usdcAmountInWallet).greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
98339
- try {
98340
- const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
98341
- {
98342
- to: Protocols.VAULT.name,
98343
- from: Protocols.EXTENDED.name,
98344
- amount: vesuAmount.minus(usdcAmountInWallet)
98345
- },
98346
- extendedAdapter,
98347
- vesuAdapter
98616
+ if (vesuAmountDifferenceAbs.greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
98617
+ if (vesuAmountDifference.lessThanOrEqualTo(0)) {
98618
+ logger2.warn(
98619
+ `Vesu amount difference is negative or zero: ${vesuAmountDifference.toNumber()}. Skipping operation.`
98348
98620
  );
98349
- if (!vesuStatus) {
98621
+ } else {
98622
+ try {
98623
+ const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
98624
+ {
98625
+ to: Protocols.VAULT.name,
98626
+ from: Protocols.EXTENDED.name,
98627
+ amount: vesuAmountDifference
98628
+ },
98629
+ extendedAdapter,
98630
+ vesuAdapter
98631
+ );
98632
+ if (!vesuStatus) {
98633
+ logger2.error(`Failed to move assets to vesu - operation returned false status`);
98634
+ return [];
98635
+ }
98636
+ calls.push(...vesuCalls);
98637
+ } catch (err2) {
98638
+ logger2.error(`Failed moving assets to vault: ${err2}`);
98350
98639
  return [];
98351
98640
  }
98352
- calls.push(...vesuCalls);
98353
- } catch (err2) {
98354
- logger2.error(`Failed moving assets to vault: ${err2}`);
98355
98641
  }
98356
98642
  }
98357
98643
  return calls;
@@ -98362,6 +98648,38 @@ spurious results.`);
98362
98648
  }
98363
98649
  async moveAssets(params, extendedAdapter, vesuAdapter) {
98364
98650
  try {
98651
+ if (params.amount.lessThanOrEqualTo(0)) {
98652
+ logger2.error(
98653
+ `Invalid amount for moveAssets: ${params.amount.toNumber()}. Amount must be positive.`
98654
+ );
98655
+ return {
98656
+ calls: [],
98657
+ status: false
98658
+ };
98659
+ }
98660
+ const amountAbs = params.amount.abs();
98661
+ if (params.from === Protocols.EXTENDED.name || params.to === Protocols.EXTENDED.name) {
98662
+ if (amountAbs.lessThanOrEqualTo(extendedAdapter.minimumExtendedMovementAmount)) {
98663
+ logger2.warn(
98664
+ `Amount ${amountAbs.toNumber()} is below minimum Extended movement amount ${extendedAdapter.minimumExtendedMovementAmount}. Skipping operation.`
98665
+ );
98666
+ return {
98667
+ calls: [],
98668
+ status: false
98669
+ };
98670
+ }
98671
+ }
98672
+ if (params.from === Protocols.VESU.name || params.to === Protocols.VESU.name) {
98673
+ if (amountAbs.lessThanOrEqualTo(vesuAdapter.minimumVesuMovementAmount)) {
98674
+ logger2.warn(
98675
+ `Amount ${amountAbs.toNumber()} is below minimum Vesu movement amount ${vesuAdapter.minimumVesuMovementAmount}. Skipping operation.`
98676
+ );
98677
+ return {
98678
+ calls: [],
98679
+ status: false
98680
+ };
98681
+ }
98682
+ }
98365
98683
  const avnuAdapter = await this.getAvnuAdapter();
98366
98684
  if (!avnuAdapter) {
98367
98685
  logger2.error(`avnu adapter not found: ${avnuAdapter}`);
@@ -98422,12 +98740,13 @@ spurious results.`);
98422
98740
  );
98423
98741
  if (!openLongPosition) {
98424
98742
  logger2.error(`error opening long position: ${openLongPosition}`);
98425
- return {
98426
- calls: [],
98427
- status: false
98428
- };
98429
98743
  }
98430
98744
  await new Promise((resolve) => setTimeout(resolve, 5e3));
98745
+ const updatedHoldings = await extendedAdapter.getExtendedDepositAmount();
98746
+ if (!updatedHoldings || new Web3Number(updatedHoldings.availableForWithdrawal, USDC_TOKEN_DECIMALS).lessThan(params.amount.abs())) {
98747
+ logger2.error(`Insufficient balance after opening position. Available: ${updatedHoldings?.availableForWithdrawal}, Needed: ${params.amount.abs()}`);
98748
+ return { calls: [], status: false };
98749
+ }
98431
98750
  }
98432
98751
  const withdrawalFromExtended = await extendedAdapter.withdrawFromExtended(params.amount);
98433
98752
  if (withdrawalFromExtended) {