@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.
@@ -28684,6 +28684,7 @@ ${r2}}` : "}", l2;
28684
28684
  OrderType: () => OrderType,
28685
28685
  PRICE_ROUTER: () => PRICE_ROUTER,
28686
28686
  PositionSide: () => PositionSide,
28687
+ PositionTypeAvnuExtended: () => PositionTypeAvnuExtended,
28687
28688
  Pragma: () => Pragma,
28688
28689
  Pricer: () => Pricer,
28689
28690
  PricerBase: () => PricerBase,
@@ -55997,20 +55998,13 @@ ${JSON.stringify(data, null, 2)}`;
55997
55998
  async getDexPrice(baseToken, quoteToken, amount) {
55998
55999
  const lstTokenInfo = baseToken;
55999
56000
  const lstUnderlyingTokenInfo = quoteToken;
56000
- console.log("lstTokenInfo", lstTokenInfo);
56001
- console.log("lstUnderlyingTokenInfo", lstUnderlyingTokenInfo);
56002
- console.log("amount", amount);
56003
56001
  const quote = await this.getQuote(
56004
56002
  lstTokenInfo.address.address,
56005
56003
  lstUnderlyingTokenInfo.address.address,
56006
56004
  amount
56007
56005
  );
56008
- console.log("quote", quote);
56009
56006
  const outputAmount = Web3Number.fromWei(quote.total_calculated, lstUnderlyingTokenInfo.decimals);
56010
- console.log("outputAmount", outputAmount);
56011
- console.log("amount", amount);
56012
56007
  const price = outputAmount.toNumber() / amount.toNumber();
56013
- console.log("price", price);
56014
56008
  logger2.verbose(`${_EkuboQuoter.name}:: LST Dex Price: ${price}`);
56015
56009
  return price;
56016
56010
  }
@@ -56029,16 +56023,12 @@ ${JSON.stringify(data, null, 2)}`;
56029
56023
  // debt collateral
56030
56024
  async getSwapLimitAmount(fromToken, toToken, amount, max_slippage = 2e-3) {
56031
56025
  const isExactAmountIn = amount.greaterThanOrEqualTo(0);
56032
- console.log("isExactAmountIn", isExactAmountIn);
56033
56026
  logger2.verbose(`${_EkuboQuoter.name}::getSwapLimitAmount isExactAmountIn: ${isExactAmountIn}, fromToken: ${fromToken.symbol}, toToken: ${toToken.symbol}, amount: ${amount}`);
56034
56027
  const isYieldToken = this.tokenMarketData.isAPYSupported(toToken);
56035
56028
  console.log("isYieldToken", isYieldToken);
56036
56029
  const baseToken = isExactAmountIn ? toToken : fromToken;
56037
56030
  const quoteToken = isExactAmountIn ? fromToken : toToken;
56038
- console.log("baseToken", baseToken);
56039
- console.log("quoteToken", quoteToken);
56040
56031
  const dexPrice = await this.getDexPrice(baseToken, quoteToken, amount);
56041
- console.log("dexPrice", dexPrice);
56042
56032
  const trueExchangeRate = isYieldToken ? await this.tokenMarketData.getTruePrice(baseToken) : dexPrice;
56043
56033
  console.log("trueExchangeRate", trueExchangeRate);
56044
56034
  if (isExactAmountIn) {
@@ -92375,6 +92365,7 @@ spurious results.`);
92375
92365
  var AVNU_API = "https://starknet.api.avnu.fi/swap/v2/quotes";
92376
92366
  var USDC_TOKEN_DECIMALS = 6;
92377
92367
  var USDC_TOKEN_ADDRESS = "0x053C91253BC9682c04929cA02ED00b3E423f6710D2ee7e0D5EBB06F3eCF368A8";
92368
+ var BUFFER_USDC_IN_WITHDRAWAL = 5;
92378
92369
  var WBTC_TOKEN_ADDRESS = "0x3fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac";
92379
92370
  var WBTC_TOKEN_DECIMALS = 8;
92380
92371
  var MAINTENANCE_MARGIN = 0.01;
@@ -92390,7 +92381,8 @@ spurious results.`);
92390
92381
  var MAX_RETRIES = Number(process.env.MAX_RETRIES ?? 3);
92391
92382
  var MAX_DELAY = Number(process.env.MAX_DELAY ?? 100);
92392
92383
  var EXTEND_MARKET_NAME = "BTC-USD";
92393
- var LIMIT_BALANCE = Number(process.env.LIMIT_BALANCE ?? 10);
92384
+ var LIMIT_BALANCE = Number(process.env.LIMIT_BALANCE ?? 0.05);
92385
+ var LIMIT_BALANCE_VALUE = 10;
92394
92386
  var REBALANCER_INTERVAL = Number(process.env.REBALANCER_INTERVAL ?? 18e4);
92395
92387
  var WITHDRAWAL_INTERVAL = Number(process.env.WITHDRAWAL_INTERVAL ?? 18e6);
92396
92388
  var INVESTING_INTERVAL = Number(process.env.INVESTING_INTERVAL ?? 18e4);
@@ -92408,8 +92400,6 @@ spurious results.`);
92408
92400
  var MINIMUM_DEBT_AMOUNT_VESU_FOR_REBALANCING = Number(process.env.MINIMUM_DEBT_AMOUNT_VESU_FOR_REBALANCING ?? 1);
92409
92401
  var MINIMUM_EXTENDED_POSITION_SIZE = 1e-4;
92410
92402
  var MINIMUM_WBTC_DIFFERENCE_FOR_AVNU_SWAP = 1e-5;
92411
- var MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED = 700;
92412
- var MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED = -100;
92413
92403
 
92414
92404
  // src/strategies/vesu-extended-strategy/utils/helper.ts
92415
92405
  var returnFormattedAmount = (amount, toTokenDecimals) => {
@@ -92429,8 +92419,7 @@ spurious results.`);
92429
92419
  vesu_leverage: 0
92430
92420
  };
92431
92421
  }
92432
- const extendedBTCExposure = extendedPosition.length > 0 ? new Web3Number(extendedPosition[0].size, WBTC_TOKEN_DECIMALS) : new Web3Number(0, WBTC_TOKEN_DECIMALS);
92433
- const extendedExposureUSD = extendedBTCExposure.multipliedBy(collateralPrice);
92422
+ const extendedExposureUSD = extendedPosition.length > 0 ? new Web3Number(extendedPosition[0].value, WBTC_TOKEN_DECIMALS) : new Web3Number(0, WBTC_TOKEN_DECIMALS);
92434
92423
  const vesuBTCExposureUSD = collateralUnits.multipliedBy(collateralPrice);
92435
92424
  const numerator1 = vesu_leverage * amount + vesuBTCExposureUSD.toNumber();
92436
92425
  const numerator2 = extendedExposureUSD.toNumber();
@@ -92466,8 +92455,7 @@ spurious results.`);
92466
92455
  logger2.error("error getting extended positions");
92467
92456
  return null;
92468
92457
  }
92469
- const extendedBTCExposure = extendedPosition.length > 0 ? new Web3Number(extendedPosition[0].size, WBTC_TOKEN_DECIMALS) : new Web3Number(0, WBTC_TOKEN_DECIMALS);
92470
- const extendedExposureUSD = extendedBTCExposure.multipliedBy(collateralPrice);
92458
+ const extendedExposureUSD = extendedPosition.length > 0 ? new Web3Number(extendedPosition[0].value, USDC_TOKEN_DECIMALS) : new Web3Number(0, USDC_TOKEN_DECIMALS);
92471
92459
  const vesuExposureUSD = collateralUnits.multipliedBy(collateralPrice);
92472
92460
  if (vesuExposureUSD.lessThan(0)) {
92473
92461
  return {
@@ -92485,9 +92473,14 @@ spurious results.`);
92485
92473
  vesu_leverage
92486
92474
  };
92487
92475
  }
92476
+ console.log("the vesu exposure usd is", vesuExposureUSD.toNumber());
92477
+ console.log("the extended exposure usd is", extendedExposureUSD.toNumber());
92478
+ console.log("the amount in usdc is", amountInUsdc.toNumber());
92479
+ console.log("the extended leverage is", extended_leverage);
92480
+ console.log("the vesu leverage is", vesu_leverage);
92488
92481
  const numerator1 = amountInUsdc.multipliedBy(extended_leverage);
92489
- const numerator2 = vesuExposureUSD.multipliedBy(vesu_leverage);
92490
- const numerator3 = extendedExposureUSD.multipliedBy(extended_leverage).multipliedBy(-1);
92482
+ const numerator2 = vesuExposureUSD;
92483
+ const numerator3 = extendedExposureUSD.multipliedBy(-1);
92491
92484
  const finalNumerator = numerator1.plus(numerator2).plus(numerator3);
92492
92485
  const denominator = extended_leverage + vesu_leverage;
92493
92486
  const vesuAmountInUSDC = finalNumerator.dividedBy(denominator);
@@ -92497,6 +92490,7 @@ spurious results.`);
92497
92490
  "the extended amount in usdc is",
92498
92491
  extendedAmountInUSDC.toNumber()
92499
92492
  );
92493
+ await new Promise((resolve) => setTimeout(resolve, 1e4));
92500
92494
  return {
92501
92495
  vesu_amount: vesuAmountInUSDC,
92502
92496
  extended_amount: extendedAmountInUSDC,
@@ -92518,10 +92512,10 @@ spurious results.`);
92518
92512
  const extended_leverage_max = 1 / (MAINTENANCE_MARGIN + MAX_PRICE_DROP_PERCENTAGE);
92519
92513
  return Math.floor(extended_leverage_max);
92520
92514
  };
92521
- var calculateDebtAmount = (collateralAmount, debtAmount, debtPrice, maxLtv = MAX_LTV_BTC_USDC, addedAmount, collateralPrice, isDeposit) => {
92515
+ var calculateDebtAmount = (collateralAmount, debtAmount, debtPrice, maxLtv = MAX_LIQUIDATION_RATIO, addedAmount, collateralPrice, isDeposit) => {
92522
92516
  try {
92523
- const marginAmount = addedAmount.multipliedBy(isDeposit ? 1 : -1);
92524
- const numerator1 = collateralAmount.plus(addedAmount).multipliedBy(collateralPrice).multipliedBy(maxLtv);
92517
+ const addedCollateral = addedAmount.multipliedBy(isDeposit ? 1 : -1);
92518
+ const numerator1 = collateralAmount.plus(addedCollateral).multipliedBy(collateralPrice).multipliedBy(maxLtv);
92525
92519
  const numerator2 = debtAmount.multipliedBy(debtPrice).multipliedBy(TARGET_HF);
92526
92520
  const denominator = TARGET_HF - maxLtv;
92527
92521
  const x_debt_usd = numerator1.minus(numerator2).dividedBy(denominator);
@@ -92556,16 +92550,16 @@ spurious results.`);
92556
92550
  const extendedHoldings = await client.getHoldings();
92557
92551
  const extended_leverage = calculateExtendedLevergae();
92558
92552
  const latestPosition = (await client.getPositions()).data.pop();
92559
- console.log("the latest position is", latestPosition, extendedHoldings);
92560
92553
  if (!extendedHoldings || !latestPosition) {
92561
92554
  logger2.error(`error getting extended position: extendedHoldings=${extendedHoldings}, latestPosition=${latestPosition}`);
92562
92555
  return null;
92563
92556
  }
92564
- const positionValueInUSD = latestPosition.value;
92557
+ const positionValueInUSD = new Web3Number(latestPosition.value, USDC_TOKEN_DECIMALS);
92565
92558
  const equity = extendedHoldings.data.equity;
92566
- const deposit = Number(positionValueInUSD) / extended_leverage - Number(equity);
92567
- return new Web3Number(Math.floor(deposit / 0.2) * 0.2, USDC_TOKEN_DECIMALS);
92559
+ const deposit = positionValueInUSD.dividedBy(extended_leverage).minus(equity).toFixed(2);
92560
+ return new Web3Number(deposit, USDC_TOKEN_DECIMALS);
92568
92561
  } catch (err2) {
92562
+ logger2.error(`error calculating amount deposit on extended when incurring losses: ${err2}`);
92569
92563
  return null;
92570
92564
  }
92571
92565
  };
@@ -92643,21 +92637,36 @@ spurious results.`);
92643
92637
  vaultAllocator: config3.vaultAllocator,
92644
92638
  id: ""
92645
92639
  });
92646
- this.tokenMarketData = new TokenMarketData(this.config.pricer, this.config.networkConfig);
92640
+ this.minimumVesuMovementAmount = config3.minimumVesuMovementAmount ?? 5;
92641
+ this.tokenMarketData = new TokenMarketData(
92642
+ this.config.pricer,
92643
+ this.config.networkConfig
92644
+ );
92647
92645
  }
92648
92646
  async getAPY(supportedPosition) {
92649
92647
  const CACHE_KEY = `apy_${this.config.poolId.address}_${supportedPosition.asset.symbol}`;
92650
92648
  const cacheData = this.getCache(CACHE_KEY);
92651
- console.log(`${_VesuMultiplyAdapter.name}::getAPY cacheData: ${JSON.stringify(cacheData)}`, this.vesuAdapter.config.poolId.shortString(), this.vesuAdapter.config.collateral.symbol, this.vesuAdapter.config.debt.symbol);
92649
+ console.log(
92650
+ `${_VesuMultiplyAdapter.name}::getAPY cacheData: ${JSON.stringify(
92651
+ cacheData
92652
+ )}`,
92653
+ this.vesuAdapter.config.poolId.shortString(),
92654
+ this.vesuAdapter.config.collateral.symbol,
92655
+ this.vesuAdapter.config.debt.symbol
92656
+ );
92652
92657
  if (cacheData) {
92653
92658
  return cacheData;
92654
92659
  }
92655
92660
  try {
92656
92661
  const allVesuPools = await VesuAdapter.getVesuPools();
92657
92662
  const asset = supportedPosition.asset;
92658
- const pool = allVesuPools.pools.find((p) => this.vesuAdapter.config.poolId.eqString(num_exports.getHexString(p.id)));
92663
+ const pool = allVesuPools.pools.find(
92664
+ (p) => this.vesuAdapter.config.poolId.eqString(num_exports.getHexString(p.id))
92665
+ );
92659
92666
  if (!pool) {
92660
- logger2.warn(`VesuMultiplyAdapter: Pool not found for token ${asset.symbol}`);
92667
+ logger2.warn(
92668
+ `VesuMultiplyAdapter: Pool not found for token ${asset.symbol}`
92669
+ );
92661
92670
  return {
92662
92671
  apy: 0,
92663
92672
  type: "base" /* BASE */
@@ -92667,7 +92676,9 @@ spurious results.`);
92667
92676
  (a) => a.symbol.toLowerCase() === asset.symbol.toLowerCase()
92668
92677
  )?.stats;
92669
92678
  if (!assetStats) {
92670
- logger2.warn(`VesuMultiplyAdapter: Asset stats not found for token ${asset.symbol}`);
92679
+ logger2.warn(
92680
+ `VesuMultiplyAdapter: Asset stats not found for token ${asset.symbol}`
92681
+ );
92671
92682
  return {
92672
92683
  apy: 0,
92673
92684
  type: "base" /* BASE */
@@ -92678,7 +92689,9 @@ spurious results.`);
92678
92689
  apy = Number(assetStats.borrowApr?.value || 0) / 1e18;
92679
92690
  } else {
92680
92691
  const isAssetBTC = asset.symbol.toLowerCase().includes("btc");
92681
- const baseAPY = Number(isAssetBTC ? assetStats.btcFiSupplyApr?.value + assetStats.supplyApy?.value : assetStats.supplyApy?.value || 0) / 1e18;
92692
+ const baseAPY = Number(
92693
+ isAssetBTC ? assetStats.btcFiSupplyApr?.value + assetStats.supplyApy?.value : assetStats.supplyApy?.value || 0
92694
+ ) / 1e18;
92682
92695
  const rewardAPY = Number(assetStats.defiSpringSupplyApr?.value || "0") / 1e18;
92683
92696
  const isSupported = this.tokenMarketData.isAPYSupported(asset);
92684
92697
  apy = baseAPY + rewardAPY;
@@ -92694,7 +92707,10 @@ spurious results.`);
92694
92707
  this.setCache(CACHE_KEY, result2, 3e5);
92695
92708
  return result2;
92696
92709
  } catch (error2) {
92697
- logger2.error(`VesuMultiplyAdapter: Error getting APY for ${supportedPosition.asset.symbol}:`, error2);
92710
+ logger2.error(
92711
+ `VesuMultiplyAdapter: Error getting APY for ${supportedPosition.asset.symbol}:`,
92712
+ error2
92713
+ );
92698
92714
  throw error2;
92699
92715
  }
