@strkfarm/sdk 2.0.0-dev.2 → 2.0.0-dev.21

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.
@@ -4269,20 +4269,13 @@ var EkuboQuoter = class _EkuboQuoter {
4269
4269
  async getDexPrice(baseToken, quoteToken, amount) {
4270
4270
  const lstTokenInfo = baseToken;
4271
4271
  const lstUnderlyingTokenInfo = quoteToken;
4272
- console.log("lstTokenInfo", lstTokenInfo);
4273
- console.log("lstUnderlyingTokenInfo", lstUnderlyingTokenInfo);
4274
- console.log("amount", amount);
4275
4272
  const quote = await this.getQuote(
4276
4273
  lstTokenInfo.address.address,
4277
4274
  lstUnderlyingTokenInfo.address.address,
4278
4275
  amount
4279
4276
  );
4280
- console.log("quote", quote);
4281
4277
  const outputAmount = Web3Number.fromWei(quote.total_calculated, lstUnderlyingTokenInfo.decimals);
4282
- console.log("outputAmount", outputAmount);
4283
- console.log("amount", amount);
4284
4278
  const price = outputAmount.toNumber() / amount.toNumber();
4285
- console.log("price", price);
4286
4279
  logger.verbose(`${_EkuboQuoter.name}:: LST Dex Price: ${price}`);
4287
4280
  return price;
4288
4281
  }
@@ -4301,16 +4294,12 @@ var EkuboQuoter = class _EkuboQuoter {
4301
4294
  // debt collateral
4302
4295
  async getSwapLimitAmount(fromToken, toToken, amount, max_slippage = 2e-3) {
4303
4296
  const isExactAmountIn = amount.greaterThanOrEqualTo(0);
4304
- console.log("isExactAmountIn", isExactAmountIn);
4305
4297
  logger.verbose(`${_EkuboQuoter.name}::getSwapLimitAmount isExactAmountIn: ${isExactAmountIn}, fromToken: ${fromToken.symbol}, toToken: ${toToken.symbol}, amount: ${amount}`);
4306
4298
  const isYieldToken = this.tokenMarketData.isAPYSupported(toToken);
4307
4299
  console.log("isYieldToken", isYieldToken);
4308
4300
  const baseToken = isExactAmountIn ? toToken : fromToken;
4309
4301
  const quoteToken = isExactAmountIn ? fromToken : toToken;
4310
- console.log("baseToken", baseToken);
4311
- console.log("quoteToken", quoteToken);
4312
4302
  const dexPrice = await this.getDexPrice(baseToken, quoteToken, amount);
4313
- console.log("dexPrice", dexPrice);
4314
4303
  const trueExchangeRate = isYieldToken ? await this.tokenMarketData.getTruePrice(baseToken) : dexPrice;
4315
4304
  console.log("trueExchangeRate", trueExchangeRate);
4316
4305
  if (isExactAmountIn) {
@@ -4341,7 +4330,6 @@ var EkuboQuoter = class _EkuboQuoter {
4341
4330
  return quote.splits.map((split) => {
4342
4331
  const isNegativeAmount = BigInt(split.amount_specified) <= 0n;
4343
4332
  const token = isNegativeAmount ? toTokenInfo : fromTokenInfo;
4344
- console.log("token for withdrawal", token, isNegativeAmount);
4345
4333
  return {
4346
4334
  route: split.route.map((_route) => ({
4347
4335
  pool_key: {
@@ -4532,7 +4520,22 @@ var ExtendedWrapper = class {
4532
4520
  `HTTP ${response.status}: ${errorData.detail || response.statusText}`
4533
4521
  );
4534
4522
  }
4535
- const data = await response.json();
4523
+ const text = await response.text();
4524
+ const MAX_SAFE_INTEGER_STR = "9007199254740991";
4525
+ const largeIntegerRegex = /"data"\s*:\s*(\d{16,})/g;
4526
+ const modifiedText = text.replace(largeIntegerRegex, (match, largeInt) => {
4527
+ if (largeInt.length > MAX_SAFE_INTEGER_STR.length || largeInt.length === MAX_SAFE_INTEGER_STR.length && largeInt > MAX_SAFE_INTEGER_STR) {
4528
+ return `"data":"${largeInt}"`;
4529
+ }
4530
+ return match;
4531
+ });
4532
+ const data = JSON.parse(modifiedText);
4533
+ if (data && typeof data.data === "string" && /^\d+$/.test(data.data)) {
4534
+ const numValue = Number(data.data);
4535
+ if (Number.isSafeInteger(numValue)) {
4536
+ data.data = numValue;
4537
+ }
4538
+ }
4536
4539
  return data;
4537
4540
  } catch (error) {
4538
4541
  lastError = error;
@@ -4592,6 +4595,7 @@ var ExtendedWrapper = class {
4592
4595
  }
4593
4596
  /**
4594
4597
  * Initiate a withdrawal from Extended Exchange
4598
+ * Returns data as number | string to preserve precision for large integers
4595
4599
  */
4596
4600
  async withdraw(request) {
4597
4601
  return this.makeRequest("/api/v1/withdraw", {
@@ -4730,6 +4734,7 @@ var ExtendedWrapper = class {
4730
4734
  }
4731
4735
  /**
4732
4736
  * Withdraw USDC (convenience method)
4737
+ * Returns data as number | string to preserve precision for large integers
4733
4738
  */
4734
4739
  async withdrawUSDC(amount) {
4735
4740
  return this.withdraw({ amount, asset: "USDC" });
@@ -4739,11 +4744,13 @@ var ExtendedWrapper = class {
4739
4744
  * @param marketName - The name of the market to get funding rates for
4740
4745
  * @returns The funding rates for the specified market
4741
4746
  */
4742
- async getFundingRates(marketName, side) {
4747
+ async getFundingRates(marketName, side, startTime, endTime) {
4748
+ const endTimeParam = endTime !== void 0 ? `&end_time=${endTime}` : "";
4749
+ const startTimeParam = startTime !== void 0 ? `&start_time=${startTime}` : "";
4743
4750
  return this.makeRequest(
4744
4751
  `/api/v1/markets/funding-rates?market_name=${encodeURIComponent(
4745
4752
  marketName
4746
- )}&side=${encodeURIComponent(side)}`
4753
+ )}&side=${encodeURIComponent(side)}${startTimeParam}${endTimeParam}`
4747
4754
  );
4748
4755
  }
4749
4756
  };
@@ -27402,11 +27409,6 @@ var VesuAdapter = class _VesuAdapter extends CacheClass {
27402
27409
  if (!this.pricer) {
27403
27410
  throw new Error("Pricer is not initialized");
27404
27411
  }
27405
- const CACHE_KEY = `positions_${blockNumber}_${this.config.poolId.shortString()}_${this.config.collateral.symbol}_${this.config.debt.symbol}`;
27406
- const cacheData = this.getCache(CACHE_KEY);
27407
- if (cacheData) {
27408
- return cacheData;
27409
- }
27410
27412
  const { contract, isV2 } = this.getVesuSingletonContract(config, this.config.poolId);
27411
27413
  const output = await contract.call(isV2 ? "position" : "position_unsafe", [
27412
27414
  ...isV2 ? [] : [this.config.poolId.address],
@@ -27432,7 +27434,6 @@ var VesuAdapter = class _VesuAdapter extends CacheClass {
27432
27434
  usdValue: debtAmount.multipliedBy(token2Price.price).toNumber(),
27433
27435
  remarks: "Debt"
27434
27436
  }];
27435
- this.setCache(CACHE_KEY, value, 6e4);
27436
27437
  return value.map((v) => ({ ...v, protocol: Protocols.VESU }));
27437
27438
  }
27438
27439
  async getCollateralization(config, blockNumber = "latest") {
@@ -28355,15 +28356,14 @@ var MAX_PRICE_DROP_PERCENTAGE = Number(process.env.MAX_PRICE_DROP_PERCENTAGE ??
28355
28356
  var MAX_LTV_BTC_USDC = 0.8428;
28356
28357
  var MAX_LIQUIDATION_RATIO = 0.86;
28357
28358
  var VAULT_ID_EXTENDED = process.env.VAULT_ID_EXTENDED ?? 220774;
28358
- var WALLET_ADDRESS = process.env.WALLET_ADDRESS ?? "0x07b84bb6E87588BdAde0bfe6173A615b3C220F9C3803456aE183C50EA1d15Ba1";
28359
- var TESTNET_WALLET_ADDRESS = process.env.TESTNET_WALLET_ADDRESS ?? "0x07b84bb6E87588BdAde0bfe6173A615b3C220F9C3803456aE183C50EA1d15Ba1";
28360
- var TEST_WALLET_2 = process.env.TEST_WALLET_2 ?? "0x004C1bdC61DAc7947F3C93d0163d660012E2aB0521567f7155fcf502848791A7";
28359
+ var WALLET_ADDRESS = process.env.WALLET_ADDRESS ?? "0x007E24592287427aaE9d291770B17d582E8A45f3aE54228F998793Ec769B7D13";
28361
28360
  var STRK_API_TEST_RPC = process.env.STRK_API_TEST_RPC ?? "https://sepolia.starknet.a5a.ch";
28362
28361
  var STRK_API_RPC = process.env.STRK_API_RPC ?? "https://mainnet.starknet.a5a.ch";
28363
28362
  var MAX_RETRIES = Number(process.env.MAX_RETRIES ?? 3);
28364
28363
  var MAX_DELAY = Number(process.env.MAX_DELAY ?? 100);
28365
28364
  var EXTEND_MARKET_NAME = "BTC-USD";
28366
- var LIMIT_BALANCE = Number(process.env.LIMIT_BALANCE ?? 10);
28365
+ var LIMIT_BALANCE = Number(process.env.LIMIT_BALANCE ?? 0.05);
28366
+ var LIMIT_BALANCE_VALUE = 10;
28367
28367
  var REBALANCER_INTERVAL = Number(process.env.REBALANCER_INTERVAL ?? 18e4);
28368
28368
  var WITHDRAWAL_INTERVAL = Number(process.env.WITHDRAWAL_INTERVAL ?? 18e6);
28369
28369
  var INVESTING_INTERVAL = Number(process.env.INVESTING_INTERVAL ?? 18e4);
@@ -28381,8 +28381,6 @@ var PRICE_MAX_SLIPPAGE_EKUBO = Number(process.env.PRICE_MAX_SLIPPAGE_EKUBO ?? 5e
28381
28381
  var MINIMUM_DEBT_AMOUNT_VESU_FOR_REBALANCING = Number(process.env.MINIMUM_DEBT_AMOUNT_VESU_FOR_REBALANCING ?? 1);
28382
28382
  var MINIMUM_EXTENDED_POSITION_SIZE = 1e-4;
28383
28383
  var MINIMUM_WBTC_DIFFERENCE_FOR_AVNU_SWAP = 1e-5;
28384
- var MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED = 700;
28385
- var MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED = -100;
28386
28384
 
28387
28385
  // src/strategies/vesu-extended-strategy/utils/helper.ts
28388
28386
  var returnFormattedAmount = (amount, toTokenDecimals) => {
@@ -28402,8 +28400,7 @@ var calculateAmountDistribution = async (amount, client, marketName, collateralP
28402
28400
  vesu_leverage: 0
28403
28401
  };
28404
28402
  }
28405
- const extendedBTCExposure = extendedPosition.length > 0 ? new Web3Number(extendedPosition[0].size, WBTC_TOKEN_DECIMALS) : new Web3Number(0, WBTC_TOKEN_DECIMALS);
28406
- const extendedExposureUSD = extendedBTCExposure.multipliedBy(collateralPrice);
28403
+ const extendedExposureUSD = extendedPosition.length > 0 ? new Web3Number(extendedPosition[0].value, WBTC_TOKEN_DECIMALS) : new Web3Number(0, WBTC_TOKEN_DECIMALS);
28407
28404
  const vesuBTCExposureUSD = collateralUnits.multipliedBy(collateralPrice);
28408
28405
  const numerator1 = vesu_leverage * amount + vesuBTCExposureUSD.toNumber();
28409
28406
  const numerator2 = extendedExposureUSD.toNumber();
@@ -28440,7 +28437,6 @@ var calculateAmountDistributionForWithdrawal = async (amountInUsdc, collateralPr
28440
28437
  return null;
28441
28438
  }
28442
28439
  const extendedExposureUSD = extendedPosition.length > 0 ? new Web3Number(extendedPosition[0].value, USDC_TOKEN_DECIMALS) : new Web3Number(0, USDC_TOKEN_DECIMALS);
28443
- console.log("THe collateral is", collateralPrice, collateralUnits);
28444
28440
  const vesuExposureUSD = collateralUnits.multipliedBy(collateralPrice);
28445
28441
  if (vesuExposureUSD.lessThan(0)) {
28446
28442
  return {
@@ -28497,10 +28493,10 @@ var calculateExtendedLevergae = () => {
28497
28493
  const extended_leverage_max = 1 / (MAINTENANCE_MARGIN + MAX_PRICE_DROP_PERCENTAGE);
28498
28494
  return Math.floor(extended_leverage_max);
28499
28495
  };
28500
- var calculateDebtAmount = (collateralAmount, debtAmount, debtPrice, maxLtv = MAX_LTV_BTC_USDC, addedAmount, collateralPrice, isDeposit) => {
28496
+ var calculateDebtAmount = (collateralAmount, debtAmount, debtPrice, maxLtv = MAX_LIQUIDATION_RATIO, addedAmount, collateralPrice, isDeposit) => {
28501
28497
  try {
28502
- const marginAmount = addedAmount.multipliedBy(isDeposit ? 1 : -1);
28503
- const numerator1 = collateralAmount.plus(addedAmount).multipliedBy(collateralPrice).multipliedBy(maxLtv);
28498
+ const addedCollateral = addedAmount.multipliedBy(isDeposit ? 1 : -1);
28499
+ const numerator1 = collateralAmount.plus(addedCollateral).multipliedBy(collateralPrice).multipliedBy(maxLtv);
28504
28500
  const numerator2 = debtAmount.multipliedBy(debtPrice).multipliedBy(TARGET_HF);
28505
28501
  const denominator = TARGET_HF - maxLtv;
28506
28502
  const x_debt_usd = numerator1.minus(numerator2).dividedBy(denominator);
@@ -28535,19 +28531,34 @@ var calculateAmountDepositOnExtendedWhenIncurringLosses = async (client) => {
28535
28531
  const extendedHoldings = await client.getHoldings();
28536
28532
  const extended_leverage = calculateExtendedLevergae();
28537
28533
  const latestPosition = (await client.getPositions()).data.pop();
28538
- console.log("the latest position is", latestPosition, extendedHoldings);
28539
28534
  if (!extendedHoldings || !latestPosition) {
28540
28535
  logger.error(`error getting extended position: extendedHoldings=${extendedHoldings}, latestPosition=${latestPosition}`);
28541
28536
  return null;
28542
28537
  }
28543
- const positionValueInUSD = latestPosition.value;
28538
+ const positionValueInUSD = new Web3Number(latestPosition.value, USDC_TOKEN_DECIMALS);
28544
28539
  const equity = extendedHoldings.data.equity;
28545
- const deposit = Number(positionValueInUSD) / extended_leverage - Number(equity);
28546
- return new Web3Number(Math.floor(deposit / 0.2) * 0.2, USDC_TOKEN_DECIMALS);
28540
+ const deposit = positionValueInUSD.dividedBy(extended_leverage).minus(equity).toFixed(2);
28541
+ return new Web3Number(deposit, USDC_TOKEN_DECIMALS);
28547
28542
  } catch (err) {
28543
+ logger.error(`error calculating amount deposit on extended when incurring losses: ${err}`);
28548
28544
  return null;
28549
28545
  }
28550
28546
  };
28547
+ var calculateWBTCAmountToMaintainLTV = (collateralAmount, debtAmount, debtPrice, maxLtv = MAX_LIQUIDATION_RATIO, collateralPrice, targetHF = TARGET_HF) => {
28548
+ try {
28549
+ const numerator1 = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLtv);
28550
+ const numerator2 = debtAmount.multipliedBy(debtPrice).multipliedBy(targetHF);
28551
+ const denominator = maxLtv;
28552
+ const collateralAmountToMaintainLTV = numerator2.minus(numerator1).dividedBy(denominator);
28553
+ let deltaCollateralAmountUnits = new Web3Number(
28554
+ collateralAmountToMaintainLTV.dividedBy(collateralPrice).toFixed(WBTC_TOKEN_DECIMALS),
28555
+ WBTC_TOKEN_DECIMALS
28556
+ );
28557
+ return { deltaCollateralAmountUnits };
28558
+ } catch (err) {
28559
+ return { deltaCollateralAmountUnits: null };
28560
+ }
28561
+ };
28551
28562
  var calculateExposureDelta = (exposure_extended, exposure_vesu) => {
28552
28563
  const exposure_delta = new Web3Number(exposure_extended - exposure_vesu, 2);
28553
28564
  return exposure_delta.absoluteValue().toNumber();
@@ -28622,21 +28633,36 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28622
28633
  vaultAllocator: config.vaultAllocator,
28623
28634
  id: ""
28624
28635
  });
28625
- this.tokenMarketData = new TokenMarketData(this.config.pricer, this.config.networkConfig);
28636
+ this.minimumVesuMovementAmount = config.minimumVesuMovementAmount ?? 5;
28637
+ this.tokenMarketData = new TokenMarketData(
28638
+ this.config.pricer,
28639
+ this.config.networkConfig
28640
+ );
28626
28641
  }
28627
28642
  async getAPY(supportedPosition) {
28628
28643
  const CACHE_KEY = `apy_${this.config.poolId.address}_${supportedPosition.asset.symbol}`;
28629
28644
  const cacheData = this.getCache(CACHE_KEY);
28630
- console.log(`${_VesuMultiplyAdapter.name}::getAPY cacheData: ${JSON.stringify(cacheData)}`, this.vesuAdapter.config.poolId.shortString(), this.vesuAdapter.config.collateral.symbol, this.vesuAdapter.config.debt.symbol);
28645
+ console.log(
28646
+ `${_VesuMultiplyAdapter.name}::getAPY cacheData: ${JSON.stringify(
28647
+ cacheData
28648
+ )}`,
28649
+ this.vesuAdapter.config.poolId.shortString(),
28650
+ this.vesuAdapter.config.collateral.symbol,
28651
+ this.vesuAdapter.config.debt.symbol
28652
+ );
28631
28653
  if (cacheData) {
28632
28654
  return cacheData;
28633
28655
  }
28634
28656
  try {
28635
28657
  const allVesuPools = await VesuAdapter.getVesuPools();
28636
28658
  const asset = supportedPosition.asset;
28637
- const pool = allVesuPools.pools.find((p) => this.vesuAdapter.config.poolId.eqString(num9.getHexString(p.id)));
28659
+ const pool = allVesuPools.pools.find(
28660
+ (p) => this.vesuAdapter.config.poolId.eqString(num9.getHexString(p.id))
28661
+ );
28638
28662
  if (!pool) {
28639
- logger.warn(`VesuMultiplyAdapter: Pool not found for token ${asset.symbol}`);
28663
+ logger.warn(
28664
+ `VesuMultiplyAdapter: Pool not found for token ${asset.symbol}`
28665
+ );
28640
28666
  return {
28641
28667
  apy: 0,
28642
28668
  type: "base" /* BASE */
@@ -28646,7 +28672,9 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28646
28672
  (a) => a.symbol.toLowerCase() === asset.symbol.toLowerCase()
28647
28673
  )?.stats;
28648
28674
  if (!assetStats) {
28649
- logger.warn(`VesuMultiplyAdapter: Asset stats not found for token ${asset.symbol}`);
28675
+ logger.warn(
28676
+ `VesuMultiplyAdapter: Asset stats not found for token ${asset.symbol}`
28677
+ );
28650
28678
  return {
28651
28679
  apy: 0,
28652
28680
  type: "base" /* BASE */
@@ -28657,7 +28685,9 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28657
28685
  apy = Number(assetStats.borrowApr?.value || 0) / 1e18;
28658
28686
  } else {
28659
28687
  const isAssetBTC = asset.symbol.toLowerCase().includes("btc");
28660
- const baseAPY = Number(isAssetBTC ? assetStats.btcFiSupplyApr?.value + assetStats.supplyApy?.value : assetStats.supplyApy?.value || 0) / 1e18;
28688
+ const baseAPY = Number(
28689
+ isAssetBTC ? assetStats.btcFiSupplyApr?.value + assetStats.supplyApy?.value : assetStats.supplyApy?.value || 0
28690
+ ) / 1e18;
28661
28691
  const rewardAPY = Number(assetStats.defiSpringSupplyApr?.value || "0") / 1e18;
28662
28692
  const isSupported = this.tokenMarketData.isAPYSupported(asset);
28663
28693
  apy = baseAPY + rewardAPY;
@@ -28673,7 +28703,10 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28673
28703
  this.setCache(CACHE_KEY, result, 3e5);
28674
28704
  return result;
28675
28705
  } catch (error) {
28676
- logger.error(`VesuMultiplyAdapter: Error getting APY for ${supportedPosition.asset.symbol}:`, error);
28706
+ logger.error(
28707
+ `VesuMultiplyAdapter: Error getting APY for ${supportedPosition.asset.symbol}:`,
28708
+ error
28709
+ );
28677
28710
  throw error;
28678
28711
  }
28679
28712
  }
@@ -28686,12 +28719,16 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28686
28719
  try {
28687
28720
  this.vesuAdapter.networkConfig = this.config.networkConfig;
28688
28721
  this.vesuAdapter.pricer = this.config.pricer;
28689
- const positions = await this.vesuAdapter.getPositions(this.config.networkConfig);
28722
+ const positions = await this.vesuAdapter.getPositions(
28723
+ this.config.networkConfig
28724
+ );
28690
28725
  let position = positions.find(
28691
28726
  (p) => p.token.address.eq(supportedPosition.asset.address)
28692
28727
  );
28693
28728
  if (!position) {
28694
- logger.warn(`VesuMultiplyAdapter: Position not found for token ${supportedPosition.asset.symbol}`);
28729
+ logger.warn(
28730
+ `VesuMultiplyAdapter: Position not found for token ${supportedPosition.asset.symbol}`
28731
+ );
28695
28732
  return {
28696
28733
  amount: new Web3Number("0", supportedPosition.asset.decimals),
28697
28734
  remarks: "Position not found"
@@ -28704,12 +28741,18 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28704
28741
  this.setCache(CACHE_KEY, position, 6e4);
28705
28742
  return position;
28706
28743
  } catch (error) {
28707
- logger.error(`VesuMultiplyAdapter: Error getting position for ${supportedPosition.asset.symbol}:`, error);
28744
+ logger.error(
28745
+ `VesuMultiplyAdapter: Error getting position for ${supportedPosition.asset.symbol}:`,
28746
+ error
28747
+ );
28708
28748
  throw error;
28709
28749
  }
28710
28750
  }
28711
28751
  async maxBorrowableAPY() {
28712
- const collateralAPY = await this.getAPY({ asset: this.config.collateral, isDebt: false });
28752
+ const collateralAPY = await this.getAPY({
28753
+ asset: this.config.collateral,
28754
+ isDebt: false
28755
+ });
28713
28756
  const apy = collateralAPY.apy * 0.8;
28714
28757
  return apy;
28715
28758
  }
@@ -28719,9 +28762,15 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28719
28762
  try {
28720
28763
  this.vesuAdapter.networkConfig = this.config.networkConfig;
28721
28764
  this.vesuAdapter.pricer = this.config.pricer;
28722
- const positions = await this.vesuAdapter.getPositions(this.config.networkConfig);
28723
- const collateralPosition = positions.find((p) => p.token.address.eq(collateral.address));
28724
- const debtPosition = positions.find((p) => p.token.address.eq(debt.address));
28765
+ const positions = await this.vesuAdapter.getPositions(
28766
+ this.config.networkConfig
28767
+ );
28768
+ const collateralPosition = positions.find(
28769
+ (p) => p.token.address.eq(collateral.address)
28770
+ );
28771
+ const debtPosition = positions.find(
28772
+ (p) => p.token.address.eq(debt.address)
28773
+ );
28725
28774
  if (!collateralPosition || !debtPosition) {
28726
28775
  throw new Error("Could not find current positions");
28727
28776
  }
@@ -28731,13 +28780,23 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28731
28780
  debt,
28732
28781
  maxBorrowableAPY
28733
28782
  );
28734
- logger.verbose(`VesuMultiplyAdapter: Max borrowable: ${maxBorrowable.toNumber()}`);
28735
- const debtCap = await this.vesuAdapter.getDebtCap(this.config.networkConfig);
28783
+ logger.verbose(
28784
+ `VesuMultiplyAdapter: Max borrowable: ${maxBorrowable.toNumber()}`
28785
+ );
28786
+ const debtCap = await this.vesuAdapter.getDebtCap(
28787
+ this.config.networkConfig
28788
+ );
28736
28789
  logger.verbose(`VesuMultiplyAdapter: Debt cap: ${debtCap.toNumber()}`);
28737
28790
  const actualMaxBorrowable = maxBorrowable.minimum(debtCap);
28738
- logger.verbose(`VesuMultiplyAdapter: Actual max borrowable: ${actualMaxBorrowable.toNumber()}`);
28739
- const maxLTV = await this.vesuAdapter.getLTVConfig(this.config.networkConfig);
28740
- const collateralPrice = await this.config.pricer.getPrice(collateral.symbol);
28791
+ logger.verbose(
28792
+ `VesuMultiplyAdapter: Actual max borrowable: ${actualMaxBorrowable.toNumber()}`
28793
+ );
28794
+ const maxLTV = await this.vesuAdapter.getLTVConfig(
28795
+ this.config.networkConfig
28796
+ );
28797
+ const collateralPrice = await this.config.pricer.getPrice(
28798
+ collateral.symbol
28799
+ );
28741
28800
  if (collateralPrice.price === 0) {
28742
28801
  throw new Error("Collateral price is 0");
28743
28802
  }
@@ -28755,14 +28814,25 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28755
28814
  );
28756
28815
  const maxDepositAmount = amount ? amount.minimum(maxCollateralFromDebt) : maxCollateralFromDebt;
28757
28816
  const usdValue = await this.getUSDValue(collateral, maxDepositAmount);
28758
- logger.verbose(`VesuMultiplyAdapter: Max deposit::USD value: ${usdValue}, amount: ${maxDepositAmount.toNumber()}`);
28759
- const apys = await Promise.all([this.getAPY({ asset: collateral, isDebt: false }), this.getAPY({ asset: debt, isDebt: true })]);
28760
- logger.verbose(`VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`);
28817
+ logger.verbose(
28818
+ `VesuMultiplyAdapter: Max deposit::USD value: ${usdValue}, amount: ${maxDepositAmount.toNumber()}`
28819
+ );
28820
+ const apys = await Promise.all([
28821
+ this.getAPY({ asset: collateral, isDebt: false }),
28822
+ this.getAPY({ asset: debt, isDebt: true })
28823
+ ]);
28824
+ logger.verbose(
28825
+ `VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`
28826
+ );
28761
28827
  const borrowAmountUSD = actualMaxBorrowable.multipliedBy(debtPrice.price);
28762
- logger.verbose(`VesuMultiplyAdapter: Borrow amount: ${actualMaxBorrowable.toNumber()}, borrow amount USD: ${borrowAmountUSD.toNumber()}`);
28828
+ logger.verbose(
28829
+ `VesuMultiplyAdapter: Borrow amount: ${actualMaxBorrowable.toNumber()}, borrow amount USD: ${borrowAmountUSD.toNumber()}`
28830
+ );
28763
28831
  const netCollateralUSD = usdValue + borrowAmountUSD.toNumber();
28764
28832
  const netAPY = (apys[0].apy * netCollateralUSD + apys[1].apy * borrowAmountUSD.toNumber()) / usdValue;
28765
- logger.verbose(`VesuMultiplyAdapter: Max deposit amount: ${maxDepositAmount.toNumber()}, netAPY: ${netAPY}`);
28833
+ logger.verbose(
28834
+ `VesuMultiplyAdapter: Max deposit amount: ${maxDepositAmount.toNumber()}, netAPY: ${netAPY}`
28835
+ );
28766
28836
  return {
28767
28837
  tokenInfo: collateral,
28768
28838
  amount: maxDepositAmount,
@@ -28775,7 +28845,10 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28775
28845
  protocol: this.protocol
28776
28846
  };
28777
28847
  } catch (error) {
28778
- logger.error(`VesuMultiplyAdapter: Error calculating max deposit:`, error);
28848
+ logger.error(
28849
+ `VesuMultiplyAdapter: Error calculating max deposit:`,
28850
+ error
28851
+ );
28779
28852
  throw error;
28780
28853
  }
28781
28854
  }
@@ -28785,9 +28858,15 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28785
28858
  try {
28786
28859
  this.vesuAdapter.networkConfig = this.config.networkConfig;
28787
28860
  this.vesuAdapter.pricer = this.config.pricer;
28788
- const positions = await this.vesuAdapter.getPositions(this.config.networkConfig);
28789
- const collateralPosition = positions.find((p) => p.token.address.eq(collateral.address));
28790
- const debtPosition = positions.find((p) => p.token.address.eq(this.config.debt.address));
28861
+ const positions = await this.vesuAdapter.getPositions(
28862
+ this.config.networkConfig
28863
+ );
28864
+ const collateralPosition = positions.find(
28865
+ (p) => p.token.address.eq(collateral.address)
28866
+ );
28867
+ const debtPosition = positions.find(
28868
+ (p) => p.token.address.eq(this.config.debt.address)
28869
+ );
28791
28870
  if (!collateralPosition || !debtPosition) {
28792
28871
  throw new Error("Could not find current positions");
28793
28872
  }
@@ -28797,11 +28876,20 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28797
28876
  const result = maxWithdrawable.greaterThan(0) ? maxWithdrawable : new Web3Number("0", collateral.decimals);
28798
28877
  const usdValue = await this.getUSDValue(collateral, result);
28799
28878
  const debtUSD = debtPosition.usdValue;
28800
- logger.verbose(`VesuMultiplyAdapter: Debt USD: ${debtUSD}, collateral USD: ${usdValue}`);
28801
- const apys = await Promise.all([this.getAPY({ asset: collateral, isDebt: false }), this.getAPY({ asset: debt, isDebt: true })]);
28802
- logger.verbose(`VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`);
28879
+ logger.verbose(
28880
+ `VesuMultiplyAdapter: Debt USD: ${debtUSD}, collateral USD: ${usdValue}`
28881
+ );
28882
+ const apys = await Promise.all([
28883
+ this.getAPY({ asset: collateral, isDebt: false }),
28884
+ this.getAPY({ asset: debt, isDebt: true })
28885
+ ]);
28886
+ logger.verbose(
28887
+ `VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`
28888
+ );
28803
28889
  const netAPY = usdValue - debtUSD > 0 ? (apys[0].apy * usdValue + apys[1].apy * debtUSD) / (usdValue - debtUSD) : 0;
28804
- logger.verbose(`VesuMultiplyAdapter: Max withdraw amount: ${result.toNumber()}, netAPY: ${netAPY}`);
28890
+ logger.verbose(
28891
+ `VesuMultiplyAdapter: Max withdraw amount: ${result.toNumber()}, netAPY: ${netAPY}`
28892
+ );
28805
28893
  return {
28806
28894
  tokenInfo: collateral,
28807
28895
  amount: result,
@@ -28814,14 +28902,19 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28814
28902
  protocol: this.protocol
28815
28903
  };
28816
28904
  } catch (error) {
28817
- logger.error(`VesuMultiplyAdapter: Error calculating max withdraw:`, error);
28905
+ logger.error(
28906
+ `VesuMultiplyAdapter: Error calculating max withdraw:`,
28907
+ error
28908
+ );
28818
28909
  throw error;
28819
28910
  }
28820
28911
  }
28821
28912
  _getDepositLeaf() {
28822
28913
  const collateral = this.config.collateral;
28823
28914
  const debt = this.config.debt;
28824
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
28915
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
28916
+ this.config.poolId
28917
+ );
28825
28918
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
28826
28919
  return [
28827
28920
  // Approval step for collateral
@@ -28885,7 +28978,9 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28885
28978
  ];
28886
28979
  }
28887
28980
  _getWithdrawLeaf() {
28888
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
28981
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
28982
+ this.config.poolId
28983
+ );
28889
28984
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
28890
28985
  const collateral = this.config.collateral;
28891
28986
  const debt = this.config.debt;
@@ -28942,33 +29037,51 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28942
29037
  const leafConfigs = this._getDepositLeaf();
28943
29038
  const leaves = leafConfigs.map((config) => {
28944
29039
  const { target, method, packedArguments, sanitizer, id } = config;
28945
- const leaf = this.constructSimpleLeafData({
28946
- id,
28947
- target,
28948
- method,
28949
- packedArguments
28950
- }, sanitizer);
29040
+ const leaf = this.constructSimpleLeafData(
29041
+ {
29042
+ id,
29043
+ target,
29044
+ method,
29045
+ packedArguments
29046
+ },
29047
+ sanitizer
29048
+ );
28951
29049
  return leaf;
28952
29050
  });
28953
- return { leaves, callConstructor: this.getDepositCall.bind(this) };
29051
+ return {
29052
+ leaves,
29053
+ callConstructor: this.getDepositCall.bind(
29054
+ this
29055
+ )
29056
+ };
28954
29057
  }
28955
29058
  getWithdrawAdapter() {
28956
29059
  const leafConfigs = this._getWithdrawLeaf();
28957
29060
  const leaves = leafConfigs.map((config) => {
28958
29061
  const { target, method, packedArguments, sanitizer, id } = config;
28959
- const leaf = this.constructSimpleLeafData({
28960
- id,
28961
- target,
28962
- method,
28963
- packedArguments
28964
- }, sanitizer);
29062
+ const leaf = this.constructSimpleLeafData(
29063
+ {
29064
+ id,
29065
+ target,
29066
+ method,
29067
+ packedArguments
29068
+ },
29069
+ sanitizer
29070
+ );
28965
29071
  return leaf;
28966
29072
  });
28967
- return { leaves, callConstructor: this.getWithdrawCall.bind(this) };
29073
+ return {
29074
+ leaves,
29075
+ callConstructor: this.getWithdrawCall.bind(
29076
+ this
29077
+ )
29078
+ };
28968
29079
  }
28969
29080
  async getDepositCall(params) {
28970
29081
  const collateral = this.config.collateral;
28971
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
29082
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
29083
+ this.config.poolId
29084
+ );
28972
29085
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
28973
29086
  const uint256MarginAmount = uint25612.bnToUint256(params.amount.toWei());
28974
29087
  return [
@@ -29040,7 +29153,9 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
29040
29153
  ];
29041
29154
  }
29042
29155
  async getWithdrawCall(params) {
29043
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
29156
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
29157
+ this.config.poolId
29158
+ );
29044
29159
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
29045
29160
  return [
29046
29161
  // Switch delegation on
@@ -29095,7 +29210,11 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
29095
29210
  ];
29096
29211
  }
29097
29212
  async getMultiplyCallCalldata(params, isDeposit) {
29098
- logger.verbose(`${_VesuMultiplyAdapter.name}::getMultiplyCallCalldata params: ${JSON.stringify(params)}, isDeposit: ${isDeposit}, collateral: ${this.config.collateral.symbol}, debt: ${this.config.debt.symbol}`);
29213
+ logger.verbose(
29214
+ `${_VesuMultiplyAdapter.name}::getMultiplyCallCalldata params: ${JSON.stringify(
29215
+ params
29216
+ )}, isDeposit: ${isDeposit}, collateral: ${this.config.collateral.symbol}, debt: ${this.config.debt.symbol}`
29217
+ );
29099
29218
  const { isV2 } = getVesuSingletonAddress(this.config.poolId);
29100
29219
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
29101
29220
  const multiplyContract = new Contract12({
@@ -29105,42 +29224,83 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
29105
29224
  });
29106
29225
  let leverSwap = [];
29107
29226
  let leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
29108
- const existingPositions = await this.vesuAdapter.getPositions(this.config.networkConfig);
29109
- const collateralisation = await this.vesuAdapter.getCollateralization(this.config.networkConfig);
29227
+ const existingPositions = await this.vesuAdapter.getPositions(
29228
+ this.config.networkConfig
29229
+ );
29230
+ const collateralisation = await this.vesuAdapter.getCollateralization(
29231
+ this.config.networkConfig
29232
+ );
29110
29233
  const existingCollateralInfo = existingPositions[0];
29111
29234
  const existingDebtInfo = existingPositions[1];
29112
29235
  const isDexPriceRequired = existingDebtInfo.token.symbol !== "USDC";
29113
- logger.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
29114
- existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
29236
+ logger.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(
29237
+ existingCollateralInfo
29238
+ )},
29239
+ existingDebtInfo: ${JSON.stringify(
29240
+ existingDebtInfo
29241
+ )}, collateralisation: ${JSON.stringify(collateralisation)}`);
29115
29242
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : (await this.config.pricer.getPrice(this.config.collateral.symbol)).price;
29116
29243
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : (await this.config.pricer.getPrice(this.config.debt.symbol)).price;
29117
- logger.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
29118
- const legLTV = await this.vesuAdapter.getLTVConfig(this.config.networkConfig);
29119
- const ekuboQuoter = new EkuboQuoter(this.config.networkConfig, this.config.pricer);
29120
- const dexPrice = isDexPriceRequired ? await ekuboQuoter.getDexPrice(this.config.collateral, this.config.debt, this.config.quoteAmountToFetchPrice) : 1;
29121
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall dexPrice: ${dexPrice}, ltv: ${legLTV}`);
29244
+ logger.debug(
29245
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`
29246
+ );
29247
+ const legLTV = await this.vesuAdapter.getLTVConfig(
29248
+ this.config.networkConfig
29249
+ );
29250
+ const ekuboQuoter = new EkuboQuoter(
29251
+ this.config.networkConfig,
29252
+ this.config.pricer
29253
+ );
29254
+ const dexPrice = isDexPriceRequired ? await ekuboQuoter.getDexPrice(
29255
+ this.config.collateral,
29256
+ this.config.debt,
29257
+ this.config.quoteAmountToFetchPrice
29258
+ ) : 1;
29259
+ logger.verbose(
29260
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall dexPrice: ${dexPrice}, ltv: ${legLTV}`
29261
+ );
29122
29262
  const addedCollateral = params.amount.multipliedBy(isDeposit ? 1 : -1);
29123
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall addedCollateral: ${addedCollateral}`);
29263
+ logger.verbose(
29264
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall addedCollateral: ${addedCollateral}`
29265
+ );
29124
29266
  const numeratorPart1 = existingCollateralInfo.amount.plus(addedCollateral).multipliedBy(collateralPrice).multipliedBy(legLTV);
29125
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}`);
29267
+ logger.verbose(
29268
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}`
29269
+ );
29126
29270
  const numeratorPart2 = existingDebtInfo.amount.multipliedBy(debtPrice).multipliedBy(this.config.targetHealthFactor);
29127
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart2: ${numeratorPart2}`);
29271
+ logger.verbose(
29272
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart2: ${numeratorPart2}`
29273
+ );
29128
29274
  const denominatorPart = this.config.targetHealthFactor - legLTV / dexPrice;
29129
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall denominatorPart: ${denominatorPart}`);
29275
+ logger.verbose(
29276
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall denominatorPart: ${denominatorPart}`
29277
+ );
29130
29278
  const x_debt_usd = numeratorPart1.minus(numeratorPart2).dividedBy(denominatorPart);
29131
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall x_debt_usd: ${x_debt_usd}`);
29132
- logger.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}, numeratorPart2: ${numeratorPart2}, denominatorPart: ${denominatorPart}`);
29133
- let debtAmount = new Web3Number(x_debt_usd.dividedBy(debtPrice).toFixed(this.config.debt.decimals), this.config.debt.decimals);
29279
+ logger.verbose(
29280
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall x_debt_usd: ${x_debt_usd}`
29281
+ );
29282
+ logger.debug(
29283
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}, numeratorPart2: ${numeratorPart2}, denominatorPart: ${denominatorPart}`
29284
+ );
29285
+ let debtAmount = new Web3Number(
29286
+ x_debt_usd.dividedBy(debtPrice).toFixed(this.config.debt.decimals),
29287
+ this.config.debt.decimals
29288
+ );
29134
29289
  const marginAmount = addedCollateral;
29135
29290
  const collateralToken = this.config.collateral;
29136
29291
  const debtToken = this.config.debt;
29137
- const debtAmountInCollateralUnits = new Web3Number(debtAmount.multipliedBy(debtPrice).dividedBy(collateralPrice).multipliedBy(10 ** collateralToken.decimals).toFixed(0), collateralToken.decimals);
29292
+ const debtAmountInCollateralUnits = new Web3Number(
29293
+ debtAmount.multipliedBy(debtPrice).dividedBy(collateralPrice).multipliedBy(10 ** collateralToken.decimals).toFixed(0),
29294
+ collateralToken.decimals
29295
+ );
29138
29296
  const isIncrease = debtAmount.greaterThanOrEqualTo(0);
29139
29297
  if (isIncrease && debtAmount.lessThan(0)) {
29140
29298
  } else if (!isIncrease && debtAmount.greaterThan(0)) {
29141
29299
  debtAmount = Web3Number.fromWei(0, this.config.debt.decimals);
29142
29300
  }
29143
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall debtAmount: ${debtAmount}, marginAmount: ${marginAmount}`);
29301
+ logger.verbose(
29302
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall debtAmount: ${debtAmount}, marginAmount: ${marginAmount}`
29303
+ );
29144
29304
  if (!debtAmount.isZero()) {
29145
29305
  try {
29146
29306
  const swapQuote = await ekuboQuoter.getQuote(
@@ -29150,26 +29310,49 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
29150
29310
  // negative for exact amount out
29151
29311
  );
29152
29312
  if (swapQuote.price_impact < 0.01) {
29153
- leverSwap = ekuboQuoter.getVesuMultiplyQuote(swapQuote, debtToken, collateralToken);
29313
+ leverSwap = debtAmount.isNegative() ? ekuboQuoter.getVesuMultiplyQuote(
29314
+ swapQuote,
29315
+ collateralToken,
29316
+ debtToken
29317
+ ) : ekuboQuoter.getVesuMultiplyQuote(
29318
+ swapQuote,
29319
+ debtToken,
29320
+ collateralToken
29321
+ );
29154
29322
  const MAX_SLIPPAGE = 2e-3;
29155
29323
  if (debtAmount.greaterThan(0)) {
29156
29324
  leverSwapLimitAmount = debtAmount.multipliedBy(1 + MAX_SLIPPAGE);
29157
29325
  } else if (debtAmount.lessThan(0)) {
29158
29326
  leverSwapLimitAmount = debtAmount.abs().multipliedBy(1 - MAX_SLIPPAGE);
29159
29327
  } else {
29160
- leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
29328
+ leverSwapLimitAmount = Web3Number.fromWei(
29329
+ 0,
29330
+ this.config.debt.decimals
29331
+ );
29161
29332
  }
29162
29333
  await new Promise((resolve) => setTimeout(resolve, 1e4));
29163
29334
  } else {
29164
- throw new Error(`VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`);
29335
+ throw new Error(
29336
+ `VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`
29337
+ );
29165
29338
  }
29166
29339
  } catch (error) {
29167
- throw new Error(`VesuMultiplyAdapter: Failed to get swap quote: ${error}`);
29340
+ throw new Error(
29341
+ `VesuMultiplyAdapter: Failed to get swap quote: ${error}`
29342
+ );
29168
29343
  }
29169
29344
  }
29170
- const multiplyParams = await this.getLeverParams(isIncrease, params, leverSwap, leverSwapLimitAmount);
29345
+ const multiplyParams = await this.getLeverParams(
29346
+ isIncrease,
29347
+ params,
29348
+ leverSwap,
29349
+ leverSwapLimitAmount
29350
+ );
29171
29351
  const call = multiplyContract.populate("modify_lever", {
29172
- modify_lever_params: this.formatMultiplyParams(isIncrease, multiplyParams)
29352
+ modify_lever_params: this.formatMultiplyParams(
29353
+ isIncrease,
29354
+ multiplyParams
29355
+ )
29173
29356
  });
29174
29357
  return call.calldata;
29175
29358
  }
@@ -29183,7 +29366,10 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
29183
29366
  add_margin: params.amount,
29184
29367
  // multiplied by collateral decimals in format
29185
29368
  margin_swap: [],
29186
- margin_swap_limit_amount: Web3Number.fromWei(0, this.config.collateral.decimals),
29369
+ margin_swap_limit_amount: Web3Number.fromWei(
29370
+ 0,
29371
+ this.config.collateral.decimals
29372
+ ),
29187
29373
  lever_swap: leverSwap,
29188
29374
  lever_swap_limit_amount: leverSwapLimitAmount
29189
29375
  } : {
@@ -29197,7 +29383,10 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
29197
29383
  lever_swap_limit_amount: leverSwapLimitAmount,
29198
29384
  lever_swap_weights: [],
29199
29385
  withdraw_swap: [],
29200
- withdraw_swap_limit_amount: Web3Number.fromWei(0, this.config.collateral.decimals),
29386
+ withdraw_swap_limit_amount: Web3Number.fromWei(
29387
+ 0,
29388
+ this.config.collateral.decimals
29389
+ ),
29201
29390
  withdraw_swap_weights: [],
29202
29391
  close_position: false
29203
29392
  };
@@ -29213,12 +29402,16 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
29213
29402
  });
29214
29403
  let leverSwap = [];
29215
29404
  let leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
29216
- const existingPositions = await this.vesuAdapter.getPositions(this.config.networkConfig);
29405
+ const existingPositions = await this.vesuAdapter.getPositions(
29406
+ this.config.networkConfig
29407
+ );
29217
29408
  const existingCollateralInfo = existingPositions[0];
29218
29409
  const existingDebtInfo = existingPositions[1];
29219
29410
  const collateralToken = this.config.collateral;
29220
29411
  const debtToken = this.config.debt;
29221
- const collateralPrice = await this.config.pricer.getPrice(collateralToken.symbol);
29412
+ const collateralPrice = await this.config.pricer.getPrice(
29413
+ collateralToken.symbol
29414
+ );
29222
29415
  const debtPrice = await this.config.pricer.getPrice(debtToken.symbol);
29223
29416
  const { deltadebtAmountUnits: debtAmountToRepay } = calculateDebtReductionAmountForWithdrawal(
29224
29417
  existingDebtInfo.amount,
@@ -29232,8 +29425,14 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
29232
29425
  if (!debtAmountToRepay) {
29233
29426
  throw new Error("error calculating debt amount to repay");
29234
29427
  }
29235
- const ekuboQuoter = new EkuboQuoter(this.config.networkConfig, this.config.pricer);
29236
- const debtInDebtUnits = new Web3Number(debtAmountToRepay, debtToken.decimals).dividedBy(debtPrice.price).multipliedBy(10 ** debtToken.decimals);
29428
+ const ekuboQuoter = new EkuboQuoter(
29429
+ this.config.networkConfig,
29430
+ this.config.pricer
29431
+ );
29432
+ const debtInDebtUnits = new Web3Number(
29433
+ debtAmountToRepay,
29434
+ debtToken.decimals
29435
+ ).dividedBy(debtPrice.price).multipliedBy(10 ** debtToken.decimals);
29237
29436
  const swapQuote = await ekuboQuoter.getQuote(
29238
29437
  debtToken.address.address,
29239
29438
  collateralToken.address.address,
@@ -29241,12 +29440,23 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
29241
29440
  );
29242
29441
  const MAX_SLIPPAGE = 2e-3;
29243
29442
  if (swapQuote.price_impact < 25e-4) {
29244
- leverSwap = ekuboQuoter.getVesuMultiplyQuote(swapQuote, collateralToken, debtToken);
29443
+ leverSwap = ekuboQuoter.getVesuMultiplyQuote(
29444
+ swapQuote,
29445
+ collateralToken,
29446
+ debtToken
29447
+ );
29245
29448
  } else {
29246
- logger.error(`VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`);
29449
+ logger.error(
29450
+ `VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`
29451
+ );
29247
29452
  }
29248
29453
  leverSwapLimitAmount = new Web3Number(debtAmountToRepay, debtToken.decimals).abs().multipliedBy(1 + MAX_SLIPPAGE);
29249
- const multiplyParams = await this.getLeverParams(false, params, leverSwap, leverSwapLimitAmount);
29454
+ const multiplyParams = await this.getLeverParams(
29455
+ false,
29456
+ params,
29457
+ leverSwap,
29458
+ leverSwapLimitAmount
29459
+ );
29250
29460
  const call = multiplyContract.populate("modify_lever", {
29251
29461
  modify_lever_params: this.formatMultiplyParams(false, multiplyParams)
29252
29462
  });
@@ -29256,100 +29466,132 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
29256
29466
  if (isIncrease) {
29257
29467
  const _params2 = params;
29258
29468
  return {
29259
- action: new CairoCustomEnum3({ IncreaseLever: {
29260
- pool_id: _params2.pool_id.toBigInt(),
29261
- collateral_asset: _params2.collateral_asset.toBigInt(),
29262
- debt_asset: _params2.debt_asset.toBigInt(),
29263
- user: _params2.user.toBigInt(),
29264
- add_margin: BigInt(_params2.add_margin.toWei()),
29265
- margin_swap: _params2.margin_swap.map((swap) => ({
29469
+ action: new CairoCustomEnum3({
29470
+ IncreaseLever: {
29471
+ pool_id: _params2.pool_id.toBigInt(),
29472
+ collateral_asset: _params2.collateral_asset.toBigInt(),
29473
+ debt_asset: _params2.debt_asset.toBigInt(),
29474
+ user: _params2.user.toBigInt(),
29475
+ add_margin: BigInt(_params2.add_margin.toWei()),
29476
+ margin_swap: _params2.margin_swap.map((swap) => ({
29477
+ route: swap.route.map((route) => ({
29478
+ pool_key: {
29479
+ token0: route.pool_key.token0.toBigInt(),
29480
+ token1: route.pool_key.token1.toBigInt(),
29481
+ fee: route.pool_key.fee,
29482
+ tick_spacing: route.pool_key.tick_spacing,
29483
+ extension: BigInt(
29484
+ num9.hexToDecimalString(route.pool_key.extension)
29485
+ )
29486
+ },
29487
+ sqrt_ratio_limit: uint25612.bnToUint256(
29488
+ route.sqrt_ratio_limit.toWei()
29489
+ ),
29490
+ skip_ahead: BigInt(100)
29491
+ })),
29492
+ token_amount: {
29493
+ token: swap.token_amount.token.toBigInt(),
29494
+ amount: swap.token_amount.amount.toI129()
29495
+ }
29496
+ })),
29497
+ margin_swap_limit_amount: BigInt(
29498
+ _params2.margin_swap_limit_amount.toWei()
29499
+ ),
29500
+ lever_swap: _params2.lever_swap.map((swap) => ({
29501
+ route: swap.route.map((route) => ({
29502
+ pool_key: {
29503
+ token0: route.pool_key.token0.toBigInt(),
29504
+ token1: route.pool_key.token1.toBigInt(),
29505
+ fee: route.pool_key.fee,
29506
+ tick_spacing: route.pool_key.tick_spacing,
29507
+ extension: BigInt(
29508
+ num9.hexToDecimalString(route.pool_key.extension)
29509
+ )
29510
+ },
29511
+ sqrt_ratio_limit: uint25612.bnToUint256(
29512
+ route.sqrt_ratio_limit.toWei()
29513
+ ),
29514
+ skip_ahead: BigInt(0)
29515
+ })),
29516
+ token_amount: {
29517
+ token: swap.token_amount.token.toBigInt(),
29518
+ amount: swap.token_amount.amount.toI129()
29519
+ }
29520
+ })),
29521
+ lever_swap_limit_amount: BigInt(
29522
+ _params2.lever_swap_limit_amount.toWei()
29523
+ )
29524
+ }
29525
+ })
29526
+ };
29527
+ }
29528
+ const _params = params;
29529
+ return {
29530
+ action: new CairoCustomEnum3({
29531
+ DecreaseLever: {
29532
+ pool_id: _params.pool_id.toBigInt(),
29533
+ collateral_asset: _params.collateral_asset.toBigInt(),
29534
+ debt_asset: _params.debt_asset.toBigInt(),
29535
+ user: _params.user.toBigInt(),
29536
+ sub_margin: BigInt(_params.sub_margin.toWei()),
29537
+ recipient: _params.recipient.toBigInt(),
29538
+ lever_swap: _params.lever_swap.map((swap) => ({
29266
29539
  route: swap.route.map((route) => ({
29267
29540
  pool_key: {
29268
29541
  token0: route.pool_key.token0.toBigInt(),
29269
29542
  token1: route.pool_key.token1.toBigInt(),
29270
29543
  fee: route.pool_key.fee,
29271
29544
  tick_spacing: route.pool_key.tick_spacing,
29272
- extension: BigInt(num9.hexToDecimalString(route.pool_key.extension))
29545
+ extension: ContractAddr.from(
29546
+ route.pool_key.extension
29547
+ ).toBigInt()
29273
29548
  },
29274
- sqrt_ratio_limit: uint25612.bnToUint256(route.sqrt_ratio_limit.toWei()),
29275
- skip_ahead: BigInt(100)
29549
+ sqrt_ratio_limit: uint25612.bnToUint256(
29550
+ route.sqrt_ratio_limit.toWei()
29551
+ ),
29552
+ skip_ahead: BigInt(route.skip_ahead.toWei())
29276
29553
  })),
29277
29554
  token_amount: {
29278
29555
  token: swap.token_amount.token.toBigInt(),
29279
29556
  amount: swap.token_amount.amount.toI129()
29280
29557
  }
29281
29558
  })),
29282
- margin_swap_limit_amount: BigInt(_params2.margin_swap_limit_amount.toWei()),
29283
- lever_swap: _params2.lever_swap.map((swap) => ({
29559
+ lever_swap_limit_amount: BigInt(
29560
+ _params.lever_swap_limit_amount.toWei()
29561
+ ),
29562
+ lever_swap_weights: _params.lever_swap_weights.map(
29563
+ (weight) => BigInt(weight.toWei())
29564
+ ),
29565
+ withdraw_swap: _params.withdraw_swap.map((swap) => ({
29284
29566
  route: swap.route.map((route) => ({
29285
29567
  pool_key: {
29286
29568
  token0: route.pool_key.token0.toBigInt(),
29287
29569
  token1: route.pool_key.token1.toBigInt(),
29288
29570
  fee: route.pool_key.fee,
29289
29571
  tick_spacing: route.pool_key.tick_spacing,
29290
- extension: BigInt(num9.hexToDecimalString(route.pool_key.extension))
29572
+ extension: ContractAddr.from(
29573
+ route.pool_key.extension
29574
+ ).toBigInt()
29291
29575
  },
29292
- sqrt_ratio_limit: uint25612.bnToUint256(route.sqrt_ratio_limit.toWei()),
29293
- skip_ahead: BigInt(0)
29576
+ sqrt_ratio_limit: uint25612.bnToUint256(
29577
+ route.sqrt_ratio_limit.toWei()
29578
+ ),
29579
+ skip_ahead: BigInt(route.skip_ahead.toWei())
29294
29580
  })),
29295
29581
  token_amount: {
29296
29582
  token: swap.token_amount.token.toBigInt(),
29297
29583
  amount: swap.token_amount.amount.toI129()
29298
29584
  }
29299
29585
  })),
29300
- lever_swap_limit_amount: BigInt(_params2.lever_swap_limit_amount.toWei())
29301
- } })
29302
- };
29303
- }
29304
- const _params = params;
29305
- return {
29306
- action: new CairoCustomEnum3({ DecreaseLever: {
29307
- pool_id: _params.pool_id.toBigInt(),
29308
- collateral_asset: _params.collateral_asset.toBigInt(),
29309
- debt_asset: _params.debt_asset.toBigInt(),
29310
- user: _params.user.toBigInt(),
29311
- sub_margin: BigInt(_params.sub_margin.toWei()),
29312
- recipient: _params.recipient.toBigInt(),
29313
- lever_swap: _params.lever_swap.map((swap) => ({
29314
- route: swap.route.map((route) => ({
29315
- pool_key: {
29316
- token0: route.pool_key.token0.toBigInt(),
29317
- token1: route.pool_key.token1.toBigInt(),
29318
- fee: route.pool_key.fee,
29319
- tick_spacing: route.pool_key.tick_spacing,
29320
- extension: ContractAddr.from(route.pool_key.extension).toBigInt()
29321
- },
29322
- sqrt_ratio_limit: uint25612.bnToUint256(route.sqrt_ratio_limit.toWei()),
29323
- skip_ahead: BigInt(route.skip_ahead.toWei())
29324
- })),
29325
- token_amount: {
29326
- token: swap.token_amount.token.toBigInt(),
29327
- amount: swap.token_amount.amount.toI129()
29328
- }
29329
- })),
29330
- lever_swap_limit_amount: BigInt(_params.lever_swap_limit_amount.toWei()),
29331
- lever_swap_weights: _params.lever_swap_weights.map((weight) => BigInt(weight.toWei())),
29332
- withdraw_swap: _params.withdraw_swap.map((swap) => ({
29333
- route: swap.route.map((route) => ({
29334
- pool_key: {
29335
- token0: route.pool_key.token0.toBigInt(),
29336
- token1: route.pool_key.token1.toBigInt(),
29337
- fee: route.pool_key.fee,
29338
- tick_spacing: route.pool_key.tick_spacing,
29339
- extension: ContractAddr.from(route.pool_key.extension).toBigInt()
29340
- },
29341
- sqrt_ratio_limit: uint25612.bnToUint256(route.sqrt_ratio_limit.toWei()),
29342
- skip_ahead: BigInt(route.skip_ahead.toWei())
29343
- })),
29344
- token_amount: {
29345
- token: swap.token_amount.token.toBigInt(),
29346
- amount: swap.token_amount.amount.toI129()
29347
- }
29348
- })),
29349
- withdraw_swap_limit_amount: BigInt(_params.withdraw_swap_limit_amount.toWei()),
29350
- withdraw_swap_weights: _params.withdraw_swap_weights.map((weight) => BigInt(weight.toWei())),
29351
- close_position: _params.close_position
29352
- } })
29586
+ withdraw_swap_limit_amount: BigInt(
29587
+ _params.withdraw_swap_limit_amount.toWei()
29588
+ ),
29589
+ withdraw_swap_weights: _params.withdraw_swap_weights.map(
29590
+ (weight) => BigInt(weight.toWei())
29591
+ ),
29592
+ close_position: _params.close_position
29593
+ }
29594
+ })
29353
29595
  };
29354
29596
  }
29355
29597
  async getHealthFactor() {
@@ -29358,11 +29600,15 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
29358
29600
  }
29359
29601
  async getNetAPY() {
29360
29602
  const positions = await this.getPositions();
29361
- logger.verbose(`${this.name}::getNetAPY: positions: ${JSON.stringify(positions)}`);
29603
+ logger.verbose(
29604
+ `${this.name}::getNetAPY: positions: ${JSON.stringify(positions)}`
29605
+ );
29362
29606
  const allZero = positions.every((p) => p.usdValue === 0);
29363
29607
  if (allZero) {
29364
29608
  const collateralUSD = 1e3;
29365
- const maxLTV = await this.vesuAdapter.getLTVConfig(this.config.networkConfig);
29609
+ const maxLTV = await this.vesuAdapter.getLTVConfig(
29610
+ this.config.networkConfig
29611
+ );
29366
29612
  const targetHF = this.config.targetHealthFactor;
29367
29613
  const maxDebt = HealthFactorMath.getMaxDebtAmountOnLooping(
29368
29614
  new Web3Number(collateralUSD, this.config.collateral.decimals),
@@ -29393,18 +29639,20 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29393
29639
  super(config, _ExtendedAdapter.name, Protocols.EXTENDED);
29394
29640
  this.config = config;
29395
29641
  const client = new wrapper_default({
29396
- baseUrl: this.config.extendedBackendUrl,
29397
- apiKey: this.config.extendedApiKey,
29642
+ baseUrl: this.config.extendedBackendWriteUrl,
29643
+ apiKey: "",
29398
29644
  timeout: this.config.extendedTimeout,
29399
29645
  retries: this.config.extendedRetries
29400
29646
  });
29647
+ this.minimumExtendedMovementAmount = this.config.minimumExtendedMovementAmount ?? 5;
29401
29648
  this.client = client;
29649
+ this.retryDelayForOrderStatus = this.config.retryDelayForOrderStatus ?? 3e3;
29402
29650
  }
29403
29651
  //abstract means the method has no implementation in this class; instead, child classes must implement it.
29404
29652
  async getAPY(supportedPosition) {
29405
29653
  const side = supportedPosition.isDebt ? "LONG" : "SHORT";
29406
- const fundingRates = await this.client.getFundingRates(this.config.extendedMarketName, side);
29407
- if (fundingRates.status !== "OK") {
29654
+ const fundingRates = await this.getFundingRates(side);
29655
+ if (!fundingRates.success) {
29408
29656
  logger.error("error getting funding rates", fundingRates);
29409
29657
  return { apy: 0, type: "base" /* BASE */ };
29410
29658
  }
@@ -29412,10 +29660,26 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29412
29660
  const apy = Number(fundingRate.f) * 365 * 24;
29413
29661
  return { apy, type: "base" /* BASE */ };
29414
29662
  }
29415
- async getPosition(supportedPosition) {
29416
- if (!this.client) {
29417
- throw new Error("Client not initialized");
29663
+ async getFundingRates(side, startTime, endTime) {
29664
+ try {
29665
+ const response = await axios9.get(`${this.config.extendedBackendReadUrl}/fundingRates/${this.config.extendedMarketName}/${side}`, {
29666
+ params: {
29667
+ startTime: startTime ? startTime.toString() : void 0,
29668
+ endTime: endTime ? endTime.toString() : void 0
29669
+ }
29670
+ });
29671
+ if (!response.data.success) {
29672
+ logger.error("error getting funding rates", response.data);
29673
+ return { success: false, data: [] };
29674
+ }
29675
+ logger.info("success getting funding rates", response.data.data);
29676
+ return { success: true, data: response.data.data };
29677
+ } catch (err) {
29678
+ logger.error("error getting funding rates", err);
29679
+ return { success: false, data: [] };
29418
29680
  }
29681
+ }
29682
+ async getPosition(supportedPosition) {
29419
29683
  const holdings = await this.getExtendedDepositAmount();
29420
29684
  if (!holdings) {
29421
29685
  throw new Error("No position found");
@@ -29423,7 +29687,7 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29423
29687
  const amount = holdings.equity;
29424
29688
  return Promise.resolve({
29425
29689
  amount: new Web3Number(amount, 0),
29426
- remarks: `${holdings.availableForWithdrawal} ${holdings.equity}`
29690
+ remarks: `Extended Equity`
29427
29691
  });
29428
29692
  }
29429
29693
  async maxDeposit(amount) {
@@ -29447,14 +29711,14 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29447
29711
  });
29448
29712
  }
29449
29713
  _getDepositLeaf() {
29450
- const usdceToken = Global.getDefaultTokens().find((token) => token.symbol === "USDCe");
29714
+ const usdceToken = Global.getDefaultTokens().find(
29715
+ (token) => token.symbol === "USDCe"
29716
+ );
29451
29717
  return [
29452
29718
  {
29453
29719
  target: this.config.supportedPositions[0].asset.address,
29454
29720
  method: "approve",
29455
- packedArguments: [
29456
- AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()
29457
- ],
29721
+ packedArguments: [AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()],
29458
29722
  id: `extended_approve_${this.config.supportedPositions[0].asset.symbol}`,
29459
29723
  sanitizer: AVNU_LEGACY_SANITIZER
29460
29724
  },
@@ -29485,25 +29749,33 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29485
29749
  const leafConfigs = this._getSwapFromLegacyLeaf();
29486
29750
  const leaves = leafConfigs.map((config) => {
29487
29751
  const { target, method, packedArguments, sanitizer, id } = config;
29488
- const leaf = this.constructSimpleLeafData({
29489
- id,
29490
- target,
29491
- method,
29492
- packedArguments
29493
- }, sanitizer);
29752
+ const leaf = this.constructSimpleLeafData(
29753
+ {
29754
+ id,
29755
+ target,
29756
+ method,
29757
+ packedArguments
29758
+ },
29759
+ sanitizer
29760
+ );
29494
29761
  return leaf;
29495
29762
  });
29496
- return { leaves, callConstructor: this.getSwapFromLegacyCall.bind(this) };
29763
+ return {
29764
+ leaves,
29765
+ callConstructor: this.getSwapFromLegacyCall.bind(
29766
+ this
29767
+ )
29768
+ };
29497
29769
  }
29498
29770
  _getSwapFromLegacyLeaf() {
29499
- const usdceToken = Global.getDefaultTokens().find((token) => token.symbol === "USDCe");
29771
+ const usdceToken = Global.getDefaultTokens().find(
29772
+ (token) => token.symbol === "USDCe"
29773
+ );
29500
29774
  return [
29501
29775
  {
29502
29776
  target: usdceToken.address,
29503
29777
  method: "approve",
29504
- packedArguments: [
29505
- AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()
29506
- ],
29778
+ packedArguments: [AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()],
29507
29779
  id: `extendedswaplegacyapprove_${usdceToken.symbol}`,
29508
29780
  sanitizer: AVNU_LEGACY_SANITIZER
29509
29781
  },
@@ -29522,11 +29794,13 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29522
29794
  async getDepositCall(params) {
29523
29795
  try {
29524
29796
  const usdcToken = this.config.supportedPositions[0].asset;
29525
- const usdceToken = Global.getDefaultTokens().find((token) => token.symbol === "USDCe");
29526
- const salt = Math.floor(
29527
- Math.random() * 10 ** usdcToken.decimals
29797
+ const usdceToken = Global.getDefaultTokens().find(
29798
+ (token) => token.symbol === "USDCe"
29799
+ );
29800
+ const salt = Math.floor(Math.random() * 10 ** usdcToken.decimals);
29801
+ const amount = uint25613.bnToUint256(
29802
+ params.amount.multipliedBy(10).toWei()
29528
29803
  );
29529
- const amount = uint25613.bnToUint256(params.amount.multipliedBy(10).toWei());
29530
29804
  const quotes = await this.config.avnuAdapter.getQuotesAvnu(
29531
29805
  usdcToken.address.toString(),
29532
29806
  usdceToken.address.toString(),
@@ -29539,7 +29813,9 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29539
29813
  logger.error("error getting quotes from avnu");
29540
29814
  return [];
29541
29815
  }
29542
- const getCalldata = await this.config.avnuAdapter.getSwapCallData(quotes);
29816
+ const getCalldata = await this.config.avnuAdapter.getSwapCallData(
29817
+ quotes
29818
+ );
29543
29819
  const swapCallData = getCalldata[0];
29544
29820
  return [
29545
29821
  {
@@ -29615,8 +29891,12 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29615
29891
  async getSwapFromLegacyCall(params) {
29616
29892
  try {
29617
29893
  const usdcToken = this.config.supportedPositions[0].asset;
29618
- const usdceToken = Global.getDefaultTokens().find((token) => token.symbol === "USDCe");
29619
- const amount = uint25613.bnToUint256(params.amount.multipliedBy(10).toWei());
29894
+ const usdceToken = Global.getDefaultTokens().find(
29895
+ (token) => token.symbol === "USDCe"
29896
+ );
29897
+ const amount = uint25613.bnToUint256(
29898
+ params.amount.multipliedBy(10).toWei()
29899
+ );
29620
29900
  const quotes = await this.config.avnuAdapter.getQuotesAvnu(
29621
29901
  usdceToken.address.toString(),
29622
29902
  usdcToken.address.toString(),
@@ -29629,7 +29909,9 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29629
29909
  logger.error("error getting quotes from avnu");
29630
29910
  return [];
29631
29911
  }
29632
- const getCalldata = await this.config.avnuAdapter.getSwapCallData(quotes);
29912
+ const getCalldata = await this.config.avnuAdapter.getSwapCallData(
29913
+ quotes
29914
+ );
29633
29915
  const swapCallData = getCalldata[0];
29634
29916
  return [
29635
29917
  {
@@ -29675,38 +29957,131 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29675
29957
  async withdrawFromExtended(amount) {
29676
29958
  try {
29677
29959
  if (!this.client) {
29678
- throw new Error("Client not initialized");
29960
+ logger.error("Client not initialized");
29961
+ return {
29962
+ status: false,
29963
+ receivedTxnHash: false
29964
+ };
29965
+ }
29966
+ if (amount.lessThanOrEqualTo(0)) {
29967
+ logger.error(
29968
+ `Invalid withdrawal amount: ${amount.toNumber()}. Amount must be positive.`
29969
+ );
29970
+ return {
29971
+ status: false,
29972
+ receivedTxnHash: false
29973
+ };
29974
+ }
29975
+ if (amount.lessThanOrEqualTo(this.minimumExtendedMovementAmount)) {
29976
+ logger.warn(
29977
+ `Withdrawal amount ${amount.toNumber()} is below minimum Extended movement amount ${this.minimumExtendedMovementAmount}. Skipping withdrawal.`
29978
+ );
29979
+ return {
29980
+ status: false,
29981
+ receivedTxnHash: false
29982
+ };
29983
+ }
29984
+ const holdings = await this.getExtendedDepositAmount();
29985
+ if (!holdings) {
29986
+ logger.error(
29987
+ "Cannot get holdings - unable to validate withdrawal amount"
29988
+ );
29989
+ return {
29990
+ status: false,
29991
+ receivedTxnHash: false
29992
+ };
29993
+ }
29994
+ const availableForWithdrawal = parseFloat(
29995
+ holdings.availableForWithdrawal
29996
+ );
29997
+ if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
29998
+ logger.error(
29999
+ `Invalid availableForWithdrawal: ${holdings.availableForWithdrawal}. Expected a finite, non-negative number.`
30000
+ );
30001
+ return {
30002
+ status: false,
30003
+ receivedTxnHash: false
30004
+ };
30005
+ }
30006
+ const withdrawalAmount = amount.toNumber();
30007
+ if (withdrawalAmount > availableForWithdrawal) {
30008
+ logger.error(
30009
+ `Withdrawal amount ${withdrawalAmount} exceeds available balance ${availableForWithdrawal}`
30010
+ );
30011
+ return {
30012
+ status: false,
30013
+ receivedTxnHash: false
30014
+ };
29679
30015
  }
29680
- const withdrawalRequest = await this.client.withdrawUSDC(amount.toFixed(2));
30016
+ logger.info(
30017
+ `Withdrawing ${withdrawalAmount} from Extended. Available balance: ${availableForWithdrawal}`
30018
+ );
30019
+ const withdrawalRequest = await this.client.withdrawUSDC(
30020
+ amount.toFixed(2)
30021
+ );
29681
30022
  if (withdrawalRequest.status === "OK") {
29682
- const withdrawalStatus = await this.getDepositOrWithdrawalStatus(withdrawalRequest.data, "WITHDRAWAL" /* WITHDRAWAL */);
29683
- return withdrawalStatus;
30023
+ const withdrawalStatus = await this.getDepositOrWithdrawalStatus(
30024
+ withdrawalRequest.data,
30025
+ "WITHDRAWAL" /* WITHDRAWAL */
30026
+ );
30027
+ return {
30028
+ status: true,
30029
+ receivedTxnHash: withdrawalStatus
30030
+ };
29684
30031
  }
29685
- return false;
30032
+ logger.error(
30033
+ `Withdrawal request failed with status: ${withdrawalRequest.status}`
30034
+ );
30035
+ return {
30036
+ status: false,
30037
+ receivedTxnHash: false
30038
+ };
29686
30039
  } catch (error) {
29687
30040
  logger.error(`Error creating Withdraw Call: ${error}`);
29688
- return false;
30041
+ return {
30042
+ status: false,
30043
+ receivedTxnHash: false
30044
+ };
29689
30045
  }
29690
30046
  }
29691
30047
  async getHealthFactor() {
29692
30048
  return Promise.resolve(1);
29693
30049
  }
29694
30050
  async getExtendedDepositAmount() {
29695
- if (this.client === null) {
29696
- logger.error("error initializing client");
29697
- return void 0;
29698
- }
29699
- const result = await this.client.getHoldings();
29700
- if (!result) {
29701
- logger.error(`error getting holdings: ${result}`);
29702
- return void 0;
29703
- }
29704
- const holdings = result.data;
29705
- if (!holdings) {
29706
- logger.error(`error getting holdings: ${holdings}`);
30051
+ try {
30052
+ const result = await axios9.get(`${this.config.extendedBackendReadUrl}/holdings`);
30053
+ if (!result.data) {
30054
+ logger.error("error getting holdings - API returned null/undefined");
30055
+ return void 0;
30056
+ }
30057
+ if (!result.data.success) {
30058
+ logger.error(
30059
+ `error getting holdings - API returned status: ${result.status}`
30060
+ );
30061
+ return void 0;
30062
+ }
30063
+ const holdings = result.data.data;
30064
+ if (!holdings) {
30065
+ logger.warn(
30066
+ "holdings data is null/undefined - treating as zero balance"
30067
+ );
30068
+ return {
30069
+ collateral_name: "",
30070
+ balance: "0",
30071
+ equity: "0",
30072
+ availableForTrade: "0",
30073
+ availableForWithdrawal: "0",
30074
+ unrealisedPnl: "0",
30075
+ initialMargin: "0",
30076
+ marginRatio: "0",
30077
+ updatedTime: Date.now()
30078
+ };
30079
+ }
30080
+ return holdings;
30081
+ } catch (error) {
30082
+ logger.error(`error getting holdings - exception: ${error}`);
29707
30083
  return void 0;
29708
30084
  }
29709
- return holdings;
29710
30085
  }
29711
30086
  async setLeverage(leverage, marketName) {
29712
30087
  if (this.client === null) {
@@ -29723,46 +30098,52 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29723
30098
  return false;
29724
30099
  }
29725
30100
  async getAllOpenPositions() {
29726
- if (this.client === null) {
29727
- logger.error("error initializing client");
29728
- return null;
29729
- }
29730
- const response = await this.client.getPositionsForMarket(
29731
- this.config.extendedMarketName
29732
- );
29733
- if (response.status === "OK") {
29734
- if (response.data.length === 0) {
29735
- return [];
29736
- } else {
29737
- return response.data;
30101
+ try {
30102
+ const response = await axios9.get(`${this.config.extendedBackendReadUrl}/positions`);
30103
+ if (response.data.success) {
30104
+ if (response.data.data.length === 0) {
30105
+ return [];
30106
+ } else {
30107
+ return response.data.data;
30108
+ }
29738
30109
  }
30110
+ return null;
30111
+ } catch (err) {
30112
+ logger.error("error getting all open positions", err);
30113
+ return null;
29739
30114
  }
29740
- return null;
29741
30115
  }
29742
30116
  async getOrderHistory(marketName) {
29743
- if (this.client === null) {
29744
- logger.error("error initializing client");
30117
+ try {
30118
+ const result = await axios9.get(`${this.config.extendedBackendReadUrl}/marketOrders/${marketName}`);
30119
+ if (!result.data.success) {
30120
+ return null;
30121
+ }
30122
+ return result.data.data;
30123
+ } catch (err) {
30124
+ logger.error("error getting order history", err);
29745
30125
  return null;
29746
30126
  }
29747
- const result = await this.client.getOrderHistory(marketName);
29748
- return result.data;
29749
30127
  }
29750
30128
  async getOrderStatus(orderId, marketName) {
29751
- if (this.client === null) {
29752
- logger.error("error initializing client");
29753
- return null;
29754
- }
29755
- const orderhistory = await this.getOrderHistory(marketName);
29756
- if (!orderhistory || orderhistory.length === 0) {
29757
- logger.error(`error getting order: ${orderId}`);
30129
+ try {
30130
+ if (this.client === null) {
30131
+ logger.error("error initializing client");
30132
+ return null;
30133
+ }
30134
+ const orderhistory = await this.getOrderHistory(marketName);
30135
+ if (!orderhistory || orderhistory.length === 0) {
30136
+ return null;
30137
+ }
30138
+ const order = orderhistory.slice(0, 20).find((order2) => order2.id.toString() === orderId);
30139
+ if (order) {
30140
+ return order;
30141
+ }
29758
30142
  return null;
29759
- }
29760
- const order = orderhistory.slice(0, 3).find((order2) => order2.id.toString() === orderId);
29761
- if (!order) {
29762
- logger.error(`error getting order: ${order}`);
30143
+ } catch (error) {
30144
+ logger.error(`error getting order status: ${error}`);
29763
30145
  return null;
29764
30146
  }
29765
- return order;
29766
30147
  }
29767
30148
  async fetchOrderBookBTCUSDC() {
29768
30149
  try {
@@ -29813,14 +30194,40 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29813
30194
  logger.error("error depositing or setting leverage");
29814
30195
  return null;
29815
30196
  }
29816
- const positions = await this.getAllOpenPositions();
29817
- if (positions === null) {
30197
+ const { ask, bid } = await this.fetchOrderBookBTCUSDC();
30198
+ if (!ask || !bid || ask.lessThanOrEqualTo(0) || bid.lessThanOrEqualTo(0)) {
30199
+ logger.error(
30200
+ `Invalid orderbook prices: ask=${ask?.toNumber()}, bid=${bid?.toNumber()}`
30201
+ );
29818
30202
  return null;
29819
30203
  }
29820
- const { ask, bid } = await this.fetchOrderBookBTCUSDC();
29821
30204
  const spread = ask.minus(bid);
29822
- let price = ask.plus(bid).div(2);
29823
- side === "SELL" /* SELL */ ? price = price.minus(spread.times(0.2 * attempt)) : price = price.plus(spread.times(0.2 * attempt));
30205
+ const midPrice = ask.plus(bid).div(2);
30206
+ const MAX_PRICE_DEVIATION_MULTIPLIER = 0.5;
30207
+ const priceAdjustmentMultiplier = Math.min(
30208
+ 0.2 * attempt,
30209
+ MAX_PRICE_DEVIATION_MULTIPLIER
30210
+ );
30211
+ const priceAdjustment = spread.times(priceAdjustmentMultiplier);
30212
+ let price = midPrice;
30213
+ if (side === "SELL" /* SELL */) {
30214
+ price = midPrice.minus(priceAdjustment);
30215
+ } else {
30216
+ price = midPrice.plus(priceAdjustment);
30217
+ }
30218
+ const maxDeviation = midPrice.times(0.5);
30219
+ if (price.minus(midPrice).abs().greaterThan(maxDeviation)) {
30220
+ logger.error(
30221
+ `Price deviation too large on attempt ${attempt}: price=${price.toNumber()}, midPrice=${midPrice.toNumber()}, deviation=${price.minus(midPrice).abs().toNumber()}`
30222
+ );
30223
+ if (attempt >= maxAttempts) {
30224
+ return null;
30225
+ }
30226
+ price = side === "SELL" /* SELL */ ? midPrice.minus(maxDeviation) : midPrice.plus(maxDeviation);
30227
+ }
30228
+ logger.info(
30229
+ `createOrder attempt ${attempt}/${maxAttempts}: side=${side}, midPrice=${midPrice.toNumber()}, adjustedPrice=${price.toNumber()}, adjustment=${priceAdjustmentMultiplier * 100}%`
30230
+ );
29824
30231
  const amount_in_token = (btcAmount * parseInt(leverage)).toFixed(
29825
30232
  this.config.extendedPrecision
29826
30233
  );
@@ -29831,14 +30238,57 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29831
30238
  price.toFixed(0),
29832
30239
  side
29833
30240
  );
29834
- if (!result) {
30241
+ if (!result || !result.position_id) {
30242
+ logger.error("Failed to create order - no position_id returned");
29835
30243
  return null;
29836
30244
  }
29837
- await new Promise((resolve) => setTimeout(resolve, 5e3));
29838
- const openOrder = await this.getOrderStatus(result.position_id, this.config.extendedMarketName);
29839
- if (!openOrder || openOrder.status !== "FILLED" /* FILLED */) {
30245
+ const positionId = result.position_id;
30246
+ logger.info(
30247
+ `Order created with position_id: ${positionId}. Waiting for API to update...`
30248
+ );
30249
+ let openOrder = await this.getOrderStatus(
30250
+ positionId,
30251
+ this.config.extendedMarketName
30252
+ );
30253
+ const maxStatusRetries = 3;
30254
+ const statusRetryDelay = 5e3;
30255
+ if (!openOrder) {
30256
+ logger.warn(
30257
+ `Order ${positionId} not found in API yet. Retrying status fetch (max ${maxStatusRetries} times)...`
30258
+ );
30259
+ for (let statusRetry = 1; statusRetry <= maxStatusRetries; statusRetry++) {
30260
+ await new Promise((resolve) => setTimeout(resolve, statusRetryDelay));
30261
+ openOrder = await this.getOrderStatus(
30262
+ positionId,
30263
+ this.config.extendedMarketName
30264
+ );
30265
+ if (openOrder) {
30266
+ logger.info(
30267
+ `Order ${positionId} found after ${statusRetry} status retry(ies)`
30268
+ );
30269
+ break;
30270
+ }
30271
+ logger.warn(
30272
+ `Order ${positionId} still not found after ${statusRetry}/${maxStatusRetries} status retries`
30273
+ );
30274
+ }
30275
+ }
30276
+ if (openOrder && openOrder.status === "FILLED" /* FILLED */) {
30277
+ logger.info(
30278
+ `Order ${positionId} successfully filled with quantity ${openOrder.qty}`
30279
+ );
30280
+ return {
30281
+ position_id: positionId,
30282
+ btc_exposure: openOrder.qty
30283
+ };
30284
+ } else if (openOrder && openOrder.status !== "FILLED" /* FILLED */) {
30285
+ logger.warn(
30286
+ `Order ${positionId} found but status is ${openOrder.status}, not FILLED. Retrying order creation...`
30287
+ );
29840
30288
  if (attempt >= maxAttempts) {
29841
- logger.error("Max retries reached \u2014 could not verify open position");
30289
+ logger.error(
30290
+ `Max retries reached \u2014 order ${positionId} status is ${openOrder.status}, not FILLED`
30291
+ );
29842
30292
  return null;
29843
30293
  } else {
29844
30294
  const backoff = 2e3 * attempt;
@@ -29852,13 +30302,18 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29852
30302
  );
29853
30303
  }
29854
30304
  } else {
30305
+ logger.warn(
30306
+ `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.`
30307
+ );
29855
30308
  return {
29856
- position_id: result.position_id,
29857
- btc_exposure: openOrder.qty
30309
+ position_id: positionId,
30310
+ btc_exposure: amount_in_token
29858
30311
  };
29859
30312
  }
29860
30313
  } catch (err) {
29861
- logger.error(`createShortOrder failed on attempt ${attempt}: ${err.message}`);
30314
+ logger.error(
30315
+ `createShortOrder failed on attempt ${attempt}: ${err.message}`
30316
+ );
29862
30317
  if (attempt < maxAttempts) {
29863
30318
  const backoff = 1200 * attempt;
29864
30319
  logger.info(`Retrying after ${backoff}ms...`);
@@ -29897,28 +30352,101 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29897
30352
  }
29898
30353
  }
29899
30354
  async getDepositOrWithdrawalStatus(orderId, operationsType) {
29900
- try {
29901
- let transferHistory = await this.client.getAssetOperations({
29902
- operationsType: [operationsType],
29903
- operationsStatus: ["COMPLETED" /* COMPLETED */]
29904
- });
29905
- if (operationsType === "DEPOSIT" /* DEPOSIT */) {
29906
- const myTransferStatus = transferHistory.data.find((operation) => operation.transactionHash === orderId);
29907
- if (!myTransferStatus) {
29908
- return true;
30355
+ const maxAttempts = 15;
30356
+ const retryDelayMs = 3e4;
30357
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
30358
+ try {
30359
+ let transferHistory = await this.client.getAssetOperations({
30360
+ operationsType: [operationsType],
30361
+ operationsStatus: ["COMPLETED" /* COMPLETED */]
30362
+ });
30363
+ if (operationsType === "DEPOSIT" /* DEPOSIT */) {
30364
+ const myTransferStatus = transferHistory.data.find(
30365
+ (operation) => operation.transactionHash?.toLowerCase() === orderId.toString().toLowerCase()
30366
+ );
30367
+ if (!myTransferStatus) {
30368
+ if (attempt < maxAttempts) {
30369
+ logger.info(
30370
+ `Deposit operation not found for transactionHash ${orderId}, retrying (attempt ${attempt}/${maxAttempts})...`
30371
+ );
30372
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
30373
+ continue;
30374
+ }
30375
+ logger.warn(
30376
+ `Deposit operation not found for transactionHash ${orderId} after ${maxAttempts} attempts`
30377
+ );
30378
+ return false;
30379
+ }
30380
+ if (myTransferStatus.status === "COMPLETED" /* COMPLETED */) {
30381
+ logger.info(
30382
+ `Deposit operation ${orderId} completed successfully`
30383
+ );
30384
+ return true;
30385
+ } else {
30386
+ if (attempt < maxAttempts) {
30387
+ logger.info(
30388
+ `Deposit operation ${orderId} found but status is ${myTransferStatus.status}, not COMPLETED. Retrying (attempt ${attempt}/${maxAttempts})...`
30389
+ );
30390
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
30391
+ continue;
30392
+ }
30393
+ logger.warn(
30394
+ `Deposit operation ${orderId} status is ${myTransferStatus.status} after ${maxAttempts} attempts, expected COMPLETED`
30395
+ );
30396
+ return false;
30397
+ }
30398
+ } else {
30399
+ const myTransferStatus = transferHistory.data.find(
30400
+ (operation) => operation.id === orderId.toString()
30401
+ );
30402
+ if (!myTransferStatus) {
30403
+ if (attempt < maxAttempts) {
30404
+ logger.info(
30405
+ `Withdrawal status not found for orderId ${orderId} in completed operations, retrying (attempt ${attempt}/${maxAttempts})...`
30406
+ );
30407
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
30408
+ continue;
30409
+ }
30410
+ logger.warn(
30411
+ `Withdrawal operation not found for orderId ${orderId} after ${maxAttempts} attempts`
30412
+ );
30413
+ return false;
30414
+ }
30415
+ if (myTransferStatus.status === "COMPLETED" /* COMPLETED */) {
30416
+ logger.info(
30417
+ `Withdrawal operation ${orderId} completed successfully`
30418
+ );
30419
+ return true;
30420
+ } else {
30421
+ if (attempt < maxAttempts) {
30422
+ logger.info(
30423
+ `Withdrawal operation ${orderId} found but status is ${myTransferStatus.status}, not COMPLETED. Retrying (attempt ${attempt}/${maxAttempts})...`
30424
+ );
30425
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
30426
+ continue;
30427
+ }
30428
+ logger.warn(
30429
+ `Withdrawal operation ${orderId} status is ${myTransferStatus.status} after ${maxAttempts} attempts, expected COMPLETED`
30430
+ );
30431
+ return false;
30432
+ }
29909
30433
  }
29910
- return true;
29911
- } else {
29912
- const myTransferStatus = transferHistory.data.find((operation) => operation.id.toString() === orderId.toString());
29913
- if (!myTransferStatus) {
29914
- return true;
30434
+ } catch (err) {
30435
+ logger.error(
30436
+ `error getting deposit or withdrawal status (attempt ${attempt}/${maxAttempts}): ${err}`
30437
+ );
30438
+ if (attempt < maxAttempts) {
30439
+ logger.info(`Retrying after ${retryDelayMs}ms...`);
30440
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
30441
+ continue;
29915
30442
  }
29916
- return true;
30443
+ logger.error(
30444
+ `Max retry attempts reached for getDepositOrWithdrawalStatus`
30445
+ );
30446
+ return false;
29917
30447
  }
29918
- } catch (err) {
29919
- logger.error(`error getting deposit or withdrawal status: ${err}`);
29920
- return false;
29921
30448
  }
30449
+ return false;
29922
30450
  }
29923
30451
  };
29924
30452
 
@@ -29998,12 +30526,351 @@ var UnusedBalanceAdapter = class _UnusedBalanceAdapter extends BaseAdapter {
29998
30526
  }
29999
30527
  };
30000
30528
 
30529
+ // src/strategies/universal-adapters/avnu-adapter.ts
30530
+ import { hash as hash7, uint256 as uint25614 } from "starknet";
30531
+ import axios10 from "axios";
30532
+ var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
30533
+ constructor(config) {
30534
+ super(config, _AvnuAdapter.name, Protocols.AVNU);
30535
+ this.config = config;
30536
+ this.avnuWrapper = new AvnuWrapper();
30537
+ }
30538
+ //abstract means the method has no implementation in this class; instead, child classes must implement it.
30539
+ async getAPY(supportedPosition) {
30540
+ return Promise.resolve({ apy: 0, type: "base" /* BASE */ });
30541
+ }
30542
+ async getPosition(supportedPosition) {
30543
+ return Promise.resolve({ amount: new Web3Number(0, 0), remarks: "Avnu Positions" });
30544
+ }
30545
+ async maxDeposit(amount) {
30546
+ return Promise.resolve({
30547
+ tokenInfo: this.config.baseToken,
30548
+ amount: new Web3Number(0, 0),
30549
+ usdValue: 0,
30550
+ apy: { apy: 0, type: "base" /* BASE */ },
30551
+ protocol: Protocols.AVNU,
30552
+ remarks: ""
30553
+ });
30554
+ }
30555
+ async maxWithdraw() {
30556
+ return Promise.resolve({
30557
+ tokenInfo: this.config.baseToken,
30558
+ amount: new Web3Number(0, 0),
30559
+ usdValue: 0,
30560
+ apy: { apy: 0, type: "base" /* BASE */ },
30561
+ protocol: Protocols.AVNU,
30562
+ remarks: ""
30563
+ });
30564
+ }
30565
+ _getDepositLeaf() {
30566
+ const vaultAllocator = ContractAddr.from(
30567
+ this.config.vaultAllocator.address
30568
+ );
30569
+ return [
30570
+ {
30571
+ target: this.config.supportedPositions[0].asset.address,
30572
+ method: "approve",
30573
+ packedArguments: [
30574
+ AVNU_EXCHANGE.toBigInt()
30575
+ ],
30576
+ sanitizer: SIMPLE_SANITIZER,
30577
+ id: `approve_${this.config.supportedPositions[0].asset.symbol}`
30578
+ },
30579
+ {
30580
+ target: AVNU_EXCHANGE,
30581
+ method: "multi_route_swap",
30582
+ packedArguments: [
30583
+ this.config.supportedPositions[0].asset.address.toBigInt(),
30584
+ //usdc
30585
+ this.config.supportedPositions[1].asset.address.toBigInt(),
30586
+ //wbtc
30587
+ vaultAllocator.toBigInt()
30588
+ ],
30589
+ sanitizer: SIMPLE_SANITIZER,
30590
+ id: `asutb_${this.config.supportedPositions[0].asset.symbol}_${this.config.supportedPositions[1].asset.symbol}`
30591
+ }
30592
+ ];
30593
+ }
30594
+ _getWithdrawLeaf() {
30595
+ const vaultAllocator = ContractAddr.from(
30596
+ this.config.vaultAllocator.address
30597
+ );
30598
+ const toToken = this.config.supportedPositions[0].asset;
30599
+ const fromToken = this.config.supportedPositions[1].asset;
30600
+ return [
30601
+ {
30602
+ target: fromToken.address,
30603
+ method: "approve",
30604
+ packedArguments: [
30605
+ AVNU_EXCHANGE.toBigInt()
30606
+ ],
30607
+ sanitizer: SIMPLE_SANITIZER,
30608
+ id: `approve_${fromToken.symbol}`
30609
+ },
30610
+ {
30611
+ target: AVNU_EXCHANGE,
30612
+ method: "multi_route_swap",
30613
+ packedArguments: [
30614
+ fromToken.address.toBigInt(),
30615
+ //wbtc
30616
+ toToken.address.toBigInt(),
30617
+ //usdc
30618
+ vaultAllocator.toBigInt()
30619
+ ],
30620
+ sanitizer: SIMPLE_SANITIZER,
30621
+ id: `asbtu_${fromToken.symbol}_${fromToken.symbol}`
30622
+ }
30623
+ ];
30624
+ }
30625
+ _getLegacySwapLeaf() {
30626
+ return [];
30627
+ }
30628
+ async getDepositCall(params) {
30629
+ try {
30630
+ const fromToken = this.config.supportedPositions[0].asset;
30631
+ const toToken = this.config.supportedPositions[1].asset;
30632
+ const vaultAllocator = ContractAddr.from(
30633
+ this.config.vaultAllocator.address
30634
+ );
30635
+ const quote = await this.getQuotesAvnu(
30636
+ fromToken.address.toString(),
30637
+ toToken.address.toString(),
30638
+ params.amount.toNumber(),
30639
+ vaultAllocator.address.toString(),
30640
+ toToken.decimals,
30641
+ true
30642
+ );
30643
+ if (!quote) {
30644
+ logger.error("error getting quote from avnu");
30645
+ return [];
30646
+ }
30647
+ const getCalldata = await this.avnuWrapper.getSwapCallData(
30648
+ quote,
30649
+ vaultAllocator.address
30650
+ );
30651
+ const swapCallData = getCalldata[0];
30652
+ const amount = uint25614.bnToUint256(quote.sellAmountInUsd * 10 ** 7);
30653
+ return [
30654
+ {
30655
+ sanitizer: SIMPLE_SANITIZER,
30656
+ call: {
30657
+ contractAddress: fromToken.address,
30658
+ selector: hash7.getSelectorFromName("approve"),
30659
+ calldata: [
30660
+ AVNU_EXCHANGE.toBigInt(),
30661
+ toBigInt(amount.low.toString()),
30662
+ // amount low
30663
+ toBigInt(amount.high.toString())
30664
+ // amount high
30665
+ ]
30666
+ }
30667
+ },
30668
+ {
30669
+ sanitizer: SIMPLE_SANITIZER,
30670
+ call: {
30671
+ contractAddress: AVNU_EXCHANGE,
30672
+ selector: hash7.getSelectorFromName("multi_route_swap"),
30673
+ calldata: swapCallData
30674
+ }
30675
+ }
30676
+ ];
30677
+ } catch (error) {
30678
+ logger.error(`Error getting Avnu quote: ${error}`);
30679
+ return [];
30680
+ }
30681
+ }
30682
+ //Swap wbtc to usdc
30683
+ async getWithdrawCall(params) {
30684
+ try {
30685
+ const toToken = this.config.supportedPositions[0].asset;
30686
+ const fromToken = this.config.supportedPositions[1].asset;
30687
+ const vaultAllocator = ContractAddr.from(
30688
+ this.config.vaultAllocator.address
30689
+ );
30690
+ const quote = await this.getQuotesAvnu(
30691
+ fromToken.address.toString(),
30692
+ toToken.address.toString(),
30693
+ params.amount.toNumber(),
30694
+ vaultAllocator.address.toString(),
30695
+ fromToken.decimals,
30696
+ false
30697
+ );
30698
+ if (!quote) {
30699
+ logger.error("No quotes available for this swap, error in quotes avnu");
30700
+ return [];
30701
+ }
30702
+ const getCalldata = await this.avnuWrapper.getSwapCallData(
30703
+ quote,
30704
+ vaultAllocator.address
30705
+ );
30706
+ const swapCallData = getCalldata[0];
30707
+ const amount = uint25614.bnToUint256(params.amount.toWei());
30708
+ return [
30709
+ {
30710
+ sanitizer: SIMPLE_SANITIZER,
30711
+ call: {
30712
+ contractAddress: fromToken.address,
30713
+ selector: hash7.getSelectorFromName("approve"),
30714
+ calldata: [
30715
+ AVNU_EXCHANGE.toBigInt(),
30716
+ toBigInt(amount.low.toString()),
30717
+ // amount low
30718
+ toBigInt(amount.high.toString())
30719
+ // amount high
30720
+ ]
30721
+ }
30722
+ },
30723
+ {
30724
+ sanitizer: SIMPLE_SANITIZER,
30725
+ call: {
30726
+ contractAddress: AVNU_EXCHANGE,
30727
+ selector: hash7.getSelectorFromName("multi_route_swap"),
30728
+ calldata: swapCallData
30729
+ }
30730
+ }
30731
+ ];
30732
+ } catch (error) {
30733
+ logger.error(`Error getting Avnu quote: ${error}`);
30734
+ return [];
30735
+ }
30736
+ }
30737
+ async getSwapCallData(quote) {
30738
+ return await this.avnuWrapper.getSwapCallData(quote, this.config.vaultAllocator.address);
30739
+ }
30740
+ async getHealthFactor() {
30741
+ return Promise.resolve(1);
30742
+ }
30743
+ async fetchQuoteWithRetry(params, retries = 5) {
30744
+ for (let attempt = 0; attempt < retries; attempt++) {
30745
+ try {
30746
+ const response = await axios10.get(this.config.baseUrl, { params });
30747
+ if (response.data && response.data.length > 0) {
30748
+ return response;
30749
+ }
30750
+ throw new Error("Empty response data");
30751
+ } catch (err) {
30752
+ logger.error(`Error fetching quote with retry: ${err}`);
30753
+ if (attempt === retries - 1) {
30754
+ throw err;
30755
+ }
30756
+ await new Promise((resolve) => setTimeout(resolve, MAX_DELAY));
30757
+ }
30758
+ }
30759
+ throw new Error("Failed to fetch quote after retries");
30760
+ }
30761
+ async getQuotesAvnu(from_token_address, to_token_address, amount, takerAddress, toTokenDecimals, usdcToBtc, maxIterations = 5, tolerance = 5e3) {
30762
+ try {
30763
+ const fromToken = this.config.supportedPositions[0].asset;
30764
+ const toToken = this.config.supportedPositions[1].asset;
30765
+ if (!usdcToBtc) {
30766
+ const sellAmount2 = returnFormattedAmount(amount, toTokenDecimals);
30767
+ const params2 = {
30768
+ sellTokenAddress: from_token_address,
30769
+ buyTokenAddress: to_token_address,
30770
+ takerAddress,
30771
+ sellAmount: sellAmount2
30772
+ };
30773
+ const finalQuote2 = await this.fetchQuoteWithRetry(params2);
30774
+ if (!finalQuote2.data.length) {
30775
+ logger.error("No quotes available for this swap, error in quotes avnu");
30776
+ return null;
30777
+ }
30778
+ const dataObject2 = finalQuote2.data[0];
30779
+ return dataObject2;
30780
+ }
30781
+ const btcPrice = await this.getPriceOfToken(toToken.address.toString());
30782
+ if (!btcPrice) {
30783
+ logger.error(`error getting btc price: ${btcPrice}`);
30784
+ return null;
30785
+ }
30786
+ const estimatedUsdcAmount = Math.floor(amount * btcPrice);
30787
+ logger.info(`${_AvnuAdapter.name}::getQuotesAvnu estimatedUsdcAmount: ${estimatedUsdcAmount}`);
30788
+ const targetBtcBig = BigInt(returnFormattedAmount(amount, toTokenDecimals));
30789
+ logger.info(`${_AvnuAdapter.name}::getQuotesAvnu targetBtcBig: ${targetBtcBig}`);
30790
+ let low = BigInt(
30791
+ Math.floor(
30792
+ estimatedUsdcAmount * 10 ** fromToken.decimals * 0.9
30793
+ )
30794
+ );
30795
+ let high = BigInt(
30796
+ Math.floor(
30797
+ estimatedUsdcAmount * 10 ** fromToken.decimals * 1.1
30798
+ )
30799
+ );
30800
+ let mid = 0n;
30801
+ for (let i = 0; i < maxIterations; i++) {
30802
+ mid = (low + high) / 2n;
30803
+ const sellAmount2 = returnFormattedAmount(Number(mid), 0);
30804
+ const quote = await this.fetchQuoteWithRetry({
30805
+ sellTokenAddress: from_token_address,
30806
+ buyTokenAddress: to_token_address,
30807
+ takerAddress,
30808
+ sellAmount: sellAmount2
30809
+ });
30810
+ const gotBtc = BigInt(quote.data[0].buyAmount);
30811
+ if (gotBtc === targetBtcBig) return quote.data[0];
30812
+ if (gotBtc > targetBtcBig) {
30813
+ high = mid;
30814
+ } else {
30815
+ low = mid;
30816
+ }
30817
+ if (gotBtc >= targetBtcBig && gotBtc <= targetBtcBig + BigInt(tolerance)) {
30818
+ return quote.data[0];
30819
+ }
30820
+ }
30821
+ let sellAmount = returnFormattedAmount(
30822
+ Number(mid),
30823
+ 0
30824
+ );
30825
+ const params = {
30826
+ sellTokenAddress: from_token_address,
30827
+ buyTokenAddress: to_token_address,
30828
+ takerAddress,
30829
+ sellAmount
30830
+ };
30831
+ const finalQuote = await this.fetchQuoteWithRetry(params);
30832
+ if (!finalQuote.data.length) {
30833
+ logger.error("No quotes available for this swap, error in quotes avnu");
30834
+ return null;
30835
+ }
30836
+ const dataObject = finalQuote.data[0];
30837
+ const wbtcAmountOut = parseInt(dataObject.buyAmount.toString(), 16);
30838
+ logger.info(`${_AvnuAdapter.name}::getQuotesAvnu finalAmountOfWbtcOut : ${wbtcAmountOut} ${dataObject.buyAmount} ${dataObject.sellAmount.toString()} ${dataObject.sellAmount.toString()}`);
30839
+ return dataObject;
30840
+ } catch (err) {
30841
+ logger.error(`No quotes available for this swap: ${err}`);
30842
+ return null;
30843
+ }
30844
+ }
30845
+ async getPriceOfToken(tokenAddress, retries = MAX_RETRIES) {
30846
+ try {
30847
+ const url = `https://starknet.impulse.avnu.fi/v1/tokens/${tokenAddress}/prices/line`;
30848
+ const response = await axios10.get(url);
30849
+ const length = response.data.length;
30850
+ return response.data[length - 1].value;
30851
+ } catch (err) {
30852
+ if (retries > 0) {
30853
+ await new Promise((resolve) => setTimeout(resolve, MAX_DELAY));
30854
+ return this.getPriceOfToken(tokenAddress, retries - 1);
30855
+ } else {
30856
+ logger.error(`Failed to fetch price for ${tokenAddress} after ${MAX_RETRIES} attempts`);
30857
+ return null;
30858
+ }
30859
+ }
30860
+ }
30861
+ };
30862
+
30001
30863
  // src/strategies/universal-strategy.tsx
30002
30864
  var AUMTypes = /* @__PURE__ */ ((AUMTypes2) => {
30003
30865
  AUMTypes2["FINALISED"] = "finalised";
30004
30866
  AUMTypes2["DEFISPRING"] = "defispring";
30005
30867
  return AUMTypes2;
30006
30868
  })(AUMTypes || {});
30869
+ var PositionTypeAvnuExtended = /* @__PURE__ */ ((PositionTypeAvnuExtended2) => {
30870
+ PositionTypeAvnuExtended2["OPEN"] = "open";
30871
+ PositionTypeAvnuExtended2["CLOSE"] = "close";
30872
+ return PositionTypeAvnuExtended2;
30873
+ })(PositionTypeAvnuExtended || {});
30007
30874
  var UNIVERSAL_MANAGE_IDS = /* @__PURE__ */ ((UNIVERSAL_MANAGE_IDS2) => {
30008
30875
  UNIVERSAL_MANAGE_IDS2["FLASH_LOAN"] = "flash_loan_init";
30009
30876
  UNIVERSAL_MANAGE_IDS2["VESU_LEG1"] = "vesu_leg1";
@@ -33184,7 +34051,8 @@ function getLooperSettings(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
33184
34051
  minHealthFactor: vaultSettings.minHealthFactor,
33185
34052
  quoteAmountToFetchPrice: vaultSettings.quoteAmountToFetchPrice,
33186
34053
  ...baseAdapterConfig,
33187
- supportedPositions: [{ asset: lstToken, isDebt: false }, { asset: Global.getDefaultTokens().find((token) => token.symbol === position), isDebt: true }]
34054
+ supportedPositions: [{ asset: lstToken, isDebt: false }, { asset: Global.getDefaultTokens().find((token) => token.symbol === position), isDebt: true }],
34055
+ minimumVesuMovementAmount: 0
33188
34056
  }));
33189
34057
  const unusedBalanceAdapter = new UnusedBalanceAdapter({
33190
34058
  ...baseAdapterConfig
@@ -33413,335 +34281,15 @@ var HyperLSTStrategies = [
33413
34281
  getStrategySettings("mRe7YIELD", "mRe7YIELD", hypermRe7YIELD, false, false)
33414
34282
  ];
33415
34283
 
33416
- // src/strategies/universal-adapters/avnu-adapter.ts
33417
- import { hash as hash7, uint256 as uint25614 } from "starknet";
33418
- import axios10 from "axios";
33419
- var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
33420
- constructor(config) {
33421
- super(config, _AvnuAdapter.name, Protocols.AVNU);
33422
- this.config = config;
33423
- this.avnuWrapper = new AvnuWrapper();
33424
- }
33425
- //abstract means the method has no implementation in this class; instead, child classes must implement it.
33426
- async getAPY(supportedPosition) {
33427
- return Promise.resolve({ apy: 0, type: "base" /* BASE */ });
33428
- }
33429
- async getPosition(supportedPosition) {
33430
- return Promise.resolve({ amount: new Web3Number(0, 0), remarks: "" });
33431
- }
33432
- async maxDeposit(amount) {
33433
- return Promise.resolve({
33434
- tokenInfo: this.config.baseToken,
33435
- amount: new Web3Number(0, 0),
33436
- usdValue: 0,
33437
- apy: { apy: 0, type: "base" /* BASE */ },
33438
- protocol: Protocols.AVNU,
33439
- remarks: ""
33440
- });
33441
- }
33442
- async maxWithdraw() {
33443
- return Promise.resolve({
33444
- tokenInfo: this.config.baseToken,
33445
- amount: new Web3Number(0, 0),
33446
- usdValue: 0,
33447
- apy: { apy: 0, type: "base" /* BASE */ },
33448
- protocol: Protocols.AVNU,
33449
- remarks: ""
33450
- });
33451
- }
33452
- _getDepositLeaf() {
33453
- const vaultAllocator = ContractAddr.from(
33454
- this.config.vaultAllocator.address
33455
- );
33456
- return [
33457
- {
33458
- target: this.config.supportedPositions[0].asset.address,
33459
- method: "approve",
33460
- packedArguments: [
33461
- AVNU_EXCHANGE.toBigInt()
33462
- ],
33463
- sanitizer: SIMPLE_SANITIZER,
33464
- id: `approve_${this.config.supportedPositions[0].asset.symbol}`
33465
- },
33466
- {
33467
- target: AVNU_EXCHANGE,
33468
- method: "multi_route_swap",
33469
- packedArguments: [
33470
- this.config.supportedPositions[0].asset.address.toBigInt(),
33471
- //usdc
33472
- this.config.supportedPositions[1].asset.address.toBigInt(),
33473
- //wbtc
33474
- vaultAllocator.toBigInt()
33475
- ],
33476
- sanitizer: SIMPLE_SANITIZER,
33477
- id: `asutb_${this.config.supportedPositions[0].asset.symbol}_${this.config.supportedPositions[1].asset.symbol}`
33478
- }
33479
- ];
33480
- }
33481
- _getWithdrawLeaf() {
33482
- const vaultAllocator = ContractAddr.from(
33483
- this.config.vaultAllocator.address
33484
- );
33485
- const toToken = this.config.supportedPositions[0].asset;
33486
- const fromToken = this.config.supportedPositions[1].asset;
33487
- return [
33488
- {
33489
- target: fromToken.address,
33490
- method: "approve",
33491
- packedArguments: [
33492
- AVNU_EXCHANGE.toBigInt()
33493
- ],
33494
- sanitizer: SIMPLE_SANITIZER,
33495
- id: `approve_${fromToken.symbol}`
33496
- },
33497
- {
33498
- target: AVNU_EXCHANGE,
33499
- method: "multi_route_swap",
33500
- packedArguments: [
33501
- fromToken.address.toBigInt(),
33502
- //wbtc
33503
- toToken.address.toBigInt(),
33504
- //usdc
33505
- vaultAllocator.toBigInt()
33506
- ],
33507
- sanitizer: SIMPLE_SANITIZER,
33508
- id: `asbtu_${fromToken.symbol}_${fromToken.symbol}`
33509
- }
33510
- ];
33511
- }
33512
- _getLegacySwapLeaf() {
33513
- return [];
33514
- }
33515
- async getDepositCall(params) {
33516
- try {
33517
- const fromToken = this.config.supportedPositions[0].asset;
33518
- const toToken = this.config.supportedPositions[1].asset;
33519
- const vaultAllocator = ContractAddr.from(
33520
- this.config.vaultAllocator.address
33521
- );
33522
- const quote = await this.getQuotesAvnu(
33523
- fromToken.address.toString(),
33524
- toToken.address.toString(),
33525
- params.amount.toNumber(),
33526
- vaultAllocator.address.toString(),
33527
- toToken.decimals,
33528
- true
33529
- );
33530
- if (!quote) {
33531
- logger.error("error getting quote from avnu");
33532
- return [];
33533
- }
33534
- const getCalldata = await this.avnuWrapper.getSwapCallData(
33535
- quote,
33536
- vaultAllocator.address
33537
- );
33538
- const swapCallData = getCalldata[0];
33539
- const amount = uint25614.bnToUint256(quote.sellAmountInUsd * 10 ** 7);
33540
- return [
33541
- {
33542
- sanitizer: SIMPLE_SANITIZER,
33543
- call: {
33544
- contractAddress: fromToken.address,
33545
- selector: hash7.getSelectorFromName("approve"),
33546
- calldata: [
33547
- AVNU_EXCHANGE.toBigInt(),
33548
- toBigInt(amount.low.toString()),
33549
- // amount low
33550
- toBigInt(amount.high.toString())
33551
- // amount high
33552
- ]
33553
- }
33554
- },
33555
- {
33556
- sanitizer: SIMPLE_SANITIZER,
33557
- call: {
33558
- contractAddress: AVNU_EXCHANGE,
33559
- selector: hash7.getSelectorFromName("multi_route_swap"),
33560
- calldata: swapCallData
33561
- }
33562
- }
33563
- ];
33564
- } catch (error) {
33565
- logger.error(`Error getting Avnu quote: ${error}`);
33566
- return [];
33567
- }
33568
- }
33569
- //Swap wbtc to usdc
33570
- async getWithdrawCall(params) {
33571
- try {
33572
- const toToken = this.config.supportedPositions[0].asset;
33573
- const fromToken = this.config.supportedPositions[1].asset;
33574
- const vaultAllocator = ContractAddr.from(
33575
- this.config.vaultAllocator.address
33576
- );
33577
- const quote = await this.getQuotesAvnu(
33578
- fromToken.address.toString(),
33579
- toToken.address.toString(),
33580
- params.amount.toNumber(),
33581
- vaultAllocator.address.toString(),
33582
- fromToken.decimals,
33583
- false
33584
- );
33585
- if (!quote) {
33586
- logger.error("No quotes available for this swap, error in quotes avnu");
33587
- return [];
33588
- }
33589
- const getCalldata = await this.avnuWrapper.getSwapCallData(
33590
- quote,
33591
- vaultAllocator.address
33592
- );
33593
- const swapCallData = getCalldata[0];
33594
- const amount = uint25614.bnToUint256(params.amount.toWei());
33595
- return [
33596
- {
33597
- sanitizer: SIMPLE_SANITIZER,
33598
- call: {
33599
- contractAddress: fromToken.address,
33600
- selector: hash7.getSelectorFromName("approve"),
33601
- calldata: [
33602
- AVNU_EXCHANGE.toBigInt(),
33603
- toBigInt(amount.low.toString()),
33604
- // amount low
33605
- toBigInt(amount.high.toString())
33606
- // amount high
33607
- ]
33608
- }
33609
- },
33610
- {
33611
- sanitizer: SIMPLE_SANITIZER,
33612
- call: {
33613
- contractAddress: AVNU_EXCHANGE,
33614
- selector: hash7.getSelectorFromName("multi_route_swap"),
33615
- calldata: swapCallData
33616
- }
33617
- }
33618
- ];
33619
- } catch (error) {
33620
- logger.error(`Error getting Avnu quote: ${error}`);
33621
- return [];
33622
- }
33623
- }
33624
- async getSwapCallData(quote) {
33625
- return await this.avnuWrapper.getSwapCallData(quote, this.config.vaultAllocator.address);
33626
- }
33627
- async getHealthFactor() {
33628
- return Promise.resolve(1);
33629
- }
33630
- async fetchQuoteWithRetry(params, retries = 5) {
33631
- for (let attempt = 0; attempt < retries; attempt++) {
33632
- try {
33633
- const response = await axios10.get(this.config.baseUrl, { params });
33634
- if (response.data && response.data.length > 0) {
33635
- return response;
33636
- }
33637
- throw new Error("Empty response data");
33638
- } catch (err) {
33639
- logger.error(`Error fetching quote with retry: ${err}`);
33640
- if (attempt === retries - 1) {
33641
- throw err;
33642
- }
33643
- await new Promise((resolve) => setTimeout(resolve, MAX_DELAY));
33644
- }
33645
- }
33646
- throw new Error("Failed to fetch quote after retries");
33647
- }
33648
- async getQuotesAvnu(from_token_address, to_token_address, amount, takerAddress, toTokenDecimals, usdcToBtc, maxIterations = 5, tolerance = 1e4) {
33649
- try {
33650
- const fromToken = this.config.supportedPositions[0].asset;
33651
- const toToken = this.config.supportedPositions[1].asset;
33652
- if (!usdcToBtc) {
33653
- const sellAmount2 = returnFormattedAmount(amount, toTokenDecimals);
33654
- const params2 = {
33655
- sellTokenAddress: from_token_address,
33656
- buyTokenAddress: to_token_address,
33657
- takerAddress,
33658
- sellAmount: sellAmount2
33659
- };
33660
- const finalQuote2 = await this.fetchQuoteWithRetry(params2);
33661
- if (!finalQuote2.data.length) {
33662
- logger.error("No quotes available for this swap, error in quotes avnu");
33663
- return null;
33664
- }
33665
- const dataObject2 = finalQuote2.data[0];
33666
- return dataObject2;
33667
- }
33668
- const btcPrice = await this.getPriceOfToken(toToken.address.toString());
33669
- if (!btcPrice) {
33670
- logger.error(`error getting btc price: ${btcPrice}`);
33671
- return null;
33672
- }
33673
- const estimatedUsdcAmount = Math.floor(amount * btcPrice);
33674
- const targetBtcBig = BigInt(returnFormattedAmount(amount, toTokenDecimals));
33675
- let low = BigInt(
33676
- Math.floor(
33677
- estimatedUsdcAmount * 10 ** fromToken.decimals * 0.9
33678
- )
33679
- );
33680
- let high = BigInt(
33681
- Math.floor(
33682
- estimatedUsdcAmount * 10 ** fromToken.decimals * 1.1
33683
- )
33684
- );
33685
- let mid = 0n;
33686
- for (let i = 0; i < maxIterations; i++) {
33687
- mid = (low + high) / 2n;
33688
- const sellAmount2 = returnFormattedAmount(Number(mid), 0);
33689
- const quote = await this.fetchQuoteWithRetry({
33690
- sellTokenAddress: from_token_address,
33691
- buyTokenAddress: to_token_address,
33692
- takerAddress,
33693
- sellAmount: sellAmount2
33694
- });
33695
- const gotBtc = BigInt(quote.data[0].buyAmount);
33696
- if (gotBtc === targetBtcBig) return quote.data[0];
33697
- if (gotBtc > targetBtcBig) {
33698
- high = mid;
33699
- } else {
33700
- low = mid;
33701
- }
33702
- if (gotBtc >= targetBtcBig && gotBtc <= targetBtcBig + BigInt(tolerance)) {
33703
- return quote.data[0];
33704
- }
33705
- }
33706
- let sellAmount = returnFormattedAmount(
33707
- Number(mid),
33708
- 0
33709
- );
33710
- const params = {
33711
- sellTokenAddress: from_token_address,
33712
- buyTokenAddress: to_token_address,
33713
- takerAddress,
33714
- sellAmount
33715
- };
33716
- const finalQuote = await this.fetchQuoteWithRetry(params);
33717
- if (!finalQuote.data.length) {
33718
- logger.error("No quotes available for this swap, error in quotes avnu");
33719
- return null;
33720
- }
33721
- const dataObject = finalQuote.data[0];
33722
- return dataObject;
33723
- } catch (err) {
33724
- logger.error(`No quotes available for this swap: ${err}`);
33725
- return null;
33726
- }
33727
- }
33728
- async getPriceOfToken(tokenAddress, retries = MAX_RETRIES) {
33729
- try {
33730
- const url = `https://starknet.impulse.avnu.fi/v1/tokens/${tokenAddress}/prices/line`;
33731
- const response = await axios10.get(url);
33732
- const length = response.data.length;
33733
- return response.data[length - 1].value;
33734
- } catch (err) {
33735
- if (retries > 0) {
33736
- await new Promise((resolve) => setTimeout(resolve, MAX_DELAY));
33737
- return this.getPriceOfToken(tokenAddress, retries - 1);
33738
- } else {
33739
- logger.error(`Failed to fetch price for ${tokenAddress} after ${MAX_RETRIES} attempts`);
33740
- return null;
33741
- }
33742
- }
33743
- }
33744
- };
34284
+ // src/strategies/vesu-extended-strategy/types/transaction-metadata.ts
34285
+ var CycleType = /* @__PURE__ */ ((CycleType2) => {
34286
+ CycleType2["INVESTMENT"] = "INVESTMENT";
34287
+ CycleType2["REBALANCE_PRICE_DROP"] = "REBALANCE_PRICE_DROP";
34288
+ CycleType2["REBALANCE_PRICE_RISE"] = "REBALANCE_PRICE_RISE";
34289
+ CycleType2["WITHDRAWAL"] = "WITHDRAWAL";
34290
+ CycleType2["DELTA_NEUTRAL_ADJUSTMENT"] = "DELTA_NEUTRAL_ADJUSTMENT";
34291
+ return CycleType2;
34292
+ })(CycleType || {});
33745
34293
 
33746
34294
  // src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx
33747
34295
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
@@ -33841,15 +34389,30 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
33841
34389
  const usdceToken = Global.getDefaultTokens().find(
33842
34390
  (token) => token.symbol === "USDCe"
33843
34391
  );
34392
+ const walletBalance = await new ERC20(this.config).balanceOf(
34393
+ usdceToken.address,
34394
+ WALLET_ADDRESS,
34395
+ usdceToken.decimals
34396
+ );
34397
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::moveAssetsToVaultAllocator walletBalance: ${walletBalance}`);
34398
+ const amountToBeTransferred = amount.minimum(walletBalance);
34399
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::moveAssetsToVaultAllocator amountToBeTransferred: ${amountToBeTransferred.toNumber()}`);
34400
+ if (amountToBeTransferred.lessThan(0)) {
34401
+ logger.error(`${_VesuExtendedMultiplierStrategy.name}::moveAssetsToVaultAllocator amountToBeTransferred is less than 0: ${amountToBeTransferred.toNumber()}`);
34402
+ return {
34403
+ calls: [],
34404
+ status: false
34405
+ };
34406
+ }
33844
34407
  const approveCall = new ERC20(this.config).approve(
33845
34408
  usdceToken.address,
33846
34409
  this.metadata.additionalInfo.vaultAllocator,
33847
- amount
34410
+ amountToBeTransferred
33848
34411
  );
33849
34412
  const transferCall = new ERC20(this.config).transfer(
33850
34413
  usdceToken.address,
33851
34414
  this.metadata.additionalInfo.vaultAllocator,
33852
- amount
34415
+ amountToBeTransferred
33853
34416
  );
33854
34417
  const proofsInfo = extendedAdapter.getProofsForFromLegacySwap(
33855
34418
  this.getMerkleTree()
@@ -33857,21 +34420,43 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
33857
34420
  const proofGroups = proofsInfo.proofs;
33858
34421
  const call = this.getManageCall(
33859
34422
  proofGroups,
33860
- await proofsInfo.callConstructor({ amount })
34423
+ await proofsInfo.callConstructor({ amount: amountToBeTransferred })
33861
34424
  );
33862
- return [approveCall, transferCall, call];
34425
+ return {
34426
+ calls: [approveCall, transferCall, call],
34427
+ status: true
34428
+ };
33863
34429
  } catch (err) {
33864
34430
  logger.error(`error moving assets to vault allocator: ${err}`);
33865
- return [];
34431
+ return {
34432
+ calls: [],
34433
+ status: false
34434
+ };
33866
34435
  }
33867
34436
  }
33868
34437
  async shouldInvest() {
33869
34438
  try {
34439
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest starting`);
33870
34440
  const vesuAdapter = await this.getVesuAdapter();
33871
34441
  const extendedAdapter = await this.getExtendedAdapter();
33872
- if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
34442
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest adapters fetched: vesuAdapter=${!!vesuAdapter}, extendedAdapter=${!!extendedAdapter}, extendedAdapter.client=${!!extendedAdapter?.client}`);
34443
+ if (!vesuAdapter) {
33873
34444
  logger.error(
33874
- `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
34445
+ `Vesu adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
34446
+ );
34447
+ return {
34448
+ shouldInvest: false,
34449
+ vesuAmount: new Web3Number(0, 0),
34450
+ extendedAmount: new Web3Number(0, 0),
34451
+ extendedLeverage: 0,
34452
+ collateralPrice: 0,
34453
+ debtPrice: 0,
34454
+ vesuLeverage: 0
34455
+ };
34456
+ }
34457
+ if (!extendedAdapter) {
34458
+ logger.error(
34459
+ `Extended adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
33875
34460
  );
33876
34461
  return {
33877
34462
  shouldInvest: false,
@@ -33883,10 +34468,73 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
33883
34468
  vesuLeverage: 0
33884
34469
  };
33885
34470
  }
34471
+ if (!extendedAdapter.client) {
34472
+ logger.error(
34473
+ `Extended adapter client not initialized. This may be a temporary initialization failure - check network connectivity and API availability.`
34474
+ );
34475
+ return {
34476
+ shouldInvest: false,
34477
+ vesuAmount: new Web3Number(0, 0),
34478
+ extendedAmount: new Web3Number(0, 0),
34479
+ extendedLeverage: 0,
34480
+ collateralPrice: 0,
34481
+ debtPrice: 0,
34482
+ vesuLeverage: 0
34483
+ };
34484
+ }
34485
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest calling getUnusedBalance`);
33886
34486
  const balance = await this.getUnusedBalance();
34487
+ if (!Number.isFinite(balance.usdValue) || balance.usdValue < 0) {
34488
+ logger.error(
34489
+ `Invalid balance.usdValue: ${balance.usdValue}. Expected a finite, non-negative number.`
34490
+ );
34491
+ return {
34492
+ shouldInvest: false,
34493
+ vesuAmount: new Web3Number(0, 0),
34494
+ extendedAmount: new Web3Number(0, 0),
34495
+ extendedLeverage: 0,
34496
+ collateralPrice: 0,
34497
+ debtPrice: 0,
34498
+ vesuLeverage: 0
34499
+ };
34500
+ }
34501
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest balance: ${balance.usdValue}`);
33887
34502
  const usdcBalanceOnExtended = await extendedAdapter.getExtendedDepositAmount();
33888
- const amountToInvest = balance.amount.plus(usdcBalanceOnExtended?.availableForWithdrawal ?? 0).minus(LIMIT_BALANCE);
33889
- if (amountToInvest.lessThan(0)) {
34503
+ if (usdcBalanceOnExtended) {
34504
+ const availableForWithdrawal = parseFloat(usdcBalanceOnExtended.availableForWithdrawal);
34505
+ if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
34506
+ logger.error(
34507
+ `Invalid usdcBalanceOnExtended.availableForWithdrawal: ${usdcBalanceOnExtended.availableForWithdrawal}. Expected a finite, non-negative number.`
34508
+ );
34509
+ return {
34510
+ shouldInvest: false,
34511
+ vesuAmount: new Web3Number(0, 0),
34512
+ extendedAmount: new Web3Number(0, 0),
34513
+ extendedLeverage: 0,
34514
+ collateralPrice: 0,
34515
+ debtPrice: 0,
34516
+ vesuLeverage: 0
34517
+ };
34518
+ }
34519
+ }
34520
+ const amountToInvest = new Web3Number(balance.usdValue, USDC_TOKEN_DECIMALS).plus(usdcBalanceOnExtended?.availableForWithdrawal ?? 0).multipliedBy(1 - LIMIT_BALANCE);
34521
+ const amountToInvestNumber = amountToInvest.toNumber();
34522
+ if (!Number.isFinite(amountToInvestNumber)) {
34523
+ logger.error(
34524
+ `Invalid amountToInvest calculation result: ${amountToInvestNumber}. Calculation may have produced NaN or Infinity.`
34525
+ );
34526
+ return {
34527
+ shouldInvest: false,
34528
+ vesuAmount: new Web3Number(0, 0),
34529
+ extendedAmount: new Web3Number(0, 0),
34530
+ extendedLeverage: 0,
34531
+ collateralPrice: 0,
34532
+ debtPrice: 0,
34533
+ vesuLeverage: 0
34534
+ };
34535
+ }
34536
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvestNumber}`);
34537
+ if (amountToInvest.lessThan(LIMIT_BALANCE_VALUE)) {
33890
34538
  return {
33891
34539
  shouldInvest: false,
33892
34540
  vesuAmount: new Web3Number(0, 0),
@@ -33915,6 +34563,34 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
33915
34563
  collateralPrice,
33916
34564
  debtPrice
33917
34565
  } = await this.getAssetPrices();
34566
+ if (!Number.isFinite(collateralPrice.price) || collateralPrice.price <= 0) {
34567
+ logger.error(
34568
+ `Invalid collateralPrice: ${collateralPrice.price}. Expected a finite, positive number.`
34569
+ );
34570
+ return {
34571
+ shouldInvest: false,
34572
+ vesuAmount: new Web3Number(0, 0),
34573
+ extendedAmount: new Web3Number(0, 0),
34574
+ extendedLeverage: 0,
34575
+ collateralPrice: 0,
34576
+ debtPrice: 0,
34577
+ vesuLeverage: 0
34578
+ };
34579
+ }
34580
+ if (!Number.isFinite(debtPrice.price) || debtPrice.price <= 0) {
34581
+ logger.error(
34582
+ `Invalid debtPrice: ${debtPrice.price}. Expected a finite, positive number.`
34583
+ );
34584
+ return {
34585
+ shouldInvest: false,
34586
+ vesuAmount: new Web3Number(0, 0),
34587
+ extendedAmount: new Web3Number(0, 0),
34588
+ extendedLeverage: 0,
34589
+ collateralPrice: 0,
34590
+ debtPrice: 0,
34591
+ vesuLeverage: 0
34592
+ };
34593
+ }
33918
34594
  const { vesu_amount, extended_amount, extended_leverage, vesu_leverage } = await calculateAmountDistribution(
33919
34595
  amountToInvest.toNumber(),
33920
34596
  extendedAdapter.client,
@@ -33938,6 +34614,7 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
33938
34614
  vesuLeverage: 0
33939
34615
  };
33940
34616
  }
34617
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest vesu_amount: ${vesu_amount.toNumber()}, extended_amount: ${extended_amount.toNumber()}`);
33941
34618
  return {
33942
34619
  shouldInvest: true,
33943
34620
  vesuAmount: vesu_amount,
@@ -33964,111 +34641,251 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
33964
34641
  try {
33965
34642
  const vesuAdapter = await this.getVesuAdapter();
33966
34643
  const extendedAdapter = await this.getExtendedAdapter();
33967
- let calls = [];
33968
34644
  if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
33969
34645
  logger.error(
33970
34646
  `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
33971
34647
  );
33972
- return calls;
34648
+ return [];
34649
+ }
34650
+ const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
34651
+ if (!extendedHoldings) {
34652
+ logger.error(`error getting extended holdings: ${extendedHoldings}`);
34653
+ return [];
33973
34654
  }
33974
- if (extendedAmount.lessThan(0)) {
34655
+ const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
34656
+ const usdcAmountOnExtendedAvailableForWithdrawal = parseFloat(
34657
+ extendedHoldings.availableForWithdrawal
34658
+ );
34659
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldMoveAssets calculating movements - Extended current: ${usdcAmountOnExtendedAvailableForWithdrawal}, Wallet: ${usdcAmountInWallet.toNumber()}, Target Extended: ${extendedAmount.toNumber()}, Target Vesu: ${vesuAmount.toNumber()}`);
34660
+ let totalExtendedWithdrawal = new Web3Number(0, USDC_TOKEN_DECIMALS);
34661
+ let totalExtendedDeposit = new Web3Number(0, USDC_TOKEN_DECIMALS);
34662
+ if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34663
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmount.abs());
34664
+ }
34665
+ const extendedTargetAmount = extendedAmount.abs();
34666
+ let projectedExtendedBalance = usdcAmountOnExtendedAvailableForWithdrawal;
34667
+ if (extendedAmount.isNegative()) {
34668
+ projectedExtendedBalance = projectedExtendedBalance - extendedAmount.abs().toNumber();
34669
+ }
34670
+ const extendedAmountDifference = extendedTargetAmount.minus(projectedExtendedBalance);
34671
+ const extendedAmountDifferenceAbs = extendedAmountDifference.abs();
34672
+ if (extendedAmountDifference.lessThan(0)) {
34673
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmountDifferenceAbs);
34674
+ } else if (extendedAmountDifference.greaterThan(0)) {
34675
+ totalExtendedDeposit = totalExtendedDeposit.plus(extendedAmountDifference);
34676
+ }
34677
+ const vesuTargetAmount = vesuAmount.abs();
34678
+ const projectedWalletBalance = usdcAmountInWallet.plus(totalExtendedWithdrawal).minus(totalExtendedDeposit);
34679
+ let vesuAmountDifference = vesuTargetAmount.minus(projectedWalletBalance);
34680
+ const vesuAmountDifferenceAbs = vesuAmountDifference.abs();
34681
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldMoveAssets calculated movements - Extended withdrawal: ${totalExtendedWithdrawal.toNumber()}, Extended deposit: ${totalExtendedDeposit.toNumber()}, Extended diff: ${extendedAmountDifference.toNumber()}, Projected wallet: ${projectedWalletBalance.toNumber()}, Vesu diff: ${vesuAmountDifference.toNumber()}`);
34682
+ let calls = [];
34683
+ let transactionResults = [];
34684
+ if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
33975
34685
  try {
33976
- const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
34686
+ const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
33977
34687
  {
33978
34688
  to: Protocols.VAULT.name,
33979
34689
  from: Protocols.EXTENDED.name,
33980
- amount: extendedAmount.abs()
34690
+ amount: extendedAmount.abs(),
34691
+ cycleType: "INVESTMENT" /* INVESTMENT */
33981
34692
  },
33982
34693
  extendedAdapter,
33983
34694
  vesuAdapter
33984
34695
  );
33985
34696
  if (extendedStatus) {
33986
- calls.push(...extendedCalls);
34697
+ transactionResults.push({
34698
+ status: extendedStatus,
34699
+ calls: extendedCalls,
34700
+ transactionMetadata: {
34701
+ ...extendedTransactionMetadata,
34702
+ transactionType: "DEPOSIT"
34703
+ }
34704
+ });
33987
34705
  } else {
33988
- return [];
34706
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmount.abs() }, "NONE", "INVESTMENT" /* INVESTMENT */)];
33989
34707
  }
33990
34708
  } catch (err) {
33991
34709
  logger.error(`Failed moving assets to vault: ${err}`);
34710
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmount.abs() }, "NONE", "INVESTMENT" /* INVESTMENT */)];
33992
34711
  }
