@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.mjs CHANGED
@@ -29930,8 +29930,47 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29930
29930
  async withdrawFromExtended(amount) {
29931
29931
  try {
29932
29932
  if (!this.client) {
29933
- throw new Error("Client not initialized");
29933
+ logger.error("Client not initialized");
29934
+ return false;
29935
+ }
29936
+ if (amount.lessThanOrEqualTo(0)) {
29937
+ logger.error(
29938
+ `Invalid withdrawal amount: ${amount.toNumber()}. Amount must be positive.`
29939
+ );
29940
+ return false;
29941
+ }
29942
+ if (amount.lessThanOrEqualTo(this.minimumExtendedMovementAmount)) {
29943
+ logger.warn(
29944
+ `Withdrawal amount ${amount.toNumber()} is below minimum Extended movement amount ${this.minimumExtendedMovementAmount}. Skipping withdrawal.`
29945
+ );
29946
+ return false;
29947
+ }
29948
+ const holdings = await this.getExtendedDepositAmount();
29949
+ if (!holdings) {
29950
+ logger.error(
29951
+ "Cannot get holdings - unable to validate withdrawal amount"
29952
+ );
29953
+ return false;
29954
+ }
29955
+ const availableForWithdrawal = parseFloat(
29956
+ holdings.availableForWithdrawal
29957
+ );
29958
+ if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
29959
+ logger.error(
29960
+ `Invalid availableForWithdrawal: ${holdings.availableForWithdrawal}. Expected a finite, non-negative number.`
29961
+ );
29962
+ return false;
29963
+ }
29964
+ const withdrawalAmount = amount.toNumber();
29965
+ if (withdrawalAmount > availableForWithdrawal) {
29966
+ logger.error(
29967
+ `Withdrawal amount ${withdrawalAmount} exceeds available balance ${availableForWithdrawal}`
29968
+ );
29969
+ return false;
29934
29970
  }
29971
+ logger.info(
29972
+ `Withdrawing ${withdrawalAmount} from Extended. Available balance: ${availableForWithdrawal}`
29973
+ );
29935
29974
  const withdrawalRequest = await this.client.withdrawUSDC(
29936
29975
  amount.toFixed(2)
29937
29976
  );
@@ -29942,6 +29981,9 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29942
29981
  );
29943
29982
  return withdrawalStatus;
29944
29983
  }
29984
+ logger.error(
29985
+ `Withdrawal request failed with status: ${withdrawalRequest.status}`
29986
+ );
29945
29987
  return false;
29946
29988
  } catch (error) {
29947
29989
  logger.error(`Error creating Withdraw Call: ${error}`);
@@ -29952,21 +29994,44 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29952
29994
  return Promise.resolve(1);
29953
29995
  }