92700
92716
  }
@@ -92707,12 +92723,16 @@ spurious results.`);
92707
92723
  try {
92708
92724
  this.vesuAdapter.networkConfig = this.config.networkConfig;
92709
92725
  this.vesuAdapter.pricer = this.config.pricer;
92710
- const positions = await this.vesuAdapter.getPositions(this.config.networkConfig);
92726
+ const positions = await this.vesuAdapter.getPositions(
92727
+ this.config.networkConfig
92728
+ );
92711
92729
  let position = positions.find(
92712
92730
  (p) => p.token.address.eq(supportedPosition.asset.address)
92713
92731
  );
92714
92732
  if (!position) {
92715
- logger2.warn(`VesuMultiplyAdapter: Position not found for token ${supportedPosition.asset.symbol}`);
92733
+ logger2.warn(
92734
+ `VesuMultiplyAdapter: Position not found for token ${supportedPosition.asset.symbol}`
92735
+ );
92716
92736
  return {
92717
92737
  amount: new Web3Number("0", supportedPosition.asset.decimals),
92718
92738
  remarks: "Position not found"
@@ -92725,12 +92745,18 @@ spurious results.`);
92725
92745
  this.setCache(CACHE_KEY, position, 6e4);
92726
92746
  return position;
92727
92747
  } catch (error2) {
92728
- logger2.error(`VesuMultiplyAdapter: Error getting position for ${supportedPosition.asset.symbol}:`, error2);
92748
+ logger2.error(
92749
+ `VesuMultiplyAdapter: Error getting position for ${supportedPosition.asset.symbol}:`,
92750
+ error2
92751
+ );
92729
92752
  throw error2;
92730
92753
  }
92731
92754
  }
92732
92755
  async maxBorrowableAPY() {
92733
- const collateralAPY = await this.getAPY({ asset: this.config.collateral, isDebt: false });
92756
+ const collateralAPY = await this.getAPY({
92757
+ asset: this.config.collateral,
92758
+ isDebt: false
92759
+ });
92734
92760
  const apy = collateralAPY.apy * 0.8;
92735
92761
  return apy;
92736
92762
  }
@@ -92740,9 +92766,15 @@ spurious results.`);
92740
92766
  try {
92741
92767
  this.vesuAdapter.networkConfig = this.config.networkConfig;
92742
92768
  this.vesuAdapter.pricer = this.config.pricer;
92743
- const positions = await this.vesuAdapter.getPositions(this.config.networkConfig);
92744
- const collateralPosition = positions.find((p) => p.token.address.eq(collateral.address));
92745
- const debtPosition = positions.find((p) => p.token.address.eq(debt.address));
92769
+ const positions = await this.vesuAdapter.getPositions(
92770
+ this.config.networkConfig
92771
+ );
92772
+ const collateralPosition = positions.find(
92773
+ (p) => p.token.address.eq(collateral.address)
92774
+ );
92775
+ const debtPosition = positions.find(
92776
+ (p) => p.token.address.eq(debt.address)
92777
+ );
92746
92778
  if (!collateralPosition || !debtPosition) {
92747
92779
  throw new Error("Could not find current positions");
92748
92780
  }
@@ -92752,13 +92784,23 @@ spurious results.`);
92752
92784
  debt,
92753
92785
  maxBorrowableAPY
92754
92786
  );
92755
- logger2.verbose(`VesuMultiplyAdapter: Max borrowable: ${maxBorrowable.toNumber()}`);
92756
- const debtCap = await this.vesuAdapter.getDebtCap(this.config.networkConfig);
92787
+ logger2.verbose(
92788
+ `VesuMultiplyAdapter: Max borrowable: ${maxBorrowable.toNumber()}`
92789
+ );
92790
+ const debtCap = await this.vesuAdapter.getDebtCap(
92791
+ this.config.networkConfig
92792
+ );
92757
92793
  logger2.verbose(`VesuMultiplyAdapter: Debt cap: ${debtCap.toNumber()}`);
92758
92794
  const actualMaxBorrowable = maxBorrowable.minimum(debtCap);
92759
- logger2.verbose(`VesuMultiplyAdapter: Actual max borrowable: ${actualMaxBorrowable.toNumber()}`);
92760
- const maxLTV = await this.vesuAdapter.getLTVConfig(this.config.networkConfig);
92761
- const collateralPrice = await this.config.pricer.getPrice(collateral.symbol);
92795
+ logger2.verbose(
92796
+ `VesuMultiplyAdapter: Actual max borrowable: ${actualMaxBorrowable.toNumber()}`
92797
+ );
92798
+ const maxLTV = await this.vesuAdapter.getLTVConfig(
92799
+ this.config.networkConfig
92800
+ );
92801
+ const collateralPrice = await this.config.pricer.getPrice(
92802
+ collateral.symbol
92803
+ );
92762
92804
  if (collateralPrice.price === 0) {
92763
92805
  throw new Error("Collateral price is 0");
92764
92806
  }
@@ -92776,14 +92818,25 @@ spurious results.`);
92776
92818
  );
92777
92819
  const maxDepositAmount = amount ? amount.minimum(maxCollateralFromDebt) : maxCollateralFromDebt;
92778
92820
  const usdValue = await this.getUSDValue(collateral, maxDepositAmount);
92779
- logger2.verbose(`VesuMultiplyAdapter: Max deposit::USD value: ${usdValue}, amount: ${maxDepositAmount.toNumber()}`);
92780
- const apys = await Promise.all([this.getAPY({ asset: collateral, isDebt: false }), this.getAPY({ asset: debt, isDebt: true })]);
92781
- logger2.verbose(`VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`);
92821
+ logger2.verbose(
92822
+ `VesuMultiplyAdapter: Max deposit::USD value: ${usdValue}, amount: ${maxDepositAmount.toNumber()}`
92823
+ );
92824
+ const apys = await Promise.all([
92825
+ this.getAPY({ asset: collateral, isDebt: false }),
92826
+ this.getAPY({ asset: debt, isDebt: true })
92827
+ ]);
92828
+ logger2.verbose(
92829
+ `VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`
92830
+ );
92782
92831
  const borrowAmountUSD = actualMaxBorrowable.multipliedBy(debtPrice.price);
92783
- logger2.verbose(`VesuMultiplyAdapter: Borrow amount: ${actualMaxBorrowable.toNumber()}, borrow amount USD: ${borrowAmountUSD.toNumber()}`);
92832
+ logger2.verbose(
92833
+ `VesuMultiplyAdapter: Borrow amount: ${actualMaxBorrowable.toNumber()}, borrow amount USD: ${borrowAmountUSD.toNumber()}`
92834
+ );
92784
92835
  const netCollateralUSD = usdValue + borrowAmountUSD.toNumber();
92785
92836
  const netAPY = (apys[0].apy * netCollateralUSD + apys[1].apy * borrowAmountUSD.toNumber()) / usdValue;
92786
- logger2.verbose(`VesuMultiplyAdapter: Max deposit amount: ${maxDepositAmount.toNumber()}, netAPY: ${netAPY}`);
92837
+ logger2.verbose(
92838
+ `VesuMultiplyAdapter: Max deposit amount: ${maxDepositAmount.toNumber()}, netAPY: ${netAPY}`
92839
+ );
92787
92840
  return {
92788
92841
  tokenInfo: collateral,
92789
92842
  amount: maxDepositAmount,
@@ -92796,7 +92849,10 @@ spurious results.`);
92796
92849
  protocol: this.protocol
92797
92850
  };
92798
92851
  } catch (error2) {
92799
- logger2.error(`VesuMultiplyAdapter: Error calculating max deposit:`, error2);
92852
+ logger2.error(
92853
+ `VesuMultiplyAdapter: Error calculating max deposit:`,
92854
+ error2
92855
+ );
92800
92856
  throw error2;
92801
92857
  }
92802
92858
  }
@@ -92806,9 +92862,15 @@ spurious results.`);
92806
92862
  try {
92807
92863
  this.vesuAdapter.networkConfig = this.config.networkConfig;
92808
92864
  this.vesuAdapter.pricer = this.config.pricer;
92809
- const positions = await this.vesuAdapter.getPositions(this.config.networkConfig);
92810
- const collateralPosition = positions.find((p) => p.token.address.eq(collateral.address));
92811
- const debtPosition = positions.find((p) => p.token.address.eq(this.config.debt.address));
92865
+ const positions = await this.vesuAdapter.getPositions(
92866
+ this.config.networkConfig
92867
+ );
92868
+ const collateralPosition = positions.find(
92869
+ (p) => p.token.address.eq(collateral.address)
92870
+ );
92871
+ const debtPosition = positions.find(
92872
+ (p) => p.token.address.eq(this.config.debt.address)
92873
+ );
92812
92874
  if (!collateralPosition || !debtPosition) {
92813
92875
  throw new Error("Could not find current positions");
92814
92876
  }
@@ -92818,11 +92880,20 @@ spurious results.`);
92818
92880
  const result2 = maxWithdrawable.greaterThan(0) ? maxWithdrawable : new Web3Number("0", collateral.decimals);
92819
92881
  const usdValue = await this.getUSDValue(collateral, result2);
92820
92882
  const debtUSD = debtPosition.usdValue;
92821
- logger2.verbose(`VesuMultiplyAdapter: Debt USD: ${debtUSD}, collateral USD: ${usdValue}`);
92822
- const apys = await Promise.all([this.getAPY({ asset: collateral, isDebt: false }), this.getAPY({ asset: debt, isDebt: true })]);
92823
- logger2.verbose(`VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`);
92883
+ logger2.verbose(
92884
+ `VesuMultiplyAdapter: Debt USD: ${debtUSD}, collateral USD: ${usdValue}`
92885
+ );
92886
+ const apys = await Promise.all([
92887
+ this.getAPY({ asset: collateral, isDebt: false }),
92888
+ this.getAPY({ asset: debt, isDebt: true })
92889
+ ]);
92890
+ logger2.verbose(
92891
+ `VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`
92892
+ );
92824
92893
  const netAPY = usdValue - debtUSD > 0 ? (apys[0].apy * usdValue + apys[1].apy * debtUSD) / (usdValue - debtUSD) : 0;
92825
- logger2.verbose(`VesuMultiplyAdapter: Max withdraw amount: ${result2.toNumber()}, netAPY: ${netAPY}`);
92894
+ logger2.verbose(
92895
+ `VesuMultiplyAdapter: Max withdraw amount: ${result2.toNumber()}, netAPY: ${netAPY}`
92896
+ );
92826
92897
  return {
92827
92898
  tokenInfo: collateral,
92828
92899
  amount: result2,
@@ -92835,14 +92906,19 @@ spurious results.`);
92835
92906
  protocol: this.protocol
92836
92907
  };
92837
92908
  } catch (error2) {
92838
- logger2.error(`VesuMultiplyAdapter: Error calculating max withdraw:`, error2);
92909
+ logger2.error(
92910
+ `VesuMultiplyAdapter: Error calculating max withdraw:`,
92911
+ error2
92912
+ );
92839
92913
  throw error2;
92840
92914
  }
92841
92915
  }
92842
92916
  _getDepositLeaf() {
92843
92917
  const collateral = this.config.collateral;
92844
92918
  const debt = this.config.debt;
92845
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
92919
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
92920
+ this.config.poolId
92921
+ );
92846
92922
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
92847
92923
  return [
92848
92924
  // Approval step for collateral
@@ -92906,7 +92982,9 @@ spurious results.`);
92906
92982
  ];
92907
92983
  }
92908
92984
  _getWithdrawLeaf() {
92909
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
92985
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
92986
+ this.config.poolId
92987
+ );
92910
92988
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
92911
92989
  const collateral = this.config.collateral;
92912
92990
  const debt = this.config.debt;
@@ -92937,7 +93015,7 @@ spurious results.`);
92937
93015
  this.config.debt.address.toBigInt(),
92938
93016
  this.config.vaultAllocator.toBigInt()
92939
93017
  ],
92940
- sanitizer: SIMPLE_SANITIZER_V2,
93018
+ sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
92941
93019
  // vmw = vesu multiply withdraw
92942
93020
  id: `vmw_${this.config.poolId.shortString()}_${collateral.symbol}_${debt.symbol}`
92943
93021
  },
@@ -92963,33 +93041,51 @@ spurious results.`);
92963
93041
  const leafConfigs = this._getDepositLeaf();
92964
93042
  const leaves = leafConfigs.map((config3) => {
92965
93043
  const { target, method, packedArguments, sanitizer, id } = config3;
92966
- const leaf = this.constructSimpleLeafData({
92967
- id,
92968
- target,
92969
- method,
92970
- packedArguments
92971
- }, sanitizer);
93044
+ const leaf = this.constructSimpleLeafData(
93045
+ {
93046
+ id,
93047
+ target,
93048
+ method,
93049
+ packedArguments
93050
+ },
93051
+ sanitizer
93052
+ );
92972
93053
  return leaf;
92973
93054
  });
92974
- return { leaves, callConstructor: this.getDepositCall.bind(this) };
93055
+ return {
93056
+ leaves,
93057
+ callConstructor: this.getDepositCall.bind(
93058
+ this
93059
+ )
93060
+ };
92975
93061
  }
92976
93062
  getWithdrawAdapter() {
92977
93063
  const leafConfigs = this._getWithdrawLeaf();
92978
93064
  const leaves = leafConfigs.map((config3) => {
92979
93065
  const { target, method, packedArguments, sanitizer, id } = config3;
92980
- const leaf = this.constructSimpleLeafData({
92981
- id,
92982
- target,
92983
- method,
92984
- packedArguments
92985
- }, sanitizer);
93066
+ const leaf = this.constructSimpleLeafData(
93067
+ {
93068
+ id,
93069
+ target,
93070
+ method,
93071
+ packedArguments
93072
+ },
93073
+ sanitizer
93074
+ );
92986
93075
  return leaf;
92987
93076
  });
92988
- return { leaves, callConstructor: this.getWithdrawCall.bind(this) };
93077
+ return {
93078
+ leaves,
93079
+ callConstructor: this.getWithdrawCall.bind(
93080
+ this
93081
+ )
93082
+ };
92989
93083
  }
92990
93084
  async getDepositCall(params) {
92991
93085
  const collateral = this.config.collateral;
92992
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
93086
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
93087
+ this.config.poolId
93088
+ );
92993
93089
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
92994
93090
  const uint256MarginAmount = uint256_exports.bnToUint256(params.amount.toWei());
92995
93091
  return [
@@ -93061,7 +93157,9 @@ spurious results.`);
93061
93157
  ];
93062
93158
  }
93063
93159
  async getWithdrawCall(params) {
93064
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
93160
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
93161
+ this.config.poolId
93162
+ );
93065
93163
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
93066
93164
  return [
93067
93165
  // Switch delegation on
@@ -93086,7 +93184,7 @@ spurious results.`);
93086
93184
  },
93087
93185
  // Vesu multiply call