33993
34712
  }
33994
- if (vesuAmount.lessThan(0)) {
34713
+ if (vesuAmount.isNegative() && vesuAmount.abs().greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
33995
34714
  try {
33996
- const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
34715
+ const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
33997
34716
  {
33998
34717
  to: Protocols.EXTENDED.name,
33999
34718
  from: Protocols.VESU.name,
34000
- amount: vesuAmount.abs()
34719
+ amount: vesuAmount.abs(),
34720
+ cycleType: "INVESTMENT" /* INVESTMENT */
34001
34721
  },
34002
34722
  extendedAdapter,
34003
34723
  vesuAdapter
34004
34724
  );
34005
- calls.push(...vesuCalls);
34006
34725
  if (!vesuStatus) {
34007
- return [];
34008
- }
34726
+ return [this.createTransactionResult([], false, { from: Protocols.VESU.name, to: Protocols.EXTENDED.name, amount: vesuAmount.abs() }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34727
+ }
34728
+ transactionResults.push({
34729
+ status: vesuStatus,
34730
+ calls: vesuCalls,
34731
+ transactionMetadata: {
34732
+ ...vesuTransactionMetadata,
34733
+ transactionType: "DEPOSIT"
34734
+ }
34735
+ });
34009
34736
  } catch (err) {
34010
- logger.error(`Failed moving assets to vault: ${err}`);
34737
+ logger.error(`Failed moving assets to extended via vault allocator: ${err}`);
34738
+ return [this.createTransactionResult([], false, { from: Protocols.VESU.name, to: Protocols.EXTENDED.name, amount: vesuAmount.abs() }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34011
34739
  }
34012
34740
  }
34013
- const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
34014
- if (!extendedHoldings) {
34015
- logger.error(`error getting extended holdings: ${extendedHoldings}`);
34016
- return calls;
34017
- }
34018
- const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
34019
- const usdcAmountOnExtended = parseFloat(
34020
- extendedHoldings.availableForWithdrawal
34021
- );
34022
- if (extendedAmount.minus(usdcAmountOnExtended).greaterThan(0)) {
34023
- try {
34024
- const { calls: extendedCalls } = await this.moveAssets(
34025
- {
34026
- to: Protocols.EXTENDED.name,
34027
- from: Protocols.VAULT.name,
34028
- amount: extendedAmount.minus(usdcAmountOnExtended)
34029
- },
34030
- extendedAdapter,
34031
- vesuAdapter
34032
- );
34033
- calls.push(...extendedCalls);
34034
- } catch (err) {
34035
- logger.error(`Failed moving assets to extended: ${err}`);
34741
+ if (extendedAmountDifferenceAbs.greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34742
+ if (extendedAmountDifference.greaterThan(0)) {
34743
+ try {
34744
+ const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
34745
+ {
34746
+ to: Protocols.EXTENDED.name,
34747
+ from: Protocols.VAULT.name,
34748
+ amount: extendedAmountDifference,
34749
+ cycleType: "INVESTMENT" /* INVESTMENT */
34750
+ },
34751
+ extendedAdapter,
34752
+ vesuAdapter
34753
+ );
34754
+ if (extendedStatus) {
34755
+ transactionResults.push({
34756
+ status: extendedStatus,
34757
+ calls: extendedCalls,
34758
+ transactionMetadata: extendedTransactionMetadata
34759
+ });
34760
+ } else {
34761
+ logger.error(`Failed to move assets to extended - operation returned false status`);
34762
+ return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.EXTENDED.name, amount: extendedAmountDifference }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34763
+ }
34764
+ } catch (err) {
34765
+ logger.error(`Failed moving assets to extended: ${err}`);
34766
+ return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.EXTENDED.name, amount: extendedAmountDifference }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34767
+ }
34768
+ } else if (extendedAmountDifference.lessThan(0)) {
34769
+ try {
34770
+ const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
34771
+ {
34772
+ to: Protocols.VAULT.name,
34773
+ from: Protocols.EXTENDED.name,
34774
+ amount: extendedAmountDifferenceAbs,
34775
+ cycleType: "INVESTMENT" /* INVESTMENT */
34776
+ },
34777
+ extendedAdapter,
34778
+ vesuAdapter
34779
+ );
34780
+ if (extendedStatus) {
34781
+ transactionResults.push({
34782
+ status: extendedStatus,
34783
+ calls: extendedCalls,
34784
+ transactionMetadata: {
34785
+ ...extendedTransactionMetadata,
34786
+ transactionType: "DEPOSIT"
34787
+ }
34788
+ });
34789
+ } else {
34790
+ logger.error(`Failed to withdraw from extended - operation returned false status`);
34791
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmountDifferenceAbs }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34792
+ }
34793
+ } catch (err) {
34794
+ logger.error(`Failed moving assets from extended to vault: ${err}`);
34795
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmountDifferenceAbs }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34796
+ }
34036
34797
  }