29954
29996
  async getExtendedDepositAmount() {
29955
- if (this.client === null) {
29956
- logger.error("error initializing client");
29957
- return void 0;
29958
- }
29959
- const result = await this.client.getHoldings();
29960
- if (!result) {
29961
- logger.error(`error getting holdings: ${result}`);
29962
- return void 0;
29963
- }
29964
- const holdings = result.data;
29965
- if (!holdings) {
29966
- logger.error(`error getting holdings: ${holdings}`);
29997
+ try {
29998
+ if (this.client === null) {
29999
+ logger.error("error initializing client - client is null");
30000
+ return void 0;
30001
+ }
30002
+ const result = await this.client.getHoldings();
30003
+ if (!result) {
30004
+ logger.error("error getting holdings - API returned null/undefined");
30005
+ return void 0;
30006
+ }
30007
+ if (result.status && result.status !== "OK") {
30008
+ logger.error(
30009
+ `error getting holdings - API returned status: ${result.status}`
30010
+ );
30011
+ return void 0;
30012
+ }
30013
+ const holdings = result.data;
30014
+ if (!holdings) {
30015
+ logger.warn(
30016
+ "holdings data is null/undefined - treating as zero balance"
30017
+ );
30018
+ return {
30019
+ collateral_name: "",
30020
+ balance: "0",
30021
+ equity: "0",
30022
+ availableForTrade: "0",
30023
+ availableForWithdrawal: "0",
30024
+ unrealisedPnl: "0",
30025
+ initialMargin: "0",
30026
+ marginRatio: "0",
30027
+ updatedTime: Date.now()
30028
+ };
30029
+ }
30030
+ return holdings;
30031
+ } catch (error) {
30032
+ logger.error(`error getting holdings - exception: ${error}`);
29967
30033
  return void 0;
29968
30034
  }
29969
- return holdings;
29970
30035
  }
29971
30036
  async setLeverage(leverage, marketName) {
29972
30037
  if (this.client === null) {
@@ -30008,38 +30073,24 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30008
30073
  return result.data;
30009
30074
  }
30010
30075
  async getOrderStatus(orderId, marketName) {
30011
- if (this.client === null) {
30012
- logger.error("error initializing client");
30013
- return null;
30014
- }
30015
- let orderhistory = await this.getOrderHistory(marketName);
30016
- if (!orderhistory || orderhistory.length === 0) {
30017
- logger.error(`error getting order history: ${orderId}`);
30018
- } else {
30019
- const order = orderhistory.slice(0, 10).find((order2) => order2.id.toString() === orderId);
30020
- if (order) {
30021
- return order;
30076
+ try {
30077
+ if (this.client === null) {
30078
+ logger.error("error initializing client");
30079
+ return null;
30022
30080
  }
30023
- }
30024
- for (let attempt = 1; attempt <= 5; attempt++) {
30025
- await new Promise((resolve) => setTimeout(resolve, this.retryDelayForOrderStatus));
30026
- orderhistory = await this.getOrderHistory(marketName);
30081
+ const orderhistory = await this.getOrderHistory(marketName);
30027
30082
  if (!orderhistory || orderhistory.length === 0) {
30028
- logger.error(
30029
- `error getting order history on retry ${attempt}: ${orderId}`
30030
- );
30031
- continue;
30083
+ return null;
30032
30084
  }
30033
- const order = orderhistory.slice(0, 5).find((order2) => order2.id.toString() === orderId);
30034
- if (order && order.status === "FILLED" /* FILLED */) {
30085
+ const order = orderhistory.slice(0, 20).find((order2) => order2.id.toString() === orderId);
30086
+ if (order) {
30035
30087
  return order;
30036
30088
  }
30037
- logger.error(
30038
- `order not found in top 15 entries on retry ${attempt}: ${orderId}`
30039
- );
30089
+ return null;
30090
+ } catch (error) {
30091
+ logger.error(`error getting order status: ${error}`);
30092
+ return null;
30040
30093
  }
30041
- logger.error(`error getting order after all retries: ${orderId}`);
30042
- return null;
30043
30094
  }
30044
30095
  async fetchOrderBookBTCUSDC() {
30045
30096
  try {
@@ -30090,14 +30141,40 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30090
30141
  logger.error("error depositing or setting leverage");
30091
30142
  return null;
30092
30143
  }
30093
- const positions = await this.getAllOpenPositions();
30094
- if (positions === null) {
30144
+ const { ask, bid } = await this.fetchOrderBookBTCUSDC();
30145
+ if (!ask || !bid || ask.lessThanOrEqualTo(0) || bid.lessThanOrEqualTo(0)) {
30146
+ logger.error(
30147
+ `Invalid orderbook prices: ask=${ask?.toNumber()}, bid=${bid?.toNumber()}`
30148
+ );
30095
30149
  return null;
30096
30150
  }
30097
- const { ask, bid } = await this.fetchOrderBookBTCUSDC();
30098
30151
  const spread = ask.minus(bid);
30099
- let price = ask.plus(bid).div(2);
30100
- side === "SELL" /* SELL */ ? price = price.minus(spread.times(0.2 * attempt)) : price = price.plus(spread.times(0.2 * attempt));
30152
+ const midPrice = ask.plus(bid).div(2);
30153
+ const MAX_PRICE_DEVIATION_MULTIPLIER = 0.5;
30154
+ const priceAdjustmentMultiplier = Math.min(
30155
+ 0.2 * attempt,
30156
+ MAX_PRICE_DEVIATION_MULTIPLIER
30157
+ );
30158
+ const priceAdjustment = spread.times(priceAdjustmentMultiplier);
30159
+ let price = midPrice;
30160
+ if (side === "SELL" /* SELL */) {
30161
+ price = midPrice.minus(priceAdjustment);
30162
+ } else {
30163
+ price = midPrice.plus(priceAdjustment);
30164
+ }
30165
+ const maxDeviation = midPrice.times(0.5);
30166
+ if (price.minus(midPrice).abs().greaterThan(maxDeviation)) {
30167
+ logger.error(
30168
+ `Price deviation too large on attempt ${attempt}: price=${price.toNumber()}, midPrice=${midPrice.toNumber()}, deviation=${price.minus(midPrice).abs().toNumber()}`
30169
+ );
30170
+ if (attempt >= maxAttempts) {
30171
+ return null;
30172
+ }
30173
+ price = side === "SELL" /* SELL */ ? midPrice.minus(maxDeviation) : midPrice.plus(maxDeviation);
30174
+ }
30175
+ logger.info(
30176
+ `createOrder attempt ${attempt}/${maxAttempts}: side=${side}, midPrice=${midPrice.toNumber()}, adjustedPrice=${price.toNumber()}, adjustment=${priceAdjustmentMultiplier * 100}%`
30177
+ );
30101
30178
  const amount_in_token = (btcAmount * parseInt(leverage)).toFixed(
30102
30179
  this.config.extendedPrecision
30103
30180
  );
@@ -30108,17 +30185,57 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30108
30185
  price.toFixed(0),
30109
30186
  side
30110
30187
  );
30111
- if (!result) {
30188
+ if (!result || !result.position_id) {
30189
+ logger.error("Failed to create order - no position_id returned");
30112
30190
  return null;
30113
30191
  }
30114
- await new Promise((resolve) => setTimeout(resolve, 5e3));
30115
- const openOrder = await this.getOrderStatus(
30116
- result.position_id,
30192
+ const positionId = result.position_id;
30193
+ logger.info(
30194
+ `Order created with position_id: ${positionId}. Waiting for API to update...`
30195
+ );
30196
+ let openOrder = await this.getOrderStatus(
30197
+ positionId,
30117
30198
  this.config.extendedMarketName
30118
30199
  );
30200
+ const maxStatusRetries = 3;
30201
+ const statusRetryDelay = 5e3;
30119
30202
  if (!openOrder) {
30203
+ logger.warn(
30204
+ `Order ${positionId} not found in API yet. Retrying status fetch (max ${maxStatusRetries} times)...`
30205
+ );
30206
+ for (let statusRetry = 1; statusRetry <= maxStatusRetries; statusRetry++) {
30207
+ await new Promise((resolve) => setTimeout(resolve, statusRetryDelay));
30208
+ openOrder = await this.getOrderStatus(
30209
+ positionId,
30210
+ this.config.extendedMarketName
30211
+ );
30212
+ if (openOrder) {
30213
+ logger.info(
30214
+ `Order ${positionId} found after ${statusRetry} status retry(ies)`
30215
+ );
30216
+ break;
30217
+ }
30218
+ logger.warn(
30219
+ `Order ${positionId} still not found after ${statusRetry}/${maxStatusRetries} status retries`
30220
+ );
30221
+ }
30222
+ }
30223
+ if (openOrder && openOrder.status === "FILLED" /* FILLED */) {
30224
+ logger.info(
30225
+ `Order ${positionId} successfully filled with quantity ${openOrder.qty}`
30226
+ );
30227
+ return {
30228
+ position_id: positionId,
30229
+ btc_exposure: openOrder.qty
30230
+ };
30231
+ } else if (openOrder && openOrder.status !== "FILLED" /* FILLED */) {
30232
+ logger.warn(
30233
+ `Order ${positionId} found but status is ${openOrder.status}, not FILLED. Retrying order creation...`
30234
+ );
30120
30235
  if (attempt >= maxAttempts) {
30121
- logger.error("Max retries reached \u2014 could not verify open position");
30236
+ logger.error(
30237
+ `Max retries reached \u2014 order ${positionId} status is ${openOrder.status}, not FILLED`
30238
+ );
30122
30239
  return null;
30123
30240
  } else {
30124
30241
  const backoff = 2e3 * attempt;
@@ -30132,9 +30249,12 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
30132
30249
  );
30133
30250
  }
30134
30251
  } else {
30252
+ logger.warn(
30253
+ `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.`
30254
+ );
30135
30255
  return {
30136
- position_id: result.position_id,
30137
- btc_exposure: openOrder.qty
30256
+ position_id: positionId,
30257
+ btc_exposure: amount_in_token
30138
30258
  };
30139
30259
  }
30140
30260
  } catch (err) {
@@ -34154,11 +34274,27 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34154
34274
  }
34155
34275
  async shouldInvest() {
34156
34276
  try {
34277
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest starting`);
34157
34278
  const vesuAdapter = await this.getVesuAdapter();
34158
34279
  const extendedAdapter = await this.getExtendedAdapter();
34159
- if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
34280
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest adapters fetched: vesuAdapter=${!!vesuAdapter}, extendedAdapter=${!!extendedAdapter}, extendedAdapter.client=${!!extendedAdapter?.client}`);
34281
+ if (!vesuAdapter) {
34160
34282
  logger.error(
34161
- `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
34283
+ `Vesu adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
34284
+ );
34285
+ return {
34286
+ shouldInvest: false,
34287
+ vesuAmount: new Web3Number(0, 0),
34288
+ extendedAmount: new Web3Number(0, 0),
34289
+ extendedLeverage: 0,
34290
+ collateralPrice: 0,
34291
+ debtPrice: 0,
34292
+ vesuLeverage: 0
34293
+ };
34294
+ }
34295
+ if (!extendedAdapter) {
34296
+ logger.error(
34297
+ `Extended adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
34162
34298
  );
34163
34299
  return {
34164
34300
  shouldInvest: false,
@@ -34170,10 +34306,72 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34170
34306
  vesuLeverage: 0
34171
34307
  };
34172
34308
  }
34309
+ if (!extendedAdapter.client) {
34310
+ logger.error(
34311
+ `Extended adapter client not initialized. This may be a temporary initialization failure - check network connectivity and API availability.`
34312
+ );
34313
+ return {
34314
+ shouldInvest: false,
34315
+ vesuAmount: new Web3Number(0, 0),
34316
+ extendedAmount: new Web3Number(0, 0),
34317
+ extendedLeverage: 0,
34318
+ collateralPrice: 0,
34319
+ debtPrice: 0,
34320
+ vesuLeverage: 0
34321
+ };
34322
+ }
34323
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest calling getUnusedBalance`);
34173
34324
  const balance = await this.getUnusedBalance();
34325
+ if (!Number.isFinite(balance.usdValue) || balance.usdValue < 0) {
34326
+ logger.error(
34327
+ `Invalid balance.usdValue: ${balance.usdValue}. Expected a finite, non-negative number.`
34328
+ );
34329
+ return {
34330
+ shouldInvest: false,
34331
+ vesuAmount: new Web3Number(0, 0),
34332
+ extendedAmount: new Web3Number(0, 0),
34333
+ extendedLeverage: 0,
34334
+ collateralPrice: 0,
34335
+ debtPrice: 0,
34336
+ vesuLeverage: 0
34337
+ };
34338
+ }
34339
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest balance: ${balance.usdValue}`);
34174
34340
  const usdcBalanceOnExtended = await extendedAdapter.getExtendedDepositAmount();
34341
+ if (usdcBalanceOnExtended) {
34342
+ const availableForWithdrawal = parseFloat(usdcBalanceOnExtended.availableForWithdrawal);
34343
+ if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
34344
+ logger.error(
34345
+ `Invalid usdcBalanceOnExtended.availableForWithdrawal: ${usdcBalanceOnExtended.availableForWithdrawal}. Expected a finite, non-negative number.`
34346
+ );
34347
+ return {
34348
+ shouldInvest: false,
34349
+ vesuAmount: new Web3Number(0, 0),
34350
+ extendedAmount: new Web3Number(0, 0),
34351
+ extendedLeverage: 0,
34352
+ collateralPrice: 0,
34353
+ debtPrice: 0,
34354
+ vesuLeverage: 0
34355
+ };
34356
+ }
34357
+ }
34175
34358
  const amountToInvest = new Web3Number(balance.usdValue, USDC_TOKEN_DECIMALS).plus(usdcBalanceOnExtended?.availableForWithdrawal ?? 0).multipliedBy(1 - LIMIT_BALANCE);
34176
- logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvest.toNumber()}`);
34359
+ const amountToInvestNumber = amountToInvest.toNumber();
34360
+ if (!Number.isFinite(amountToInvestNumber)) {
34361
+ logger.error(
34362
+ `Invalid amountToInvest calculation result: ${amountToInvestNumber}. Calculation may have produced NaN or Infinity.`
34363
+ );
34364
+ return {
34365
+ shouldInvest: false,
34366
+ vesuAmount: new Web3Number(0, 0),
34367
+ extendedAmount: new Web3Number(0, 0),
34368
+ extendedLeverage: 0,
34369
+ collateralPrice: 0,
34370
+ debtPrice: 0,
34371
+ vesuLeverage: 0
34372
+ };
34373
+ }
34374
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvestNumber}`);
34177
34375
  if (amountToInvest.lessThan(0)) {
34178
34376
  return {
34179
34377
  shouldInvest: false,
@@ -34203,6 +34401,34 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34203
34401
  collateralPrice,
34204
34402
  debtPrice
34205
34403
  } = await this.getAssetPrices();
34404
+ if (!Number.isFinite(collateralPrice.price) || collateralPrice.price <= 0) {
34405
+ logger.error(
34406
+ `Invalid collateralPrice: ${collateralPrice.price}. Expected a finite, positive number.`
34407
+ );
34408
+ return {
34409
+ shouldInvest: false,
34410
+ vesuAmount: new Web3Number(0, 0),
34411
+ extendedAmount: new Web3Number(0, 0),
34412
+ extendedLeverage: 0,
34413
+ collateralPrice: 0,
34414
+ debtPrice: 0,
34415
+ vesuLeverage: 0
34416
+ };
34417
+ }
34418
+ if (!Number.isFinite(debtPrice.price) || debtPrice.price <= 0) {
34419
+ logger.error(
34420
+ `Invalid debtPrice: ${debtPrice.price}. Expected a finite, positive number.`
34421
+ );
34422
+ return {
34423
+ shouldInvest: false,
34424
+ vesuAmount: new Web3Number(0, 0),
34425
+ extendedAmount: new Web3Number(0, 0),
34426
+ extendedLeverage: 0,
34427
+ collateralPrice: 0,
34428
+ debtPrice: 0,
34429
+ vesuLeverage: 0
34430
+ };
34431
+ }
34206
34432
  const { vesu_amount, extended_amount, extended_leverage, vesu_leverage } = await calculateAmountDistribution(
34207
34433
  amountToInvest.toNumber(),
34208
34434
  extendedAdapter.client,
@@ -34253,13 +34479,45 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34253
34479
  try {
34254
34480
  const vesuAdapter = await this.getVesuAdapter();
34255
34481
  const extendedAdapter = await this.getExtendedAdapter();
34256
- let calls = [];
34257
34482
  if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
34258
34483
  logger.error(
34259
34484
  `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
34260
34485
  );
34261
- return calls;
34486
+ return [];
34487
+ }
34488
+ const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
34489
+ if (!extendedHoldings) {
34490
+ logger.error(`error getting extended holdings: ${extendedHoldings}`);
34491
+ return [];
34262
34492
  }
34493
+ const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
34494
+ const usdcAmountOnExtendedAvailableForWithdrawal = parseFloat(
34495
+ extendedHoldings.availableForWithdrawal
34496
+ );
34497
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldMoveAssets calculating movements - Extended current: ${usdcAmountOnExtendedAvailableForWithdrawal}, Wallet: ${usdcAmountInWallet.toNumber()}, Target Extended: ${extendedAmount.toNumber()}, Target Vesu: ${vesuAmount.toNumber()}`);
34498
+ let totalExtendedWithdrawal = new Web3Number(0, USDC_TOKEN_DECIMALS);
34499
+ let totalExtendedDeposit = new Web3Number(0, USDC_TOKEN_DECIMALS);
34500
+ if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34501
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmount.abs());
34502
+ }
34503
+ const extendedTargetAmount = extendedAmount.abs();
34504
+ let projectedExtendedBalance = usdcAmountOnExtendedAvailableForWithdrawal;
34505
+ if (extendedAmount.isNegative()) {
34506
+ projectedExtendedBalance = projectedExtendedBalance - extendedAmount.abs().toNumber();
34507
+ }
34508
+ const extendedAmountDifference = extendedTargetAmount.minus(projectedExtendedBalance);
34509
+ const extendedAmountDifferenceAbs = extendedAmountDifference.abs();
34510
+ if (extendedAmountDifference.lessThan(0)) {
34511
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmountDifferenceAbs);
34512
+ } else if (extendedAmountDifference.greaterThan(0)) {
34513
+ totalExtendedDeposit = totalExtendedDeposit.plus(extendedAmountDifference);
34514
+ }
34515
+ const vesuTargetAmount = vesuAmount.abs();
34516
+ const projectedWalletBalance = usdcAmountInWallet.plus(totalExtendedWithdrawal).minus(totalExtendedDeposit);
34517
+ let vesuAmountDifference = vesuTargetAmount.minus(projectedWalletBalance);
34518
+ const vesuAmountDifferenceAbs = vesuAmountDifference.abs();
34519
+ 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()}`);
34520
+ let calls = [];
34263
34521
  if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34264
34522
  try {
34265
34523
  const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
@@ -34280,7 +34538,7 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34280
34538
  logger.error(`Failed moving assets to vault: ${err}`);
34281
34539
  }
34282
34540
  }
34283
- if (vesuAmount.isNegative() && vesuAmount.lessThan(vesuAdapter.minimumVesuMovementAmount)) {
34541
+ if (vesuAmount.isNegative() && vesuAmount.abs().greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
34284
34542
  try {
34285
34543
  const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
34286
34544
  {
@@ -34299,48 +34557,76 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34299
34557
  logger.error(`Failed moving assets to vault: ${err}`);
34300
34558
  }
34301
34559
  }
34302
- const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
34303
- if (!extendedHoldings) {
34304
- logger.error(`error getting extended holdings: ${extendedHoldings}`);
34305
- return calls;
34306
- }
34307
- const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
34308
- const usdcAmountOnExtended = parseFloat(
34309
- extendedHoldings.availableForWithdrawal
34310
- );
34311
- if (extendedAmount.minus(usdcAmountOnExtended).greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34312
- try {
34313
- const { calls: extendedCalls } = await this.moveAssets(
34314
- {
34315
- to: Protocols.EXTENDED.name,
34316
- from: Protocols.VAULT.name,
34317
- amount: extendedAmount.minus(usdcAmountOnExtended)
34318
- },
34319
- extendedAdapter,
34320
- vesuAdapter
34321
- );
34322
- calls.push(...extendedCalls);
34323
- } catch (err) {
34324
- logger.error(`Failed moving assets to extended: ${err}`);
34560
+ if (extendedAmountDifferenceAbs.greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34561
+ if (extendedAmountDifference.greaterThan(0)) {
34562
+ try {
34563
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
34564
+ {
34565
+ to: Protocols.EXTENDED.name,
34566
+ from: Protocols.VAULT.name,
34567
+ amount: extendedAmountDifference
34568
+ },
34569
+ extendedAdapter,
34570
+ vesuAdapter
34571
+ );
34572
+ if (extendedStatus) {
34573
+ calls.push(...extendedCalls);
34574
+ } else {
34575
+ logger.error(`Failed to move assets to extended - operation returned false status`);
34576
+ return [];
34577
+ }
34578
+ } catch (err) {
34579
+ logger.error(`Failed moving assets to extended: ${err}`);
34580
+ return [];
34581
+ }
34582
+ } else if (extendedAmountDifference.lessThan(0)) {
34583
+ try {
34584
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
34585
+ {
34586
+ to: Protocols.VAULT.name,
34587
+ from: Protocols.EXTENDED.name,
34588
+ amount: extendedAmountDifferenceAbs
34589
+ },
34590
+ extendedAdapter,
34591
+ vesuAdapter
34592
+ );
34593
+ if (extendedStatus) {
34594
+ calls.push(...extendedCalls);
34595
+ } else {
34596
+ logger.error(`Failed to withdraw from extended - operation returned false status`);
34597
+ return [];
34598
+ }
34599
+ } catch (err) {
34600
+ logger.error(`Failed moving assets from extended to vault: ${err}`);
34601
+ return [];
34602
+ }
34325
34603
  }
34326
34604
  }
34327
- if (vesuAmount.minus(usdcAmountInWallet).greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
34328
- try {
34329
- const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
34330
- {
34331
- to: Protocols.VAULT.name,
34332
- from: Protocols.EXTENDED.name,
34333
- amount: vesuAmount.minus(usdcAmountInWallet)
34334
- },
34335
- extendedAdapter,
34336
- vesuAdapter
34605
+ if (vesuAmountDifferenceAbs.greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
34606
+ if (vesuAmountDifference.lessThanOrEqualTo(0)) {
34607
+ logger.warn(
34608
+ `Vesu amount difference is negative or zero: ${vesuAmountDifference.toNumber()}. Skipping operation.`
34337
34609
  );
34338
- if (!vesuStatus) {
34610
+ } else {
34611
+ try {
34612
+ const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
34613
+ {
34614
+ to: Protocols.VAULT.name,
34615
+ from: Protocols.EXTENDED.name,
34616
+ amount: vesuAmountDifference
34617
+ },
34618
+ extendedAdapter,
34619
+ vesuAdapter
34620
+ );
34621
+ if (!vesuStatus) {
34622
+ logger.error(`Failed to move assets to vesu - operation returned false status`);
34623
+ return [];
34624
+ }
34625
+ calls.push(...vesuCalls);
34626
+ } catch (err) {
34627
+ logger.error(`Failed moving assets to vault: ${err}`);
34339
34628
  return [];
34340
34629
  }
34341
- calls.push(...vesuCalls);
34342
- } catch (err) {
34343
- logger.error(`Failed moving assets to vault: ${err}`);
34344
34630
  }
34345
34631
  }
34346
34632
  return calls;
@@ -34351,6 +34637,38 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34351
34637
  }
34352
34638
  async moveAssets(params, extendedAdapter, vesuAdapter) {
34353
34639
  try {
34640
+ if (params.amount.lessThanOrEqualTo(0)) {
34641
+ logger.error(
34642
+ `Invalid amount for moveAssets: ${params.amount.toNumber()}. Amount must be positive.`
34643
+ );
34644
+ return {
34645
+ calls: [],
34646
+ status: false
34647
+ };
34648
+ }
34649
+ const amountAbs = params.amount.abs();
34650
+ if (params.from === Protocols.EXTENDED.name || params.to === Protocols.EXTENDED.name) {
34651
+ if (amountAbs.lessThanOrEqualTo(extendedAdapter.minimumExtendedMovementAmount)) {
34652
+ logger.warn(
34653
+ `Amount ${amountAbs.toNumber()} is below minimum Extended movement amount ${extendedAdapter.minimumExtendedMovementAmount}. Skipping operation.`
34654
+ );
34655
+ return {
34656
+ calls: [],
34657
+ status: false
34658
+ };
34659
+ }
34660
+ }
34661
+ if (params.from === Protocols.VESU.name || params.to === Protocols.VESU.name) {
34662
+ if (amountAbs.lessThanOrEqualTo(vesuAdapter.minimumVesuMovementAmount)) {
34663
+ logger.warn(
34664
+ `Amount ${amountAbs.toNumber()} is below minimum Vesu movement amount ${vesuAdapter.minimumVesuMovementAmount}. Skipping operation.`
34665
+ );
34666
+ return {
34667
+ calls: [],
34668
+ status: false
34669
+ };
34670
+ }
34671
+ }
34354
34672
  const avnuAdapter = await this.getAvnuAdapter();
34355
34673
  if (!avnuAdapter) {
34356
34674
  logger.error(`avnu adapter not found: ${avnuAdapter}`);
@@ -34411,12 +34729,13 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34411
34729
  );
34412
34730
  if (!openLongPosition) {
34413
34731
  logger.error(`error opening long position: ${openLongPosition}`);
34414
- return {
34415
- calls: [],
34416
- status: false
34417
- };
34418
34732
  }
34419
34733
  await new Promise((resolve) => setTimeout(resolve, 5e3));
34734
+ const updatedHoldings = await extendedAdapter.getExtendedDepositAmount();
34735
+ if (!updatedHoldings || new Web3Number(updatedHoldings.availableForWithdrawal, USDC_TOKEN_DECIMALS).lessThan(params.amount.abs())) {
34736
+ logger.error(`Insufficient balance after opening position. Available: ${updatedHoldings?.availableForWithdrawal}, Needed: ${params.amount.abs()}`);
34737
+ return { calls: [], status: false };
34738
+ }
34420
34739
  }
34421
34740
  const withdrawalFromExtended = await extendedAdapter.withdrawFromExtended(params.amount);
34422
34741
  if (withdrawalFromExtended) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strkfarm/sdk",
3
- "version": "2.0.0-dev.7",
3
+ "version": "2.0.0-dev.8",
4
4
  "description": "STRKFarm TS SDK (Meant for our internal use, but feel free to use it)",
5
5
  "typings": "dist/index.d.ts",
6
6
  "types": "dist/index.d.ts",