93088
93186
  {
93089
- sanitizer: SIMPLE_SANITIZER_V2,
93187
+ sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
93090
93188
  call: {
93091
93189
  contractAddress: vesuMultiply,
93092
93190
  selector: hash_exports.getSelectorFromName("modify_lever"),
@@ -93116,7 +93214,11 @@ spurious results.`);
93116
93214
  ];
93117
93215
  }
93118
93216
  async getMultiplyCallCalldata(params, isDeposit) {
93119
- logger2.verbose(`${_VesuMultiplyAdapter.name}::getMultiplyCallCalldata params: ${JSON.stringify(params)}, isDeposit: ${isDeposit}, collateral: ${this.config.collateral.symbol}, debt: ${this.config.debt.symbol}`);
93217
+ logger2.verbose(
93218
+ `${_VesuMultiplyAdapter.name}::getMultiplyCallCalldata params: ${JSON.stringify(
93219
+ params
93220
+ )}, isDeposit: ${isDeposit}, collateral: ${this.config.collateral.symbol}, debt: ${this.config.debt.symbol}`
93221
+ );
93120
93222
  const { isV2 } = getVesuSingletonAddress(this.config.poolId);
93121
93223
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
93122
93224
  const multiplyContract = new Contract({
@@ -93126,42 +93228,83 @@ spurious results.`);
93126
93228
  });
93127
93229
  let leverSwap = [];
93128
93230
  let leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
93129
- const existingPositions = await this.vesuAdapter.getPositions(this.config.networkConfig);
93130
- const collateralisation = await this.vesuAdapter.getCollateralization(this.config.networkConfig);
93231
+ const existingPositions = await this.vesuAdapter.getPositions(
93232
+ this.config.networkConfig
93233
+ );
93234
+ const collateralisation = await this.vesuAdapter.getCollateralization(
93235
+ this.config.networkConfig
93236
+ );
93131
93237
  const existingCollateralInfo = existingPositions[0];
93132
93238
  const existingDebtInfo = existingPositions[1];
93133
93239
  const isDexPriceRequired = existingDebtInfo.token.symbol !== "USDC";
93134
- logger2.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
93135
- existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
93240
+ logger2.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(
93241
+ existingCollateralInfo
93242
+ )},
93243
+ existingDebtInfo: ${JSON.stringify(
93244
+ existingDebtInfo
93245
+ )}, collateralisation: ${JSON.stringify(collateralisation)}`);
93136
93246
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : (await this.config.pricer.getPrice(this.config.collateral.symbol)).price;
93137
93247
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : (await this.config.pricer.getPrice(this.config.debt.symbol)).price;
93138
- logger2.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
93139
- const legLTV = await this.vesuAdapter.getLTVConfig(this.config.networkConfig);
93140
- const ekuboQuoter = new EkuboQuoter(this.config.networkConfig, this.config.pricer);
93141
- const dexPrice = isDexPriceRequired ? await ekuboQuoter.getDexPrice(this.config.collateral, this.config.debt, this.config.quoteAmountToFetchPrice) : 1;
93142
- logger2.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall dexPrice: ${dexPrice}, ltv: ${legLTV}`);
93248
+ logger2.debug(
93249
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`
93250
+ );
93251
+ const legLTV = await this.vesuAdapter.getLTVConfig(
93252
+ this.config.networkConfig
93253
+ );
93254
+ const ekuboQuoter = new EkuboQuoter(
93255
+ this.config.networkConfig,
93256
+ this.config.pricer
93257
+ );
93258
+ const dexPrice = isDexPriceRequired ? await ekuboQuoter.getDexPrice(
93259
+ this.config.collateral,
93260
+ this.config.debt,
93261
+ this.config.quoteAmountToFetchPrice
93262
+ ) : 1;
93263
+ logger2.verbose(
93264
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall dexPrice: ${dexPrice}, ltv: ${legLTV}`
93265
+ );
93143
93266
  const addedCollateral = params.amount.multipliedBy(isDeposit ? 1 : -1);
93144
- logger2.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall addedCollateral: ${addedCollateral}`);
93267
+ logger2.verbose(
93268
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall addedCollateral: ${addedCollateral}`
93269
+ );
93145
93270
  const numeratorPart1 = existingCollateralInfo.amount.plus(addedCollateral).multipliedBy(collateralPrice).multipliedBy(legLTV);
93146
- logger2.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}`);
93271
+ logger2.verbose(
93272
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}`
93273
+ );
93147
93274
  const numeratorPart2 = existingDebtInfo.amount.multipliedBy(debtPrice).multipliedBy(this.config.targetHealthFactor);
93148
- logger2.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart2: ${numeratorPart2}`);
93275
+ logger2.verbose(
93276
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart2: ${numeratorPart2}`
93277
+ );
93149
93278
  const denominatorPart = this.config.targetHealthFactor - legLTV / dexPrice;
93150
- logger2.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall denominatorPart: ${denominatorPart}`);
93279
+ logger2.verbose(
93280
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall denominatorPart: ${denominatorPart}`
93281
+ );
93151
93282
  const x_debt_usd = numeratorPart1.minus(numeratorPart2).dividedBy(denominatorPart);
93152
- logger2.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall x_debt_usd: ${x_debt_usd}`);
93153
- logger2.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}, numeratorPart2: ${numeratorPart2}, denominatorPart: ${denominatorPart}`);
93154
- let debtAmount = new Web3Number(x_debt_usd.dividedBy(debtPrice).toFixed(this.config.debt.decimals), this.config.debt.decimals);
93283
+ logger2.verbose(
93284
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall x_debt_usd: ${x_debt_usd}`
93285
+ );
93286
+ logger2.debug(
93287
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}, numeratorPart2: ${numeratorPart2}, denominatorPart: ${denominatorPart}`
93288
+ );
93289
+ let debtAmount = new Web3Number(
93290
+ x_debt_usd.dividedBy(debtPrice).toFixed(this.config.debt.decimals),
93291
+ this.config.debt.decimals
93292
+ );
93155
93293
  const marginAmount = addedCollateral;
93156
93294
  const collateralToken = this.config.collateral;
93157
93295
  const debtToken = this.config.debt;
93158
- const debtAmountInCollateralUnits = new Web3Number(debtAmount.multipliedBy(debtPrice).dividedBy(collateralPrice).multipliedBy(10 ** collateralToken.decimals).toFixed(0), collateralToken.decimals);
93296
+ const debtAmountInCollateralUnits = new Web3Number(
93297
+ debtAmount.multipliedBy(debtPrice).dividedBy(collateralPrice).multipliedBy(10 ** collateralToken.decimals).toFixed(0),
93298
+ collateralToken.decimals
93299
+ );
93159
93300
  const isIncrease = debtAmount.greaterThanOrEqualTo(0);
93160
93301
  if (isIncrease && debtAmount.lessThan(0)) {
93161
93302
  } else if (!isIncrease && debtAmount.greaterThan(0)) {
93162
93303
  debtAmount = Web3Number.fromWei(0, this.config.debt.decimals);
93163
93304
  }
93164
- logger2.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall debtAmount: ${debtAmount}, marginAmount: ${marginAmount}`);
93305
+ logger2.verbose(
93306
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall debtAmount: ${debtAmount}, marginAmount: ${marginAmount}`
93307
+ );
93165
93308
  if (!debtAmount.isZero()) {
93166
93309
  try {
93167
93310
  const swapQuote = await ekuboQuoter.getQuote(
@@ -93171,32 +93314,49 @@ spurious results.`);
93171
93314
  // negative for exact amount out
93172
93315
  );
93173
93316
  if (swapQuote.price_impact < 0.01) {
93174
- leverSwap = ekuboQuoter.getVesuMultiplyQuote(swapQuote, debtToken, collateralToken);
93317
+ leverSwap = debtAmount.isNegative() ? ekuboQuoter.getVesuMultiplyQuote(
93318
+ swapQuote,
93319
+ collateralToken,
93320
+ debtToken
93321
+ ) : ekuboQuoter.getVesuMultiplyQuote(
93322
+ swapQuote,
93323
+ debtToken,
93324
+ collateralToken
93325
+ );
93175
93326
  const MAX_SLIPPAGE = 2e-3;
93176
93327
  if (debtAmount.greaterThan(0)) {
93177
- console.log("debtAmountInCollateralUnits", debtAmountInCollateralUnits.toNumber());
93178
- leverSwapLimitAmount = await ekuboQuoter.getSwapLimitAmount(debtToken, collateralToken, debtAmount, MAX_SLIPPAGE);
93179
- const anotherleverSwapLimitAmount = debtAmount.multipliedBy(1 + MAX_SLIPPAGE);
93180
- console.log("anotherleverSwapLimitAmount", anotherleverSwapLimitAmount, leverSwapLimitAmount);
93328
+ leverSwapLimitAmount = debtAmount.multipliedBy(1 + MAX_SLIPPAGE);
93181
93329
  } else if (debtAmount.lessThan(0)) {
93182
- leverSwapLimitAmount = await ekuboQuoter.getSwapLimitAmount(collateralToken, debtToken, debtAmountInCollateralUnits.multipliedBy(-1), MAX_SLIPPAGE);
93183
- const anotherleverSwapLimitAmount = debtAmount.abs().multipliedBy(1 - MAX_SLIPPAGE);
93184
- console.log("anotherleverSwapLimitAmount", anotherleverSwapLimitAmount, leverSwapLimitAmount);
93330
+ leverSwapLimitAmount = debtAmount.abs().multipliedBy(1 - MAX_SLIPPAGE);
93185
93331
  } else {
93186
- leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
93332
+ leverSwapLimitAmount = Web3Number.fromWei(
93333
+ 0,
93334
+ this.config.debt.decimals
93335
+ );
93187
93336
  }
93188
93337
  await new Promise((resolve) => setTimeout(resolve, 1e4));
93189
- console.log("leverSwapLimitAmount", leverSwapLimitAmount);
93190
93338
  } else {
93191
- throw new Error(`VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`);
93339
+ throw new Error(
93340
+ `VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`
93341
+ );
93192
93342
  }
93193
93343
  } catch (error2) {
93194
- throw new Error(`VesuMultiplyAdapter: Failed to get swap quote: ${error2}`);
93344
+ throw new Error(
93345
+ `VesuMultiplyAdapter: Failed to get swap quote: ${error2}`
93346
+ );
93195
93347
  }
93196
93348
  }
93197
- const multiplyParams = await this.getLeverParams(isIncrease, params, leverSwap, leverSwapLimitAmount);
93349
+ const multiplyParams = await this.getLeverParams(
93350
+ isIncrease,
93351
+ params,
93352
+ leverSwap,
93353
+ leverSwapLimitAmount
93354
+ );
93198
93355
  const call = multiplyContract.populate("modify_lever", {
93199
- modify_lever_params: this.formatMultiplyParams(isIncrease, multiplyParams)
93356
+ modify_lever_params: this.formatMultiplyParams(
93357
+ isIncrease,
93358
+ multiplyParams
93359
+ )
93200
93360
  });
93201
93361
  return call.calldata;
93202
93362
  }
@@ -93210,7 +93370,10 @@ spurious results.`);
93210
93370
  add_margin: params.amount,
93211
93371
  // multiplied by collateral decimals in format
93212
93372
  margin_swap: [],
93213
- margin_swap_limit_amount: Web3Number.fromWei(0, this.config.collateral.decimals),
93373
+ margin_swap_limit_amount: Web3Number.fromWei(
93374
+ 0,
93375
+ this.config.collateral.decimals
93376
+ ),
93214
93377
  lever_swap: leverSwap,
93215
93378
  lever_swap_limit_amount: leverSwapLimitAmount
93216
93379
  } : {
@@ -93224,7 +93387,10 @@ spurious results.`);
93224
93387
  lever_swap_limit_amount: leverSwapLimitAmount,
93225
93388
  lever_swap_weights: [],
93226
93389
  withdraw_swap: [],
93227
- withdraw_swap_limit_amount: Web3Number.fromWei(0, this.config.collateral.decimals),
93390
+ withdraw_swap_limit_amount: Web3Number.fromWei(
93391
+ 0,
93392
+ this.config.collateral.decimals
93393
+ ),
93228
93394
  withdraw_swap_weights: [],
93229
93395
  close_position: false
93230
93396
  };
@@ -93240,12 +93406,16 @@ spurious results.`);
93240
93406
  });
93241
93407
  let leverSwap = [];
93242
93408
  let leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
93243
- const existingPositions = await this.vesuAdapter.getPositions(this.config.networkConfig);
93409
+ const existingPositions = await this.vesuAdapter.getPositions(
93410
+ this.config.networkConfig
93411
+ );
93244
93412
  const existingCollateralInfo = existingPositions[0];
93245
93413
  const existingDebtInfo = existingPositions[1];
93246
93414
  const collateralToken = this.config.collateral;
93247
93415
  const debtToken = this.config.debt;
93248
- const collateralPrice = await this.config.pricer.getPrice(collateralToken.symbol);
93416
+ const collateralPrice = await this.config.pricer.getPrice(
93417
+ collateralToken.symbol
93418
+ );
93249
93419
  const debtPrice = await this.config.pricer.getPrice(debtToken.symbol);