34037
34798
  }
34038
- if (vesuAmount.minus(usdcAmountInWallet).greaterThan(0)) {
34039
- try {
34040
- const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
34041
- {
34042
- to: Protocols.VAULT.name,
34043
- from: Protocols.EXTENDED.name,
34044
- amount: vesuAmount.minus(usdcAmountInWallet)
34045
- },
34046
- extendedAdapter,
34047
- vesuAdapter
34799
+ if (vesuAmountDifferenceAbs.greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
34800
+ if (vesuAmountDifference.lessThanOrEqualTo(0)) {
34801
+ logger.warn(
34802
+ `Vesu amount difference is negative or zero: ${vesuAmountDifference.toNumber()}. Skipping operation.`
34048
34803
  );
34049
- if (!vesuStatus) {
34050
- return [];
34804
+ } else {
34805
+ try {
34806
+ const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
34807
+ {
34808
+ to: Protocols.VAULT.name,
34809
+ from: Protocols.EXTENDED.name,
34810
+ amount: vesuAmountDifference,
34811
+ cycleType: "INVESTMENT" /* INVESTMENT */
34812
+ },
34813
+ extendedAdapter,
34814
+ vesuAdapter
34815
+ );
34816
+ if (!vesuStatus) {
34817
+ logger.error(`Failed to move assets to vesu - operation returned false status`);
34818
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: vesuAmountDifference }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34819
+ }
34820
+ transactionResults.push({
34821
+ status: vesuStatus,
34822
+ calls: vesuCalls,
34823
+ transactionMetadata: {
34824
+ ...vesuTransactionMetadata,
34825
+ transactionType: "DEPOSIT"
34826
+ }
34827
+ });
34828
+ } catch (err) {
34829
+ logger.error(`Failed moving assets to vault: ${err}`);
34830
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: vesuAmountDifference }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34051
34831
  }
34052
- calls.push(...vesuCalls);
34053
- } catch (err) {
34054
- logger.error(`Failed moving assets to vault: ${err}`);
34055
34832
  }
34056
34833
  }
34057
- return calls;
34834
+ return transactionResults;
34058
34835
  } catch (err) {
34059
34836
  logger.error(`Failed moving assets to vesu: ${err}`);
34060
- return [];
34837
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: new Web3Number(0, USDC_TOKEN_DECIMALS) }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34061
34838
  }
34062
34839
  }
34840
+ /**
34841
+ * Helper method to create transaction result with metadata
34842
+ */
34843
+ createTransactionResult(calls, status, params, transactionType, cycleType) {
34844
+ if (status) {
34845
+ return {
34846
+ calls,
34847
+ status,
34848
+ transactionMetadata: {
34849
+ protocolFrom: params.from,
34850
+ protocolTo: params.to,
34851
+ transactionType,
34852
+ usdAmount: params.amount.abs().toFixed(),
34853
+ status: "PENDING",
34854
+ cycleType
34855
+ }
34856
+ };
34857
+ }
34858
+ return { calls: [], status: false, transactionMetadata: { protocolFrom: "", protocolTo: "", transactionType: "DEPOSIT", usdAmount: "0", status: "FAILED", cycleType } };
34859
+ }
34063
34860
  async moveAssets(params, extendedAdapter, vesuAdapter) {
34064
34861
  try {
34862
+ if (params.amount.lessThanOrEqualTo(0)) {
34863
+ logger.error(
34864
+ `Invalid amount for moveAssets: ${params.amount.toNumber()}. Amount must be positive.`
34865
+ );
34866
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34867
+ }
34868
+ const amountAbs = params.amount.abs();
34869
+ if (params.from === Protocols.EXTENDED.name || params.to === Protocols.EXTENDED.name) {
34870
+ if (amountAbs.lessThanOrEqualTo(extendedAdapter.minimumExtendedMovementAmount)) {
34871
+ logger.warn(
34872
+ `Amount ${amountAbs.toNumber()} is below minimum Extended movement amount ${extendedAdapter.minimumExtendedMovementAmount}. Skipping operation.`
34873
+ );
34874
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34875
+ }
34876
+ }
34877
+ if (params.from === Protocols.VESU.name || params.to === Protocols.VESU.name) {
34878
+ if (amountAbs.lessThanOrEqualTo(vesuAdapter.minimumVesuMovementAmount)) {
34879
+ logger.warn(
34880
+ `Amount ${amountAbs.toNumber()} is below minimum Vesu movement amount ${vesuAdapter.minimumVesuMovementAmount}. Skipping operation.`
34881
+ );
34882
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34883
+ }
34884
+ }
34065
34885
  const avnuAdapter = await this.getAvnuAdapter();
34066
34886
  if (!avnuAdapter) {
34067
34887
  logger.error(`avnu adapter not found: ${avnuAdapter}`);
34068
- return {
34069
- calls: [],
34070
- status: false
34071
- };
34888
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34072
34889
  }
34073
34890
  logger.info(`moveAssets params, ${JSON.stringify(params)}`);
34074
34891
  const collateralToken = vesuAdapter.config.supportedPositions[0].asset;
@@ -34087,61 +34904,72 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34087
34904
  await proofsInfo.callConstructor({ amount: params.amount })
34088
34905
  );
34089
34906
  calls.push(call);
34090
- return {
34091
- calls: [call],
34092
- status: true
34093
- };
34907
+ return this.createTransactionResult(calls, true, params, "DEPOSIT", params.cycleType);
34094
34908
  } else if (params.to === Protocols.VAULT.name && params.from === Protocols.EXTENDED.name) {
34095
34909
  const extendedLeverage = calculateExtendedLevergae();
34096
34910
  const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
34097
34911
  if (!extendedHoldings) {
34098
34912
  logger.error(`error getting extended holdings: ${extendedHoldings}`);
34099
- return {
34100
- calls: [],
34101
- status: false
34102
- };
34913
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34103
34914
  }
34104
34915
  const extendedHoldingAmount = new Web3Number(
34105
34916
  extendedHoldings.availableForWithdrawal,
34106
34917
  USDC_TOKEN_DECIMALS
34107
34918
  );
34108
- const leftAmountAfterWithdrawalAmountInAccount = params.amount.minus(extendedHoldingAmount);
34109
- const btcAmount = leftAmountAfterWithdrawalAmountInAccount.dividedBy(collateralPrice.price);
34110
- const openLongPosition = await extendedAdapter.createOrder(
34111
- extendedLeverage.toString(),
34112
- btcAmount.toNumber(),
34113
- "BUY" /* BUY */
34114
- );
34115
- if (!openLongPosition) {
34116
- logger.error(`error opening long position: ${openLongPosition}`);
34117
- return {
34118
- calls: [],
34119
- status: false
34120
- };
34919
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::moveAssets extendedHoldingAmount: ${extendedHoldingAmount.toNumber()}`);
34920
+ if (params.amount.abs().greaterThan(extendedHoldingAmount)) {
34921
+ const leftAmountAfterWithdrawalAmountInAccount = params.amount.abs().minus(extendedHoldingAmount);
34922
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::moveAssets leftAmountAfterWithdrawalAmountInAccount: ${leftAmountAfterWithdrawalAmountInAccount.toNumber()}`);
34923
+ const btcAmount = leftAmountAfterWithdrawalAmountInAccount.dividedBy(collateralPrice.price);
34924
+ const openLongPosition = btcAmount.multipliedBy(3).greaterThan(MINIMUM_EXTENDED_POSITION_SIZE) ? await extendedAdapter.createOrder(
34925
+ extendedLeverage.toString(),
34926
+ btcAmount.toNumber(),
34927
+ "BUY" /* BUY */
34928
+ ) : await extendedAdapter.createOrder(
34929
+ extendedLeverage.toString(),
34930
+ 34e-6,
34931
+ // just in case amount falls short then we need to create a withdrawal
34932
+ "BUY" /* BUY */
34933
+ );
34934
+ if (!openLongPosition) {
34935
+ logger.error(`error opening long position: ${openLongPosition}`);
34936
+ }
34937
+ const updatedHoldings = await extendedAdapter.getExtendedDepositAmount();
34938
+ if (!updatedHoldings || new Web3Number(updatedHoldings.availableForWithdrawal, USDC_TOKEN_DECIMALS).lessThan(params.amount.abs())) {
34939
+ logger.error(`Insufficient balance after opening position. Available: ${updatedHoldings?.availableForWithdrawal}, Needed: ${params.amount.abs()}`);
34940
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34941
+ }
34121
34942
  }