93250
93420
  const { deltadebtAmountUnits: debtAmountToRepay } = calculateDebtReductionAmountForWithdrawal(
93251
93421
  existingDebtInfo.amount,
@@ -93256,27 +93426,41 @@ spurious results.`);
93256
93426
  debtPrice.price,
93257
93427
  debtToken.decimals
93258
93428
  );
93259
- console.log("debtAmountToRepay", debtAmountToRepay);
93260
93429
  if (!debtAmountToRepay) {
93261
93430
  throw new Error("error calculating debt amount to repay");
93262
93431
  }
93263
- const ekuboQuoter = new EkuboQuoter(this.config.networkConfig, this.config.pricer);
93264
- const debtInDebtUnits = new Web3Number(debtAmountToRepay, debtToken.decimals).dividedBy(debtPrice.price).multipliedBy(10 ** debtToken.decimals);
93265
- const debtInCollateralUnits = new Web3Number(debtAmountToRepay, debtToken.decimals).dividedBy(collateralPrice.price).multipliedBy(10 ** collateralToken.decimals);
93432
+ const ekuboQuoter = new EkuboQuoter(
93433
+ this.config.networkConfig,
93434
+ this.config.pricer
93435
+ );
93436
+ const debtInDebtUnits = new Web3Number(
93437
+ debtAmountToRepay,
93438
+ debtToken.decimals
93439
+ ).dividedBy(debtPrice.price).multipliedBy(10 ** debtToken.decimals);
93266
93440
  const swapQuote = await ekuboQuoter.getQuote(
93267
93441
  debtToken.address.address,
93268
93442
  collateralToken.address.address,
93269
93443
  debtInDebtUnits
93270
93444
  );
93271
93445
  const MAX_SLIPPAGE = 2e-3;
93272
- if (swapQuote.price_impact < 0.025) {
93273
- leverSwap = ekuboQuoter.getVesuMultiplyQuote(swapQuote, debtToken, collateralToken);
93446
+ if (swapQuote.price_impact < 25e-4) {
93447
+ leverSwap = ekuboQuoter.getVesuMultiplyQuote(
93448
+ swapQuote,
93449
+ collateralToken,
93450
+ debtToken
93451
+ );
93274
93452
  } else {
93275
- logger2.error(`VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`);
93453
+ logger2.error(
93454
+ `VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`
93455
+ );
93276
93456
  }
93277
- const anotherLeverSwapLimitAmount = await ekuboQuoter.getSwapLimitAmount(collateralToken, debtToken, debtInDebtUnits, MAX_SLIPPAGE);
93278
- leverSwapLimitAmount = await ekuboQuoter.getSwapLimitAmount(debtToken, collateralToken, debtInCollateralUnits, MAX_SLIPPAGE);
93279
- const multiplyParams = await this.getLeverParams(false, params, leverSwap, leverSwapLimitAmount);
93457
+ leverSwapLimitAmount = new Web3Number(debtAmountToRepay, debtToken.decimals).abs().multipliedBy(1 + MAX_SLIPPAGE);
93458
+ const multiplyParams = await this.getLeverParams(
93459
+ false,
93460
+ params,
93461
+ leverSwap,
93462
+ leverSwapLimitAmount
93463
+ );
93280
93464
  const call = multiplyContract.populate("modify_lever", {
93281
93465
  modify_lever_params: this.formatMultiplyParams(false, multiplyParams)
93282
93466
  });
@@ -93286,100 +93470,132 @@ spurious results.`);
93286
93470
  if (isIncrease) {
93287
93471
  const _params2 = params;
93288
93472
  return {
93289
- action: new CairoCustomEnum({ IncreaseLever: {
93290
- pool_id: _params2.pool_id.toBigInt(),
93291
- collateral_asset: _params2.collateral_asset.toBigInt(),
93292
- debt_asset: _params2.debt_asset.toBigInt(),
93293
- user: _params2.user.toBigInt(),
93294
- add_margin: BigInt(_params2.add_margin.toWei()),
93295
- margin_swap: _params2.margin_swap.map((swap) => ({
93473
+ action: new CairoCustomEnum({
93474
+ IncreaseLever: {
93475
+ pool_id: _params2.pool_id.toBigInt(),
93476
+ collateral_asset: _params2.collateral_asset.toBigInt(),
93477
+ debt_asset: _params2.debt_asset.toBigInt(),
93478
+ user: _params2.user.toBigInt(),
93479
+ add_margin: BigInt(_params2.add_margin.toWei()),
93480
+ margin_swap: _params2.margin_swap.map((swap) => ({
93481
+ route: swap.route.map((route) => ({
93482
+ pool_key: {
93483
+ token0: route.pool_key.token0.toBigInt(),
93484
+ token1: route.pool_key.token1.toBigInt(),
93485
+ fee: route.pool_key.fee,
93486
+ tick_spacing: route.pool_key.tick_spacing,
93487
+ extension: BigInt(
93488
+ num_exports.hexToDecimalString(route.pool_key.extension)
93489
+ )
93490
+ },
93491
+ sqrt_ratio_limit: uint256_exports.bnToUint256(
93492
+ route.sqrt_ratio_limit.toWei()
93493
+ ),
93494
+ skip_ahead: BigInt(100)
93495
+ })),
93496
+ token_amount: {
93497
+ token: swap.token_amount.token.toBigInt(),
93498
+ amount: swap.token_amount.amount.toI129()
93499
+ }
93500
+ })),
93501
+ margin_swap_limit_amount: BigInt(
93502
+ _params2.margin_swap_limit_amount.toWei()
93503
+ ),
93504
+ lever_swap: _params2.lever_swap.map((swap) => ({
93505
+ route: swap.route.map((route) => ({
93506
+ pool_key: {
93507
+ token0: route.pool_key.token0.toBigInt(),
93508
+ token1: route.pool_key.token1.toBigInt(),
93509
+ fee: route.pool_key.fee,
93510
+ tick_spacing: route.pool_key.tick_spacing,
93511
+ extension: BigInt(
93512
+ num_exports.hexToDecimalString(route.pool_key.extension)
93513
+ )
93514
+ },
93515
+ sqrt_ratio_limit: uint256_exports.bnToUint256(
93516
+ route.sqrt_ratio_limit.toWei()
93517
+ ),
93518
+ skip_ahead: BigInt(0)
93519
+ })),
93520
+ token_amount: {
93521
+ token: swap.token_amount.token.toBigInt(),
93522
+ amount: swap.token_amount.amount.toI129()
93523
+ }
93524
+ })),
93525
+ lever_swap_limit_amount: BigInt(
93526
+ _params2.lever_swap_limit_amount.toWei()
93527
+ )
93528
+ }
93529
+ })
93530
+ };
93531
+ }
93532
+ const _params = params;
93533
+ return {
93534
+ action: new CairoCustomEnum({
93535
+ DecreaseLever: {
93536
+ pool_id: _params.pool_id.toBigInt(),
93537
+ collateral_asset: _params.collateral_asset.toBigInt(),
93538
+ debt_asset: _params.debt_asset.toBigInt(),
93539
+ user: _params.user.toBigInt(),
93540
+ sub_margin: BigInt(_params.sub_margin.toWei()),
93541
+ recipient: _params.recipient.toBigInt(),
93542
+ lever_swap: _params.lever_swap.map((swap) => ({
93296
93543
  route: swap.route.map((route) => ({
93297
93544
  pool_key: {
93298
93545
  token0: route.pool_key.token0.toBigInt(),
93299
93546
  token1: route.pool_key.token1.toBigInt(),
93300
93547
  fee: route.pool_key.fee,
93301
93548
  tick_spacing: route.pool_key.tick_spacing,
93302
- extension: BigInt(num_exports.hexToDecimalString(route.pool_key.extension))
93549
+ extension: ContractAddr.from(
93550
+ route.pool_key.extension
93551
+ ).toBigInt()
93303
93552
  },
93304
- sqrt_ratio_limit: uint256_exports.bnToUint256(route.sqrt_ratio_limit.toWei()),
93305
- skip_ahead: BigInt(100)
93553
+ sqrt_ratio_limit: uint256_exports.bnToUint256(
93554
+ route.sqrt_ratio_limit.toWei()
93555
+ ),
93556
+ skip_ahead: BigInt(route.skip_ahead.toWei())
93306
93557
  })),
93307
93558
  token_amount: {
93308
93559
  token: swap.token_amount.token.toBigInt(),
93309
93560
  amount: swap.token_amount.amount.toI129()
93310
93561
  }
93311
93562
  })),
93312
- margin_swap_limit_amount: BigInt(_params2.margin_swap_limit_amount.toWei()),
93313
- lever_swap: _params2.lever_swap.map((swap) => ({
93563
+ lever_swap_limit_amount: BigInt(
93564
+ _params.lever_swap_limit_amount.toWei()
93565
+ ),
93566
+ lever_swap_weights: _params.lever_swap_weights.map(
93567
+ (weight) => BigInt(weight.toWei())
93568
+ ),
93569
+ withdraw_swap: _params.withdraw_swap.map((swap) => ({
93314
93570
  route: swap.route.map((route) => ({
93315
93571
  pool_key: {
93316
93572
  token0: route.pool_key.token0.toBigInt(),
93317
93573
  token1: route.pool_key.token1.toBigInt(),
93318
93574
  fee: route.pool_key.fee,
93319
93575
  tick_spacing: route.pool_key.tick_spacing,
93320
- extension: BigInt(num_exports.hexToDecimalString(route.pool_key.extension))
93576
+ extension: ContractAddr.from(
93577
+ route.pool_key.extension
93578
+ ).toBigInt()
93321
93579
  },
93322
- sqrt_ratio_limit: uint256_exports.bnToUint256(route.sqrt_ratio_limit.toWei()),
93323
- skip_ahead: BigInt(0)
93580
+ sqrt_ratio_limit: uint256_exports.bnToUint256(
93581
+ route.sqrt_ratio_limit.toWei()
93582
+ ),
93583
+ skip_ahead: BigInt(route.skip_ahead.toWei())
93324
93584
  })),
93325
93585
  token_amount: {
93326
93586
  token: swap.token_amount.token.toBigInt(),
93327
93587
  amount: swap.token_amount.amount.toI129()
93328
93588
  }
93329
93589
  })),
93330
- lever_swap_limit_amount: BigInt(_params2.lever_swap_limit_amount.toWei())
93331
- } })
93332
- };
93333
- }
93334
- const _params = params;
93335
- return {
93336
- action: new CairoCustomEnum({ DecreaseLever: {
93337
- pool_id: _params.pool_id.toBigInt(),
93338
- collateral_asset: _params.collateral_asset.toBigInt(),
93339
- debt_asset: _params.debt_asset.toBigInt(),
93340
- user: _params.user.toBigInt(),
93341
- sub_margin: BigInt(_params.sub_margin.toWei()),
93342
- recipient: _params.recipient.toBigInt(),
93343
- lever_swap: _params.lever_swap.map((swap) => ({
93344
- route: swap.route.map((route) => ({
93345
- pool_key: {
93346
- token0: route.pool_key.token0.toBigInt(),
93347
- token1: route.pool_key.token1.toBigInt(),
93348
- fee: route.pool_key.fee,
93349
- tick_spacing: route.pool_key.tick_spacing,
93350
- extension: ContractAddr.from(route.pool_key.extension).toBigInt()
93351
- },
93352
- sqrt_ratio_limit: uint256_exports.bnToUint256(route.sqrt_ratio_limit.toWei()),
93353
- skip_ahead: BigInt(route.skip_ahead.toWei())
93354
- })),
93355
- token_amount: {
93356
- token: swap.token_amount.token.toBigInt(),
93357
- amount: swap.token_amount.amount.toI129()
93358
- }
93359
- })),
93360
- lever_swap_limit_amount: BigInt(_params.lever_swap_limit_amount.toWei()),
93361
- lever_swap_weights: _params.lever_swap_weights.map((weight) => BigInt(weight.toWei())),
93362
- withdraw_swap: _params.withdraw_swap.map((swap) => ({
93363
- route: swap.route.map((route) => ({
93364
- pool_key: {
93365
- token0: route.pool_key.token0.toBigInt(),
93366
- token1: route.pool_key.token1.toBigInt(),
93367
- fee: route.pool_key.fee,
93368
- tick_spacing: route.pool_key.tick_spacing,
93369
- extension: ContractAddr.from(route.pool_key.extension).toBigInt()
93370
- },
93371
- sqrt_ratio_limit: uint256_exports.bnToUint256(route.sqrt_ratio_limit.toWei()),
93372
- skip_ahead: BigInt(route.skip_ahead.toWei())
93373
- })),
93374
- token_amount: {
93375
- token: swap.token_amount.token.toBigInt(),
93376
- amount: swap.token_amount.amount.toI129()
93377
- }
93378
- })),
93379
- withdraw_swap_limit_amount: BigInt(_params.withdraw_swap_limit_amount.toWei()),
93380
- withdraw_swap_weights: _params.withdraw_swap_weights.map((weight) => BigInt(weight.toWei())),
93381
- close_position: _params.close_position
93382
- } })
93590
+ withdraw_swap_limit_amount: BigInt(
93591
+ _params.withdraw_swap_limit_amount.toWei()
93592
+ ),
93593
+ withdraw_swap_weights: _params.withdraw_swap_weights.map(
93594
+ (weight) => BigInt(weight.toWei())
93595
+ ),
93596
+ close_position: _params.close_position
93597
+ }
93598
+ })
93383
93599
  };
93384
93600
  }
93385
93601
  async getHealthFactor() {
@@ -93388,11 +93604,15 @@ spurious results.`);
93388
93604
  }
93389
93605
  async getNetAPY() {
93390
93606
  const positions = await this.getPositions();
93391
- logger2.verbose(`${this.name}::getNetAPY: positions: ${JSON.stringify(positions)}`);
93607
+ logger2.verbose(
93608
+ `${this.name}::getNetAPY: positions: ${JSON.stringify(positions)}`
93609
+ );
93392
93610
  const allZero = positions.every((p) => p.usdValue === 0);
93393
93611
  if (allZero) {
93394
93612
  const collateralUSD = 1e3;
93395
- const maxLTV = await this.vesuAdapter.getLTVConfig(this.config.networkConfig);
93613
+ const maxLTV = await this.vesuAdapter.getLTVConfig(
93614
+ this.config.networkConfig
93615
+ );
93396
93616
  const targetHF = this.config.targetHealthFactor;
93397
93617
  const maxDebt = HealthFactorMath.getMaxDebtAmountOnLooping(
93398
93618
  new Web3Number(collateralUSD, this.config.collateral.decimals),
@@ -93426,12 +93646,17 @@ spurious results.`);
93426
93646
  timeout: this.config.extendedTimeout,
93427
93647
  retries: this.config.extendedRetries
93428
93648
  });
93649
+ this.minimumExtendedMovementAmount = this.config.minimumExtendedMovementAmount ?? 5;
93429
93650
  this.client = client;
93651
+ this.retryDelayForOrderStatus = this.config.retryDelayForOrderStatus ?? 3e3;
93430
93652
  }
93431
93653
  //abstract means the method has no implementation in this class; instead, child classes must implement it.
93432
93654
  async getAPY(supportedPosition) {
93433
93655
  const side = supportedPosition.isDebt ? "LONG" : "SHORT";
93434
- const fundingRates = await this.client.getFundingRates(this.config.extendedMarketName, side);
93656
+ const fundingRates = await this.client.getFundingRates(
93657
+ this.config.extendedMarketName,
93658
+ side
93659
+ );
93435
93660
  if (fundingRates.status !== "OK") {
93436
93661
  logger2.error("error getting funding rates", fundingRates);
93437
93662
  return { apy: 0, type: "base" /* BASE */ };
@@ -93475,14 +93700,14 @@ spurious results.`);
93475
93700
  });
93476
93701
  }
93477
93702
  _getDepositLeaf() {
93478
- const usdceToken = Global.getDefaultTokens().find((token) => token.symbol === "USDCe");
93703
+ const usdceToken = Global.getDefaultTokens().find(
93704
+ (token) => token.symbol === "USDCe"
93705
+ );
93479
93706
  return [
93480
93707
  {
93481
93708
  target: this.config.supportedPositions[0].asset.address,
93482
93709
  method: "approve",
93483
- packedArguments: [
93484
- AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()
93485
- ],
93710
+ packedArguments: [AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()],
93486
93711
  id: `extended_approve_${this.config.supportedPositions[0].asset.symbol}`,
93487
93712
  sanitizer: AVNU_LEGACY_SANITIZER
93488
93713
  },
@@ -93509,17 +93734,62 @@ spurious results.`);
93509
93734
  }
93510
93735
  ];
93511
93736
  }
93737
+ getSwapFromLegacyLeaf() {
93738
+ const leafConfigs = this._getSwapFromLegacyLeaf();
93739
+ const leaves = leafConfigs.map((config3) => {
93740
+ const { target, method, packedArguments, sanitizer, id } = config3;
93741
+ const leaf = this.constructSimpleLeafData(
93742
+ {
93743
+ id,
93744
+ target,
93745
+ method,
93746
+ packedArguments
93747
+ },
93748
+ sanitizer
93749
+ );
93750
+ return leaf;
93751
+ });
93752
+ return {
93753
+ leaves,
93754
+ callConstructor: this.getSwapFromLegacyCall.bind(
93755
+ this
93756
+ )
93757
+ };
93758
+ }
93759
+ _getSwapFromLegacyLeaf() {
93760
+ const usdceToken = Global.getDefaultTokens().find(
93761
+ (token) => token.symbol === "USDCe"
93762
+ );
93763
+ return [
93764
+ {
93765
+ target: usdceToken.address,
93766
+ method: "approve",
93767
+ packedArguments: [AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()],
93768
+ id: `extendedswaplegacyapprove_${usdceToken.symbol}`,
93769
+ sanitizer: AVNU_LEGACY_SANITIZER
93770
+ },
93771
+ {
93772
+ target: AVNU_EXCHANGE_FOR_LEGACY_USDC,
93773
+ method: "swap_to_new",
93774
+ packedArguments: [],
93775
+ id: `extended_swap_to_new_${usdceToken.symbol}`,
93776
+ sanitizer: AVNU_LEGACY_SANITIZER
93777
+ }
93778
+ ];
93779
+ }
93512
93780
  _getWithdrawLeaf() {
93513
93781
  return [];
93514
93782
  }
93515
93783
  async getDepositCall(params) {
93516
93784
  try {
93517
93785
  const usdcToken = this.config.supportedPositions[0].asset;
93518
- const usdceToken = Global.getDefaultTokens().find((token) => token.symbol === "USDCe");
93519
- const salt = Math.floor(
93520
- Math.random() * 10 ** usdcToken.decimals
93786
+ const usdceToken = Global.getDefaultTokens().find(
93787
+ (token) => token.symbol === "USDCe"
93788
+ );
93789
+ const salt = Math.floor(Math.random() * 10 ** usdcToken.decimals);
93790
+ const amount = uint256_exports.bnToUint256(
93791
+ params.amount.multipliedBy(10).toWei()
93521
93792
  );
93522
- const amount = uint256_exports.bnToUint256(params.amount.multipliedBy(10).toWei());
93523
93793
  const quotes = await this.config.avnuAdapter.getQuotesAvnu(
93524
93794
  usdcToken.address.toString(),
93525
93795
  usdceToken.address.toString(),
@@ -93532,7 +93802,9 @@ spurious results.`);
93532
93802
  logger2.error("error getting quotes from avnu");
93533
93803
  return [];
93534
93804
  }
93535
- const getCalldata = await this.config.avnuAdapter.getSwapCallData(quotes);
93805
+ const getCalldata = await this.config.avnuAdapter.getSwapCallData(
93806
+ quotes
93807
+ );
93536
93808
  const swapCallData = getCalldata[0];
93537
93809
  return [
93538
93810
  {
@@ -93589,6 +93861,76 @@ spurious results.`);
93589
93861
  return [];
93590
93862
  }
93591
93863
  }
93864
+ getProofsForFromLegacySwap(tree) {
93865
+ let proofGroups = [];
93866
+ const ids = this.getSwapFromLegacyLeaf().leaves.map((l) => l.readableId);
93867
+ for (const [i, v] of tree.entries()) {
93868
+ if (ids.includes(v.readableId)) {
93869
+ proofGroups.push(tree.getProof(i));
93870
+ }
93871
+ }
93872
+ if (proofGroups.length != ids.length) {
93873
+ throw new Error(`Not all proofs found for IDs: ${ids.join(", ")}`);
93874
+ }
93875
+ return {
93876
+ proofs: proofGroups,
93877
+ callConstructor: this.getSwapFromLegacyCall.bind(this)
93878
+ };
93879
+ }
93880
+ async getSwapFromLegacyCall(params) {
93881
+ try {
93882
+ const usdcToken = this.config.supportedPositions[0].asset;
93883
+ const usdceToken = Global.getDefaultTokens().find(
93884
+ (token) => token.symbol === "USDCe"
93885
+ );
93886
+ const amount = uint256_exports.bnToUint256(
93887
+ params.amount.multipliedBy(10).toWei()
93888
+ );
93889
+ const quotes = await this.config.avnuAdapter.getQuotesAvnu(
93890
+ usdceToken.address.toString(),
93891
+ usdcToken.address.toString(),
93892
+ params.amount.toNumber(),
93893
+ this.config.avnuAdapter.config.vaultAllocator.address.toString(),
93894
+ usdcToken.decimals,
93895
+ false
93896
+ );
93897
+ if (!quotes) {
93898
+ logger2.error("error getting quotes from avnu");
93899
+ return [];
93900
+ }
93901
+ const getCalldata = await this.config.avnuAdapter.getSwapCallData(
93902
+ quotes
93903
+ );
93904
+ const swapCallData = getCalldata[0];
93905
+ return [
93906
+ {
93907
+ sanitizer: AVNU_LEGACY_SANITIZER,
93908
+ call: {
93909
+ contractAddress: usdceToken.address,
93910
+ selector: hash_exports.getSelectorFromName("approve"),
93911
+ calldata: [
93912
+ AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt(),
93913
+ toBigInt3(amount.low.toString()),
93914
+ // amount low
93915
+ toBigInt3(amount.high.toString())
93916
+ // amount high
93917
+ ]
93918
+ }
93919
+ },
93920
+ {
93921
+ sanitizer: AVNU_LEGACY_SANITIZER,
93922
+ call: {
93923
+ contractAddress: AVNU_EXCHANGE_FOR_LEGACY_USDC,
93924
+ selector: hash_exports.getSelectorFromName("swap_to_new"),
93925
+ calldata: swapCallData
93926
+ }
93927
+ }
93928
+ ];
93929
+ } catch (error2) {
93930
+ logger2.error(`Error creating Deposit Call: ${error2}`);
93931
+ return [];
93932
+ }
93933
+ }
93592
93934
  //Swap wbtc to usdc
93593
93935
  async getWithdrawCall(params) {
93594
93936
  try {
@@ -93604,13 +93946,60 @@ spurious results.`);
93604
93946
  async withdrawFromExtended(amount) {
93605
93947
  try {
93606
93948
  if (!this.client) {
93607
- throw new Error("Client not initialized");
93949
+ logger2.error("Client not initialized");
93950
+ return false;
93608
93951
  }
93609
- const withdrawalRequest = this.client.withdrawUSDC(amount.toString());
93610
- if ((await withdrawalRequest).status === "OK") {
93611
- console.log("Withdrawal request successful");
93612
- return true;
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;
93613
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
+ );
93990
+ const withdrawalRequest = await this.client.withdrawUSDC(
93991
+ amount.toFixed(2)
93992
+ );
93993
+ if (withdrawalRequest.status === "OK") {
93994
+ const withdrawalStatus = await this.getDepositOrWithdrawalStatus(
93995
+ withdrawalRequest.data,
93996
+ "WITHDRAWAL" /* WITHDRAWAL */
93997
+ );
93998
+ return withdrawalStatus;
93999
+ }
94000
+ logger2.error(
94001
+ `Withdrawal request failed with status: ${withdrawalRequest.status}`
94002
+ );
93614
94003
  return false;
93615
94004
  } catch (error2) {
93616
94005
  logger2.error(`Error creating Withdraw Call: ${error2}`);
@@ -93621,21 +94010,44 @@ spurious results.`);
93621
94010
  return Promise.resolve(1);
93622
94011
  }
93623
94012
  async getExtendedDepositAmount() {
93624
- if (this.client === null) {
93625
- logger2.error("error initializing client");
93626
- return void 0;
93627
- }
93628
- const result2 = await this.client.getHoldings();
93629
- if (!result2) {
93630
- logger2.error(`error getting holdings: ${result2}`);
93631
- return void 0;
93632
- }
93633
- const holdings = result2.data;
93634
- if (!holdings) {
93635
- 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}`);
93636
94049
  return void 0;
93637
94050
  }
93638
- return holdings;
93639
94051
  }
93640
94052
  async setLeverage(leverage, marketName) {
93641
94053
  if (this.client === null) {
@@ -93677,21 +94089,24 @@ spurious results.`);
93677
94089
  return result2.data;
93678
94090
  }
93679
94091
  async getOrderStatus(orderId, marketName) {
93680
- if (this.client === null) {
93681
- logger2.error("error initializing client");
93682
- return null;
93683
- }
93684
- const orderhistory = await this.getOrderHistory(marketName);
93685
- if (!orderhistory || orderhistory.length === 0) {
93686
- logger2.error(`error getting order: ${orderId}`);
94092
+ try {
94093
+ if (this.client === null) {
94094
+ logger2.error("error initializing client");
94095
+ return null;
94096
+ }
94097
+ const orderhistory = await this.getOrderHistory(marketName);
94098
+ if (!orderhistory || orderhistory.length === 0) {
94099
+ return null;
94100
+ }
94101
+ const order = orderhistory.slice(0, 20).find((order2) => order2.id.toString() === orderId);
94102
+ if (order) {
94103
+ return order;
94104
+ }
93687
94105
  return null;
93688
- }
93689
- const order = orderhistory.slice(0, 3).find((order2) => order2.id.toString() === orderId);
93690
- if (!order) {
93691
- logger2.error(`error getting order: ${order}`);
94106
+ } catch (error2) {
94107
+ logger2.error(`error getting order status: ${error2}`);
93692
94108
  return null;
93693
94109
  }
93694
- return order;
93695
94110
  }
93696
94111
  async fetchOrderBookBTCUSDC() {
93697
94112
  try {
@@ -93742,14 +94157,40 @@ spurious results.`);
93742
94157
  logger2.error("error depositing or setting leverage");
93743
94158
  return null;
93744
94159
  }
93745
- const positions = await this.getAllOpenPositions();
93746
- 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
+ );
93747
94165
  return null;
93748
94166
  }
93749
- const { ask, bid } = await this.fetchOrderBookBTCUSDC();
93750
94167
  const spread3 = ask.minus(bid);
93751
- let price = ask.plus(bid).div(2);
93752
- 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
+ );
93753
94194
  const amount_in_token = (btcAmount * parseInt(leverage)).toFixed(
93754
94195
  this.config.extendedPrecision
93755
94196
  );
@@ -93760,14 +94201,57 @@ spurious results.`);
93760
94201
  price.toFixed(0),
93761
94202
  side
93762
94203
  );
93763
- if (!result2) {
94204
+ if (!result2 || !result2.position_id) {
94205
+ logger2.error("Failed to create order - no position_id returned");
93764
94206
  return null;
93765
94207
  }
93766
- await new Promise((resolve) => setTimeout(resolve, 5e3));
93767
- const openOrder = await this.getOrderStatus(result2.position_id, this.config.extendedMarketName);
93768
- if (!openOrder || openOrder.status !== "FILLED" /* FILLED */) {
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,
94214
+ this.config.extendedMarketName
94215
+ );
94216
+ const maxStatusRetries = 3;
94217
+ const statusRetryDelay = 5e3;
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
+ );
93769
94251
  if (attempt >= maxAttempts) {
93770
- 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
+ );
93771
94255
  return null;
93772
94256
  } else {
93773
94257
  const backoff = 2e3 * attempt;
@@ -93781,16 +94265,21 @@ spurious results.`);
93781
94265
  );
93782
94266
  }
93783
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
+ );
93784
94271
  return {
93785
- position_id: result2.position_id,
93786
- btc_exposure: openOrder.qty
94272
+ position_id: positionId,
94273
+ btc_exposure: amount_in_token
93787
94274
  };
93788
94275
  }
93789
94276
  } catch (err2) {
93790
- logger2.error(`createShortOrder failed on attempt ${attempt}: ${err2.message}`);
94277
+ logger2.error(
94278
+ `createShortOrder failed on attempt ${attempt}: ${err2.message}`
94279
+ );
93791
94280
  if (attempt < maxAttempts) {
93792
94281
  const backoff = 1200 * attempt;
93793
- console.log(`Retrying after ${backoff}ms...`);
94282
+ logger2.info(`Retrying after ${backoff}ms...`);
93794
94283
  await new Promise((resolve) => setTimeout(resolve, backoff));
93795
94284
  return this.createOrder(
93796
94285
  leverage,
@@ -93821,34 +94310,106 @@ spurious results.`);
93821
94310
  }
93822
94311
  return null;
93823
94312
  } catch (err2) {
93824
- console.log("Error opening short extended position", err2);
94313
+ logger2.error(`Error opening short extended position, ${err2}`);
93825
94314
  return null;
93826
94315
  }
93827
94316
  }
93828
94317
  async getDepositOrWithdrawalStatus(orderId, operationsType) {
93829
- try {
93830
- let transferHistory = await this.client.getAssetOperations({
93831
- operationsType: [operationsType],
93832
- operationsStatus: ["COMPLETED" /* COMPLETED */]
93833
- });
93834
- console.log("transferHistory", transferHistory);
93835
- if (operationsType === "DEPOSIT" /* DEPOSIT */) {
93836
- const myTransferStatus = transferHistory.data.find((operation) => operation.transactionHash === orderId);
93837
- if (!myTransferStatus) {
93838
- return false;
94318
+ const maxAttempts = 15;
94319
+ const retryDelayMs = 3e4;
94320
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
94321
+ try {
94322
+ let transferHistory = await this.client.getAssetOperations({
94323
+ operationsType: [operationsType],
94324
+ operationsStatus: ["COMPLETED" /* COMPLETED */]
94325
+ });
94326
+ if (operationsType === "DEPOSIT" /* DEPOSIT */) {
94327
+ const myTransferStatus = transferHistory.data.find(
94328
+ (operation) => operation.transactionHash === orderId
94329
+ );
94330
+ if (!myTransferStatus) {
94331
+ if (attempt < maxAttempts) {
94332
+ logger2.info(
94333
+ `Deposit operation not found for transactionHash ${orderId}, retrying (attempt ${attempt}/${maxAttempts})...`
94334
+ );
94335
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
94336
+ continue;
94337
+ }
94338
+ logger2.warn(
94339
+ `Deposit operation not found for transactionHash ${orderId} after ${maxAttempts} attempts`
94340
+ );
94341
+ return false;
94342
+ }
94343
+ if (myTransferStatus.status === "COMPLETED" /* COMPLETED */) {
94344
+ logger2.info(
94345
+ `Deposit operation ${orderId} completed successfully`
94346
+ );
94347
+ return true;
94348
+ } else {
94349
+ if (attempt < maxAttempts) {
94350
+ logger2.info(
94351
+ `Deposit operation ${orderId} found but status is ${myTransferStatus.status}, not COMPLETED. Retrying (attempt ${attempt}/${maxAttempts})...`
94352
+ );
94353
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
94354
+ continue;
94355
+ }
94356
+ logger2.warn(
94357
+ `Deposit operation ${orderId} status is ${myTransferStatus.status} after ${maxAttempts} attempts, expected COMPLETED`
94358
+ );
94359
+ return false;
94360
+ }
94361
+ } else {
94362
+ const myTransferStatus = transferHistory.data.find(
94363
+ (operation) => operation.id.toString() === orderId.toString()
94364
+ );
94365
+ if (!myTransferStatus) {
94366
+ if (attempt < maxAttempts) {
94367
+ logger2.info(
94368
+ `Withdrawal status not found for orderId ${orderId} in completed operations, retrying (attempt ${attempt}/${maxAttempts})...`
94369
+ );
94370
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
94371
+ continue;
94372
+ }
94373
+ logger2.warn(
94374
+ `Withdrawal operation not found for orderId ${orderId} after ${maxAttempts} attempts`
94375
+ );
94376
+ return false;
94377
+ }
94378
+ if (myTransferStatus.status === "COMPLETED" /* COMPLETED */) {
94379
+ logger2.info(
94380
+ `Withdrawal operation ${orderId} completed successfully`
94381
+ );
94382
+ return true;
94383
+ } else {
94384
+ if (attempt < maxAttempts) {
94385
+ logger2.info(
94386
+ `Withdrawal operation ${orderId} found but status is ${myTransferStatus.status}, not COMPLETED. Retrying (attempt ${attempt}/${maxAttempts})...`
94387
+ );
94388
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
94389
+ continue;
94390
+ }
94391
+ logger2.warn(
94392
+ `Withdrawal operation ${orderId} status is ${myTransferStatus.status} after ${maxAttempts} attempts, expected COMPLETED`
94393
+ );
94394
+ return false;
94395
+ }
93839
94396
  }
93840
- return true;
93841
- } else {
93842
- const myTransferStatus = transferHistory.data.find((operation) => operation.id === orderId);
93843
- if (!myTransferStatus) {
93844
- return false;
94397
+ } catch (err2) {
94398
+ logger2.error(
94399
+ `error getting deposit or withdrawal status (attempt ${attempt}/${maxAttempts}): ${err2}`
94400
+ );
94401
+ if (attempt < maxAttempts) {
94402
+ logger2.info(`Retrying after ${retryDelayMs}ms...`);
94403
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
94404
+ continue;
93845
94405
  }
93846
- return true;
94406
+ logger2.error(
94407
+ `Max retry attempts reached for getDepositOrWithdrawalStatus`
94408
+ );
94409
+ return false;
93847
94410
  }
93848
- } catch (err2) {
93849
- logger2.error(`error getting deposit or withdrawal status: ${err2}`);
93850
- return false;
93851
94411
  }
94412
+ return false;
93852
94413
  }
93853
94414
  };
93854
94415
 
@@ -93934,6 +94495,11 @@ spurious results.`);
93934
94495
  AUMTypes2["DEFISPRING"] = "defispring";
93935
94496
  return AUMTypes2;
93936
94497
  })(AUMTypes || {});
94498
+ var PositionTypeAvnuExtended = /* @__PURE__ */ ((PositionTypeAvnuExtended2) => {
94499
+ PositionTypeAvnuExtended2["OPEN"] = "open";
94500
+ PositionTypeAvnuExtended2["CLOSE"] = "close";
94501
+ return PositionTypeAvnuExtended2;
94502
+ })(PositionTypeAvnuExtended || {});
93937
94503
  var UNIVERSAL_MANAGE_IDS = /* @__PURE__ */ ((UNIVERSAL_MANAGE_IDS2) => {
93938
94504
  UNIVERSAL_MANAGE_IDS2["FLASH_LOAN"] = "flash_loan_init";
93939
94505
  UNIVERSAL_MANAGE_IDS2["VESU_LEG1"] = "vesu_leg1";
@@ -97111,7 +97677,8 @@ spurious results.`);
97111
97677
  minHealthFactor: vaultSettings.minHealthFactor,
97112
97678
  quoteAmountToFetchPrice: vaultSettings.quoteAmountToFetchPrice,
97113
97679
  ...baseAdapterConfig,
97114
- supportedPositions: [{ asset: lstToken, isDebt: false }, { asset: Global.getDefaultTokens().find((token) => token.symbol === position), isDebt: true }]
97680
+ supportedPositions: [{ asset: lstToken, isDebt: false }, { asset: Global.getDefaultTokens().find((token) => token.symbol === position), isDebt: true }],
97681
+ minimumVesuMovementAmount: 0
97115
97682
  }));