34122
- await new Promise((resolve) => setTimeout(resolve, 5e3));
34123
- const withdrawalFromExtended = await extendedAdapter.withdrawFromExtended(params.amount);
34124
- if (withdrawalFromExtended) {
34943
+ const {
34944
+ status: withdrawalFromExtendedStatus,
34945
+ receivedTxnHash: withdrawalFromExtendedTxnHash
34946
+ } = await extendedAdapter.withdrawFromExtended(params.amount);
34947
+ logger.info(`withdrawalFromExtendedStatus: ${withdrawalFromExtendedStatus}, withdrawalFromExtendedTxnHash: ${withdrawalFromExtendedTxnHash}`);
34948
+ if (withdrawalFromExtendedStatus && withdrawalFromExtendedTxnHash) {
34125
34949
  const extendedHoldings2 = await extendedAdapter.getExtendedDepositAmount();
34126
- logger.info(`extendedHoldings after withdrawal ${extendedHoldings2}`);
34127
- await new Promise((resolve) => setTimeout(resolve, 1e4));
34128
- const calls = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
34129
- if (calls.length > 0) {
34130
- return {
34131
- calls,
34132
- status: true
34133
- };
34950
+ logger.info(`extendedHoldings after withdrawal ${extendedHoldings2?.availableForWithdrawal}`);
34951
+ await new Promise((resolve) => setTimeout(resolve, 5e3));
34952
+ const { calls, status } = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
34953
+ if (calls.length > 0 && status) {
34954
+ return this.createTransactionResult(calls, true, params, "WITHDRAWAL", params.cycleType);
34955
+ } else {
34956
+ return this.createTransactionResult([], true, params, "WITHDRAWAL", params.cycleType);
34134
34957
  }
34958
+ } else if (withdrawalFromExtendedStatus && !withdrawalFromExtendedTxnHash) {
34959
+ logger.error("withdrawal from extended successful, but funds didn't get transferred to the wallet");
34960
+ return this.createTransactionResult([], true, params, "WITHDRAWAL", params.cycleType);
34135
34961
  } else {
34136
34962
  logger.error("withdrawal from extended failed");
34137
- return {
34138
- calls: [],
34139
- status: false
34140
- };
34963
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34141
34964
  }
34142
34965
  } else if (params.to === Protocols.VAULT.name && params.from === Protocols.VESU.name) {
34966
+ const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, "close" /* CLOSE */);
34967
+ if (!isPriceDifferenceBetweenAvnuAndExtended) {
34968
+ logger.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
34969
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34970
+ }
34143
34971
  const vesuAmountInBTC = new Web3Number(
34144
- params.amount.dividedBy(collateralPrice.price).toNumber(),
34972
+ params.amount.dividedBy(collateralPrice.price).toFixed(WBTC_TOKEN_DECIMALS),
34145
34973
  collateralToken.decimals
34146
34974
  );
34147
34975
  const proofsInfo = vesuAdapter.getProofs(false, this.getMerkleTree());
@@ -34159,11 +34987,13 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34159
34987
  await swapProofsInfo.callConstructor({ amount: vesuAmountInBTC })
34160
34988
  );
34161
34989
  calls.push(swapCall);
34162
- return {
34163
- calls,
34164
- status: true
34165
- };
34990
+ return this.createTransactionResult(calls, true, params, "WITHDRAWAL", params.cycleType);
34166
34991
  } else if (params.to === Protocols.EXTENDED.name && params.from === Protocols.VESU.name) {
34992
+ const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, "close" /* CLOSE */);
34993
+ if (!isPriceDifferenceBetweenAvnuAndExtended) {
34994
+ logger.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
34995
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34996
+ }
34167
34997
  const vesuAmountInBTC = new Web3Number(
34168
34998
  params.amount.dividedBy(collateralPrice.price).toNumber(),
34169
34999
  collateralToken.decimals
@@ -34193,131 +35023,32 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34193
35023
  await proofsInfoDeposit.callConstructor({ amount: params.amount })
34194
35024
  );
34195
35025
  calls.push(callDeposit);
34196
- return {
34197
- calls,
34198
- status: true
34199
- };
35026
+ return this.createTransactionResult(calls, true, params, "DEPOSIT", params.cycleType);
34200
35027
  }
34201
- return {
34202
- calls: [],
34203
- status: false
34204
- };
35028
+ logger.error(`Unsupported assets movement: ${params.from} to ${params.to}`);
35029
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34205
35030
  } catch (err) {
34206
35031
  logger.error(`error moving assets: ${err}`);
34207
- return {
34208
- calls: [],
34209
- status: false
34210
- };
35032
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34211
35033
  }