97116
97683
  const unusedBalanceAdapter = new UnusedBalanceAdapter({
97117
97684
  ...baseAdapterConfig
@@ -97425,7 +97992,7 @@ spurious results.`);
97425
97992
  packedArguments: [
97426
97993
  fromToken.address.toBigInt(),
97427
97994
  //wbtc
97428
- fromToken.address.toBigInt(),
97995
+ toToken.address.toBigInt(),
97429
97996
  //usdc
97430
97997
  vaultAllocator.toBigInt()
97431
97998
  ],
@@ -97439,13 +98006,11 @@ spurious results.`);
97439
98006
  }
97440
98007
  async getDepositCall(params) {
97441
98008
  try {
97442
- console.log("params.amount", params.amount);
97443
98009
  const fromToken = this.config.supportedPositions[0].asset;
97444
98010
  const toToken = this.config.supportedPositions[1].asset;
97445
98011
  const vaultAllocator = ContractAddr.from(
97446
98012
  this.config.vaultAllocator.address
97447
98013
  );
97448
- console.log("vaultAllocator", vaultAllocator);
97449
98014
  const quote = await this.getQuotesAvnu(
97450
98015
  fromToken.address.toString(),
97451
98016
  toToken.address.toString(),
@@ -97501,7 +98066,6 @@ spurious results.`);
97501
98066
  const vaultAllocator = ContractAddr.from(
97502
98067
  this.config.vaultAllocator.address
97503
98068
  );
97504
- console.log("params.amount", params.amount);
97505
98069
  const quote = await this.getQuotesAvnu(
97506
98070
  fromToken.address.toString(),
97507
98071
  toToken.address.toString(),
@@ -97520,8 +98084,6 @@ spurious results.`);
97520
98084
  );
97521
98085
  const swapCallData = getCalldata[0];
97522
98086
  const amount = uint256_exports.bnToUint256(params.amount.toWei());
97523
- console.log("amount", amount);
97524
- console.log("swapCallData", swapCallData);
97525
98087
  return [
97526
98088
  {
97527
98089
  sanitizer: SIMPLE_SANITIZER,
@@ -97575,7 +98137,7 @@ spurious results.`);
97575
98137
  }
97576
98138
  throw new Error("Failed to fetch quote after retries");
97577
98139
  }
97578
- async getQuotesAvnu(from_token_address, to_token_address, amount, takerAddress, toTokenDecimals, usdcToBtc, maxIterations = 5, tolerance = 1e4) {
98140
+ async getQuotesAvnu(from_token_address, to_token_address, amount, takerAddress, toTokenDecimals, usdcToBtc, maxIterations = 5, tolerance = 5e3) {
97579
98141
  try {
97580
98142
  const fromToken = this.config.supportedPositions[0].asset;
97581
98143
  const toToken = this.config.supportedPositions[1].asset;
@@ -97596,14 +98158,12 @@ spurious results.`);
97596
98158
  return dataObject2;
97597
98159
  }
97598
98160
  const btcPrice = await this.getPriceOfToken(toToken.address.toString());
97599
- console.log("btcPrice", btcPrice);
97600
98161
  if (!btcPrice) {
97601
98162
  logger2.error(`error getting btc price: ${btcPrice}`);
97602
98163
  return null;
97603
98164
  }
97604
98165
  const estimatedUsdcAmount = Math.floor(amount * btcPrice);
97605
98166
  const targetBtcBig = BigInt(returnFormattedAmount(amount, toTokenDecimals));
97606
- console.log("targetBtcBig", targetBtcBig);
97607
98167
  let low = BigInt(
97608
98168
  Math.floor(
97609
98169
  estimatedUsdcAmount * 10 ** fromToken.decimals * 0.9
@@ -97706,6 +98266,23 @@ spurious results.`);
97706
98266
  debtPrice
97707
98267
  };
97708
98268
  }
98269
+ async getUnusedBalanceUSDCE() {
98270
+ const usdceToken = Global.getDefaultTokens().find(
98271
+ (token) => token.symbol === "USDCe"
98272
+ );
98273
+ const balance = await new ERC20(this.config).balanceOf(
98274
+ usdceToken.address,
98275
+ WALLET_ADDRESS,
98276
+ usdceToken.decimals
98277
+ );
98278
+ const price = await this.pricer.getPrice(usdceToken.symbol);
98279
+ const usdValue = Number(balance.toFixed(usdceToken.decimals)) * price.price;
98280
+ return {
98281
+ tokenInfo: usdceToken,
98282
+ amount: balance,
98283
+ usdValue
98284
+ };
98285
+ }
97709
98286
  async getUnusedBalanceWBTC() {
97710
98287
  const collateralToken = this.metadata.additionalInfo.borrowable_assets[0];
97711
98288
  const balance = await new ERC20(this.config).balanceOf(
@@ -97751,22 +98328,30 @@ spurious results.`);
97751
98328
  }
97752
98329
  return extendedAdapter.adapter;
97753
98330
  }
97754
- async moveAssetsToVaultAllocator(amount) {
98331
+ async moveAssetsToVaultAllocator(amount, extendedAdapter) {
97755
98332
  try {
97756
- const usdcToken = Global.getDefaultTokens().find(
97757
- (token) => token.symbol === "USDC"
98333
+ const usdceToken = Global.getDefaultTokens().find(
98334
+ (token) => token.symbol === "USDCe"
97758
98335
  );
97759
98336
  const approveCall = new ERC20(this.config).approve(
97760
- usdcToken.address,
98337
+ usdceToken.address,
97761
98338
  this.metadata.additionalInfo.vaultAllocator,
97762
98339
  amount
97763
98340
  );
97764
98341
  const transferCall = new ERC20(this.config).transfer(
97765
- usdcToken.address,
98342
+ usdceToken.address,
97766
98343
  this.metadata.additionalInfo.vaultAllocator,
97767
98344
  amount
97768
98345
  );
97769
- return [approveCall, transferCall];
98346
+ const proofsInfo = extendedAdapter.getProofsForFromLegacySwap(
98347
+ this.getMerkleTree()
98348
+ );
98349
+ const proofGroups = proofsInfo.proofs;
98350
+ const call = this.getManageCall(
98351
+ proofGroups,
98352
+ await proofsInfo.callConstructor({ amount })
98353
+ );
98354
+ return [approveCall, transferCall, call];
97770
98355
  } catch (err2) {
97771
98356
  logger2.error(`error moving assets to vault allocator: ${err2}`);
97772
98357
  return [];
@@ -97774,11 +98359,27 @@ spurious results.`);
97774
98359
  }
97775
98360
  async shouldInvest() {
97776
98361
  try {
98362
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest starting`);
97777
98363
  const vesuAdapter = await this.getVesuAdapter();
97778
98364
  const extendedAdapter = await this.getExtendedAdapter();
97779
- if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
98365
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest adapters fetched: vesuAdapter=${!!vesuAdapter}, extendedAdapter=${!!extendedAdapter}, extendedAdapter.client=${!!extendedAdapter?.client}`);
98366
+ if (!vesuAdapter) {
97780
98367
  logger2.error(
97781
- `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
98368
+ `Vesu adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
98369
+ );
98370
+ return {
98371
+ shouldInvest: false,
98372
+ vesuAmount: new Web3Number(0, 0),
98373
+ extendedAmount: new Web3Number(0, 0),
98374
+ extendedLeverage: 0,
98375
+ collateralPrice: 0,
98376
+ debtPrice: 0,
98377
+ vesuLeverage: 0
98378
+ };
98379
+ }
98380
+ if (!extendedAdapter) {
98381
+ logger2.error(
98382
+ `Extended adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
97782
98383
  );
97783
98384
  return {
97784
98385
  shouldInvest: false,
@@ -97790,10 +98391,73 @@ spurious results.`);
97790
98391
  vesuLeverage: 0
97791
98392
  };
97792
98393
  }
98394
+ if (!extendedAdapter.client) {
98395
+ logger2.error(
98396
+ `Extended adapter client not initialized. This may be a temporary initialization failure - check network connectivity and API availability.`
98397
+ );
98398
+ return {
98399
+ shouldInvest: false,
98400
+ vesuAmount: new Web3Number(0, 0),
98401
+ extendedAmount: new Web3Number(0, 0),
98402
+ extendedLeverage: 0,
98403
+ collateralPrice: 0,
98404
+ debtPrice: 0,
98405
+ vesuLeverage: 0
98406
+ };
98407
+ }
98408
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest calling getUnusedBalance`);
97793
98409
  const balance = await this.getUnusedBalance();
98410
+ if (!Number.isFinite(balance.usdValue) || balance.usdValue < 0) {
98411
+ logger2.error(
98412
+ `Invalid balance.usdValue: ${balance.usdValue}. Expected a finite, non-negative number.`
98413
+ );
98414
+ return {
98415
+ shouldInvest: false,
98416
+ vesuAmount: new Web3Number(0, 0),
98417
+ extendedAmount: new Web3Number(0, 0),
98418
+ extendedLeverage: 0,
98419
+ collateralPrice: 0,
98420
+ debtPrice: 0,
98421
+ vesuLeverage: 0
98422
+ };
98423
+ }
98424
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest balance: ${balance.usdValue}`);
97794
98425
  const usdcBalanceOnExtended = await extendedAdapter.getExtendedDepositAmount();
97795
- const amountToInvest = balance.amount.plus(usdcBalanceOnExtended?.availableForWithdrawal ?? 0).minus(LIMIT_BALANCE);
97796
- if (amountToInvest.lessThan(0)) {
98426
+ if (usdcBalanceOnExtended) {
98427
+ const availableForWithdrawal = parseFloat(usdcBalanceOnExtended.availableForWithdrawal);
98428
+ if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
98429
+ logger2.error(
98430
+ `Invalid usdcBalanceOnExtended.availableForWithdrawal: ${usdcBalanceOnExtended.availableForWithdrawal}. Expected a finite, non-negative number.`
98431
+ );
98432
+ return {
98433
+ shouldInvest: false,
98434
+ vesuAmount: new Web3Number(0, 0),
98435
+ extendedAmount: new Web3Number(0, 0),
98436
+ extendedLeverage: 0,
98437
+ collateralPrice: 0,
98438
+ debtPrice: 0,
98439
+ vesuLeverage: 0
98440
+ };
98441
+ }
98442
+ }
98443
+ const amountToInvest = new Web3Number(balance.usdValue, USDC_TOKEN_DECIMALS).plus(usdcBalanceOnExtended?.availableForWithdrawal ?? 0).multipliedBy(1 - LIMIT_BALANCE);
98444
+ const amountToInvestNumber = amountToInvest.toNumber();
98445
+ if (!Number.isFinite(amountToInvestNumber)) {
98446
+ logger2.error(
98447
+ `Invalid amountToInvest calculation result: ${amountToInvestNumber}. Calculation may have produced NaN or Infinity.`
98448
+ );
98449
+ return {
98450
+ shouldInvest: false,
98451
+ vesuAmount: new Web3Number(0, 0),
98452
+ extendedAmount: new Web3Number(0, 0),
98453
+ extendedLeverage: 0,
98454
+ collateralPrice: 0,
98455
+ debtPrice: 0,
98456
+ vesuLeverage: 0
98457
+ };
98458
+ }
98459
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvestNumber}`);
98460
+ if (amountToInvest.lessThan(LIMIT_BALANCE_VALUE)) {
97797
98461
  return {
97798
98462
  shouldInvest: false,
97799
98463
  vesuAmount: new Web3Number(0, 0),
@@ -97822,6 +98486,34 @@ spurious results.`);
97822
98486
  collateralPrice,
97823
98487
  debtPrice
97824
98488
  } = await this.getAssetPrices();
98489
+ if (!Number.isFinite(collateralPrice.price) || collateralPrice.price <= 0) {
98490
+ logger2.error(
98491
+ `Invalid collateralPrice: ${collateralPrice.price}. Expected a finite, positive number.`
98492
+ );
98493
+ return {
98494
+ shouldInvest: false,
98495
+ vesuAmount: new Web3Number(0, 0),
98496
+ extendedAmount: new Web3Number(0, 0),
98497
+ extendedLeverage: 0,
98498
+ collateralPrice: 0,
98499
+ debtPrice: 0,
98500
+ vesuLeverage: 0
98501
+ };
98502
+ }
98503
+ if (!Number.isFinite(debtPrice.price) || debtPrice.price <= 0) {
98504
+ logger2.error(
98505
+ `Invalid debtPrice: ${debtPrice.price}. Expected a finite, positive number.`
98506
+ );
98507
+ return {
98508
+ shouldInvest: false,
98509
+ vesuAmount: new Web3Number(0, 0),
98510
+ extendedAmount: new Web3Number(0, 0),
98511
+ extendedLeverage: 0,
98512
+ collateralPrice: 0,
98513
+ debtPrice: 0,
98514
+ vesuLeverage: 0
98515
+ };
98516
+ }
97825
98517
  const { vesu_amount, extended_amount, extended_leverage, vesu_leverage } = await calculateAmountDistribution(
97826
98518
  amountToInvest.toNumber(),
97827
98519
  extendedAdapter.client,
@@ -97845,6 +98537,7 @@ spurious results.`);
97845
98537
  vesuLeverage: 0
97846
98538
  };
97847
98539
  }