34212
35034
  }
34213
35035
  async handleDeposit() {
34214
35036
  try {
34215
- const vesuAdapter = await this.getVesuAdapter();
34216
- const extendedAdapter = await this.getExtendedAdapter();
34217
- const avnuAdapter = await this.getAvnuAdapter();
34218
- if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client || !avnuAdapter) {
34219
- logger.error(
34220
- "vesu or extended adapter not found",
34221
- vesuAdapter,
34222
- extendedAdapter
34223
- );
34224
- return {
34225
- extendedAmountInBTC: new Web3Number(0, 0),
34226
- calls: []
34227
- };
34228
- }
34229
- const extendedLeverage = calculateExtendedLevergae();
34230
- const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter);
34231
- if (!isPriceDifferenceBetweenAvnuAndExtended) {
34232
- logger.error("price difference between avnu and extended doesn't fit the range");
34233
- return {
34234
- extendedAmountInBTC: new Web3Number(0, 0),
34235
- calls: []
34236
- };
34237
- }
34238
- const position = await extendedAdapter.getAllOpenPositions();
34239
- if (!position) {
34240
- logger.error("error getting extended position", position);
34241
- return {
34242
- extendedAmountInBTC: new Web3Number(0, 0),
34243
- calls: []
34244
- };
34245
- }
34246
- const extendedPositionValue = position.length > 0 ? parseFloat(position[0].value) : 0;
34247
- const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
34248
- if (!extendedHoldings) {
34249
- logger.error(`error getting extended holdings: ${extendedHoldings}`);
34250
- return {
34251
- extendedAmountInBTC: new Web3Number(0, 0),
34252
- calls: []
34253
- };
34254
- }
34255
- const extendedHoldingAmount = new Web3Number(
34256
- extendedHoldings.availableForWithdrawal,
34257
- USDC_TOKEN_DECIMALS
34258
- );
34259
- const {
34260
- collateralTokenAmount
34261
- } = await vesuAdapter.vesuAdapter.getAssetPrices();
34262
- const { collateralPrice } = await this.getAssetPrices();
34263
- const { vesuAmountInBTC, extendedAmountInBTC } = calculateVesUPositionSizeGivenExtended(
34264
- extendedPositionValue,
34265
- extendedHoldingAmount,
34266
- collateralTokenAmount,
34267
- collateralPrice.price
34268
- );
34269
- logger.info(`vesuAmountInBTC ${vesuAmountInBTC}, extendedAmountInBTC ${extendedAmountInBTC}`);
34270
- let calls = [];
34271
- if (vesuAmountInBTC.greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)) {
34272
- const proofsInfo = vesuAdapter.getProofs(true, this.getMerkleTree());
34273
- const proofGroups = proofsInfo.proofs;
34274
- const call = this.getManageCall(
34275
- proofGroups,
34276
- await proofsInfo.callConstructor({
34277
- amount: vesuAmountInBTC
34278
- })
34279
- );
34280
- const { amount: wbtcAmountInVaultAllocator } = await this.getUnusedBalanceWBTC();
34281
- if (wbtcAmountInVaultAllocator.lessThan(vesuAmountInBTC)) {
34282
- logger.info(`WBTC amount in vault allocator is less than vesu amount required in WBTC thus swapping, wbtcAmountInVaultAllocator: ${wbtcAmountInVaultAllocator}, vesuAmountInBTC: ${vesuAmountInBTC}`);
34283
- const swapProofsInfo = avnuAdapter.getProofs(true, this.getMerkleTree());
34284
- const swapProofGroups = swapProofsInfo.proofs;
34285
- const swapCall = this.getManageCall(
34286
- swapProofGroups,
34287
- await swapProofsInfo.callConstructor({
34288
- amount: vesuAmountInBTC
34289
- })
34290
- );
34291
- calls.push(swapCall);
34292
- }
34293
- calls.push(call);
34294
- }
34295
- const shortPosition = extendedAmountInBTC.multipliedBy(3).abs().greaterThan(MINIMUM_EXTENDED_POSITION_SIZE) ? await extendedAdapter.createOrder(
34296
- extendedLeverage.toString(),
34297
- extendedAmountInBTC.toNumber(),
34298
- "SELL" /* SELL */
34299
- ) : null;
34300
- if (!shortPosition && extendedAmountInBTC.multipliedBy(3).abs().greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)) {
34301
- logger.error(`error creating short position thus no position to be opened on vesu: ${shortPosition}`);
34302
- return {
34303
- extendedAmountInBTC: new Web3Number(0, 0),
34304
- calls: []
34305
- };
34306
- }
34307
- return {
34308
- extendedAmountInBTC,
34309
- calls
34310
- };
35037
+ return this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.VAULT.name, amount: new Web3Number(0, 0) }, "NONE", "INVESTMENT" /* INVESTMENT */);
34311
35038
  } catch (err) {
34312
35039
  logger.error(`error handling deposit: ${err}`);
34313
- return {
34314
- extendedAmountInBTC: new Web3Number(0, 0),
34315
- calls: []
34316
- };
34317
- ;
35040
+ return this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.VAULT.name, amount: new Web3Number(0, 0) }, "NONE", "INVESTMENT" /* INVESTMENT */);
34318
35041
  }
34319
35042
  }