98540
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest vesu_amount: ${vesu_amount.toNumber()}, extended_amount: ${extended_amount.toNumber()}`);
97848
98541
  return {
97849
98542
  shouldInvest: true,
97850
98543
  vesuAmount: vesu_amount,
@@ -97871,18 +98564,48 @@ spurious results.`);
97871
98564
  try {
97872
98565
  const vesuAdapter = await this.getVesuAdapter();
97873
98566
  const extendedAdapter = await this.getExtendedAdapter();
97874
- let calls = [];
97875
98567
  if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
97876
98568
  logger2.error(
97877
98569
  `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
97878
98570
  );
97879
- return calls;
98571
+ return [];
97880
98572
  }
97881
- console.log("extendedAmount", extendedAmount);
97882
- console.log("vesuAmount", vesuAmount);
97883
- if (extendedAmount.lessThan(0)) {
98573
+ const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
98574
+ if (!extendedHoldings) {
98575
+ logger2.error(`error getting extended holdings: ${extendedHoldings}`);
98576
+ return [];
98577
+ }
98578
+ const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
98579
+ const usdcAmountOnExtendedAvailableForWithdrawal = parseFloat(
98580
+ extendedHoldings.availableForWithdrawal
98581
+ );
98582
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldMoveAssets calculating movements - Extended current: ${usdcAmountOnExtendedAvailableForWithdrawal}, Wallet: ${usdcAmountInWallet.toNumber()}, Target Extended: ${extendedAmount.toNumber()}, Target Vesu: ${vesuAmount.toNumber()}`);
98583
+ let totalExtendedWithdrawal = new Web3Number(0, USDC_TOKEN_DECIMALS);
98584
+ let totalExtendedDeposit = new Web3Number(0, USDC_TOKEN_DECIMALS);
98585
+ if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
98586
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmount.abs());
98587
+ }
98588
+ const extendedTargetAmount = extendedAmount.abs();
98589
+ let projectedExtendedBalance = usdcAmountOnExtendedAvailableForWithdrawal;
98590
+ if (extendedAmount.isNegative()) {
98591
+ projectedExtendedBalance = projectedExtendedBalance - extendedAmount.abs().toNumber();
98592
+ }
98593
+ const extendedAmountDifference = extendedTargetAmount.minus(projectedExtendedBalance);
98594
+ const extendedAmountDifferenceAbs = extendedAmountDifference.abs();
98595
+ if (extendedAmountDifference.lessThan(0)) {
98596
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmountDifferenceAbs);
98597
+ } else if (extendedAmountDifference.greaterThan(0)) {
98598
+ totalExtendedDeposit = totalExtendedDeposit.plus(extendedAmountDifference);
98599
+ }
98600
+ const vesuTargetAmount = vesuAmount.abs();
98601
+ const projectedWalletBalance = usdcAmountInWallet.plus(totalExtendedWithdrawal).minus(totalExtendedDeposit);
98602
+ let vesuAmountDifference = vesuTargetAmount.minus(projectedWalletBalance);
98603
+ const vesuAmountDifferenceAbs = vesuAmountDifference.abs();
98604
+ 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()}`);
98605
+ let calls = [];
98606
+ if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
97884
98607
  try {
97885
- const extendedCalls = await this.moveAssets(
98608
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
97886
98609
  {
97887
98610
  to: Protocols.VAULT.name,
97888
98611
  from: Protocols.EXTENDED.name,
@@ -97891,14 +98614,18 @@ spurious results.`);
97891
98614
  extendedAdapter,
97892
98615
  vesuAdapter
97893
98616
  );
97894
- calls.push(...extendedCalls);
98617
+ if (extendedStatus) {
98618
+ calls.push(...extendedCalls);
98619
+ } else {
98620
+ return [];
98621
+ }
97895
98622
  } catch (err2) {
97896
98623
  logger2.error(`Failed moving assets to vault: ${err2}`);
97897
98624
  }
97898
98625
  }
97899
- if (vesuAmount.lessThan(0)) {
98626
+ if (vesuAmount.isNegative() && vesuAmount.abs().greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
97900
98627
  try {
97901
- const vesuCalls = await this.moveAssets(
98628
+ const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
97902
98629
  {
97903
98630
  to: Protocols.EXTENDED.name,
97904
98631
  from: Protocols.VESU.name,
@@ -97908,49 +98635,83 @@ spurious results.`);
97908
98635
  vesuAdapter
97909
98636
  );
97910
98637
  calls.push(...vesuCalls);
98638
+ if (!vesuStatus) {
98639
+ return [];
98640
+ }
97911
98641
  } catch (err2) {
97912
98642
  logger2.error(`Failed moving assets to vault: ${err2}`);
97913
98643
  }
97914
98644
  }
97915
- const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
97916
- if (!extendedHoldings) {
97917
- logger2.error(`error getting extended holdings: ${extendedHoldings}`);
97918
- return calls;
97919
- }
97920
- const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
97921
- const usdcAmountOnExtended = parseFloat(
97922
- extendedHoldings.availableForWithdrawal
97923
- );
97924
- if (extendedAmount.minus(usdcAmountOnExtended).greaterThan(0)) {
97925
- try {
97926
- const extendedCalls = await this.moveAssets(
97927
- {
97928
- to: Protocols.EXTENDED.name,
97929
- from: Protocols.VAULT.name,
97930
- amount: extendedAmount.minus(usdcAmountOnExtended)
97931
- },
97932
- extendedAdapter,
97933
- vesuAdapter
97934
- );
97935
- calls.push(...extendedCalls);
97936
- } catch (err2) {
97937
- logger2.error(`Failed moving assets to extended: ${err2}`);
98645
+ if (extendedAmountDifferenceAbs.greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
98646
+ if (extendedAmountDifference.greaterThan(0)) {
98647
+ try {
98648
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
98649
+ {
98650
+ to: Protocols.EXTENDED.name,
98651
+ from: Protocols.VAULT.name,
98652
+ amount: extendedAmountDifference
98653
+ },
98654
+ extendedAdapter,
98655
+ vesuAdapter
98656
+ );
98657
+ if (extendedStatus) {
98658
+ calls.push(...extendedCalls);
98659
+ } else {
98660
+ logger2.error(`Failed to move assets to extended - operation returned false status`);
98661
+ return [];
98662
+ }
98663
+ } catch (err2) {
98664
+ logger2.error(`Failed moving assets to extended: ${err2}`);
98665
+ return [];
98666
+ }
98667
+ } else if (extendedAmountDifference.lessThan(0)) {
98668
+ try {
98669
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
98670
+ {
98671
+ to: Protocols.VAULT.name,
98672
+ from: Protocols.EXTENDED.name,
98673
+ amount: extendedAmountDifferenceAbs
98674
+ },
98675
+ extendedAdapter,
98676
+ vesuAdapter
98677
+ );
98678
+ if (extendedStatus) {
98679
+ calls.push(...extendedCalls);
98680
+ } else {
98681
+ logger2.error(`Failed to withdraw from extended - operation returned false status`);
98682
+ return [];
98683
+ }
98684
+ } catch (err2) {
98685
+ logger2.error(`Failed moving assets from extended to vault: ${err2}`);
98686
+ return [];
98687
+ }
97938
98688
  }
97939
98689
  }
97940
- if (vesuAmount.minus(usdcAmountInWallet).greaterThan(0)) {
97941
- try {
97942
- const vesuCalls = await this.moveAssets(
97943
- {
97944
- to: Protocols.VESU.name,
97945
- from: Protocols.EXTENDED.name,
97946
- amount: vesuAmount.minus(usdcAmountInWallet)
97947
- },
97948
- extendedAdapter,
97949
- vesuAdapter
98690
+ if (vesuAmountDifferenceAbs.greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
98691
+ if (vesuAmountDifference.lessThanOrEqualTo(0)) {
98692
+ logger2.warn(
98693
+ `Vesu amount difference is negative or zero: ${vesuAmountDifference.toNumber()}. Skipping operation.`
97950
98694
  );
97951
- calls.push(...vesuCalls);
97952
- } catch (err2) {
97953
- logger2.error(`Failed moving assets to vault: ${err2}`);
98695
+ } else {
98696
+ try {
98697
+ const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
98698
+ {
98699
+ to: Protocols.VAULT.name,
98700
+ from: Protocols.EXTENDED.name,
98701
+ amount: vesuAmountDifference
98702
+ },
98703
+ extendedAdapter,
98704
+ vesuAdapter
98705
+ );
98706
+ if (!vesuStatus) {
98707
+ logger2.error(`Failed to move assets to vesu - operation returned false status`);
98708
+ return [];
98709
+ }
98710
+ calls.push(...vesuCalls);
98711
+ } catch (err2) {
98712
+ logger2.error(`Failed moving assets to vault: ${err2}`);
98713
+ return [];
98714
+ }
97954
98715
  }
97955
98716
  }
97956
98717
  return calls;
@@ -97961,12 +98722,47 @@ spurious results.`);
97961
98722
  }
97962
98723
  async moveAssets(params, extendedAdapter, vesuAdapter) {
97963
98724
  try {
98725
+ if (params.amount.lessThanOrEqualTo(0)) {
98726
+ logger2.error(
98727
+ `Invalid amount for moveAssets: ${params.amount.toNumber()}. Amount must be positive.`
98728
+ );
98729
+ return {
98730
+ calls: [],
98731
+ status: false
98732
+ };
98733
+ }
98734
+ const amountAbs = params.amount.abs();
98735
+ if (params.from === Protocols.EXTENDED.name || params.to === Protocols.EXTENDED.name) {
98736
+ if (amountAbs.lessThanOrEqualTo(extendedAdapter.minimumExtendedMovementAmount)) {
98737
+ logger2.warn(
98738
+ `Amount ${amountAbs.toNumber()} is below minimum Extended movement amount ${extendedAdapter.minimumExtendedMovementAmount}. Skipping operation.`
98739
+ );
98740
+ return {
98741
+ calls: [],
98742
+ status: false
98743
+ };
98744
+ }
98745
+ }
98746
+ if (params.from === Protocols.VESU.name || params.to === Protocols.VESU.name) {
98747
+ if (amountAbs.lessThanOrEqualTo(vesuAdapter.minimumVesuMovementAmount)) {
98748
+ logger2.warn(
98749
+ `Amount ${amountAbs.toNumber()} is below minimum Vesu movement amount ${vesuAdapter.minimumVesuMovementAmount}. Skipping operation.`
98750
+ );
98751
+ return {
98752
+ calls: [],
98753
+ status: false
98754
+ };
98755
+ }
98756
+ }
97964
98757
  const avnuAdapter = await this.getAvnuAdapter();
97965
98758
  if (!avnuAdapter) {
97966
98759
  logger2.error(`avnu adapter not found: ${avnuAdapter}`);
97967
- return [];
98760
+ return {
98761
+ calls: [],
98762
+ status: false
98763
+ };
97968
98764
  }
97969
- logger2.info("moveAssets params", params);
98765
+ logger2.info(`moveAssets params, ${JSON.stringify(params)}`);
97970
98766
  const collateralToken = vesuAdapter.config.supportedPositions[0].asset;
97971
98767
  const {
97972
98768
  collateralPrice
@@ -97983,19 +98779,76 @@ spurious results.`);
97983
98779
  await proofsInfo.callConstructor({ amount: params.amount })
97984
98780
  );
97985
98781
  calls.push(call);
97986
- return calls;
98782
+ return {
98783
+ calls: [call],
98784
+ status: true
98785
+ };
97987
98786
  } else if (params.to === Protocols.VAULT.name && params.from === Protocols.EXTENDED.name) {
98787
+ const extendedLeverage = calculateExtendedLevergae();
98788
+ const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
98789
+ if (!extendedHoldings) {
98790
+ logger2.error(`error getting extended holdings: ${extendedHoldings}`);
98791
+ return {
98792
+ calls: [],
98793
+ status: false
98794
+ };
98795
+ }
98796
+ const extendedHoldingAmount = new Web3Number(
98797
+ extendedHoldings.availableForWithdrawal,
98798
+ USDC_TOKEN_DECIMALS
98799
+ );
98800
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::moveAssets extendedHoldingAmount: ${extendedHoldingAmount.toNumber()}`);
98801
+ if (params.amount.abs().greaterThan(extendedHoldingAmount)) {
98802
+ const leftAmountAfterWithdrawalAmountInAccount = params.amount.abs().minus(extendedHoldingAmount);
98803
+ logger2.info(`${_VesuExtendedMultiplierStrategy.name}::moveAssets leftAmountAfterWithdrawalAmountInAccount: ${leftAmountAfterWithdrawalAmountInAccount.toNumber()}`);
98804
+ const btcAmount = leftAmountAfterWithdrawalAmountInAccount.dividedBy(collateralPrice.price);
98805
+ const openLongPosition = btcAmount.multipliedBy(3).greaterThan(MINIMUM_EXTENDED_POSITION_SIZE) ? await extendedAdapter.createOrder(
98806
+ extendedLeverage.toString(),
98807
+ btcAmount.toNumber(),
98808
+ "BUY" /* BUY */
98809
+ ) : await extendedAdapter.createOrder(
98810
+ extendedLeverage.toString(),
98811
+ 35e-6,
98812
+ // just in case amount falls short then we need to create a withdrawal
98813
+ "BUY" /* BUY */
98814
+ );
98815
+ if (!openLongPosition) {
98816
+ logger2.error(`error opening long position: ${openLongPosition}`);
98817
+ }
98818
+ const updatedHoldings = await extendedAdapter.getExtendedDepositAmount();
98819
+ if (!updatedHoldings || new Web3Number(updatedHoldings.availableForWithdrawal, USDC_TOKEN_DECIMALS).lessThan(params.amount.abs())) {
98820
+ logger2.error(`Insufficient balance after opening position. Available: ${updatedHoldings?.availableForWithdrawal}, Needed: ${params.amount.abs()}`);
98821
+ return { calls: [], status: false };
98822
+ }
98823
+ }
97988
98824
  const withdrawalFromExtended = await extendedAdapter.withdrawFromExtended(params.amount);
97989
98825
  if (withdrawalFromExtended) {
97990
- const calls = await this.moveAssetsToVaultAllocator(params.amount);
98826
+ const extendedHoldings2 = await extendedAdapter.getExtendedDepositAmount();
98827
+ logger2.info(`extendedHoldings after withdrawal ${extendedHoldings2?.availableForWithdrawal}`);
98828
+ await new Promise((resolve) => setTimeout(resolve, 5e3));
98829
+ const calls = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
97991
98830
  if (calls.length > 0) {
97992
- return calls;
98831
+ return {
98832
+ calls,
98833
+ status: true
98834
+ };
97993
98835
  }
97994
98836
  } else {
97995
98837
  logger2.error("withdrawal from extended failed");
98838
+ return {
98839
+ calls: [],
98840
+ status: false
98841
+ };
97996
98842
  }
97997
- return [];
97998
98843
  } else if (params.to === Protocols.VAULT.name && params.from === Protocols.VESU.name) {
98844
+ const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, "close" /* CLOSE */);
98845
+ if (!isPriceDifferenceBetweenAvnuAndExtended) {
98846
+ logger2.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
98847
+ return {
98848
+ calls: [],
98849
+ status: false
98850
+ };
98851
+ }
97999
98852
  const vesuAmountInBTC = new Web3Number(
98000
98853
  params.amount.dividedBy(collateralPrice.price).toNumber(),
98001
98854
  collateralToken.decimals
@@ -98015,8 +98868,19 @@ spurious results.`);
98015
98868
  await swapProofsInfo.callConstructor({ amount: vesuAmountInBTC })
98016
98869
  );
98017
98870
  calls.push(swapCall);
98018
- return calls;
98871
+ return {
98872
+ calls,
98873
+ status: true
98874
+ };
98019
98875
  } else if (params.to === Protocols.EXTENDED.name && params.from === Protocols.VESU.name) {
98876
+ const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, "close" /* CLOSE */);
98877
+ if (!isPriceDifferenceBetweenAvnuAndExtended) {
98878
+ logger2.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
98879
+ return {
98880
+ calls: [],
98881
+ status: false
98882
+ };
98883
+ }
98020
98884
  const vesuAmountInBTC = new Web3Number(
98021
98885
  params.amount.dividedBy(collateralPrice.price).toNumber(),
98022
98886
  collateralToken.decimals
@@ -98046,13 +98910,21 @@ spurious results.`);
98046
98910
  await proofsInfoDeposit.callConstructor({ amount: params.amount })
98047
98911
  );
98048
98912
  calls.push(callDeposit);
98049
- return calls;
98913
+ return {
98914
+ calls,
98915
+ status: true
98916
+ };
98050
98917
  }
98051
- console.warn("moveAssets received unsupported route:", params);
98052
- return [];
98918
+ return {
98919
+ calls: [],
98920
+ status: false
98921
+ };
98053
98922
  } catch (err2) {
98054
98923
  logger2.error(`error moving assets: ${err2}`);
98055
- return [];
98924
+ return {
98925
+ calls: [],
98926
+ status: false
98927
+ };
98056
98928
  }
98057
98929
  }
98058
98930
  async handleDeposit() {
@@ -98072,7 +98944,7 @@ spurious results.`);
98072
98944
  };
98073
98945
  }
98074
98946
  const extendedLeverage = calculateExtendedLevergae();
98075
- const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter);
98947
+ const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, "open" /* OPEN */);
98076
98948
  if (!isPriceDifferenceBetweenAvnuAndExtended) {
98077
98949
  logger2.error("price difference between avnu and extended doesn't fit the range");
98078
98950
  return {
@@ -98089,6 +98961,7 @@ spurious results.`);
98089
98961
  };
98090
98962
  }
98091
98963
  const extendedPositionValue = position.length > 0 ? parseFloat(position[0].value) : 0;
98964
+ const BUFFER_AMOUNT_IN_AVAILABLE_FOR_TRADE = BUFFER_USDC_IN_WITHDRAWAL;
98092
98965
  const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
98093
98966
  if (!extendedHoldings) {
98094
98967
  logger2.error(`error getting extended holdings: ${extendedHoldings}`);
@@ -98107,12 +98980,11 @@ spurious results.`);
98107
98980
  const { collateralPrice } = await this.getAssetPrices();
98108
98981
  const { vesuAmountInBTC, extendedAmountInBTC } = calculateVesUPositionSizeGivenExtended(
98109
98982
  extendedPositionValue,
98110
- extendedHoldingAmount,
98983
+ extendedHoldingAmount.minus(BUFFER_AMOUNT_IN_AVAILABLE_FOR_TRADE),
98111
98984
  collateralTokenAmount,
98112
98985
  collateralPrice.price
98113
98986
  );
98114
- console.log("vesuAmountInBTC", vesuAmountInBTC);
98115
- console.log("extendedAmountInBTC", extendedAmountInBTC);
98987
+ logger2.info(`vesuAmountInBTC ${vesuAmountInBTC}, extendedAmountInBTC ${extendedAmountInBTC}`);
98116
98988
  let calls = [];
98117
98989
  if (vesuAmountInBTC.greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)) {
98118
98990
  const proofsInfo = vesuAdapter.getProofs(true, this.getMerkleTree());
@@ -98125,7 +98997,6 @@ spurious results.`);
98125
98997
  );
98126
98998
  const { amount: wbtcAmountInVaultAllocator } = await this.getUnusedBalanceWBTC();
98127
98999
  if (wbtcAmountInVaultAllocator.lessThan(vesuAmountInBTC)) {
98128
- console.log("error wbtc amount in vault allocator is less than vesu amount in btc", wbtcAmountInVaultAllocator, vesuAmountInBTC);
98129
99000
  const swapProofsInfo = avnuAdapter.getProofs(true, this.getMerkleTree());
98130
99001
  const swapProofGroups = swapProofsInfo.proofs;
98131
99002
  const swapCall = this.getManageCall(
@@ -98160,68 +99031,98 @@ spurious results.`);
98160
99031
  extendedAmountInBTC: new Web3Number(0, 0),
98161
99032
  calls: []
98162
99033
  };
98163
- ;
98164
99034
  }
98165
99035
  }
98166
- async checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter) {
99036
+ async checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, positionType) {
98167
99037
  const {
98168
99038
  ask,
98169
99039
  bid
98170
99040
  } = await extendedAdapter.fetchOrderBookBTCUSDC();
98171
99041
  const price = ask.plus(bid).dividedBy(2);
98172
- const btcToken = vesuAdapter.config.supportedPositions[1].asset;
99042
+ const btcToken = vesuAdapter.config.supportedPositions[0].asset;
98173
99043
  const btcPriceAvnu = await avnuAdapter.getPriceOfToken(btcToken.address.toString());
98174
99044
  if (!btcPriceAvnu) {
98175
99045
  logger2.error(`error getting btc price avnu: ${btcPriceAvnu}`);
98176
99046
  return false;
98177
99047
  }
98178
- const priceDifference = price.minus(btcPriceAvnu).toNumber();
98179
- if (priceDifference < MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED && priceDifference > MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED) {
98180
- return true;
99048
+ const priceDifference = new Web3Number(price.minus(btcPriceAvnu).toFixed(2), 0);
99049
+ if (priceDifference.isNegative()) {
99050
+ return false;
99051
+ }
99052
+ if (positionType === "open" /* OPEN */) {
99053
+ logger2.info(`price difference between avnu and extended for open position: ${priceDifference.toNumber()}, minimumExtendedPriceDifferenceForSwapOpen: ${avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen}`);
99054
+ const result2 = priceDifference.greaterThanOrEqualTo(avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen);
99055
+ logger2.info(`result: ${result2}`);
99056
+ return result2;
99057
+ } else {
99058
+ logger2.info(`price difference between avnu and extended for close position: ${priceDifference.toNumber()}, maximumExtendedPriceDifferenceForSwapClosing: ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
99059
+ const result2 = priceDifference.lessThanOrEqualTo(avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing);
99060
+ logger2.info(`result: ${result2}`);
99061
+ return result2;
98181
99062
  }
98182
- logger2.error(`price difference between avnu and extended doesn't fit the range, priceDifference: ${priceDifference}`);
98183
- return false;
98184
99063
  }
98185
99064
  async handleWithdraw(amount) {
98186
99065
  try {
98187
99066
  const usdcBalanceVaultAllocator = await this.getUnusedBalance();
98188
- const usdcBalanceDifference = amount.minus(usdcBalanceVaultAllocator.usdValue);
99067
+ const usdcBalanceDifference = amount.plus(BUFFER_USDC_IN_WITHDRAWAL).minus(usdcBalanceVaultAllocator.usdValue);
98189
99068
  logger2.info(`usdcBalanceDifference, ${usdcBalanceDifference.toNumber()}`);
99069
+ let calls = [];
99070
+ let status = true;
98190
99071
  if (usdcBalanceDifference.lessThan(0)) {
98191
- const withdrawCall = await this.getBringLiquidityCall({
98192
- amount
99072
+ const withdrawCall2 = await this.getBringLiquidityCall({
99073
+ amount: usdcBalanceVaultAllocator.amount
98193
99074
  });
98194
- logger2.info("withdraw call", withdrawCall);
98195
- return [withdrawCall];
99075
+ logger2.info("withdraw call", withdrawCall2);
99076
+ calls.push(withdrawCall2);
99077
+ return {
99078
+ calls,
99079
+ status: true
99080
+ };
98196
99081
  }
98197
99082
  const vesuAdapter = await this.getVesuAdapter();
98198
99083
  const extendedAdapter = await this.getExtendedAdapter();
98199
99084
  if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
99085
+ status = false;
98200
99086
  logger2.error(
98201
99087
  `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
98202
99088
  );
98203
- return [];
99089
+ return {
99090
+ calls,
99091
+ status
99092
+ };
98204
99093
  }
98205
99094
  const { collateralTokenAmount } = await vesuAdapter.vesuAdapter.getAssetPrices();
98206
99095
  const {
98207
99096
  collateralPrice
98208
99097
  } = await this.getAssetPrices();
98209
99098
  const extendedPositon = await extendedAdapter.getAllOpenPositions();
99099
+ if (!extendedPositon) {
99100
+ status = false;
99101
+ logger2.error("error getting extended position", extendedPositon);
99102
+ return {
99103
+ calls,
99104
+ status
99105
+ };
99106
+ }
98210
99107
  const amountDistributionForWithdrawal = await calculateAmountDistributionForWithdrawal(
98211
- amount,
99108
+ usdcBalanceDifference,
98212
99109
  collateralPrice.price,
98213
99110
  collateralTokenAmount,
98214
99111
  extendedPositon
98215
99112
  );
98216
99113
  if (!amountDistributionForWithdrawal) {
99114
+ status = false;
98217
99115
  logger2.error(
98218
99116
  `error calculating amount distribution for withdrawal: ${amountDistributionForWithdrawal}`
98219
99117
  );
98220
- return [];
99118
+ return {
99119
+ calls,
99120
+ status
99121
+ };
98221
99122
  }
98222
99123
  const { vesu_amount, extended_amount } = amountDistributionForWithdrawal;
98223
- if (vesu_amount.greaterThan(0)) {
98224
- const result2 = await this.moveAssets(
99124
+ if (status && vesu_amount.greaterThan(0)) {
99125
+ const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
98225
99126
  {
98226
99127
  amount: vesu_amount,
98227
99128
  from: Protocols.VESU.name,
@@ -98230,10 +99131,11 @@ spurious results.`);
98230
99131
  extendedAdapter,
98231
99132
  vesuAdapter
98232
99133
  );
98233
- return result2;
99134
+ status = vesuStatus;
99135
+ calls.push(...vesuCalls);
98234
99136
  }
98235
- if (extended_amount.greaterThan(0)) {
98236
- const result2 = await this.moveAssets(
99137
+ if (status && extended_amount.greaterThan(0)) {
99138
+ const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
98237
99139
  {
98238
99140
  amount: extended_amount,
98239
99141
  from: Protocols.EXTENDED.name,
@@ -98242,12 +99144,32 @@ spurious results.`);
98242
99144
  extendedAdapter,
98243
99145
  vesuAdapter
98244
99146
  );
98245
- return result2;
99147
+ status = extendedStatus;
99148
+ if (status) {
99149
+ calls.push(...extendedCalls);
99150
+ } else {
99151
+ logger2.error("error moving assets to vault: extendedStatus: ${extendedStatus}");
99152
+ return {
99153
+ calls: [],
99154
+ status
99155
+ };
99156
+ }
98246
99157
  }
98247
- return [];
99158
+ const withdrawCall = await this.getBringLiquidityCall({
99159
+ amount
99160
+ });
99161
+ logger2.info("withdraw call", withdrawCall);
99162
+ calls.push(withdrawCall);
99163
+ return {
99164
+ calls,
99165
+ status
99166
+ };
98248
99167
  } catch (err2) {
98249
99168
  logger2.error(`error handling withdrawal: ${err2}`);
98250
- return [];
99169
+ return {
99170
+ calls: [],
99171
+ status: false
99172
+ };
98251
99173
  }
98252
99174
  }
98253
99175
  async getAUM() {
@@ -98295,7 +99217,7 @@ spurious results.`);
98295
99217
  };
98296
99218
  }
98297
99219
  };
98298
- function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1, extendedBackendUrl, extendedApiKey, vaultIdExtended) {
99220
+ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1, extendedBackendUrl, extendedApiKey, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing) {
98299
99221
  vaultSettings.leafAdapters = [];
98300
99222
  const wbtcToken = Global.getDefaultTokens().find(
98301
99223
  (token) => token.symbol === lstSymbol
@@ -98319,7 +99241,9 @@ spurious results.`);
98319
99241
  ...baseAdapterConfig,
98320
99242
  avnuContract: AVNU_MIDDLEWARE,
98321
99243
  slippage: 0.01,
98322
- baseUrl: AVNU_QUOTE_URL
99244
+ baseUrl: AVNU_QUOTE_URL,
99245
+ minimumExtendedPriceDifferenceForSwapOpen,
99246
+ maximumExtendedPriceDifferenceForSwapClosing
98323
99247
  });
98324
99248
  const extendedAdapter = new ExtendedAdapter({
98325
99249
  ...baseAdapterConfig,
@@ -98335,7 +99259,10 @@ spurious results.`);
98335
99259
  extendedBaseUrl: "https://api.starknet.extended.exchange",
98336
99260
  extendedMarketName: "BTC-USD",
98337
99261
  extendedPrecision: 5,
98338
- avnuAdapter
99262
+ avnuAdapter,
99263
+ retryDelayForOrderStatus: minimumExtendedRetriesDelayForOrderStatus ?? 3e3,
99264
+ minimumExtendedMovementAmount: minimumExtendedMovementAmount ?? 5
99265
+ //5 usdcs
98339
99266
  });
98340
99267
  const vesuMultiplyAdapter = new VesuMultiplyAdapter({
98341
99268
  poolId: pool1,
@@ -98348,7 +99275,9 @@ spurious results.`);
98348
99275
  supportedPositions: [
98349
99276
  { asset: wbtcToken, isDebt: false },
98350
99277
  { asset: usdcToken, isDebt: true }
98351
- ]
99278
+ ],
99279
+ minimumVesuMovementAmount: minimumVesuMovementAmount ?? 5
99280
+ //5 usdc
98352
99281
  });
98353
99282
  const unusedBalanceAdapter = new UnusedBalanceAdapter({
98354
99283
  ...baseAdapterConfig
@@ -98381,6 +99310,7 @@ spurious results.`);
98381
99310
  () => vesuMultiplyAdapter.getWithdrawLeaf()
98382
99311
  );
98383
99312
  vaultSettings.leafAdapters.push(() => extendedAdapter.getDepositLeaf());
99313
+ vaultSettings.leafAdapters.push(() => extendedAdapter.getSwapFromLegacyLeaf());
98384
99314
  vaultSettings.leafAdapters.push(() => avnuAdapter.getDepositLeaf());
98385
99315
  vaultSettings.leafAdapters.push(() => avnuAdapter.getWithdrawLeaf());
98386
99316
  vaultSettings.leafAdapters.push(
@@ -98462,12 +99392,12 @@ spurious results.`);
98462
99392
  borrowable_assets: [Global.getDefaultTokens().find((token) => token.symbol === "WBTC")],
98463
99393
  minimumWBTCDifferenceForAvnuSwap: MINIMUM_WBTC_DIFFERENCE_FOR_AVNU_SWAP
98464
99394
  };
98465
- var VesuExtendedTestStrategies = (extendedBackendUrl, extendedApiKey, vaultIdExtended) => {
99395
+ var VesuExtendedTestStrategies = (extendedBackendUrl, extendedApiKey, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing) => {
98466
99396
  return [
98467
- getStrategySettingsVesuExtended("WBTC", "USDC", re7UsdcPrimeDevansh, false, false, extendedBackendUrl, extendedApiKey, vaultIdExtended)
99397
+ getStrategySettingsVesuExtended("WBTC", "USDC", re7UsdcPrimeDevansh, false, false, extendedBackendUrl, extendedApiKey, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing)
98468
99398
  ];
98469
99399
  };
98470
- function getStrategySettingsVesuExtended(lstSymbol, underlyingSymbol, addresses, isPreview = false, isLST, extendedBackendUrl, extendedApiKey, vaultIdExtended) {
99400
+ function getStrategySettingsVesuExtended(lstSymbol, underlyingSymbol, addresses, isPreview = false, isLST, extendedBackendUrl, extendedApiKey, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing) {
98471
99401
  return {
98472
99402
  name: `Extended Test ${underlyingSymbol}`,
98473
99403
  description: getDescription2(lstSymbol, underlyingSymbol),
@@ -98475,7 +99405,7 @@ spurious results.`);
98475
99405
  launchBlock: 0,
98476
99406
  type: "Other",
98477
99407
  depositTokens: [Global.getDefaultTokens().find((token) => token.symbol === underlyingSymbol)],
98478
- additionalInfo: getLooperSettings2(lstSymbol, underlyingSymbol, addresses, VesuPools.Re7USDCPrime, extendedBackendUrl, extendedApiKey, vaultIdExtended),
99408
+ additionalInfo: getLooperSettings2(lstSymbol, underlyingSymbol, addresses, VesuPools.Re7USDCPrime, extendedBackendUrl, extendedApiKey, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing),
98479
99409
  risk: {
98480
99410
  riskFactor: _riskFactor3,
98481
99411
  netRisk: _riskFactor3.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor3.reduce((acc, curr) => acc + curr.weight, 0),