34320
- async checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter) {
35043
+ /**
35044
+ * Check if the price difference between avnu and extended is within the acceptable range to enhance the position size or close the position
35045
+ * @param extendedAdapter - the extended adapter
35046
+ * @param vesuAdapter - the vesu adapter
35047
+ * @param avnuAdapter - the avnu adapter
35048
+ * @param positionType - the position type (open or close)
35049
+ * @returns true if the price difference is within the acceptable range, false otherwise
35050
+ */
35051
+ async checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, positionType) {
34321
35052
  const {
34322
35053
  ask,
34323
35054
  bid
@@ -34329,13 +35060,30 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34329
35060
  logger.error(`error getting btc price avnu: ${btcPriceAvnu}`);
34330
35061
  return false;
34331
35062
  }
34332
- const priceDifference = price.minus(btcPriceAvnu).toNumber();
34333
- if (priceDifference < MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED && priceDifference > MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED) {
34334
- return true;
35063
+ logger.info(`price: ${price}`);
35064
+ logger.info(`btcPriceAvnu: ${btcPriceAvnu}`);
35065
+ const priceDifference = new Web3Number(price.minus(btcPriceAvnu).toFixed(2), 0);
35066
+ logger.info(`priceDifference: ${priceDifference}`);
35067
+ if (priceDifference.isNegative()) {
35068
+ return false;
35069
+ }
35070
+ if (positionType === "open" /* OPEN */) {
35071
+ logger.info(`price difference between avnu and extended for open position: ${priceDifference.toNumber()}, minimumExtendedPriceDifferenceForSwapOpen: ${avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen}`);
35072
+ const result = priceDifference.greaterThanOrEqualTo(avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen);
35073
+ logger.info(`result: ${result}`);
35074
+ return result;
35075
+ } else {
35076
+ logger.info(`price difference between avnu and extended for close position: ${priceDifference.toNumber()}, maximumExtendedPriceDifferenceForSwapClosing: ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
35077
+ const result = priceDifference.lessThanOrEqualTo(avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing);
35078
+ logger.info(`result: ${result}`);
35079
+ return result;
34335
35080
  }
34336
- logger.error(`price difference between avnu and extended doesn't fit the range, priceDifference: ${priceDifference}`);
34337
- return false;
34338
35081
  }
35082
+ /**
35083
+ * Handle the withdrawal of assets from the vault
35084
+ * @param amount - the amount to withdraw in USDC
35085
+ * @returns the calls to be executed and the status of the calls generated along with the metadata for the calls
35086
+ */
34339
35087
  async handleWithdraw(amount) {
34340
35088
  try {
34341
35089
  const usdcBalanceVaultAllocator = await this.getUnusedBalance();
@@ -34347,12 +35095,8 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34347
35095
  const withdrawCall2 = await this.getBringLiquidityCall({
34348
35096
  amount: usdcBalanceVaultAllocator.amount
34349
35097
  });
34350
- logger.info("withdraw call", withdrawCall2);
34351
35098
  calls.push(withdrawCall2);
34352
- return {
34353
- calls,
34354
- status: true
34355
- };
35099
+ return [this.createTransactionResult(calls, true, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "WITHDRAWAL", "WITHDRAWAL" /* WITHDRAWAL */)];
34356
35100
  }
34357
35101
  const vesuAdapter = await this.getVesuAdapter();
34358
35102
  const extendedAdapter = await this.getExtendedAdapter();
@@ -34361,11 +35105,9 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34361
35105
  logger.error(
34362
35106
  `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
34363
35107
  );
34364
- return {
34365
- calls,
34366
- status
34367
- };
35108
+ return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE", "WITHDRAWAL" /* WITHDRAWAL */)];
34368
35109
  }
35110
+ let transactionResults = [];
34369
35111
  const { collateralTokenAmount } = await vesuAdapter.vesuAdapter.getAssetPrices();
34370
35112
  const {
34371
35113
  collateralPrice
@@ -34374,10 +35116,7 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34374
35116
  if (!extendedPositon) {
34375
35117
  status = false;
34376
35118
  logger.error("error getting extended position", extendedPositon);
34377
- return {
34378
- calls,
34379
- status
34380
- };
35119
+ return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE", "WITHDRAWAL" /* WITHDRAWAL */)];
34381
35120
  }
34382
35121
  const amountDistributionForWithdrawal = await calculateAmountDistributionForWithdrawal(
34383
35122
  usdcBalanceDifference,
@@ -34390,61 +35129,70 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34390
35129
  logger.error(
34391
35130
  `error calculating amount distribution for withdrawal: ${amountDistributionForWithdrawal}`
34392
35131
  );
34393
- return {
34394
- calls,
34395
- status
34396
- };
35132
+ return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE", "WITHDRAWAL" /* WITHDRAWAL */)];
34397
35133
  }
34398
35134
  const { vesu_amount, extended_amount } = amountDistributionForWithdrawal;
34399
35135
  if (status && vesu_amount.greaterThan(0)) {
34400
- const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
35136
+ const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
34401
35137
  {
34402
35138
  amount: vesu_amount,
34403
35139
  from: Protocols.VESU.name,
34404
- to: Protocols.VAULT.name
35140
+ to: Protocols.VAULT.name,
35141
+ cycleType: "WITHDRAWAL" /* WITHDRAWAL */
34405
35142
  },
34406
35143
  extendedAdapter,
34407
35144
  vesuAdapter
34408
35145
  );
34409
35146
  status = vesuStatus;
34410
- calls.push(...vesuCalls);
35147
+ transactionResults.push({
35148
+ status: vesuStatus,
35149
+ calls: vesuCalls,
35150
+ transactionMetadata: vesuTransactionMetadata
35151
+ });
34411
35152
  }
34412
35153
  if (status && extended_amount.greaterThan(0)) {
34413
- const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
35154
+ const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
34414
35155
  {
34415
35156
  amount: extended_amount,
34416
35157
  from: Protocols.EXTENDED.name,
34417
- to: Protocols.VAULT.name
35158
+ to: Protocols.VAULT.name,
35159
+ cycleType: "WITHDRAWAL" /* WITHDRAWAL */
34418
35160
  },
34419
35161
  extendedAdapter,
34420
35162
  vesuAdapter
34421
35163
  );
34422
35164
  status = extendedStatus;
34423
35165
  if (status) {
34424
- calls.push(...extendedCalls);
35166
+ transactionResults.push({
35167
+ status: extendedStatus,
35168
+ calls: extendedCalls,
35169
+ transactionMetadata: extendedTransactionMetadata
35170
+ });
34425
35171
  } else {
34426
35172
  logger.error("error moving assets to vault: extendedStatus: ${extendedStatus}");
34427
- return {
34428
- calls: [],
34429
- status
34430
- };
35173
+ return [this.createTransactionResult([], status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE", "WITHDRAWAL" /* WITHDRAWAL */)];
34431
35174
  }
34432
35175
  }
34433
35176
  const withdrawCall = await this.getBringLiquidityCall({
34434
35177
  amount
34435
35178
  });
34436
35179
  logger.info("withdraw call", withdrawCall);
34437
- calls.push(withdrawCall);
34438
- return {
34439
- calls,
34440
- status
34441
- };
35180
+ transactionResults.push({
35181
+ status,
35182
+ calls: [withdrawCall],
35183
+ transactionMetadata: {
35184
+ protocolFrom: Protocols.VAULT.name,
35185
+ protocolTo: Protocols.NONE.name,
35186
+ transactionType: "WITHDRAWAL",
35187
+ usdAmount: amount.toFixed(),
35188
+ status: "PENDING",
35189
+ cycleType: "WITHDRAWAL" /* WITHDRAWAL */
35190
+ }
35191
+ });
35192
+ return transactionResults;
34442
35193
  } catch (err) {
34443
35194
  logger.error(`error handling withdrawal: ${err}`);
34444
- return {
34445
- calls: [],
34446
- status: false
34447
- };
35195
+ return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE", "WITHDRAWAL" /* WITHDRAWAL */)];
34448
35196
  }
34449
35197
  }
34450
35198
  async getAUM() {
@@ -34491,8 +35239,182 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34491
35239
  splits: [realAUM, estimatedAUMDelta]
34492
35240
  };
34493
35241
  }
35242
+ async processTransactionDataFromSDK(txnData) {
35243
+ try {
35244
+ const txnsToBeExecuted = txnData.filter((txn) => {
35245
+ return txn.transactionMetadata.transactionType !== "NONE" && txn.transactionMetadata.protocolFrom !== "" && txn.transactionMetadata.protocolTo !== "";
35246
+ });
35247
+ const callsToBeExecutedFinal = txnsToBeExecuted.flatMap((txn) => txn.calls);
35248
+ const txnMetadata = txnsToBeExecuted.map((txn) => txn.transactionMetadata);
35249
+ return { callsToBeExecutedFinal, txnMetadata };
35250
+ } catch (err) {
35251
+ logger.error(`error processing transaction data from SDK: ${err}`);
35252
+ return null;
35253
+ }
35254
+ }
35255
+ async processTransactionMetadata(txnMetadata, extendedIntentFulfilled) {
35256
+ try {
35257
+ const txnMetadataNew = txnMetadata.map((txn) => {
35258
+ const isExtendedProtocol = txn.protocolFrom === Protocols.EXTENDED.name || txn.protocolTo === Protocols.EXTENDED.name;
35259
+ if (isExtendedProtocol) {
35260
+ txn.status = extendedIntentFulfilled ? "COMPLETED" : "PENDING";
35261
+ } else {
35262
+ txn.status = "COMPLETED";
35263
+ }
35264
+ return txn;
35265
+ });
35266
+ return txnMetadataNew;
35267
+ } catch (err) {
35268
+ logger.error(`error processing transaction data from SDK: ${err}`);
35269
+ return null;
35270
+ }
35271
+ }
35272
+ async getMaxBorrowableAmount() {
35273
+ const vesuAdapter = await this.getVesuAdapter();
35274
+ const extendedAdapter = await this.getExtendedAdapter();
35275
+ if (!vesuAdapter || !extendedAdapter) {
35276
+ return new Web3Number(0, 0);
35277
+ }
35278
+ const extendedFundingRate = new Web3Number((await extendedAdapter.getNetAPY()).toFixed(4), 0);
35279
+ const extendedPositions = await extendedAdapter.getAllOpenPositions();
35280
+ if (!extendedPositions || extendedPositions.length === 0) {
35281
+ logger.info(`no extended positions found`);
35282
+ return new Web3Number(0, 0);
35283
+ }
35284
+ const extendePositionSizeUSD = new Web3Number(extendedPositions[0].value || 0, 0);
35285
+ const vesuPositions = await vesuAdapter.getPositions();
35286
+ const vesuSupplyApy = vesuPositions[0].apy.apy;
35287
+ const vesuCollateralSizeUSD = new Web3Number(vesuPositions[0].usdValue.toFixed(USDC_TOKEN_DECIMALS), USDC_TOKEN_DECIMALS);
35288
+ const vesuDebtSizeUSD = new Web3Number(vesuPositions[1].usdValue.toFixed(USDC_TOKEN_DECIMALS), USDC_TOKEN_DECIMALS);
35289
+ const num1 = extendePositionSizeUSD.multipliedBy(extendedFundingRate);
35290
+ const num22 = vesuCollateralSizeUSD.multipliedBy(vesuSupplyApy);
35291
+ const num32 = vesuDebtSizeUSD.abs();
35292
+ const maxBorrowApy = num1.plus(num22).minus(0.1).dividedBy(num32);
35293
+ const vesuMaxBorrowableAmount = await vesuAdapter.vesuAdapter.getMaxBorrowableByInterestRate(this.config, vesuAdapter.config.debt, maxBorrowApy.toNumber());
35294
+ return new Web3Number(vesuMaxBorrowableAmount.toFixed(USDC_TOKEN_DECIMALS), USDC_TOKEN_DECIMALS);
35295
+ }
35296
+ async getVesuHealthFactors() {
35297
+ const vesuAdapter = await this.getVesuAdapter();
35298
+ const extendedAdapter = await this.getExtendedAdapter();
35299
+ if (!vesuAdapter || !extendedAdapter) {
35300
+ return [0, 0];
35301
+ }
35302
+ const vesuPositions = await vesuAdapter.getPositions();
35303
+ const vesuCollateralSizeUSD = new Web3Number(vesuPositions[0].usdValue.toFixed(USDC_TOKEN_DECIMALS), 0);
35304
+ const vesuDebtSizeUSD = new Web3Number(vesuPositions[1].usdValue.toFixed(USDC_TOKEN_DECIMALS), 0);
35305
+ const actualLtv = vesuDebtSizeUSD.dividedBy(vesuCollateralSizeUSD).abs();
35306
+ logger.info(`actualLtv: ${actualLtv.toNumber()}`);
35307
+ const maxLtv = new Web3Number(await vesuAdapter.vesuAdapter.getLTVConfig(this.config), 4);
35308
+ const healthFactor = new Web3Number(maxLtv.dividedBy(actualLtv).toFixed(4), 4);
35309
+ logger.info(`healthFactor: ${healthFactor.toNumber()}`);
35310
+ const extendedBalance = await extendedAdapter.getExtendedDepositAmount();
35311
+ if (!extendedBalance) {
35312
+ return [0, 0];
35313
+ }
35314
+ const extendedLeverage = new Web3Number((Number(extendedBalance.marginRatio) * 100).toFixed(4), 4);
35315
+ logger.info(`extendedLeverage: ${extendedLeverage.toNumber()}`);
35316
+ return [healthFactor.toNumber(), extendedLeverage.toNumber()];
35317
+ }
35318
+ async netAPY() {
35319
+ const allPositions = [];
35320
+ for (let adapter of this.metadata.additionalInfo.adapters) {
35321
+ if (adapter.adapter.name !== ExtendedAdapter.name) {
35322
+ let positions = await adapter.adapter.getPositions();
35323
+ if (positions.length > 0) {
35324
+ allPositions.push(...positions);
35325
+ }
35326
+ }
35327
+ }
35328
+ const extendedAdapter = await this.getExtendedAdapter();
35329
+ if (!extendedAdapter) {
35330
+ return {
35331
+ net: 0,
35332
+ splits: []
35333
+ };
35334
+ }
35335
+ let vesuPositions = allPositions.filter((item) => item.protocol === Protocols.VESU);
35336
+ vesuPositions.map((item) => {
35337
+ item.apy.apy = item.apy.apy * 0.1;
35338
+ });
35339
+ const extendedPositions = await extendedAdapter.getAllOpenPositions();
35340
+ const usdcToken = Global.getDefaultTokens().find((token) => token.symbol === "USDC");
35341
+ if (!extendedPositions || !usdcToken) {
35342
+ return {
35343
+ net: 0,
35344
+ splits: []
35345
+ };
35346
+ }
35347
+ const extendedPosition = extendedPositions[0] || 0;
35348
+ const extendedEquity = (await extendedAdapter.getExtendedDepositAmount())?.equity || 0;
35349
+ const extendedApy = await extendedAdapter.getNetAPY();
35350
+ const totalHoldingsUSDValue = allPositions.reduce((acc, curr) => acc + curr.usdValue, 0) + Number(extendedEquity);
35351
+ console.log(totalHoldingsUSDValue);
35352
+ const extendedPositionSizeMultipliedByApy = Number(extendedPosition.value) * extendedApy;
35353
+ let weightedAPYs = allPositions.reduce((acc, curr) => acc + curr.apy.apy * curr.usdValue, 0) + extendedPositionSizeMultipliedByApy;
35354
+ console.log(weightedAPYs);
35355
+ const netAPY = weightedAPYs / totalHoldingsUSDValue;
35356
+ console.log(netAPY);
35357
+ allPositions.push({
35358
+ tokenInfo: usdcToken,
35359
+ amount: new Web3Number(extendedPosition.size, 0),
35360
+ usdValue: Number(extendedEquity),
35361
+ apy: { apy: extendedApy, type: "base" /* BASE */ },
35362
+ remarks: "finalised" /* FINALISED */,
35363
+ protocol: Protocols.EXTENDED
35364
+ });
35365
+ return {
35366
+ net: netAPY,
35367
+ splits: allPositions.map((p) => ({ apy: p.apy.apy, id: p.remarks ?? "" }))
35368
+ };
35369
+ }
35370
+ async getWalletHoldings() {
35371
+ const usdceToken = Global.getDefaultTokens().find((token) => token.symbol === "USDCe");
35372
+ const wbtcToken = Global.getDefaultTokens().find((token) => token.symbol === "WBTC");
35373
+ const usdcToken = Global.getDefaultTokens().find((token) => token.symbol === "USDC");
35374
+ if (!usdceToken || !wbtcToken || !usdcToken) {
35375
+ return [];
35376
+ }
35377
+ const walletAddress = this.metadata.additionalInfo.walletAddress;
35378
+ const usdceWalletBalance = await new ERC20(this.config).balanceOf(
35379
+ usdceToken.address,
35380
+ walletAddress,
35381
+ usdceToken.decimals
35382
+ );
35383
+ const usdcWalletBalance = await new ERC20(this.config).balanceOf(
35384
+ usdcToken.address,
35385
+ walletAddress,
35386
+ usdcToken.decimals
35387
+ );
35388
+ const wbtcWalletBalance = await new ERC20(this.config).balanceOf(
35389
+ wbtcToken.address,
35390
+ walletAddress,
35391
+ wbtcToken.decimals
35392
+ );
35393
+ const price = await this.pricer.getPrice(usdceToken.symbol);
35394
+ const wbtcPrice = await this.pricer.getPrice(wbtcToken.symbol);
35395
+ const usdceUsdValue = Number(usdceWalletBalance.toFixed(usdceToken.decimals)) * price.price;
35396
+ const usdcUsdValue = Number(usdcWalletBalance.toFixed(usdcToken.decimals)) * price.price;
35397
+ const wbtcUsdValue = Number(wbtcWalletBalance.toFixed(wbtcToken.decimals)) * wbtcPrice.price;
35398
+ return [
35399
+ {
35400
+ tokenInfo: usdceToken,
35401
+ amount: usdceWalletBalance,
35402
+ usdValue: usdceUsdValue
35403
+ },
35404
+ {
35405
+ tokenInfo: usdcToken,
35406
+ amount: usdcWalletBalance,
35407
+ usdValue: usdcUsdValue
35408
+ },
35409
+ {
35410
+ tokenInfo: wbtcToken,
35411
+ amount: wbtcWalletBalance,
35412
+ usdValue: wbtcUsdValue
35413
+ }
35414
+ ];
35415
+ }
34494
35416
  };
34495
- function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1, extendedBackendUrl, extendedApiKey, vaultIdExtended) {
35417
+ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1, extendedBackendReadUrl, extendedBackendWriteUrl, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing) {
34496
35418
  vaultSettings.leafAdapters = [];
34497
35419
  const wbtcToken = Global.getDefaultTokens().find(
34498
35420
  (token) => token.symbol === lstSymbol
@@ -34516,7 +35438,9 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1, e
34516
35438
  ...baseAdapterConfig,
34517
35439
  avnuContract: AVNU_MIDDLEWARE,
34518
35440
  slippage: 0.01,
34519
- baseUrl: AVNU_QUOTE_URL
35441
+ baseUrl: AVNU_QUOTE_URL,
35442
+ minimumExtendedPriceDifferenceForSwapOpen,
35443
+ maximumExtendedPriceDifferenceForSwapClosing
34520
35444
  });
34521
35445
  const extendedAdapter = new ExtendedAdapter({
34522
35446
  ...baseAdapterConfig,
@@ -34525,14 +35449,17 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1, e
34525
35449
  ],
34526
35450
  vaultIdExtended,
34527
35451
  extendedContract: EXTENDED_CONTRACT,
34528
- extendedBackendUrl,
34529
- extendedApiKey,
35452
+ extendedBackendWriteUrl,
35453
+ extendedBackendReadUrl,
34530
35454
  extendedTimeout: 3e4,
34531
35455
  extendedRetries: 3,
34532
35456
  extendedBaseUrl: "https://api.starknet.extended.exchange",
34533
35457
  extendedMarketName: "BTC-USD",
34534
35458
  extendedPrecision: 5,
34535
- avnuAdapter
35459
+ avnuAdapter,
35460
+ retryDelayForOrderStatus: minimumExtendedRetriesDelayForOrderStatus ?? 3e3,
35461
+ minimumExtendedMovementAmount: minimumExtendedMovementAmount ?? 5
35462
+ //5 usdcs
34536
35463
  });
34537
35464
  const vesuMultiplyAdapter = new VesuMultiplyAdapter({
34538
35465
  poolId: pool1,
@@ -34545,7 +35472,9 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1, e
34545
35472
  supportedPositions: [
34546
35473
  { asset: wbtcToken, isDebt: false },
34547
35474
  { asset: usdcToken, isDebt: true }
34548
- ]
35475
+ ],
35476
+ minimumVesuMovementAmount: minimumVesuMovementAmount ?? 5
35477
+ //5 usdc
34549
35478
  });
34550
35479
  const unusedBalanceAdapter = new UnusedBalanceAdapter({
34551
35480
  ...baseAdapterConfig
@@ -34641,11 +35570,11 @@ function VaultDescription2(lstSymbol, underlyingSymbol) {
34641
35570
  ] });
34642
35571
  }
34643
35572
  var re7UsdcPrimeDevansh = {
34644
- vaultAddress: ContractAddr.from("0x520a2e945dd0762e5284fc1b012f62ca04e238e105eb362d5e0ce208928729d"),
34645
- manager: ContractAddr.from("0x6abe24d31cbc16d7c4acb2421a826f96273e225b4a2d168d91e65123da0bfb9"),
34646
- vaultAllocator: ContractAddr.from("0x6e4f716e22efb164ee4a831233e513f45396ad3be4cff3c07386be0226febed"),
34647
- redeemRequestNFT: ContractAddr.from("0x66060e1874e05506b18e6029188ec49bf231a411ad57642311bbdf3cb22e5f"),
34648
- aumOracle: ContractAddr.from("0x301d883b9b45c76132638e39326b3f464c492599623263d405ec0df991e27ab"),
35573
+ vaultAddress: ContractAddr.from("0x058905be22d6a81792df79425dc9641cf3e1b77f36748631b7d7e5d713a32b55"),
35574
+ manager: ContractAddr.from("0x02648d703783feb2d967cf0520314cb5aa800d69a9426f3e3b317395af44de16"),
35575
+ vaultAllocator: ContractAddr.from("0x07d533c838eab6a4d854dd3aea96a55993fccd35821921970d00bde946b63b6f"),
35576
+ redeemRequestNFT: ContractAddr.from("0x01ef91f08fb99729c00f82fc6e0ece37917bcc43952596c19996259dc8adbbba"),
35577
+ aumOracle: ContractAddr.from("0x030b6acfec162f5d6e72b8a4d2798aedce78fb39de78a8f549f7cd277ae8bc8d"),
34649
35578
  leafAdapters: [],
34650
35579
  adapters: [],
34651
35580
  targetHealthFactor: 1.4,
@@ -34658,14 +35587,15 @@ var re7UsdcPrimeDevansh = {
34658
35587
  Global.getDefaultTokens().find((token) => token.symbol === "WBTC").decimals
34659
35588
  ),
34660
35589
  borrowable_assets: [Global.getDefaultTokens().find((token) => token.symbol === "WBTC")],
34661
- minimumWBTCDifferenceForAvnuSwap: MINIMUM_WBTC_DIFFERENCE_FOR_AVNU_SWAP
35590
+ minimumWBTCDifferenceForAvnuSwap: MINIMUM_WBTC_DIFFERENCE_FOR_AVNU_SWAP,
35591
+ walletAddress: WALLET_ADDRESS
34662
35592
  };
34663
- var VesuExtendedTestStrategies = (extendedBackendUrl, extendedApiKey, vaultIdExtended) => {
35593
+ var VesuExtendedTestStrategies = (extendedBackendReadUrl, extendedBackendWriteUrl, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing) => {
34664
35594
  return [
34665
- getStrategySettingsVesuExtended("WBTC", "USDC", re7UsdcPrimeDevansh, false, false, extendedBackendUrl, extendedApiKey, vaultIdExtended)
35595
+ getStrategySettingsVesuExtended("WBTC", "USDC", re7UsdcPrimeDevansh, false, false, extendedBackendReadUrl, extendedBackendWriteUrl, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing)
34666
35596
  ];
34667
35597
  };
34668
- function getStrategySettingsVesuExtended(lstSymbol, underlyingSymbol, addresses, isPreview = false, isLST, extendedBackendUrl, extendedApiKey, vaultIdExtended) {
35598
+ function getStrategySettingsVesuExtended(lstSymbol, underlyingSymbol, addresses, isPreview = false, isLST, extendedBackendReadUrl, extendedBackendWriteUrl, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing) {
34669
35599
  return {
34670
35600
  name: `Extended Test ${underlyingSymbol}`,
34671
35601
  description: getDescription2(lstSymbol, underlyingSymbol),
@@ -34673,7 +35603,7 @@ function getStrategySettingsVesuExtended(lstSymbol, underlyingSymbol, addresses,
34673
35603
  launchBlock: 0,
34674
35604
  type: "Other",
34675
35605
  depositTokens: [Global.getDefaultTokens().find((token) => token.symbol === underlyingSymbol)],
34676
- additionalInfo: getLooperSettings2(lstSymbol, underlyingSymbol, addresses, VesuPools.Re7USDCPrime, extendedBackendUrl, extendedApiKey, vaultIdExtended),
35606
+ additionalInfo: getLooperSettings2(lstSymbol, underlyingSymbol, addresses, VesuPools.Re7USDCPrime, extendedBackendReadUrl, extendedBackendWriteUrl, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing),
34677
35607
  risk: {
34678
35608
  riskFactor: _riskFactor3,
34679
35609
  netRisk: _riskFactor3.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor3.reduce((acc, curr) => acc + curr.weight, 0),
@@ -38358,11 +39288,13 @@ export {
38358
39288
  AssetOperationStatus,
38359
39289
  AssetOperationType,
38360
39290
  AutoCompounderSTRK,
39291
+ AvnuAdapter,
38361
39292
  AvnuWrapper,
38362
39293
  BaseAdapter,
38363
39294
  BaseStrategy,
38364
39295
  CommonAdapter,
38365
39296
  ContractAddr,
39297
+ CycleType,
38366
39298
  ERC20,
38367
39299
  EXTENDED_CONTRACT,
38368
39300
  EXTENDED_SANITIZER,
@@ -38389,6 +39321,7 @@ export {
38389
39321
  OrderType,
38390
39322
  PRICE_ROUTER,
38391
39323
  PositionSide,
39324
+ PositionTypeAvnuExtended,
38392
39325
  Pragma,
38393
39326
  Pricer,
38394
39327
  PricerBase,
@@ -38432,6 +39365,7 @@ export {
38432
39365
  calculateExtendedLevergae,
38433
39366
  calculateVesUPositionSizeGivenExtended,
38434
39367
  calculateVesuLeverage,
39368
+ calculateWBTCAmountToMaintainLTV,
38435
39369
  extensionMap,
38436
39370
  getContractDetails,
38437
39371
  getFAQs,