@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.
package/dist/index.mjs CHANGED
@@ -4328,20 +4328,13 @@ var EkuboQuoter = class _EkuboQuoter {
4328
4328
  async getDexPrice(baseToken, quoteToken, amount) {
4329
4329
  const lstTokenInfo = baseToken;
4330
4330
  const lstUnderlyingTokenInfo = quoteToken;
4331
- console.log("lstTokenInfo", lstTokenInfo);
4332
- console.log("lstUnderlyingTokenInfo", lstUnderlyingTokenInfo);
4333
- console.log("amount", amount);
4334
4331
  const quote = await this.getQuote(
4335
4332
  lstTokenInfo.address.address,
4336
4333
  lstUnderlyingTokenInfo.address.address,
4337
4334
  amount
4338
4335
  );
4339
- console.log("quote", quote);
4340
4336
  const outputAmount = Web3Number.fromWei(quote.total_calculated, lstUnderlyingTokenInfo.decimals);
4341
- console.log("outputAmount", outputAmount);
4342
- console.log("amount", amount);
4343
4337
  const price = outputAmount.toNumber() / amount.toNumber();
4344
- console.log("price", price);
4345
4338
  logger.verbose(`${_EkuboQuoter.name}:: LST Dex Price: ${price}`);
4346
4339
  return price;
4347
4340
  }
@@ -4360,16 +4353,12 @@ var EkuboQuoter = class _EkuboQuoter {
4360
4353
  // debt collateral
4361
4354
  async getSwapLimitAmount(fromToken, toToken, amount, max_slippage = 2e-3) {
4362
4355
  const isExactAmountIn = amount.greaterThanOrEqualTo(0);
4363
- console.log("isExactAmountIn", isExactAmountIn);
4364
4356
  logger.verbose(`${_EkuboQuoter.name}::getSwapLimitAmount isExactAmountIn: ${isExactAmountIn}, fromToken: ${fromToken.symbol}, toToken: ${toToken.symbol}, amount: ${amount}`);
4365
4357
  const isYieldToken = this.tokenMarketData.isAPYSupported(toToken);
4366
4358
  console.log("isYieldToken", isYieldToken);
4367
4359
  const baseToken = isExactAmountIn ? toToken : fromToken;
4368
4360
  const quoteToken = isExactAmountIn ? fromToken : toToken;
4369
- console.log("baseToken", baseToken);
4370
- console.log("quoteToken", quoteToken);
4371
4361
  const dexPrice = await this.getDexPrice(baseToken, quoteToken, amount);
4372
- console.log("dexPrice", dexPrice);
4373
4362
  const trueExchangeRate = isYieldToken ? await this.tokenMarketData.getTruePrice(baseToken) : dexPrice;
4374
4363
  console.log("trueExchangeRate", trueExchangeRate);
4375
4364
  if (isExactAmountIn) {
@@ -4400,7 +4389,6 @@ var EkuboQuoter = class _EkuboQuoter {
4400
4389
  return quote.splits.map((split) => {
4401
4390
  const isNegativeAmount = BigInt(split.amount_specified) <= 0n;
4402
4391
  const token = isNegativeAmount ? toTokenInfo : fromTokenInfo;
4403
- console.log("token for withdrawal", token, isNegativeAmount);
4404
4392
  return {
4405
4393
  route: split.route.map((_route) => ({
4406
4394
  pool_key: {
@@ -27077,11 +27065,6 @@ var VesuAdapter = class _VesuAdapter extends CacheClass {
27077
27065
  if (!this.pricer) {
27078
27066
  throw new Error("Pricer is not initialized");
27079
27067
  }
27080
- const CACHE_KEY = `positions_${blockNumber}_${this.config.poolId.shortString()}_${this.config.collateral.symbol}_${this.config.debt.symbol}`;
27081
- const cacheData = this.getCache(CACHE_KEY);
27082
- if (cacheData) {
27083
- return cacheData;
27084
- }
27085
27068
  const { contract, isV2 } = this.getVesuSingletonContract(config, this.config.poolId);
27086
27069
  const output = await contract.call(isV2 ? "position" : "position_unsafe", [
27087
27070
  ...isV2 ? [] : [this.config.poolId.address],
@@ -27107,7 +27090,6 @@ var VesuAdapter = class _VesuAdapter extends CacheClass {
27107
27090
  usdValue: debtAmount.multipliedBy(token2Price.price).toNumber(),
27108
27091
  remarks: "Debt"
27109
27092
  }];
27110
- this.setCache(CACHE_KEY, value, 6e4);
27111
27093
  return value.map((v) => ({ ...v, protocol: Protocols.VESU }));
27112
27094
  }
27113
27095
  async getCollateralization(config, blockNumber = "latest") {
@@ -28030,15 +28012,14 @@ var MAX_PRICE_DROP_PERCENTAGE = Number(process.env.MAX_PRICE_DROP_PERCENTAGE ??
28030
28012
  var MAX_LTV_BTC_USDC = 0.8428;
28031
28013
  var MAX_LIQUIDATION_RATIO = 0.86;
28032
28014
  var VAULT_ID_EXTENDED = process.env.VAULT_ID_EXTENDED ?? 220774;
28033
- var WALLET_ADDRESS = process.env.WALLET_ADDRESS ?? "0x07b84bb6E87588BdAde0bfe6173A615b3C220F9C3803456aE183C50EA1d15Ba1";
28034
- var TESTNET_WALLET_ADDRESS = process.env.TESTNET_WALLET_ADDRESS ?? "0x07b84bb6E87588BdAde0bfe6173A615b3C220F9C3803456aE183C50EA1d15Ba1";
28035
- var TEST_WALLET_2 = process.env.TEST_WALLET_2 ?? "0x004C1bdC61DAc7947F3C93d0163d660012E2aB0521567f7155fcf502848791A7";
28015
+ var WALLET_ADDRESS = process.env.WALLET_ADDRESS ?? "0x007E24592287427aaE9d291770B17d582E8A45f3aE54228F998793Ec769B7D13";
28036
28016
  var STRK_API_TEST_RPC = process.env.STRK_API_TEST_RPC ?? "https://sepolia.starknet.a5a.ch";
28037
28017
  var STRK_API_RPC = process.env.STRK_API_RPC ?? "https://mainnet.starknet.a5a.ch";
28038
28018
  var MAX_RETRIES = Number(process.env.MAX_RETRIES ?? 3);
28039
28019
  var MAX_DELAY = Number(process.env.MAX_DELAY ?? 100);
28040
28020
  var EXTEND_MARKET_NAME = "BTC-USD";
28041
- var LIMIT_BALANCE = Number(process.env.LIMIT_BALANCE ?? 10);
28021
+ var LIMIT_BALANCE = Number(process.env.LIMIT_BALANCE ?? 0.05);
28022
+ var LIMIT_BALANCE_VALUE = 10;
28042
28023
  var REBALANCER_INTERVAL = Number(process.env.REBALANCER_INTERVAL ?? 18e4);
28043
28024
  var WITHDRAWAL_INTERVAL = Number(process.env.WITHDRAWAL_INTERVAL ?? 18e6);
28044
28025
  var INVESTING_INTERVAL = Number(process.env.INVESTING_INTERVAL ?? 18e4);
@@ -28056,8 +28037,6 @@ var PRICE_MAX_SLIPPAGE_EKUBO = Number(process.env.PRICE_MAX_SLIPPAGE_EKUBO ?? 5e
28056
28037
  var MINIMUM_DEBT_AMOUNT_VESU_FOR_REBALANCING = Number(process.env.MINIMUM_DEBT_AMOUNT_VESU_FOR_REBALANCING ?? 1);
28057
28038
  var MINIMUM_EXTENDED_POSITION_SIZE = 1e-4;
28058
28039
  var MINIMUM_WBTC_DIFFERENCE_FOR_AVNU_SWAP = 1e-5;
28059
- var MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED = 700;
28060
- var MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED = -100;
28061
28040
 
28062
28041
  // src/strategies/vesu-extended-strategy/utils/helper.ts
28063
28042
  var returnFormattedAmount = (amount, toTokenDecimals) => {
@@ -28077,8 +28056,7 @@ var calculateAmountDistribution = async (amount, client, marketName, collateralP
28077
28056
  vesu_leverage: 0
28078
28057
  };
28079
28058
  }
28080
- const extendedBTCExposure = extendedPosition.length > 0 ? new Web3Number(extendedPosition[0].size, WBTC_TOKEN_DECIMALS) : new Web3Number(0, WBTC_TOKEN_DECIMALS);
28081
- const extendedExposureUSD = extendedBTCExposure.multipliedBy(collateralPrice);
28059
+ const extendedExposureUSD = extendedPosition.length > 0 ? new Web3Number(extendedPosition[0].value, WBTC_TOKEN_DECIMALS) : new Web3Number(0, WBTC_TOKEN_DECIMALS);
28082
28060
  const vesuBTCExposureUSD = collateralUnits.multipliedBy(collateralPrice);
28083
28061
  const numerator1 = vesu_leverage * amount + vesuBTCExposureUSD.toNumber();
28084
28062
  const numerator2 = extendedExposureUSD.toNumber();
@@ -28115,7 +28093,6 @@ var calculateAmountDistributionForWithdrawal = async (amountInUsdc, collateralPr
28115
28093
  return null;
28116
28094
  }
28117
28095
  const extendedExposureUSD = extendedPosition.length > 0 ? new Web3Number(extendedPosition[0].value, USDC_TOKEN_DECIMALS) : new Web3Number(0, USDC_TOKEN_DECIMALS);
28118
- console.log("THe collateral is", collateralPrice, collateralUnits);
28119
28096
  const vesuExposureUSD = collateralUnits.multipliedBy(collateralPrice);
28120
28097
  if (vesuExposureUSD.lessThan(0)) {
28121
28098
  return {
@@ -28172,10 +28149,10 @@ var calculateExtendedLevergae = () => {
28172
28149
  const extended_leverage_max = 1 / (MAINTENANCE_MARGIN + MAX_PRICE_DROP_PERCENTAGE);
28173
28150
  return Math.floor(extended_leverage_max);
28174
28151
  };
28175
- var calculateDebtAmount = (collateralAmount, debtAmount, debtPrice, maxLtv = MAX_LTV_BTC_USDC, addedAmount, collateralPrice, isDeposit) => {
28152
+ var calculateDebtAmount = (collateralAmount, debtAmount, debtPrice, maxLtv = MAX_LIQUIDATION_RATIO, addedAmount, collateralPrice, isDeposit) => {
28176
28153
  try {
28177
- const marginAmount = addedAmount.multipliedBy(isDeposit ? 1 : -1);
28178
- const numerator1 = collateralAmount.plus(addedAmount).multipliedBy(collateralPrice).multipliedBy(maxLtv);
28154
+ const addedCollateral = addedAmount.multipliedBy(isDeposit ? 1 : -1);
28155
+ const numerator1 = collateralAmount.plus(addedCollateral).multipliedBy(collateralPrice).multipliedBy(maxLtv);
28179
28156
  const numerator2 = debtAmount.multipliedBy(debtPrice).multipliedBy(TARGET_HF);
28180
28157
  const denominator = TARGET_HF - maxLtv;
28181
28158
  const x_debt_usd = numerator1.minus(numerator2).dividedBy(denominator);
@@ -28210,19 +28187,34 @@ var calculateAmountDepositOnExtendedWhenIncurringLosses = async (client) => {
28210
28187
  const extendedHoldings = await client.getHoldings();
28211
28188
  const extended_leverage = calculateExtendedLevergae();
28212
28189
  const latestPosition = (await client.getPositions()).data.pop();
28213
- console.log("the latest position is", latestPosition, extendedHoldings);
28214
28190
  if (!extendedHoldings || !latestPosition) {
28215
28191
  logger.error(`error getting extended position: extendedHoldings=${extendedHoldings}, latestPosition=${latestPosition}`);
28216
28192
  return null;
28217
28193
  }
28218
- const positionValueInUSD = latestPosition.value;
28194
+ const positionValueInUSD = new Web3Number(latestPosition.value, USDC_TOKEN_DECIMALS);
28219
28195
  const equity = extendedHoldings.data.equity;
28220
- const deposit = Number(positionValueInUSD) / extended_leverage - Number(equity);
28221
- return new Web3Number(Math.floor(deposit / 0.2) * 0.2, USDC_TOKEN_DECIMALS);
28196
+ const deposit = positionValueInUSD.dividedBy(extended_leverage).minus(equity).toFixed(2);
28197
+ return new Web3Number(deposit, USDC_TOKEN_DECIMALS);
28222
28198
  } catch (err) {
28199
+ logger.error(`error calculating amount deposit on extended when incurring losses: ${err}`);
28223
28200
  return null;
28224
28201
  }
28225
28202
  };
28203
+ var calculateWBTCAmountToMaintainLTV = (collateralAmount, debtAmount, debtPrice, maxLtv = MAX_LIQUIDATION_RATIO, collateralPrice, targetHF = TARGET_HF) => {
28204
+ try {
28205
+ const numerator1 = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLtv);
28206
+ const numerator2 = debtAmount.multipliedBy(debtPrice).multipliedBy(targetHF);
28207
+ const denominator = maxLtv;
28208
+ const collateralAmountToMaintainLTV = numerator2.minus(numerator1).dividedBy(denominator);
28209
+ let deltaCollateralAmountUnits = new Web3Number(
28210
+ collateralAmountToMaintainLTV.dividedBy(collateralPrice).toFixed(WBTC_TOKEN_DECIMALS),
28211
+ WBTC_TOKEN_DECIMALS
28212
+ );
28213
+ return { deltaCollateralAmountUnits };
28214
+ } catch (err) {
28215
+ return { deltaCollateralAmountUnits: null };
28216
+ }
28217
+ };
28226
28218
  var calculateExposureDelta = (exposure_extended, exposure_vesu) => {
28227
28219
  const exposure_delta = new Web3Number(exposure_extended - exposure_vesu, 2);
28228
28220
  return exposure_delta.absoluteValue().toNumber();
@@ -28297,21 +28289,36 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28297
28289
  vaultAllocator: config.vaultAllocator,
28298
28290
  id: ""
28299
28291
  });
28300
- this.tokenMarketData = new TokenMarketData(this.config.pricer, this.config.networkConfig);
28292
+ this.minimumVesuMovementAmount = config.minimumVesuMovementAmount ?? 5;
28293
+ this.tokenMarketData = new TokenMarketData(
28294
+ this.config.pricer,
28295
+ this.config.networkConfig
28296
+ );
28301
28297
  }
28302
28298
  async getAPY(supportedPosition) {
28303
28299
  const CACHE_KEY = `apy_${this.config.poolId.address}_${supportedPosition.asset.symbol}`;
28304
28300
  const cacheData = this.getCache(CACHE_KEY);
28305
- console.log(`${_VesuMultiplyAdapter.name}::getAPY cacheData: ${JSON.stringify(cacheData)}`, this.vesuAdapter.config.poolId.shortString(), this.vesuAdapter.config.collateral.symbol, this.vesuAdapter.config.debt.symbol);
28301
+ console.log(
28302
+ `${_VesuMultiplyAdapter.name}::getAPY cacheData: ${JSON.stringify(
28303
+ cacheData
28304
+ )}`,
28305
+ this.vesuAdapter.config.poolId.shortString(),
28306
+ this.vesuAdapter.config.collateral.symbol,
28307
+ this.vesuAdapter.config.debt.symbol
28308
+ );
28306
28309
  if (cacheData) {
28307
28310
  return cacheData;
28308
28311
  }
28309
28312
  try {
28310
28313
  const allVesuPools = await VesuAdapter.getVesuPools();
28311
28314
  const asset = supportedPosition.asset;
28312
- const pool = allVesuPools.pools.find((p) => this.vesuAdapter.config.poolId.eqString(num9.getHexString(p.id)));
28315
+ const pool = allVesuPools.pools.find(
28316
+ (p) => this.vesuAdapter.config.poolId.eqString(num9.getHexString(p.id))
28317
+ );
28313
28318
  if (!pool) {
28314
- logger.warn(`VesuMultiplyAdapter: Pool not found for token ${asset.symbol}`);
28319
+ logger.warn(
28320
+ `VesuMultiplyAdapter: Pool not found for token ${asset.symbol}`
28321
+ );
28315
28322
  return {
28316
28323
  apy: 0,
28317
28324
  type: "base" /* BASE */
@@ -28321,7 +28328,9 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28321
28328
  (a) => a.symbol.toLowerCase() === asset.symbol.toLowerCase()
28322
28329
  )?.stats;
28323
28330
  if (!assetStats) {
28324
- logger.warn(`VesuMultiplyAdapter: Asset stats not found for token ${asset.symbol}`);
28331
+ logger.warn(
28332
+ `VesuMultiplyAdapter: Asset stats not found for token ${asset.symbol}`
28333
+ );
28325
28334
  return {
28326
28335
  apy: 0,
28327
28336
  type: "base" /* BASE */
@@ -28332,7 +28341,9 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28332
28341
  apy = Number(assetStats.borrowApr?.value || 0) / 1e18;
28333
28342
  } else {
28334
28343
  const isAssetBTC = asset.symbol.toLowerCase().includes("btc");
28335
- const baseAPY = Number(isAssetBTC ? assetStats.btcFiSupplyApr?.value + assetStats.supplyApy?.value : assetStats.supplyApy?.value || 0) / 1e18;
28344
+ const baseAPY = Number(
28345
+ isAssetBTC ? assetStats.btcFiSupplyApr?.value + assetStats.supplyApy?.value : assetStats.supplyApy?.value || 0
28346
+ ) / 1e18;
28336
28347
  const rewardAPY = Number(assetStats.defiSpringSupplyApr?.value || "0") / 1e18;
28337
28348
  const isSupported = this.tokenMarketData.isAPYSupported(asset);
28338
28349
  apy = baseAPY + rewardAPY;
@@ -28348,7 +28359,10 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28348
28359
  this.setCache(CACHE_KEY, result, 3e5);
28349
28360
  return result;
28350
28361
  } catch (error) {
28351
- logger.error(`VesuMultiplyAdapter: Error getting APY for ${supportedPosition.asset.symbol}:`, error);
28362
+ logger.error(
28363
+ `VesuMultiplyAdapter: Error getting APY for ${supportedPosition.asset.symbol}:`,
28364
+ error
28365
+ );
28352
28366
  throw error;
28353
28367
  }
28354
28368
  }
@@ -28361,12 +28375,16 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28361
28375
  try {
28362
28376
  this.vesuAdapter.networkConfig = this.config.networkConfig;
28363
28377
  this.vesuAdapter.pricer = this.config.pricer;
28364
- const positions = await this.vesuAdapter.getPositions(this.config.networkConfig);
28378
+ const positions = await this.vesuAdapter.getPositions(
28379
+ this.config.networkConfig
28380
+ );
28365
28381
  let position = positions.find(
28366
28382
  (p) => p.token.address.eq(supportedPosition.asset.address)
28367
28383
  );
28368
28384
  if (!position) {
28369
- logger.warn(`VesuMultiplyAdapter: Position not found for token ${supportedPosition.asset.symbol}`);
28385
+ logger.warn(
28386
+ `VesuMultiplyAdapter: Position not found for token ${supportedPosition.asset.symbol}`
28387
+ );
28370
28388
  return {
28371
28389
  amount: new Web3Number("0", supportedPosition.asset.decimals),
28372
28390
  remarks: "Position not found"
@@ -28379,12 +28397,18 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28379
28397
  this.setCache(CACHE_KEY, position, 6e4);
28380
28398
  return position;
28381
28399
  } catch (error) {
28382
- logger.error(`VesuMultiplyAdapter: Error getting position for ${supportedPosition.asset.symbol}:`, error);
28400
+ logger.error(
28401
+ `VesuMultiplyAdapter: Error getting position for ${supportedPosition.asset.symbol}:`,
28402
+ error
28403
+ );
28383
28404
  throw error;
28384
28405
  }
28385
28406
  }
28386
28407
  async maxBorrowableAPY() {
28387
- const collateralAPY = await this.getAPY({ asset: this.config.collateral, isDebt: false });
28408
+ const collateralAPY = await this.getAPY({
28409
+ asset: this.config.collateral,
28410
+ isDebt: false
28411
+ });
28388
28412
  const apy = collateralAPY.apy * 0.8;
28389
28413
  return apy;
28390
28414
  }
@@ -28394,9 +28418,15 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28394
28418
  try {
28395
28419
  this.vesuAdapter.networkConfig = this.config.networkConfig;
28396
28420
  this.vesuAdapter.pricer = this.config.pricer;
28397
- const positions = await this.vesuAdapter.getPositions(this.config.networkConfig);
28398
- const collateralPosition = positions.find((p) => p.token.address.eq(collateral.address));
28399
- const debtPosition = positions.find((p) => p.token.address.eq(debt.address));
28421
+ const positions = await this.vesuAdapter.getPositions(
28422
+ this.config.networkConfig
28423
+ );
28424
+ const collateralPosition = positions.find(
28425
+ (p) => p.token.address.eq(collateral.address)
28426
+ );
28427
+ const debtPosition = positions.find(
28428
+ (p) => p.token.address.eq(debt.address)
28429
+ );
28400
28430
  if (!collateralPosition || !debtPosition) {
28401
28431
  throw new Error("Could not find current positions");
28402
28432
  }
@@ -28406,13 +28436,23 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28406
28436
  debt,
28407
28437
  maxBorrowableAPY
28408
28438
  );
28409
- logger.verbose(`VesuMultiplyAdapter: Max borrowable: ${maxBorrowable.toNumber()}`);
28410
- const debtCap = await this.vesuAdapter.getDebtCap(this.config.networkConfig);
28439
+ logger.verbose(
28440
+ `VesuMultiplyAdapter: Max borrowable: ${maxBorrowable.toNumber()}`
28441
+ );
28442
+ const debtCap = await this.vesuAdapter.getDebtCap(
28443
+ this.config.networkConfig
28444
+ );
28411
28445
  logger.verbose(`VesuMultiplyAdapter: Debt cap: ${debtCap.toNumber()}`);
28412
28446
  const actualMaxBorrowable = maxBorrowable.minimum(debtCap);
28413
- logger.verbose(`VesuMultiplyAdapter: Actual max borrowable: ${actualMaxBorrowable.toNumber()}`);
28414
- const maxLTV = await this.vesuAdapter.getLTVConfig(this.config.networkConfig);
28415
- const collateralPrice = await this.config.pricer.getPrice(collateral.symbol);
28447
+ logger.verbose(
28448
+ `VesuMultiplyAdapter: Actual max borrowable: ${actualMaxBorrowable.toNumber()}`
28449
+ );
28450
+ const maxLTV = await this.vesuAdapter.getLTVConfig(
28451
+ this.config.networkConfig
28452
+ );
28453
+ const collateralPrice = await this.config.pricer.getPrice(
28454
+ collateral.symbol
28455
+ );
28416
28456
  if (collateralPrice.price === 0) {
28417
28457
  throw new Error("Collateral price is 0");
28418
28458
  }
@@ -28430,14 +28470,25 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28430
28470
  );
28431
28471
  const maxDepositAmount = amount ? amount.minimum(maxCollateralFromDebt) : maxCollateralFromDebt;
28432
28472
  const usdValue = await this.getUSDValue(collateral, maxDepositAmount);
28433
- logger.verbose(`VesuMultiplyAdapter: Max deposit::USD value: ${usdValue}, amount: ${maxDepositAmount.toNumber()}`);
28434
- const apys = await Promise.all([this.getAPY({ asset: collateral, isDebt: false }), this.getAPY({ asset: debt, isDebt: true })]);
28435
- logger.verbose(`VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`);
28473
+ logger.verbose(
28474
+ `VesuMultiplyAdapter: Max deposit::USD value: ${usdValue}, amount: ${maxDepositAmount.toNumber()}`
28475
+ );
28476
+ const apys = await Promise.all([
28477
+ this.getAPY({ asset: collateral, isDebt: false }),
28478
+ this.getAPY({ asset: debt, isDebt: true })
28479
+ ]);
28480
+ logger.verbose(
28481
+ `VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`
28482
+ );
28436
28483
  const borrowAmountUSD = actualMaxBorrowable.multipliedBy(debtPrice.price);
28437
- logger.verbose(`VesuMultiplyAdapter: Borrow amount: ${actualMaxBorrowable.toNumber()}, borrow amount USD: ${borrowAmountUSD.toNumber()}`);
28484
+ logger.verbose(
28485
+ `VesuMultiplyAdapter: Borrow amount: ${actualMaxBorrowable.toNumber()}, borrow amount USD: ${borrowAmountUSD.toNumber()}`
28486
+ );
28438
28487
  const netCollateralUSD = usdValue + borrowAmountUSD.toNumber();
28439
28488
  const netAPY = (apys[0].apy * netCollateralUSD + apys[1].apy * borrowAmountUSD.toNumber()) / usdValue;
28440
- logger.verbose(`VesuMultiplyAdapter: Max deposit amount: ${maxDepositAmount.toNumber()}, netAPY: ${netAPY}`);
28489
+ logger.verbose(
28490
+ `VesuMultiplyAdapter: Max deposit amount: ${maxDepositAmount.toNumber()}, netAPY: ${netAPY}`
28491
+ );
28441
28492
  return {
28442
28493
  tokenInfo: collateral,
28443
28494
  amount: maxDepositAmount,
@@ -28450,7 +28501,10 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28450
28501
  protocol: this.protocol
28451
28502
  };
28452
28503
  } catch (error) {
28453
- logger.error(`VesuMultiplyAdapter: Error calculating max deposit:`, error);
28504
+ logger.error(
28505
+ `VesuMultiplyAdapter: Error calculating max deposit:`,
28506
+ error
28507
+ );
28454
28508
  throw error;
28455
28509
  }
28456
28510
  }
@@ -28460,9 +28514,15 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28460
28514
  try {
28461
28515
  this.vesuAdapter.networkConfig = this.config.networkConfig;
28462
28516
  this.vesuAdapter.pricer = this.config.pricer;
28463
- const positions = await this.vesuAdapter.getPositions(this.config.networkConfig);
28464
- const collateralPosition = positions.find((p) => p.token.address.eq(collateral.address));
28465
- const debtPosition = positions.find((p) => p.token.address.eq(this.config.debt.address));
28517
+ const positions = await this.vesuAdapter.getPositions(
28518
+ this.config.networkConfig
28519
+ );
28520
+ const collateralPosition = positions.find(
28521
+ (p) => p.token.address.eq(collateral.address)
28522
+ );
28523
+ const debtPosition = positions.find(
28524
+ (p) => p.token.address.eq(this.config.debt.address)
28525
+ );
28466
28526
  if (!collateralPosition || !debtPosition) {
28467
28527
  throw new Error("Could not find current positions");
28468
28528
  }
@@ -28472,11 +28532,20 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28472
28532
  const result = maxWithdrawable.greaterThan(0) ? maxWithdrawable : new Web3Number("0", collateral.decimals);
28473
28533
  const usdValue = await this.getUSDValue(collateral, result);
28474
28534
  const debtUSD = debtPosition.usdValue;
28475
- logger.verbose(`VesuMultiplyAdapter: Debt USD: ${debtUSD}, collateral USD: ${usdValue}`);
28476
- const apys = await Promise.all([this.getAPY({ asset: collateral, isDebt: false }), this.getAPY({ asset: debt, isDebt: true })]);
28477
- logger.verbose(`VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`);
28535
+ logger.verbose(
28536
+ `VesuMultiplyAdapter: Debt USD: ${debtUSD}, collateral USD: ${usdValue}`
28537
+ );
28538
+ const apys = await Promise.all([
28539
+ this.getAPY({ asset: collateral, isDebt: false }),
28540
+ this.getAPY({ asset: debt, isDebt: true })
28541
+ ]);
28542
+ logger.verbose(
28543
+ `VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`
28544
+ );
28478
28545
  const netAPY = usdValue - debtUSD > 0 ? (apys[0].apy * usdValue + apys[1].apy * debtUSD) / (usdValue - debtUSD) : 0;
28479
- logger.verbose(`VesuMultiplyAdapter: Max withdraw amount: ${result.toNumber()}, netAPY: ${netAPY}`);
28546
+ logger.verbose(
28547
+ `VesuMultiplyAdapter: Max withdraw amount: ${result.toNumber()}, netAPY: ${netAPY}`
28548
+ );
28480
28549
  return {
28481
28550
  tokenInfo: collateral,
28482
28551
  amount: result,
@@ -28489,14 +28558,19 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28489
28558
  protocol: this.protocol
28490
28559
  };
28491
28560
  } catch (error) {
28492
- logger.error(`VesuMultiplyAdapter: Error calculating max withdraw:`, error);
28561
+ logger.error(
28562
+ `VesuMultiplyAdapter: Error calculating max withdraw:`,
28563
+ error
28564
+ );
28493
28565
  throw error;
28494
28566
  }
28495
28567
  }
28496
28568
  _getDepositLeaf() {
28497
28569
  const collateral = this.config.collateral;
28498
28570
  const debt = this.config.debt;
28499
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
28571
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
28572
+ this.config.poolId
28573
+ );
28500
28574
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
28501
28575
  return [
28502
28576
  // Approval step for collateral
@@ -28560,7 +28634,9 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28560
28634
  ];
28561
28635
  }
28562
28636
  _getWithdrawLeaf() {
28563
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
28637
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
28638
+ this.config.poolId
28639
+ );
28564
28640
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
28565
28641
  const collateral = this.config.collateral;
28566
28642
  const debt = this.config.debt;
@@ -28617,33 +28693,51 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28617
28693
  const leafConfigs = this._getDepositLeaf();
28618
28694
  const leaves = leafConfigs.map((config) => {
28619
28695
  const { target, method, packedArguments, sanitizer, id } = config;
28620
- const leaf = this.constructSimpleLeafData({
28621
- id,
28622
- target,
28623
- method,
28624
- packedArguments
28625
- }, sanitizer);
28696
+ const leaf = this.constructSimpleLeafData(
28697
+ {
28698
+ id,
28699
+ target,
28700
+ method,
28701
+ packedArguments
28702
+ },
28703
+ sanitizer
28704
+ );
28626
28705
  return leaf;
28627
28706
  });
28628
- return { leaves, callConstructor: this.getDepositCall.bind(this) };
28707
+ return {
28708
+ leaves,
28709
+ callConstructor: this.getDepositCall.bind(
28710
+ this
28711
+ )
28712
+ };
28629
28713
  }
28630
28714
  getWithdrawAdapter() {
28631
28715
  const leafConfigs = this._getWithdrawLeaf();
28632
28716
  const leaves = leafConfigs.map((config) => {
28633
28717
  const { target, method, packedArguments, sanitizer, id } = config;
28634
- const leaf = this.constructSimpleLeafData({
28635
- id,
28636
- target,
28637
- method,
28638
- packedArguments
28639
- }, sanitizer);
28718
+ const leaf = this.constructSimpleLeafData(
28719
+ {
28720
+ id,
28721
+ target,
28722
+ method,
28723
+ packedArguments
28724
+ },
28725
+ sanitizer
28726
+ );
28640
28727
  return leaf;
28641
28728
  });
28642
- return { leaves, callConstructor: this.getWithdrawCall.bind(this) };
28729
+ return {
28730
+ leaves,
28731
+ callConstructor: this.getWithdrawCall.bind(
28732
+ this
28733
+ )
28734
+ };
28643
28735
  }
28644
28736
  async getDepositCall(params) {
28645
28737
  const collateral = this.config.collateral;
28646
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
28738
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
28739
+ this.config.poolId
28740
+ );
28647
28741
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
28648
28742
  const uint256MarginAmount = uint25612.bnToUint256(params.amount.toWei());
28649
28743
  return [
@@ -28715,7 +28809,9 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28715
28809
  ];
28716
28810
  }
28717
28811
  async getWithdrawCall(params) {
28718
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
28812
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
28813
+ this.config.poolId
28814
+ );
28719
28815
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
28720
28816
  return [
28721
28817
  // Switch delegation on
@@ -28770,7 +28866,11 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28770
28866
  ];
28771
28867
  }
28772
28868
  async getMultiplyCallCalldata(params, isDeposit) {
28773
- logger.verbose(`${_VesuMultiplyAdapter.name}::getMultiplyCallCalldata params: ${JSON.stringify(params)}, isDeposit: ${isDeposit}, collateral: ${this.config.collateral.symbol}, debt: ${this.config.debt.symbol}`);
28869
+ logger.verbose(
28870
+ `${_VesuMultiplyAdapter.name}::getMultiplyCallCalldata params: ${JSON.stringify(
28871
+ params
28872
+ )}, isDeposit: ${isDeposit}, collateral: ${this.config.collateral.symbol}, debt: ${this.config.debt.symbol}`
28873
+ );
28774
28874
  const { isV2 } = getVesuSingletonAddress(this.config.poolId);
28775
28875
  const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
28776
28876
  const multiplyContract = new Contract12({
@@ -28780,42 +28880,83 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28780
28880
  });
28781
28881
  let leverSwap = [];
28782
28882
  let leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
28783
- const existingPositions = await this.vesuAdapter.getPositions(this.config.networkConfig);
28784
- const collateralisation = await this.vesuAdapter.getCollateralization(this.config.networkConfig);
28883
+ const existingPositions = await this.vesuAdapter.getPositions(
28884
+ this.config.networkConfig
28885
+ );
28886
+ const collateralisation = await this.vesuAdapter.getCollateralization(
28887
+ this.config.networkConfig
28888
+ );
28785
28889
  const existingCollateralInfo = existingPositions[0];
28786
28890
  const existingDebtInfo = existingPositions[1];
28787
28891
  const isDexPriceRequired = existingDebtInfo.token.symbol !== "USDC";
28788
- logger.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
28789
- existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
28892
+ logger.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(
28893
+ existingCollateralInfo
28894
+ )},
28895
+ existingDebtInfo: ${JSON.stringify(
28896
+ existingDebtInfo
28897
+ )}, collateralisation: ${JSON.stringify(collateralisation)}`);
28790
28898
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : (await this.config.pricer.getPrice(this.config.collateral.symbol)).price;
28791
28899
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : (await this.config.pricer.getPrice(this.config.debt.symbol)).price;
28792
- logger.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
28793
- const legLTV = await this.vesuAdapter.getLTVConfig(this.config.networkConfig);
28794
- const ekuboQuoter = new EkuboQuoter(this.config.networkConfig, this.config.pricer);
28795
- const dexPrice = isDexPriceRequired ? await ekuboQuoter.getDexPrice(this.config.collateral, this.config.debt, this.config.quoteAmountToFetchPrice) : 1;
28796
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall dexPrice: ${dexPrice}, ltv: ${legLTV}`);
28900
+ logger.debug(
28901
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`
28902
+ );
28903
+ const legLTV = await this.vesuAdapter.getLTVConfig(
28904
+ this.config.networkConfig
28905
+ );
28906
+ const ekuboQuoter = new EkuboQuoter(
28907
+ this.config.networkConfig,
28908
+ this.config.pricer
28909
+ );
28910
+ const dexPrice = isDexPriceRequired ? await ekuboQuoter.getDexPrice(
28911
+ this.config.collateral,
28912
+ this.config.debt,
28913
+ this.config.quoteAmountToFetchPrice
28914
+ ) : 1;
28915
+ logger.verbose(
28916
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall dexPrice: ${dexPrice}, ltv: ${legLTV}`
28917
+ );
28797
28918
  const addedCollateral = params.amount.multipliedBy(isDeposit ? 1 : -1);
28798
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall addedCollateral: ${addedCollateral}`);
28919
+ logger.verbose(
28920
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall addedCollateral: ${addedCollateral}`
28921
+ );
28799
28922
  const numeratorPart1 = existingCollateralInfo.amount.plus(addedCollateral).multipliedBy(collateralPrice).multipliedBy(legLTV);
28800
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}`);
28923
+ logger.verbose(
28924
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}`
28925
+ );
28801
28926
  const numeratorPart2 = existingDebtInfo.amount.multipliedBy(debtPrice).multipliedBy(this.config.targetHealthFactor);
28802
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart2: ${numeratorPart2}`);
28927
+ logger.verbose(
28928
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart2: ${numeratorPart2}`
28929
+ );
28803
28930
  const denominatorPart = this.config.targetHealthFactor - legLTV / dexPrice;
28804
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall denominatorPart: ${denominatorPart}`);
28931
+ logger.verbose(
28932
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall denominatorPart: ${denominatorPart}`
28933
+ );
28805
28934
  const x_debt_usd = numeratorPart1.minus(numeratorPart2).dividedBy(denominatorPart);
28806
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall x_debt_usd: ${x_debt_usd}`);
28807
- logger.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}, numeratorPart2: ${numeratorPart2}, denominatorPart: ${denominatorPart}`);
28808
- let debtAmount = new Web3Number(x_debt_usd.dividedBy(debtPrice).toFixed(this.config.debt.decimals), this.config.debt.decimals);
28935
+ logger.verbose(
28936
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall x_debt_usd: ${x_debt_usd}`
28937
+ );
28938
+ logger.debug(
28939
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}, numeratorPart2: ${numeratorPart2}, denominatorPart: ${denominatorPart}`
28940
+ );
28941
+ let debtAmount = new Web3Number(
28942
+ x_debt_usd.dividedBy(debtPrice).toFixed(this.config.debt.decimals),
28943
+ this.config.debt.decimals
28944
+ );
28809
28945
  const marginAmount = addedCollateral;
28810
28946
  const collateralToken = this.config.collateral;
28811
28947
  const debtToken = this.config.debt;
28812
- const debtAmountInCollateralUnits = new Web3Number(debtAmount.multipliedBy(debtPrice).dividedBy(collateralPrice).multipliedBy(10 ** collateralToken.decimals).toFixed(0), collateralToken.decimals);
28948
+ const debtAmountInCollateralUnits = new Web3Number(
28949
+ debtAmount.multipliedBy(debtPrice).dividedBy(collateralPrice).multipliedBy(10 ** collateralToken.decimals).toFixed(0),
28950
+ collateralToken.decimals
28951
+ );
28813
28952
  const isIncrease = debtAmount.greaterThanOrEqualTo(0);
28814
28953
  if (isIncrease && debtAmount.lessThan(0)) {
28815
28954
  } else if (!isIncrease && debtAmount.greaterThan(0)) {
28816
28955
  debtAmount = Web3Number.fromWei(0, this.config.debt.decimals);
28817
28956
  }
28818
- logger.verbose(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall debtAmount: ${debtAmount}, marginAmount: ${marginAmount}`);
28957
+ logger.verbose(
28958
+ `${_VesuMultiplyAdapter.name}::getVesuMultiplyCall debtAmount: ${debtAmount}, marginAmount: ${marginAmount}`
28959
+ );
28819
28960
  if (!debtAmount.isZero()) {
28820
28961
  try {
28821
28962
  const swapQuote = await ekuboQuoter.getQuote(
@@ -28825,26 +28966,49 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28825
28966
  // negative for exact amount out
28826
28967
  );
28827
28968
  if (swapQuote.price_impact < 0.01) {
28828
- leverSwap = ekuboQuoter.getVesuMultiplyQuote(swapQuote, debtToken, collateralToken);
28969
+ leverSwap = debtAmount.isNegative() ? ekuboQuoter.getVesuMultiplyQuote(
28970
+ swapQuote,
28971
+ collateralToken,
28972
+ debtToken
28973
+ ) : ekuboQuoter.getVesuMultiplyQuote(
28974
+ swapQuote,
28975
+ debtToken,
28976
+ collateralToken
28977
+ );
28829
28978
  const MAX_SLIPPAGE = 2e-3;
28830
28979
  if (debtAmount.greaterThan(0)) {
28831
28980
  leverSwapLimitAmount = debtAmount.multipliedBy(1 + MAX_SLIPPAGE);
28832
28981
  } else if (debtAmount.lessThan(0)) {
28833
28982
  leverSwapLimitAmount = debtAmount.abs().multipliedBy(1 - MAX_SLIPPAGE);
28834
28983
  } else {
28835
- leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
28984
+ leverSwapLimitAmount = Web3Number.fromWei(
28985
+ 0,
28986
+ this.config.debt.decimals
28987
+ );
28836
28988
  }
28837
28989
  await new Promise((resolve) => setTimeout(resolve, 1e4));
28838
28990
  } else {
28839
- throw new Error(`VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`);
28991
+ throw new Error(
28992
+ `VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`
28993
+ );
28840
28994
  }
28841
28995
  } catch (error) {
28842
- throw new Error(`VesuMultiplyAdapter: Failed to get swap quote: ${error}`);
28996
+ throw new Error(
28997
+ `VesuMultiplyAdapter: Failed to get swap quote: ${error}`
28998
+ );
28843
28999
  }
28844
29000
  }
28845
- const multiplyParams = await this.getLeverParams(isIncrease, params, leverSwap, leverSwapLimitAmount);
29001
+ const multiplyParams = await this.getLeverParams(
29002
+ isIncrease,
29003
+ params,
29004
+ leverSwap,
29005
+ leverSwapLimitAmount
29006
+ );
28846
29007
  const call = multiplyContract.populate("modify_lever", {
28847
- modify_lever_params: this.formatMultiplyParams(isIncrease, multiplyParams)
29008
+ modify_lever_params: this.formatMultiplyParams(
29009
+ isIncrease,
29010
+ multiplyParams
29011
+ )
28848
29012
  });
28849
29013
  return call.calldata;
28850
29014
  }
@@ -28858,7 +29022,10 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28858
29022
  add_margin: params.amount,
28859
29023
  // multiplied by collateral decimals in format
28860
29024
  margin_swap: [],
28861
- margin_swap_limit_amount: Web3Number.fromWei(0, this.config.collateral.decimals),
29025
+ margin_swap_limit_amount: Web3Number.fromWei(
29026
+ 0,
29027
+ this.config.collateral.decimals
29028
+ ),
28862
29029
  lever_swap: leverSwap,
28863
29030
  lever_swap_limit_amount: leverSwapLimitAmount
28864
29031
  } : {
@@ -28872,7 +29039,10 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28872
29039
  lever_swap_limit_amount: leverSwapLimitAmount,
28873
29040
  lever_swap_weights: [],
28874
29041
  withdraw_swap: [],
28875
- withdraw_swap_limit_amount: Web3Number.fromWei(0, this.config.collateral.decimals),
29042
+ withdraw_swap_limit_amount: Web3Number.fromWei(
29043
+ 0,
29044
+ this.config.collateral.decimals
29045
+ ),
28876
29046
  withdraw_swap_weights: [],
28877
29047
  close_position: false
28878
29048
  };
@@ -28888,12 +29058,16 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28888
29058
  });
28889
29059
  let leverSwap = [];
28890
29060
  let leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
28891
- const existingPositions = await this.vesuAdapter.getPositions(this.config.networkConfig);
29061
+ const existingPositions = await this.vesuAdapter.getPositions(
29062
+ this.config.networkConfig
29063
+ );
28892
29064
  const existingCollateralInfo = existingPositions[0];
28893
29065
  const existingDebtInfo = existingPositions[1];
28894
29066
  const collateralToken = this.config.collateral;
28895
29067
  const debtToken = this.config.debt;
28896
- const collateralPrice = await this.config.pricer.getPrice(collateralToken.symbol);
29068
+ const collateralPrice = await this.config.pricer.getPrice(
29069
+ collateralToken.symbol
29070
+ );
28897
29071
  const debtPrice = await this.config.pricer.getPrice(debtToken.symbol);
28898
29072
  const { deltadebtAmountUnits: debtAmountToRepay } = calculateDebtReductionAmountForWithdrawal(
28899
29073
  existingDebtInfo.amount,
@@ -28907,8 +29081,14 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28907
29081
  if (!debtAmountToRepay) {
28908
29082
  throw new Error("error calculating debt amount to repay");
28909
29083
  }
28910
- const ekuboQuoter = new EkuboQuoter(this.config.networkConfig, this.config.pricer);
28911
- const debtInDebtUnits = new Web3Number(debtAmountToRepay, debtToken.decimals).dividedBy(debtPrice.price).multipliedBy(10 ** debtToken.decimals);
29084
+ const ekuboQuoter = new EkuboQuoter(
29085
+ this.config.networkConfig,
29086
+ this.config.pricer
29087
+ );
29088
+ const debtInDebtUnits = new Web3Number(
29089
+ debtAmountToRepay,
29090
+ debtToken.decimals
29091
+ ).dividedBy(debtPrice.price).multipliedBy(10 ** debtToken.decimals);
28912
29092
  const swapQuote = await ekuboQuoter.getQuote(
28913
29093
  debtToken.address.address,
28914
29094
  collateralToken.address.address,
@@ -28916,12 +29096,23 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28916
29096
  );
28917
29097
  const MAX_SLIPPAGE = 2e-3;
28918
29098
  if (swapQuote.price_impact < 25e-4) {
28919
- leverSwap = ekuboQuoter.getVesuMultiplyQuote(swapQuote, collateralToken, debtToken);
29099
+ leverSwap = ekuboQuoter.getVesuMultiplyQuote(
29100
+ swapQuote,
29101
+ collateralToken,
29102
+ debtToken
29103
+ );
28920
29104
  } else {
28921
- logger.error(`VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`);
29105
+ logger.error(
29106
+ `VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`
29107
+ );
28922
29108
  }
28923
29109
  leverSwapLimitAmount = new Web3Number(debtAmountToRepay, debtToken.decimals).abs().multipliedBy(1 + MAX_SLIPPAGE);
28924
- const multiplyParams = await this.getLeverParams(false, params, leverSwap, leverSwapLimitAmount);
29110
+ const multiplyParams = await this.getLeverParams(
29111
+ false,
29112
+ params,
29113
+ leverSwap,
29114
+ leverSwapLimitAmount
29115
+ );
28925
29116
  const call = multiplyContract.populate("modify_lever", {
28926
29117
  modify_lever_params: this.formatMultiplyParams(false, multiplyParams)
28927
29118
  });
@@ -28931,100 +29122,132 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
28931
29122
  if (isIncrease) {
28932
29123
  const _params2 = params;
28933
29124
  return {
28934
- action: new CairoCustomEnum3({ IncreaseLever: {
28935
- pool_id: _params2.pool_id.toBigInt(),
28936
- collateral_asset: _params2.collateral_asset.toBigInt(),
28937
- debt_asset: _params2.debt_asset.toBigInt(),
28938
- user: _params2.user.toBigInt(),
28939
- add_margin: BigInt(_params2.add_margin.toWei()),
28940
- margin_swap: _params2.margin_swap.map((swap) => ({
29125
+ action: new CairoCustomEnum3({
29126
+ IncreaseLever: {
29127
+ pool_id: _params2.pool_id.toBigInt(),
29128
+ collateral_asset: _params2.collateral_asset.toBigInt(),
29129
+ debt_asset: _params2.debt_asset.toBigInt(),
29130
+ user: _params2.user.toBigInt(),
29131
+ add_margin: BigInt(_params2.add_margin.toWei()),
29132
+ margin_swap: _params2.margin_swap.map((swap) => ({
29133
+ route: swap.route.map((route) => ({
29134
+ pool_key: {
29135
+ token0: route.pool_key.token0.toBigInt(),
29136
+ token1: route.pool_key.token1.toBigInt(),
29137
+ fee: route.pool_key.fee,
29138
+ tick_spacing: route.pool_key.tick_spacing,
29139
+ extension: BigInt(
29140
+ num9.hexToDecimalString(route.pool_key.extension)
29141
+ )
29142
+ },
29143
+ sqrt_ratio_limit: uint25612.bnToUint256(
29144
+ route.sqrt_ratio_limit.toWei()
29145
+ ),
29146
+ skip_ahead: BigInt(100)
29147
+ })),
29148
+ token_amount: {
29149
+ token: swap.token_amount.token.toBigInt(),
29150
+ amount: swap.token_amount.amount.toI129()
29151
+ }
29152
+ })),
29153
+ margin_swap_limit_amount: BigInt(
29154
+ _params2.margin_swap_limit_amount.toWei()
29155
+ ),
29156
+ lever_swap: _params2.lever_swap.map((swap) => ({
29157
+ route: swap.route.map((route) => ({
29158
+ pool_key: {
29159
+ token0: route.pool_key.token0.toBigInt(),
29160
+ token1: route.pool_key.token1.toBigInt(),
29161
+ fee: route.pool_key.fee,
29162
+ tick_spacing: route.pool_key.tick_spacing,
29163
+ extension: BigInt(
29164
+ num9.hexToDecimalString(route.pool_key.extension)
29165
+ )
29166
+ },
29167
+ sqrt_ratio_limit: uint25612.bnToUint256(
29168
+ route.sqrt_ratio_limit.toWei()
29169
+ ),
29170
+ skip_ahead: BigInt(0)
29171
+ })),
29172
+ token_amount: {
29173
+ token: swap.token_amount.token.toBigInt(),
29174
+ amount: swap.token_amount.amount.toI129()
29175
+ }
29176
+ })),
29177
+ lever_swap_limit_amount: BigInt(
29178
+ _params2.lever_swap_limit_amount.toWei()
29179
+ )
29180
+ }
29181
+ })
29182
+ };
29183
+ }
29184
+ const _params = params;
29185
+ return {
29186
+ action: new CairoCustomEnum3({
29187
+ DecreaseLever: {
29188
+ pool_id: _params.pool_id.toBigInt(),
29189
+ collateral_asset: _params.collateral_asset.toBigInt(),
29190
+ debt_asset: _params.debt_asset.toBigInt(),
29191
+ user: _params.user.toBigInt(),
29192
+ sub_margin: BigInt(_params.sub_margin.toWei()),
29193
+ recipient: _params.recipient.toBigInt(),
29194
+ lever_swap: _params.lever_swap.map((swap) => ({
28941
29195
  route: swap.route.map((route) => ({
28942
29196
  pool_key: {
28943
29197
  token0: route.pool_key.token0.toBigInt(),
28944
29198
  token1: route.pool_key.token1.toBigInt(),
28945
29199
  fee: route.pool_key.fee,
28946
29200
  tick_spacing: route.pool_key.tick_spacing,
28947
- extension: BigInt(num9.hexToDecimalString(route.pool_key.extension))
29201
+ extension: ContractAddr.from(
29202
+ route.pool_key.extension
29203
+ ).toBigInt()
28948
29204
  },
28949
- sqrt_ratio_limit: uint25612.bnToUint256(route.sqrt_ratio_limit.toWei()),
28950
- skip_ahead: BigInt(100)
29205
+ sqrt_ratio_limit: uint25612.bnToUint256(
29206
+ route.sqrt_ratio_limit.toWei()
29207
+ ),
29208
+ skip_ahead: BigInt(route.skip_ahead.toWei())
28951
29209
  })),
28952
29210
  token_amount: {
28953
29211
  token: swap.token_amount.token.toBigInt(),
28954
29212
  amount: swap.token_amount.amount.toI129()
28955
29213
  }
28956
29214
  })),
28957
- margin_swap_limit_amount: BigInt(_params2.margin_swap_limit_amount.toWei()),
28958
- lever_swap: _params2.lever_swap.map((swap) => ({
29215
+ lever_swap_limit_amount: BigInt(
29216
+ _params.lever_swap_limit_amount.toWei()
29217
+ ),
29218
+ lever_swap_weights: _params.lever_swap_weights.map(
29219
+ (weight) => BigInt(weight.toWei())
29220
+ ),
29221
+ withdraw_swap: _params.withdraw_swap.map((swap) => ({
28959
29222
  route: swap.route.map((route) => ({
28960
29223
  pool_key: {
28961
29224
  token0: route.pool_key.token0.toBigInt(),
28962
29225
  token1: route.pool_key.token1.toBigInt(),
28963
29226
  fee: route.pool_key.fee,
28964
29227
  tick_spacing: route.pool_key.tick_spacing,
28965
- extension: BigInt(num9.hexToDecimalString(route.pool_key.extension))
29228
+ extension: ContractAddr.from(
29229
+ route.pool_key.extension
29230
+ ).toBigInt()
28966
29231
  },
28967
- sqrt_ratio_limit: uint25612.bnToUint256(route.sqrt_ratio_limit.toWei()),
28968
- skip_ahead: BigInt(0)
29232
+ sqrt_ratio_limit: uint25612.bnToUint256(
29233
+ route.sqrt_ratio_limit.toWei()
29234
+ ),
29235
+ skip_ahead: BigInt(route.skip_ahead.toWei())
28969
29236
  })),
28970
29237
  token_amount: {
28971
29238
  token: swap.token_amount.token.toBigInt(),
28972
29239
  amount: swap.token_amount.amount.toI129()
28973
29240
  }
28974
29241
  })),
28975
- lever_swap_limit_amount: BigInt(_params2.lever_swap_limit_amount.toWei())
28976
- } })
28977
- };
28978
- }
28979
- const _params = params;
28980
- return {
28981
- action: new CairoCustomEnum3({ DecreaseLever: {
28982
- pool_id: _params.pool_id.toBigInt(),
28983
- collateral_asset: _params.collateral_asset.toBigInt(),
28984
- debt_asset: _params.debt_asset.toBigInt(),
28985
- user: _params.user.toBigInt(),
28986
- sub_margin: BigInt(_params.sub_margin.toWei()),
28987
- recipient: _params.recipient.toBigInt(),
28988
- lever_swap: _params.lever_swap.map((swap) => ({
28989
- route: swap.route.map((route) => ({
28990
- pool_key: {
28991
- token0: route.pool_key.token0.toBigInt(),
28992
- token1: route.pool_key.token1.toBigInt(),
28993
- fee: route.pool_key.fee,
28994
- tick_spacing: route.pool_key.tick_spacing,
28995
- extension: ContractAddr.from(route.pool_key.extension).toBigInt()
28996
- },
28997
- sqrt_ratio_limit: uint25612.bnToUint256(route.sqrt_ratio_limit.toWei()),
28998
- skip_ahead: BigInt(route.skip_ahead.toWei())
28999
- })),
29000
- token_amount: {
29001
- token: swap.token_amount.token.toBigInt(),
29002
- amount: swap.token_amount.amount.toI129()
29003
- }
29004
- })),
29005
- lever_swap_limit_amount: BigInt(_params.lever_swap_limit_amount.toWei()),
29006
- lever_swap_weights: _params.lever_swap_weights.map((weight) => BigInt(weight.toWei())),
29007
- withdraw_swap: _params.withdraw_swap.map((swap) => ({
29008
- route: swap.route.map((route) => ({
29009
- pool_key: {
29010
- token0: route.pool_key.token0.toBigInt(),
29011
- token1: route.pool_key.token1.toBigInt(),
29012
- fee: route.pool_key.fee,
29013
- tick_spacing: route.pool_key.tick_spacing,
29014
- extension: ContractAddr.from(route.pool_key.extension).toBigInt()
29015
- },
29016
- sqrt_ratio_limit: uint25612.bnToUint256(route.sqrt_ratio_limit.toWei()),
29017
- skip_ahead: BigInt(route.skip_ahead.toWei())
29018
- })),
29019
- token_amount: {
29020
- token: swap.token_amount.token.toBigInt(),
29021
- amount: swap.token_amount.amount.toI129()
29022
- }
29023
- })),
29024
- withdraw_swap_limit_amount: BigInt(_params.withdraw_swap_limit_amount.toWei()),
29025
- withdraw_swap_weights: _params.withdraw_swap_weights.map((weight) => BigInt(weight.toWei())),
29026
- close_position: _params.close_position
29027
- } })
29242
+ withdraw_swap_limit_amount: BigInt(
29243
+ _params.withdraw_swap_limit_amount.toWei()
29244
+ ),
29245
+ withdraw_swap_weights: _params.withdraw_swap_weights.map(
29246
+ (weight) => BigInt(weight.toWei())
29247
+ ),
29248
+ close_position: _params.close_position
29249
+ }
29250
+ })
29028
29251
  };
29029
29252
  }
29030
29253
  async getHealthFactor() {
@@ -29033,11 +29256,15 @@ var VesuMultiplyAdapter = class _VesuMultiplyAdapter extends BaseAdapter {
29033
29256
  }
29034
29257
  async getNetAPY() {
29035
29258
  const positions = await this.getPositions();
29036
- logger.verbose(`${this.name}::getNetAPY: positions: ${JSON.stringify(positions)}`);
29259
+ logger.verbose(
29260
+ `${this.name}::getNetAPY: positions: ${JSON.stringify(positions)}`
29261
+ );
29037
29262
  const allZero = positions.every((p) => p.usdValue === 0);
29038
29263
  if (allZero) {
29039
29264
  const collateralUSD = 1e3;
29040
- const maxLTV = await this.vesuAdapter.getLTVConfig(this.config.networkConfig);
29265
+ const maxLTV = await this.vesuAdapter.getLTVConfig(
29266
+ this.config.networkConfig
29267
+ );
29041
29268
  const targetHF = this.config.targetHealthFactor;
29042
29269
  const maxDebt = HealthFactorMath.getMaxDebtAmountOnLooping(
29043
29270
  new Web3Number(collateralUSD, this.config.collateral.decimals),
@@ -29180,7 +29407,22 @@ var ExtendedWrapper = class {
29180
29407
  `HTTP ${response.status}: ${errorData.detail || response.statusText}`
29181
29408
  );
29182
29409
  }
29183
- const data = await response.json();
29410
+ const text = await response.text();
29411
+ const MAX_SAFE_INTEGER_STR = "9007199254740991";
29412
+ const largeIntegerRegex = /"data"\s*:\s*(\d{16,})/g;
29413
+ const modifiedText = text.replace(largeIntegerRegex, (match, largeInt) => {
29414
+ if (largeInt.length > MAX_SAFE_INTEGER_STR.length || largeInt.length === MAX_SAFE_INTEGER_STR.length && largeInt > MAX_SAFE_INTEGER_STR) {
29415
+ return `"data":"${largeInt}"`;
29416
+ }
29417
+ return match;
29418
+ });
29419
+ const data = JSON.parse(modifiedText);
29420
+ if (data && typeof data.data === "string" && /^\d+$/.test(data.data)) {
29421
+ const numValue = Number(data.data);
29422
+ if (Number.isSafeInteger(numValue)) {
29423
+ data.data = numValue;
29424
+ }
29425
+ }
29184
29426
  return data;
29185
29427
  } catch (error) {
29186
29428
  lastError = error;
@@ -29240,6 +29482,7 @@ var ExtendedWrapper = class {
29240
29482
  }
29241
29483
  /**
29242
29484
  * Initiate a withdrawal from Extended Exchange
29485
+ * Returns data as number | string to preserve precision for large integers
29243
29486
  */
29244
29487
  async withdraw(request) {
29245
29488
  return this.makeRequest("/api/v1/withdraw", {
@@ -29378,6 +29621,7 @@ var ExtendedWrapper = class {
29378
29621
  }
29379
29622
  /**
29380
29623
  * Withdraw USDC (convenience method)
29624
+ * Returns data as number | string to preserve precision for large integers
29381
29625
  */
29382
29626
  async withdrawUSDC(amount) {
29383
29627
  return this.withdraw({ amount, asset: "USDC" });
@@ -29387,11 +29631,13 @@ var ExtendedWrapper = class {
29387
29631
  * @param marketName - The name of the market to get funding rates for
29388
29632
  * @returns The funding rates for the specified market
29389
29633
  */
29390
- async getFundingRates(marketName, side) {
29634
+ async getFundingRates(marketName, side, startTime, endTime) {
29635
+ const endTimeParam = endTime !== void 0 ? `&end_time=${endTime}` : "";
29636
+ const startTimeParam = startTime !== void 0 ? `&start_time=${startTime}` : "";
29391
29637
  return this.makeRequest(
29392
29638
  `/api/v1/markets/funding-rates?market_name=${encodeURIComponent(
29393
29639
  marketName
29394
- )}&side=${encodeURIComponent(side)}`
29640
+ )}&side=${encodeURIComponent(side)}${startTimeParam}${endTimeParam}`
29395
29641
  );
29396
29642
  }
29397
29643
  };
@@ -29404,18 +29650,20 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29404
29650
  super(config, _ExtendedAdapter.name, Protocols.EXTENDED);
29405
29651
  this.config = config;
29406
29652
  const client = new wrapper_default({
29407
- baseUrl: this.config.extendedBackendUrl,
29408
- apiKey: this.config.extendedApiKey,
29653
+ baseUrl: this.config.extendedBackendWriteUrl,
29654
+ apiKey: "",
29409
29655
  timeout: this.config.extendedTimeout,
29410
29656
  retries: this.config.extendedRetries
29411
29657
  });
29658
+ this.minimumExtendedMovementAmount = this.config.minimumExtendedMovementAmount ?? 5;
29412
29659
  this.client = client;
29660
+ this.retryDelayForOrderStatus = this.config.retryDelayForOrderStatus ?? 3e3;
29413
29661
  }
29414
29662
  //abstract means the method has no implementation in this class; instead, child classes must implement it.
29415
29663
  async getAPY(supportedPosition) {
29416
29664
  const side = supportedPosition.isDebt ? "LONG" : "SHORT";
29417
- const fundingRates = await this.client.getFundingRates(this.config.extendedMarketName, side);
29418
- if (fundingRates.status !== "OK") {
29665
+ const fundingRates = await this.getFundingRates(side);
29666
+ if (!fundingRates.success) {
29419
29667
  logger.error("error getting funding rates", fundingRates);
29420
29668
  return { apy: 0, type: "base" /* BASE */ };
29421
29669
  }
@@ -29423,10 +29671,26 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29423
29671
  const apy = Number(fundingRate.f) * 365 * 24;
29424
29672
  return { apy, type: "base" /* BASE */ };
29425
29673
  }
29426
- async getPosition(supportedPosition) {
29427
- if (!this.client) {
29428
- throw new Error("Client not initialized");
29674
+ async getFundingRates(side, startTime, endTime) {
29675
+ try {
29676
+ const response = await axios8.get(`${this.config.extendedBackendReadUrl}/fundingRates/${this.config.extendedMarketName}/${side}`, {
29677
+ params: {
29678
+ startTime: startTime ? startTime.toString() : void 0,
29679
+ endTime: endTime ? endTime.toString() : void 0
29680
+ }
29681
+ });
29682
+ if (!response.data.success) {
29683
+ logger.error("error getting funding rates", response.data);
29684
+ return { success: false, data: [] };
29685
+ }
29686
+ logger.info("success getting funding rates", response.data.data);
29687
+ return { success: true, data: response.data.data };
29688
+ } catch (err) {
29689
+ logger.error("error getting funding rates", err);
29690
+ return { success: false, data: [] };
29429
29691
  }
29692
+ }
29693
+ async getPosition(supportedPosition) {
29430
29694
  const holdings = await this.getExtendedDepositAmount();
29431
29695
  if (!holdings) {
29432
29696
  throw new Error("No position found");
@@ -29434,7 +29698,7 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29434
29698
  const amount = holdings.equity;
29435
29699
  return Promise.resolve({
29436
29700
  amount: new Web3Number(amount, 0),
29437
- remarks: `${holdings.availableForWithdrawal} ${holdings.equity}`
29701
+ remarks: `Extended Equity`
29438
29702
  });
29439
29703
  }
29440
29704
  async maxDeposit(amount) {
@@ -29458,14 +29722,14 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29458
29722
  });
29459
29723
  }
29460
29724
  _getDepositLeaf() {
29461
- const usdceToken = Global.getDefaultTokens().find((token) => token.symbol === "USDCe");
29725
+ const usdceToken = Global.getDefaultTokens().find(
29726
+ (token) => token.symbol === "USDCe"
29727
+ );
29462
29728
  return [
29463
29729
  {
29464
29730
  target: this.config.supportedPositions[0].asset.address,
29465
29731
  method: "approve",
29466
- packedArguments: [
29467
- AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()
29468
- ],
29732
+ packedArguments: [AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()],
29469
29733
  id: `extended_approve_${this.config.supportedPositions[0].asset.symbol}`,
29470
29734
  sanitizer: AVNU_LEGACY_SANITIZER
29471
29735
  },
@@ -29496,25 +29760,33 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29496
29760
  const leafConfigs = this._getSwapFromLegacyLeaf();
29497
29761
  const leaves = leafConfigs.map((config) => {
29498
29762
  const { target, method, packedArguments, sanitizer, id } = config;
29499
- const leaf = this.constructSimpleLeafData({
29500
- id,
29501
- target,
29502
- method,
29503
- packedArguments
29504
- }, sanitizer);
29763
+ const leaf = this.constructSimpleLeafData(
29764
+ {
29765
+ id,
29766
+ target,
29767
+ method,
29768
+ packedArguments
29769
+ },
29770
+ sanitizer
29771
+ );
29505
29772
  return leaf;
29506
29773
  });
29507
- return { leaves, callConstructor: this.getSwapFromLegacyCall.bind(this) };
29774
+ return {
29775
+ leaves,
29776
+ callConstructor: this.getSwapFromLegacyCall.bind(
29777
+ this
29778
+ )
29779
+ };
29508
29780
  }
29509
29781
  _getSwapFromLegacyLeaf() {
29510
- const usdceToken = Global.getDefaultTokens().find((token) => token.symbol === "USDCe");
29782
+ const usdceToken = Global.getDefaultTokens().find(
29783
+ (token) => token.symbol === "USDCe"
29784
+ );
29511
29785
  return [
29512
29786
  {
29513
29787
  target: usdceToken.address,
29514
29788
  method: "approve",
29515
- packedArguments: [
29516
- AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()
29517
- ],
29789
+ packedArguments: [AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()],
29518
29790
  id: `extendedswaplegacyapprove_${usdceToken.symbol}`,
29519
29791
  sanitizer: AVNU_LEGACY_SANITIZER
29520
29792
  },
@@ -29533,11 +29805,13 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29533
29805
  async getDepositCall(params) {
29534
29806
  try {
29535
29807
  const usdcToken = this.config.supportedPositions[0].asset;
29536
- const usdceToken = Global.getDefaultTokens().find((token) => token.symbol === "USDCe");
29537
- const salt = Math.floor(
29538
- Math.random() * 10 ** usdcToken.decimals
29808
+ const usdceToken = Global.getDefaultTokens().find(
29809
+ (token) => token.symbol === "USDCe"
29810
+ );
29811
+ const salt = Math.floor(Math.random() * 10 ** usdcToken.decimals);
29812
+ const amount = uint25613.bnToUint256(
29813
+ params.amount.multipliedBy(10).toWei()
29539
29814
  );
29540
- const amount = uint25613.bnToUint256(params.amount.multipliedBy(10).toWei());
29541
29815
  const quotes = await this.config.avnuAdapter.getQuotesAvnu(
29542
29816
  usdcToken.address.toString(),
29543
29817
  usdceToken.address.toString(),
@@ -29550,7 +29824,9 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29550
29824
  logger.error("error getting quotes from avnu");
29551
29825
  return [];
29552
29826
  }
29553
- const getCalldata = await this.config.avnuAdapter.getSwapCallData(quotes);
29827
+ const getCalldata = await this.config.avnuAdapter.getSwapCallData(
29828
+ quotes
29829
+ );
29554
29830
  const swapCallData = getCalldata[0];
29555
29831
  return [
29556
29832
  {
@@ -29626,8 +29902,12 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29626
29902
  async getSwapFromLegacyCall(params) {
29627
29903
  try {
29628
29904
  const usdcToken = this.config.supportedPositions[0].asset;
29629
- const usdceToken = Global.getDefaultTokens().find((token) => token.symbol === "USDCe");
29630
- const amount = uint25613.bnToUint256(params.amount.multipliedBy(10).toWei());
29905
+ const usdceToken = Global.getDefaultTokens().find(
29906
+ (token) => token.symbol === "USDCe"
29907
+ );
29908
+ const amount = uint25613.bnToUint256(
29909
+ params.amount.multipliedBy(10).toWei()
29910
+ );
29631
29911
  const quotes = await this.config.avnuAdapter.getQuotesAvnu(
29632
29912
  usdceToken.address.toString(),
29633
29913
  usdcToken.address.toString(),
@@ -29640,7 +29920,9 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29640
29920
  logger.error("error getting quotes from avnu");
29641
29921
  return [];
29642
29922
  }
29643
- const getCalldata = await this.config.avnuAdapter.getSwapCallData(quotes);
29923
+ const getCalldata = await this.config.avnuAdapter.getSwapCallData(
29924
+ quotes
29925
+ );
29644
29926
  const swapCallData = getCalldata[0];
29645
29927
  return [
29646
29928
  {
@@ -29686,38 +29968,131 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29686
29968
  async withdrawFromExtended(amount) {
29687
29969
  try {
29688
29970
  if (!this.client) {
29689
- throw new Error("Client not initialized");
29971
+ logger.error("Client not initialized");
29972
+ return {
29973
+ status: false,
29974
+ receivedTxnHash: false
29975
+ };
29976
+ }
29977
+ if (amount.lessThanOrEqualTo(0)) {
29978
+ logger.error(
29979
+ `Invalid withdrawal amount: ${amount.toNumber()}. Amount must be positive.`
29980
+ );
29981
+ return {
29982
+ status: false,
29983
+ receivedTxnHash: false
29984
+ };
29985
+ }
29986
+ if (amount.lessThanOrEqualTo(this.minimumExtendedMovementAmount)) {
29987
+ logger.warn(
29988
+ `Withdrawal amount ${amount.toNumber()} is below minimum Extended movement amount ${this.minimumExtendedMovementAmount}. Skipping withdrawal.`
29989
+ );
29990
+ return {
29991
+ status: false,
29992
+ receivedTxnHash: false
29993
+ };
29994
+ }
29995
+ const holdings = await this.getExtendedDepositAmount();
29996
+ if (!holdings) {
29997
+ logger.error(
29998
+ "Cannot get holdings - unable to validate withdrawal amount"
29999
+ );
30000
+ return {
30001
+ status: false,
30002
+ receivedTxnHash: false
30003
+ };
30004
+ }
30005
+ const availableForWithdrawal = parseFloat(
30006
+ holdings.availableForWithdrawal
30007
+ );
30008
+ if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
30009
+ logger.error(
30010
+ `Invalid availableForWithdrawal: ${holdings.availableForWithdrawal}. Expected a finite, non-negative number.`
30011
+ );
30012
+ return {
30013
+ status: false,
30014
+ receivedTxnHash: false
30015
+ };
30016
+ }
30017
+ const withdrawalAmount = amount.toNumber();
30018
+ if (withdrawalAmount > availableForWithdrawal) {
30019
+ logger.error(
30020
+ `Withdrawal amount ${withdrawalAmount} exceeds available balance ${availableForWithdrawal}`
30021
+ );
30022
+ return {
30023
+ status: false,
30024
+ receivedTxnHash: false
30025
+ };
29690
30026
  }
29691
- const withdrawalRequest = await this.client.withdrawUSDC(amount.toFixed(2));
30027
+ logger.info(
30028
+ `Withdrawing ${withdrawalAmount} from Extended. Available balance: ${availableForWithdrawal}`
30029
+ );
30030
+ const withdrawalRequest = await this.client.withdrawUSDC(
30031
+ amount.toFixed(2)
30032
+ );
29692
30033
  if (withdrawalRequest.status === "OK") {
29693
- const withdrawalStatus = await this.getDepositOrWithdrawalStatus(withdrawalRequest.data, "WITHDRAWAL" /* WITHDRAWAL */);
29694
- return withdrawalStatus;
30034
+ const withdrawalStatus = await this.getDepositOrWithdrawalStatus(
30035
+ withdrawalRequest.data,
30036
+ "WITHDRAWAL" /* WITHDRAWAL */
30037
+ );
30038
+ return {
30039
+ status: true,
30040
+ receivedTxnHash: withdrawalStatus
30041
+ };
29695
30042
  }
29696
- return false;
30043
+ logger.error(
30044
+ `Withdrawal request failed with status: ${withdrawalRequest.status}`
30045
+ );
30046
+ return {
30047
+ status: false,
30048
+ receivedTxnHash: false
30049
+ };
29697
30050
  } catch (error) {
29698
30051
  logger.error(`Error creating Withdraw Call: ${error}`);
29699
- return false;
30052
+ return {
30053
+ status: false,
30054
+ receivedTxnHash: false
30055
+ };
29700
30056
  }
29701
30057
  }
29702
30058
  async getHealthFactor() {
29703
30059
  return Promise.resolve(1);
29704
30060
  }
29705
30061
  async getExtendedDepositAmount() {
29706
- if (this.client === null) {
29707
- logger.error("error initializing client");
29708
- return void 0;
29709
- }
29710
- const result = await this.client.getHoldings();
29711
- if (!result) {
29712
- logger.error(`error getting holdings: ${result}`);
29713
- return void 0;
29714
- }
29715
- const holdings = result.data;
29716
- if (!holdings) {
29717
- logger.error(`error getting holdings: ${holdings}`);
30062
+ try {
30063
+ const result = await axios8.get(`${this.config.extendedBackendReadUrl}/holdings`);
30064
+ if (!result.data) {
30065
+ logger.error("error getting holdings - API returned null/undefined");
30066
+ return void 0;
30067
+ }
30068
+ if (!result.data.success) {
30069
+ logger.error(
30070
+ `error getting holdings - API returned status: ${result.status}`
30071
+ );
30072
+ return void 0;
30073
+ }
30074
+ const holdings = result.data.data;
30075
+ if (!holdings) {
30076
+ logger.warn(
30077
+ "holdings data is null/undefined - treating as zero balance"
30078
+ );
30079
+ return {
30080
+ collateral_name: "",
30081
+ balance: "0",
30082
+ equity: "0",
30083
+ availableForTrade: "0",
30084
+ availableForWithdrawal: "0",
30085
+ unrealisedPnl: "0",
30086
+ initialMargin: "0",
30087
+ marginRatio: "0",
30088
+ updatedTime: Date.now()
30089
+ };
30090
+ }
30091
+ return holdings;
30092
+ } catch (error) {
30093
+ logger.error(`error getting holdings - exception: ${error}`);
29718
30094
  return void 0;
29719
30095
  }
29720
- return holdings;
29721
30096
  }
29722
30097
  async setLeverage(leverage, marketName) {
29723
30098
  if (this.client === null) {
@@ -29734,46 +30109,52 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29734
30109
  return false;
29735
30110
  }
29736
30111
  async getAllOpenPositions() {
29737
- if (this.client === null) {
29738
- logger.error("error initializing client");
29739
- return null;
29740
- }
29741
- const response = await this.client.getPositionsForMarket(
29742
- this.config.extendedMarketName
29743
- );
29744
- if (response.status === "OK") {
29745
- if (response.data.length === 0) {
29746
- return [];
29747
- } else {
29748
- return response.data;
30112
+ try {
30113
+ const response = await axios8.get(`${this.config.extendedBackendReadUrl}/positions`);
30114
+ if (response.data.success) {
30115
+ if (response.data.data.length === 0) {
30116
+ return [];
30117
+ } else {
30118
+ return response.data.data;
30119
+ }
29749
30120
  }
30121
+ return null;
30122
+ } catch (err) {
30123
+ logger.error("error getting all open positions", err);
30124
+ return null;
29750
30125
  }
29751
- return null;
29752
30126
  }
29753
30127
  async getOrderHistory(marketName) {
29754
- if (this.client === null) {
29755
- logger.error("error initializing client");
30128
+ try {
30129
+ const result = await axios8.get(`${this.config.extendedBackendReadUrl}/marketOrders/${marketName}`);
30130
+ if (!result.data.success) {
30131
+ return null;
30132
+ }
30133
+ return result.data.data;
30134
+ } catch (err) {
30135
+ logger.error("error getting order history", err);
29756
30136
  return null;
29757
30137
  }
29758
- const result = await this.client.getOrderHistory(marketName);
29759
- return result.data;
29760
30138
  }
29761
30139
  async getOrderStatus(orderId, marketName) {
29762
- if (this.client === null) {
29763
- logger.error("error initializing client");
29764
- return null;
29765
- }
29766
- const orderhistory = await this.getOrderHistory(marketName);
29767
- if (!orderhistory || orderhistory.length === 0) {
29768
- logger.error(`error getting order: ${orderId}`);
30140
+ try {
30141
+ if (this.client === null) {
30142
+ logger.error("error initializing client");
30143
+ return null;
30144
+ }
30145
+ const orderhistory = await this.getOrderHistory(marketName);
30146
+ if (!orderhistory || orderhistory.length === 0) {
30147
+ return null;
30148
+ }
30149
+ const order = orderhistory.slice(0, 20).find((order2) => order2.id.toString() === orderId);
30150
+ if (order) {
30151
+ return order;
30152
+ }
29769
30153
  return null;
29770
- }
29771
- const order = orderhistory.slice(0, 3).find((order2) => order2.id.toString() === orderId);
29772
- if (!order) {
29773
- logger.error(`error getting order: ${order}`);
30154
+ } catch (error) {
30155
+ logger.error(`error getting order status: ${error}`);
29774
30156
  return null;
29775
30157
  }
29776
- return order;
29777
30158
  }
29778
30159
  async fetchOrderBookBTCUSDC() {
29779
30160
  try {
@@ -29824,14 +30205,40 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29824
30205
  logger.error("error depositing or setting leverage");
29825
30206
  return null;
29826
30207
  }
29827
- const positions = await this.getAllOpenPositions();
29828
- if (positions === null) {
30208
+ const { ask, bid } = await this.fetchOrderBookBTCUSDC();
30209
+ if (!ask || !bid || ask.lessThanOrEqualTo(0) || bid.lessThanOrEqualTo(0)) {
30210
+ logger.error(
30211
+ `Invalid orderbook prices: ask=${ask?.toNumber()}, bid=${bid?.toNumber()}`
30212
+ );
29829
30213
  return null;
29830
30214
  }
29831
- const { ask, bid } = await this.fetchOrderBookBTCUSDC();
29832
30215
  const spread = ask.minus(bid);
29833
- let price = ask.plus(bid).div(2);
29834
- side === "SELL" /* SELL */ ? price = price.minus(spread.times(0.2 * attempt)) : price = price.plus(spread.times(0.2 * attempt));
30216
+ const midPrice = ask.plus(bid).div(2);
30217
+ const MAX_PRICE_DEVIATION_MULTIPLIER = 0.5;
30218
+ const priceAdjustmentMultiplier = Math.min(
30219
+ 0.2 * attempt,
30220
+ MAX_PRICE_DEVIATION_MULTIPLIER
30221
+ );
30222
+ const priceAdjustment = spread.times(priceAdjustmentMultiplier);
30223
+ let price = midPrice;
30224
+ if (side === "SELL" /* SELL */) {
30225
+ price = midPrice.minus(priceAdjustment);
30226
+ } else {
30227
+ price = midPrice.plus(priceAdjustment);
30228
+ }
30229
+ const maxDeviation = midPrice.times(0.5);
30230
+ if (price.minus(midPrice).abs().greaterThan(maxDeviation)) {
30231
+ logger.error(
30232
+ `Price deviation too large on attempt ${attempt}: price=${price.toNumber()}, midPrice=${midPrice.toNumber()}, deviation=${price.minus(midPrice).abs().toNumber()}`
30233
+ );
30234
+ if (attempt >= maxAttempts) {
30235
+ return null;
30236
+ }
30237
+ price = side === "SELL" /* SELL */ ? midPrice.minus(maxDeviation) : midPrice.plus(maxDeviation);
30238
+ }
30239
+ logger.info(
30240
+ `createOrder attempt ${attempt}/${maxAttempts}: side=${side}, midPrice=${midPrice.toNumber()}, adjustedPrice=${price.toNumber()}, adjustment=${priceAdjustmentMultiplier * 100}%`
30241
+ );
29835
30242
  const amount_in_token = (btcAmount * parseInt(leverage)).toFixed(
29836
30243
  this.config.extendedPrecision
29837
30244
  );
@@ -29842,14 +30249,57 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29842
30249
  price.toFixed(0),
29843
30250
  side
29844
30251
  );
29845
- if (!result) {
30252
+ if (!result || !result.position_id) {
30253
+ logger.error("Failed to create order - no position_id returned");
29846
30254
  return null;
29847
30255
  }
29848
- await new Promise((resolve) => setTimeout(resolve, 5e3));
29849
- const openOrder = await this.getOrderStatus(result.position_id, this.config.extendedMarketName);
29850
- if (!openOrder || openOrder.status !== "FILLED" /* FILLED */) {
30256
+ const positionId = result.position_id;
30257
+ logger.info(
30258
+ `Order created with position_id: ${positionId}. Waiting for API to update...`
30259
+ );
30260
+ let openOrder = await this.getOrderStatus(
30261
+ positionId,
30262
+ this.config.extendedMarketName
30263
+ );
30264
+ const maxStatusRetries = 3;
30265
+ const statusRetryDelay = 5e3;
30266
+ if (!openOrder) {
30267
+ logger.warn(
30268
+ `Order ${positionId} not found in API yet. Retrying status fetch (max ${maxStatusRetries} times)...`
30269
+ );
30270
+ for (let statusRetry = 1; statusRetry <= maxStatusRetries; statusRetry++) {
30271
+ await new Promise((resolve) => setTimeout(resolve, statusRetryDelay));
30272
+ openOrder = await this.getOrderStatus(
30273
+ positionId,
30274
+ this.config.extendedMarketName
30275
+ );
30276
+ if (openOrder) {
30277
+ logger.info(
30278
+ `Order ${positionId} found after ${statusRetry} status retry(ies)`
30279
+ );
30280
+ break;
30281
+ }
30282
+ logger.warn(
30283
+ `Order ${positionId} still not found after ${statusRetry}/${maxStatusRetries} status retries`
30284
+ );
30285
+ }
30286
+ }
30287
+ if (openOrder && openOrder.status === "FILLED" /* FILLED */) {
30288
+ logger.info(
30289
+ `Order ${positionId} successfully filled with quantity ${openOrder.qty}`
30290
+ );
30291
+ return {
30292
+ position_id: positionId,
30293
+ btc_exposure: openOrder.qty
30294
+ };
30295
+ } else if (openOrder && openOrder.status !== "FILLED" /* FILLED */) {
30296
+ logger.warn(
30297
+ `Order ${positionId} found but status is ${openOrder.status}, not FILLED. Retrying order creation...`
30298
+ );
29851
30299
  if (attempt >= maxAttempts) {
29852
- logger.error("Max retries reached \u2014 could not verify open position");
30300
+ logger.error(
30301
+ `Max retries reached \u2014 order ${positionId} status is ${openOrder.status}, not FILLED`
30302
+ );
29853
30303
  return null;
29854
30304
  } else {
29855
30305
  const backoff = 2e3 * attempt;
@@ -29863,13 +30313,18 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29863
30313
  );
29864
30314
  }
29865
30315
  } else {
30316
+ logger.warn(
30317
+ `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.`
30318
+ );
29866
30319
  return {
29867
- position_id: result.position_id,
29868
- btc_exposure: openOrder.qty
30320
+ position_id: positionId,
30321
+ btc_exposure: amount_in_token
29869
30322
  };
29870
30323
  }
29871
30324
  } catch (err) {
29872
- logger.error(`createShortOrder failed on attempt ${attempt}: ${err.message}`);
30325
+ logger.error(
30326
+ `createShortOrder failed on attempt ${attempt}: ${err.message}`
30327
+ );
29873
30328
  if (attempt < maxAttempts) {
29874
30329
  const backoff = 1200 * attempt;
29875
30330
  logger.info(`Retrying after ${backoff}ms...`);
@@ -29908,28 +30363,101 @@ var ExtendedAdapter = class _ExtendedAdapter extends BaseAdapter {
29908
30363
  }
29909
30364
  }
29910
30365
  async getDepositOrWithdrawalStatus(orderId, operationsType) {
29911
- try {
29912
- let transferHistory = await this.client.getAssetOperations({
29913
- operationsType: [operationsType],
29914
- operationsStatus: ["COMPLETED" /* COMPLETED */]
29915
- });
29916
- if (operationsType === "DEPOSIT" /* DEPOSIT */) {
29917
- const myTransferStatus = transferHistory.data.find((operation) => operation.transactionHash === orderId);
29918
- if (!myTransferStatus) {
29919
- return true;
30366
+ const maxAttempts = 15;
30367
+ const retryDelayMs = 3e4;
30368
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
30369
+ try {
30370
+ let transferHistory = await this.client.getAssetOperations({
30371
+ operationsType: [operationsType],
30372
+ operationsStatus: ["COMPLETED" /* COMPLETED */]
30373
+ });
30374
+ if (operationsType === "DEPOSIT" /* DEPOSIT */) {
30375
+ const myTransferStatus = transferHistory.data.find(
30376
+ (operation) => operation.transactionHash?.toLowerCase() === orderId.toString().toLowerCase()
30377
+ );
30378
+ if (!myTransferStatus) {
30379
+ if (attempt < maxAttempts) {
30380
+ logger.info(
30381
+ `Deposit operation not found for transactionHash ${orderId}, retrying (attempt ${attempt}/${maxAttempts})...`
30382
+ );
30383
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
30384
+ continue;
30385
+ }
30386
+ logger.warn(
30387
+ `Deposit operation not found for transactionHash ${orderId} after ${maxAttempts} attempts`
30388
+ );
30389
+ return false;
30390
+ }
30391
+ if (myTransferStatus.status === "COMPLETED" /* COMPLETED */) {
30392
+ logger.info(
30393
+ `Deposit operation ${orderId} completed successfully`
30394
+ );
30395
+ return true;
30396
+ } else {
30397
+ if (attempt < maxAttempts) {
30398
+ logger.info(
30399
+ `Deposit operation ${orderId} found but status is ${myTransferStatus.status}, not COMPLETED. Retrying (attempt ${attempt}/${maxAttempts})...`
30400
+ );
30401
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
30402
+ continue;
30403
+ }
30404
+ logger.warn(
30405
+ `Deposit operation ${orderId} status is ${myTransferStatus.status} after ${maxAttempts} attempts, expected COMPLETED`
30406
+ );
30407
+ return false;
30408
+ }
30409
+ } else {
30410
+ const myTransferStatus = transferHistory.data.find(
30411
+ (operation) => operation.id === orderId.toString()
30412
+ );
30413
+ if (!myTransferStatus) {
30414
+ if (attempt < maxAttempts) {
30415
+ logger.info(
30416
+ `Withdrawal status not found for orderId ${orderId} in completed operations, retrying (attempt ${attempt}/${maxAttempts})...`
30417
+ );
30418
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
30419
+ continue;
30420
+ }
30421
+ logger.warn(
30422
+ `Withdrawal operation not found for orderId ${orderId} after ${maxAttempts} attempts`
30423
+ );
30424
+ return false;
30425
+ }
30426
+ if (myTransferStatus.status === "COMPLETED" /* COMPLETED */) {
30427
+ logger.info(
30428
+ `Withdrawal operation ${orderId} completed successfully`
30429
+ );
30430
+ return true;
30431
+ } else {
30432
+ if (attempt < maxAttempts) {
30433
+ logger.info(
30434
+ `Withdrawal operation ${orderId} found but status is ${myTransferStatus.status}, not COMPLETED. Retrying (attempt ${attempt}/${maxAttempts})...`
30435
+ );
30436
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
30437
+ continue;
30438
+ }
30439
+ logger.warn(
30440
+ `Withdrawal operation ${orderId} status is ${myTransferStatus.status} after ${maxAttempts} attempts, expected COMPLETED`
30441
+ );
30442
+ return false;
30443
+ }
29920
30444
  }
29921
- return true;
29922
- } else {
29923
- const myTransferStatus = transferHistory.data.find((operation) => operation.id.toString() === orderId.toString());
29924
- if (!myTransferStatus) {
29925
- return true;
30445
+ } catch (err) {
30446
+ logger.error(
30447
+ `error getting deposit or withdrawal status (attempt ${attempt}/${maxAttempts}): ${err}`
30448
+ );
30449
+ if (attempt < maxAttempts) {
30450
+ logger.info(`Retrying after ${retryDelayMs}ms...`);
30451
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
30452
+ continue;
29926
30453
  }
29927
- return true;
30454
+ logger.error(
30455
+ `Max retry attempts reached for getDepositOrWithdrawalStatus`
30456
+ );
30457
+ return false;
29928
30458
  }
29929
- } catch (err) {
29930
- logger.error(`error getting deposit or withdrawal status: ${err}`);
29931
- return false;
29932
30459
  }
30460
+ return false;
29933
30461
  }
29934
30462
  };
29935
30463
 
@@ -30009,12 +30537,351 @@ var UnusedBalanceAdapter = class _UnusedBalanceAdapter extends BaseAdapter {
30009
30537
  }
30010
30538
  };
30011
30539
 
30540
+ // src/strategies/universal-adapters/avnu-adapter.ts
30541
+ import { hash as hash7, uint256 as uint25614 } from "starknet";
30542
+ import axios9 from "axios";
30543
+ var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
30544
+ constructor(config) {
30545
+ super(config, _AvnuAdapter.name, Protocols.AVNU);
30546
+ this.config = config;
30547
+ this.avnuWrapper = new AvnuWrapper();
30548
+ }
30549
+ //abstract means the method has no implementation in this class; instead, child classes must implement it.
30550
+ async getAPY(supportedPosition) {
30551
+ return Promise.resolve({ apy: 0, type: "base" /* BASE */ });
30552
+ }
30553
+ async getPosition(supportedPosition) {
30554
+ return Promise.resolve({ amount: new Web3Number(0, 0), remarks: "Avnu Positions" });
30555
+ }
30556
+ async maxDeposit(amount) {
30557
+ return Promise.resolve({
30558
+ tokenInfo: this.config.baseToken,
30559
+ amount: new Web3Number(0, 0),
30560
+ usdValue: 0,
30561
+ apy: { apy: 0, type: "base" /* BASE */ },
30562
+ protocol: Protocols.AVNU,
30563
+ remarks: ""
30564
+ });
30565
+ }
30566
+ async maxWithdraw() {
30567
+ return Promise.resolve({
30568
+ tokenInfo: this.config.baseToken,
30569
+ amount: new Web3Number(0, 0),
30570
+ usdValue: 0,
30571
+ apy: { apy: 0, type: "base" /* BASE */ },
30572
+ protocol: Protocols.AVNU,
30573
+ remarks: ""
30574
+ });
30575
+ }
30576
+ _getDepositLeaf() {
30577
+ const vaultAllocator = ContractAddr.from(
30578
+ this.config.vaultAllocator.address
30579
+ );
30580
+ return [
30581
+ {
30582
+ target: this.config.supportedPositions[0].asset.address,
30583
+ method: "approve",
30584
+ packedArguments: [
30585
+ AVNU_EXCHANGE.toBigInt()
30586
+ ],
30587
+ sanitizer: SIMPLE_SANITIZER,
30588
+ id: `approve_${this.config.supportedPositions[0].asset.symbol}`
30589
+ },
30590
+ {
30591
+ target: AVNU_EXCHANGE,
30592
+ method: "multi_route_swap",
30593
+ packedArguments: [
30594
+ this.config.supportedPositions[0].asset.address.toBigInt(),
30595
+ //usdc
30596
+ this.config.supportedPositions[1].asset.address.toBigInt(),
30597
+ //wbtc
30598
+ vaultAllocator.toBigInt()
30599
+ ],
30600
+ sanitizer: SIMPLE_SANITIZER,
30601
+ id: `asutb_${this.config.supportedPositions[0].asset.symbol}_${this.config.supportedPositions[1].asset.symbol}`
30602
+ }
30603
+ ];
30604
+ }
30605
+ _getWithdrawLeaf() {
30606
+ const vaultAllocator = ContractAddr.from(
30607
+ this.config.vaultAllocator.address
30608
+ );
30609
+ const toToken = this.config.supportedPositions[0].asset;
30610
+ const fromToken = this.config.supportedPositions[1].asset;
30611
+ return [
30612
+ {
30613
+ target: fromToken.address,
30614
+ method: "approve",
30615
+ packedArguments: [
30616
+ AVNU_EXCHANGE.toBigInt()
30617
+ ],
30618
+ sanitizer: SIMPLE_SANITIZER,
30619
+ id: `approve_${fromToken.symbol}`
30620
+ },
30621
+ {
30622
+ target: AVNU_EXCHANGE,
30623
+ method: "multi_route_swap",
30624
+ packedArguments: [
30625
+ fromToken.address.toBigInt(),
30626
+ //wbtc
30627
+ toToken.address.toBigInt(),
30628
+ //usdc
30629
+ vaultAllocator.toBigInt()
30630
+ ],
30631
+ sanitizer: SIMPLE_SANITIZER,
30632
+ id: `asbtu_${fromToken.symbol}_${fromToken.symbol}`
30633
+ }
30634
+ ];
30635
+ }
30636
+ _getLegacySwapLeaf() {
30637
+ return [];
30638
+ }
30639
+ async getDepositCall(params) {
30640
+ try {
30641
+ const fromToken = this.config.supportedPositions[0].asset;
30642
+ const toToken = this.config.supportedPositions[1].asset;
30643
+ const vaultAllocator = ContractAddr.from(
30644
+ this.config.vaultAllocator.address
30645
+ );
30646
+ const quote = await this.getQuotesAvnu(
30647
+ fromToken.address.toString(),
30648
+ toToken.address.toString(),
30649
+ params.amount.toNumber(),
30650
+ vaultAllocator.address.toString(),
30651
+ toToken.decimals,
30652
+ true
30653
+ );
30654
+ if (!quote) {
30655
+ logger.error("error getting quote from avnu");
30656
+ return [];
30657
+ }
30658
+ const getCalldata = await this.avnuWrapper.getSwapCallData(
30659
+ quote,
30660
+ vaultAllocator.address
30661
+ );
30662
+ const swapCallData = getCalldata[0];
30663
+ const amount = uint25614.bnToUint256(quote.sellAmountInUsd * 10 ** 7);
30664
+ return [
30665
+ {
30666
+ sanitizer: SIMPLE_SANITIZER,
30667
+ call: {
30668
+ contractAddress: fromToken.address,
30669
+ selector: hash7.getSelectorFromName("approve"),
30670
+ calldata: [
30671
+ AVNU_EXCHANGE.toBigInt(),
30672
+ toBigInt(amount.low.toString()),
30673
+ // amount low
30674
+ toBigInt(amount.high.toString())
30675
+ // amount high
30676
+ ]
30677
+ }
30678
+ },
30679
+ {
30680
+ sanitizer: SIMPLE_SANITIZER,
30681
+ call: {
30682
+ contractAddress: AVNU_EXCHANGE,
30683
+ selector: hash7.getSelectorFromName("multi_route_swap"),
30684
+ calldata: swapCallData
30685
+ }
30686
+ }
30687
+ ];
30688
+ } catch (error) {
30689
+ logger.error(`Error getting Avnu quote: ${error}`);
30690
+ return [];
30691
+ }
30692
+ }
30693
+ //Swap wbtc to usdc
30694
+ async getWithdrawCall(params) {
30695
+ try {
30696
+ const toToken = this.config.supportedPositions[0].asset;
30697
+ const fromToken = this.config.supportedPositions[1].asset;
30698
+ const vaultAllocator = ContractAddr.from(
30699
+ this.config.vaultAllocator.address
30700
+ );
30701
+ const quote = await this.getQuotesAvnu(
30702
+ fromToken.address.toString(),
30703
+ toToken.address.toString(),
30704
+ params.amount.toNumber(),
30705
+ vaultAllocator.address.toString(),
30706
+ fromToken.decimals,
30707
+ false
30708
+ );
30709
+ if (!quote) {
30710
+ logger.error("No quotes available for this swap, error in quotes avnu");
30711
+ return [];
30712
+ }
30713
+ const getCalldata = await this.avnuWrapper.getSwapCallData(
30714
+ quote,
30715
+ vaultAllocator.address
30716
+ );
30717
+ const swapCallData = getCalldata[0];
30718
+ const amount = uint25614.bnToUint256(params.amount.toWei());
30719
+ return [
30720
+ {
30721
+ sanitizer: SIMPLE_SANITIZER,
30722
+ call: {
30723
+ contractAddress: fromToken.address,
30724
+ selector: hash7.getSelectorFromName("approve"),
30725
+ calldata: [
30726
+ AVNU_EXCHANGE.toBigInt(),
30727
+ toBigInt(amount.low.toString()),
30728
+ // amount low
30729
+ toBigInt(amount.high.toString())
30730
+ // amount high
30731
+ ]
30732
+ }
30733
+ },
30734
+ {
30735
+ sanitizer: SIMPLE_SANITIZER,
30736
+ call: {
30737
+ contractAddress: AVNU_EXCHANGE,
30738
+ selector: hash7.getSelectorFromName("multi_route_swap"),
30739
+ calldata: swapCallData
30740
+ }
30741
+ }
30742
+ ];
30743
+ } catch (error) {
30744
+ logger.error(`Error getting Avnu quote: ${error}`);
30745
+ return [];
30746
+ }
30747
+ }
30748
+ async getSwapCallData(quote) {
30749
+ return await this.avnuWrapper.getSwapCallData(quote, this.config.vaultAllocator.address);
30750
+ }
30751
+ async getHealthFactor() {
30752
+ return Promise.resolve(1);
30753
+ }
30754
+ async fetchQuoteWithRetry(params, retries = 5) {
30755
+ for (let attempt = 0; attempt < retries; attempt++) {
30756
+ try {
30757
+ const response = await axios9.get(this.config.baseUrl, { params });
30758
+ if (response.data && response.data.length > 0) {
30759
+ return response;
30760
+ }
30761
+ throw new Error("Empty response data");
30762
+ } catch (err) {
30763
+ logger.error(`Error fetching quote with retry: ${err}`);
30764
+ if (attempt === retries - 1) {
30765
+ throw err;
30766
+ }
30767
+ await new Promise((resolve) => setTimeout(resolve, MAX_DELAY));
30768
+ }
30769
+ }
30770
+ throw new Error("Failed to fetch quote after retries");
30771
+ }
30772
+ async getQuotesAvnu(from_token_address, to_token_address, amount, takerAddress, toTokenDecimals, usdcToBtc, maxIterations = 5, tolerance = 5e3) {
30773
+ try {
30774
+ const fromToken = this.config.supportedPositions[0].asset;
30775
+ const toToken = this.config.supportedPositions[1].asset;
30776
+ if (!usdcToBtc) {
30777
+ const sellAmount2 = returnFormattedAmount(amount, toTokenDecimals);
30778
+ const params2 = {
30779
+ sellTokenAddress: from_token_address,
30780
+ buyTokenAddress: to_token_address,
30781
+ takerAddress,
30782
+ sellAmount: sellAmount2
30783
+ };
30784
+ const finalQuote2 = await this.fetchQuoteWithRetry(params2);
30785
+ if (!finalQuote2.data.length) {
30786
+ logger.error("No quotes available for this swap, error in quotes avnu");
30787
+ return null;
30788
+ }
30789
+ const dataObject2 = finalQuote2.data[0];
30790
+ return dataObject2;
30791
+ }
30792
+ const btcPrice = await this.getPriceOfToken(toToken.address.toString());
30793
+ if (!btcPrice) {
30794
+ logger.error(`error getting btc price: ${btcPrice}`);
30795
+ return null;
30796
+ }
30797
+ const estimatedUsdcAmount = Math.floor(amount * btcPrice);
30798
+ logger.info(`${_AvnuAdapter.name}::getQuotesAvnu estimatedUsdcAmount: ${estimatedUsdcAmount}`);
30799
+ const targetBtcBig = BigInt(returnFormattedAmount(amount, toTokenDecimals));
30800
+ logger.info(`${_AvnuAdapter.name}::getQuotesAvnu targetBtcBig: ${targetBtcBig}`);
30801
+ let low = BigInt(
30802
+ Math.floor(
30803
+ estimatedUsdcAmount * 10 ** fromToken.decimals * 0.9
30804
+ )
30805
+ );
30806
+ let high = BigInt(
30807
+ Math.floor(
30808
+ estimatedUsdcAmount * 10 ** fromToken.decimals * 1.1
30809
+ )
30810
+ );
30811
+ let mid = 0n;
30812
+ for (let i = 0; i < maxIterations; i++) {
30813
+ mid = (low + high) / 2n;
30814
+ const sellAmount2 = returnFormattedAmount(Number(mid), 0);
30815
+ const quote = await this.fetchQuoteWithRetry({
30816
+ sellTokenAddress: from_token_address,
30817
+ buyTokenAddress: to_token_address,
30818
+ takerAddress,
30819
+ sellAmount: sellAmount2
30820
+ });
30821
+ const gotBtc = BigInt(quote.data[0].buyAmount);
30822
+ if (gotBtc === targetBtcBig) return quote.data[0];
30823
+ if (gotBtc > targetBtcBig) {
30824
+ high = mid;
30825
+ } else {
30826
+ low = mid;
30827
+ }
30828
+ if (gotBtc >= targetBtcBig && gotBtc <= targetBtcBig + BigInt(tolerance)) {
30829
+ return quote.data[0];
30830
+ }
30831
+ }
30832
+ let sellAmount = returnFormattedAmount(
30833
+ Number(mid),
30834
+ 0
30835
+ );
30836
+ const params = {
30837
+ sellTokenAddress: from_token_address,
30838
+ buyTokenAddress: to_token_address,
30839
+ takerAddress,
30840
+ sellAmount
30841
+ };
30842
+ const finalQuote = await this.fetchQuoteWithRetry(params);
30843
+ if (!finalQuote.data.length) {
30844
+ logger.error("No quotes available for this swap, error in quotes avnu");
30845
+ return null;
30846
+ }
30847
+ const dataObject = finalQuote.data[0];
30848
+ const wbtcAmountOut = parseInt(dataObject.buyAmount.toString(), 16);
30849
+ logger.info(`${_AvnuAdapter.name}::getQuotesAvnu finalAmountOfWbtcOut : ${wbtcAmountOut} ${dataObject.buyAmount} ${dataObject.sellAmount.toString()} ${dataObject.sellAmount.toString()}`);
30850
+ return dataObject;
30851
+ } catch (err) {
30852
+ logger.error(`No quotes available for this swap: ${err}`);
30853
+ return null;
30854
+ }
30855
+ }
30856
+ async getPriceOfToken(tokenAddress, retries = MAX_RETRIES) {
30857
+ try {
30858
+ const url = `https://starknet.impulse.avnu.fi/v1/tokens/${tokenAddress}/prices/line`;
30859
+ const response = await axios9.get(url);
30860
+ const length = response.data.length;
30861
+ return response.data[length - 1].value;
30862
+ } catch (err) {
30863
+ if (retries > 0) {
30864
+ await new Promise((resolve) => setTimeout(resolve, MAX_DELAY));
30865
+ return this.getPriceOfToken(tokenAddress, retries - 1);
30866
+ } else {
30867
+ logger.error(`Failed to fetch price for ${tokenAddress} after ${MAX_RETRIES} attempts`);
30868
+ return null;
30869
+ }
30870
+ }
30871
+ }
30872
+ };
30873
+
30012
30874
  // src/strategies/universal-strategy.tsx
30013
30875
  var AUMTypes = /* @__PURE__ */ ((AUMTypes2) => {
30014
30876
  AUMTypes2["FINALISED"] = "finalised";
30015
30877
  AUMTypes2["DEFISPRING"] = "defispring";
30016
30878
  return AUMTypes2;
30017
30879
  })(AUMTypes || {});
30880
+ var PositionTypeAvnuExtended = /* @__PURE__ */ ((PositionTypeAvnuExtended2) => {
30881
+ PositionTypeAvnuExtended2["OPEN"] = "open";
30882
+ PositionTypeAvnuExtended2["CLOSE"] = "close";
30883
+ return PositionTypeAvnuExtended2;
30884
+ })(PositionTypeAvnuExtended || {});
30018
30885
  var UNIVERSAL_MANAGE_IDS = /* @__PURE__ */ ((UNIVERSAL_MANAGE_IDS2) => {
30019
30886
  UNIVERSAL_MANAGE_IDS2["FLASH_LOAN"] = "flash_loan_init";
30020
30887
  UNIVERSAL_MANAGE_IDS2["VESU_LEG1"] = "vesu_leg1";
@@ -33195,7 +34062,8 @@ function getLooperSettings(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
33195
34062
  minHealthFactor: vaultSettings.minHealthFactor,
33196
34063
  quoteAmountToFetchPrice: vaultSettings.quoteAmountToFetchPrice,
33197
34064
  ...baseAdapterConfig,
33198
- supportedPositions: [{ asset: lstToken, isDebt: false }, { asset: Global.getDefaultTokens().find((token) => token.symbol === position), isDebt: true }]
34065
+ supportedPositions: [{ asset: lstToken, isDebt: false }, { asset: Global.getDefaultTokens().find((token) => token.symbol === position), isDebt: true }],
34066
+ minimumVesuMovementAmount: 0
33199
34067
  }));
33200
34068
  const unusedBalanceAdapter = new UnusedBalanceAdapter({
33201
34069
  ...baseAdapterConfig
@@ -33424,335 +34292,15 @@ var HyperLSTStrategies = [
33424
34292
  getStrategySettings("mRe7YIELD", "mRe7YIELD", hypermRe7YIELD, false, false)
33425
34293
  ];
33426
34294
 
33427
- // src/strategies/universal-adapters/avnu-adapter.ts
33428
- import { hash as hash7, uint256 as uint25614 } from "starknet";
33429
- import axios9 from "axios";
33430
- var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
33431
- constructor(config) {
33432
- super(config, _AvnuAdapter.name, Protocols.AVNU);
33433
- this.config = config;
33434
- this.avnuWrapper = new AvnuWrapper();
33435
- }
33436
- //abstract means the method has no implementation in this class; instead, child classes must implement it.
33437
- async getAPY(supportedPosition) {
33438
- return Promise.resolve({ apy: 0, type: "base" /* BASE */ });
33439
- }
33440
- async getPosition(supportedPosition) {
33441
- return Promise.resolve({ amount: new Web3Number(0, 0), remarks: "" });
33442
- }
33443
- async maxDeposit(amount) {
33444
- return Promise.resolve({
33445
- tokenInfo: this.config.baseToken,
33446
- amount: new Web3Number(0, 0),
33447
- usdValue: 0,
33448
- apy: { apy: 0, type: "base" /* BASE */ },
33449
- protocol: Protocols.AVNU,
33450
- remarks: ""
33451
- });
33452
- }
33453
- async maxWithdraw() {
33454
- return Promise.resolve({
33455
- tokenInfo: this.config.baseToken,
33456
- amount: new Web3Number(0, 0),
33457
- usdValue: 0,
33458
- apy: { apy: 0, type: "base" /* BASE */ },
33459
- protocol: Protocols.AVNU,
33460
- remarks: ""
33461
- });
33462
- }
33463
- _getDepositLeaf() {
33464
- const vaultAllocator = ContractAddr.from(
33465
- this.config.vaultAllocator.address
33466
- );
33467
- return [
33468
- {
33469
- target: this.config.supportedPositions[0].asset.address,
33470
- method: "approve",
33471
- packedArguments: [
33472
- AVNU_EXCHANGE.toBigInt()
33473
- ],
33474
- sanitizer: SIMPLE_SANITIZER,
33475
- id: `approve_${this.config.supportedPositions[0].asset.symbol}`
33476
- },
33477
- {
33478
- target: AVNU_EXCHANGE,
33479
- method: "multi_route_swap",
33480
- packedArguments: [
33481
- this.config.supportedPositions[0].asset.address.toBigInt(),
33482
- //usdc
33483
- this.config.supportedPositions[1].asset.address.toBigInt(),
33484
- //wbtc
33485
- vaultAllocator.toBigInt()
33486
- ],
33487
- sanitizer: SIMPLE_SANITIZER,
33488
- id: `asutb_${this.config.supportedPositions[0].asset.symbol}_${this.config.supportedPositions[1].asset.symbol}`
33489
- }
33490
- ];
33491
- }
33492
- _getWithdrawLeaf() {
33493
- const vaultAllocator = ContractAddr.from(
33494
- this.config.vaultAllocator.address
33495
- );
33496
- const toToken = this.config.supportedPositions[0].asset;
33497
- const fromToken = this.config.supportedPositions[1].asset;
33498
- return [
33499
- {
33500
- target: fromToken.address,
33501
- method: "approve",
33502
- packedArguments: [
33503
- AVNU_EXCHANGE.toBigInt()
33504
- ],
33505
- sanitizer: SIMPLE_SANITIZER,
33506
- id: `approve_${fromToken.symbol}`
33507
- },
33508
- {
33509
- target: AVNU_EXCHANGE,
33510
- method: "multi_route_swap",
33511
- packedArguments: [
33512
- fromToken.address.toBigInt(),
33513
- //wbtc
33514
- toToken.address.toBigInt(),
33515
- //usdc
33516
- vaultAllocator.toBigInt()
33517
- ],
33518
- sanitizer: SIMPLE_SANITIZER,
33519
- id: `asbtu_${fromToken.symbol}_${fromToken.symbol}`
33520
- }
33521
- ];
33522
- }
33523
- _getLegacySwapLeaf() {
33524
- return [];
33525
- }
33526
- async getDepositCall(params) {
33527
- try {
33528
- const fromToken = this.config.supportedPositions[0].asset;
33529
- const toToken = this.config.supportedPositions[1].asset;
33530
- const vaultAllocator = ContractAddr.from(
33531
- this.config.vaultAllocator.address
33532
- );
33533
- const quote = await this.getQuotesAvnu(
33534
- fromToken.address.toString(),
33535
- toToken.address.toString(),
33536
- params.amount.toNumber(),
33537
- vaultAllocator.address.toString(),
33538
- toToken.decimals,
33539
- true
33540
- );
33541
- if (!quote) {
33542
- logger.error("error getting quote from avnu");
33543
- return [];
33544
- }
33545
- const getCalldata = await this.avnuWrapper.getSwapCallData(
33546
- quote,
33547
- vaultAllocator.address
33548
- );
33549
- const swapCallData = getCalldata[0];
33550
- const amount = uint25614.bnToUint256(quote.sellAmountInUsd * 10 ** 7);
33551
- return [
33552
- {
33553
- sanitizer: SIMPLE_SANITIZER,
33554
- call: {
33555
- contractAddress: fromToken.address,
33556
- selector: hash7.getSelectorFromName("approve"),
33557
- calldata: [
33558
- AVNU_EXCHANGE.toBigInt(),
33559
- toBigInt(amount.low.toString()),
33560
- // amount low
33561
- toBigInt(amount.high.toString())
33562
- // amount high
33563
- ]
33564
- }
33565
- },
33566
- {
33567
- sanitizer: SIMPLE_SANITIZER,
33568
- call: {
33569
- contractAddress: AVNU_EXCHANGE,
33570
- selector: hash7.getSelectorFromName("multi_route_swap"),
33571
- calldata: swapCallData
33572
- }
33573
- }
33574
- ];
33575
- } catch (error) {
33576
- logger.error(`Error getting Avnu quote: ${error}`);
33577
- return [];
33578
- }
33579
- }
33580
- //Swap wbtc to usdc
33581
- async getWithdrawCall(params) {
33582
- try {
33583
- const toToken = this.config.supportedPositions[0].asset;
33584
- const fromToken = this.config.supportedPositions[1].asset;
33585
- const vaultAllocator = ContractAddr.from(
33586
- this.config.vaultAllocator.address
33587
- );
33588
- const quote = await this.getQuotesAvnu(
33589
- fromToken.address.toString(),
33590
- toToken.address.toString(),
33591
- params.amount.toNumber(),
33592
- vaultAllocator.address.toString(),
33593
- fromToken.decimals,
33594
- false
33595
- );
33596
- if (!quote) {
33597
- logger.error("No quotes available for this swap, error in quotes avnu");
33598
- return [];
33599
- }
33600
- const getCalldata = await this.avnuWrapper.getSwapCallData(
33601
- quote,
33602
- vaultAllocator.address
33603
- );
33604
- const swapCallData = getCalldata[0];
33605
- const amount = uint25614.bnToUint256(params.amount.toWei());
33606
- return [
33607
- {
33608
- sanitizer: SIMPLE_SANITIZER,
33609
- call: {
33610
- contractAddress: fromToken.address,
33611
- selector: hash7.getSelectorFromName("approve"),
33612
- calldata: [
33613
- AVNU_EXCHANGE.toBigInt(),
33614
- toBigInt(amount.low.toString()),
33615
- // amount low
33616
- toBigInt(amount.high.toString())
33617
- // amount high
33618
- ]
33619
- }
33620
- },
33621
- {
33622
- sanitizer: SIMPLE_SANITIZER,
33623
- call: {
33624
- contractAddress: AVNU_EXCHANGE,
33625
- selector: hash7.getSelectorFromName("multi_route_swap"),
33626
- calldata: swapCallData
33627
- }
33628
- }
33629
- ];
33630
- } catch (error) {
33631
- logger.error(`Error getting Avnu quote: ${error}`);
33632
- return [];
33633
- }
33634
- }
33635
- async getSwapCallData(quote) {
33636
- return await this.avnuWrapper.getSwapCallData(quote, this.config.vaultAllocator.address);
33637
- }
33638
- async getHealthFactor() {
33639
- return Promise.resolve(1);
33640
- }
33641
- async fetchQuoteWithRetry(params, retries = 5) {
33642
- for (let attempt = 0; attempt < retries; attempt++) {
33643
- try {
33644
- const response = await axios9.get(this.config.baseUrl, { params });
33645
- if (response.data && response.data.length > 0) {
33646
- return response;
33647
- }
33648
- throw new Error("Empty response data");
33649
- } catch (err) {
33650
- logger.error(`Error fetching quote with retry: ${err}`);
33651
- if (attempt === retries - 1) {
33652
- throw err;
33653
- }
33654
- await new Promise((resolve) => setTimeout(resolve, MAX_DELAY));
33655
- }
33656
- }
33657
- throw new Error("Failed to fetch quote after retries");
33658
- }
33659
- async getQuotesAvnu(from_token_address, to_token_address, amount, takerAddress, toTokenDecimals, usdcToBtc, maxIterations = 5, tolerance = 1e4) {
33660
- try {
33661
- const fromToken = this.config.supportedPositions[0].asset;
33662
- const toToken = this.config.supportedPositions[1].asset;
33663
- if (!usdcToBtc) {
33664
- const sellAmount2 = returnFormattedAmount(amount, toTokenDecimals);
33665
- const params2 = {
33666
- sellTokenAddress: from_token_address,
33667
- buyTokenAddress: to_token_address,
33668
- takerAddress,
33669
- sellAmount: sellAmount2
33670
- };
33671
- const finalQuote2 = await this.fetchQuoteWithRetry(params2);
33672
- if (!finalQuote2.data.length) {
33673
- logger.error("No quotes available for this swap, error in quotes avnu");
33674
- return null;
33675
- }
33676
- const dataObject2 = finalQuote2.data[0];
33677
- return dataObject2;
33678
- }
33679
- const btcPrice = await this.getPriceOfToken(toToken.address.toString());
33680
- if (!btcPrice) {
33681
- logger.error(`error getting btc price: ${btcPrice}`);
33682
- return null;
33683
- }
33684
- const estimatedUsdcAmount = Math.floor(amount * btcPrice);
33685
- const targetBtcBig = BigInt(returnFormattedAmount(amount, toTokenDecimals));
33686
- let low = BigInt(
33687
- Math.floor(
33688
- estimatedUsdcAmount * 10 ** fromToken.decimals * 0.9
33689
- )
33690
- );
33691
- let high = BigInt(
33692
- Math.floor(
33693
- estimatedUsdcAmount * 10 ** fromToken.decimals * 1.1
33694
- )
33695
- );
33696
- let mid = 0n;
33697
- for (let i = 0; i < maxIterations; i++) {
33698
- mid = (low + high) / 2n;
33699
- const sellAmount2 = returnFormattedAmount(Number(mid), 0);
33700
- const quote = await this.fetchQuoteWithRetry({
33701
- sellTokenAddress: from_token_address,
33702
- buyTokenAddress: to_token_address,
33703
- takerAddress,
33704
- sellAmount: sellAmount2
33705
- });
33706
- const gotBtc = BigInt(quote.data[0].buyAmount);
33707
- if (gotBtc === targetBtcBig) return quote.data[0];
33708
- if (gotBtc > targetBtcBig) {
33709
- high = mid;
33710
- } else {
33711
- low = mid;
33712
- }
33713
- if (gotBtc >= targetBtcBig && gotBtc <= targetBtcBig + BigInt(tolerance)) {
33714
- return quote.data[0];
33715
- }
33716
- }
33717
- let sellAmount = returnFormattedAmount(
33718
- Number(mid),
33719
- 0
33720
- );
33721
- const params = {
33722
- sellTokenAddress: from_token_address,
33723
- buyTokenAddress: to_token_address,
33724
- takerAddress,
33725
- sellAmount
33726
- };
33727
- const finalQuote = await this.fetchQuoteWithRetry(params);
33728
- if (!finalQuote.data.length) {
33729
- logger.error("No quotes available for this swap, error in quotes avnu");
33730
- return null;
33731
- }
33732
- const dataObject = finalQuote.data[0];
33733
- return dataObject;
33734
- } catch (err) {
33735
- logger.error(`No quotes available for this swap: ${err}`);
33736
- return null;
33737
- }
33738
- }
33739
- async getPriceOfToken(tokenAddress, retries = MAX_RETRIES) {
33740
- try {
33741
- const url = `https://starknet.impulse.avnu.fi/v1/tokens/${tokenAddress}/prices/line`;
33742
- const response = await axios9.get(url);
33743
- const length = response.data.length;
33744
- return response.data[length - 1].value;
33745
- } catch (err) {
33746
- if (retries > 0) {
33747
- await new Promise((resolve) => setTimeout(resolve, MAX_DELAY));
33748
- return this.getPriceOfToken(tokenAddress, retries - 1);
33749
- } else {
33750
- logger.error(`Failed to fetch price for ${tokenAddress} after ${MAX_RETRIES} attempts`);
33751
- return null;
33752
- }
33753
- }
33754
- }
33755
- };
34295
+ // src/strategies/vesu-extended-strategy/types/transaction-metadata.ts
34296
+ var CycleType = /* @__PURE__ */ ((CycleType2) => {
34297
+ CycleType2["INVESTMENT"] = "INVESTMENT";
34298
+ CycleType2["REBALANCE_PRICE_DROP"] = "REBALANCE_PRICE_DROP";
34299
+ CycleType2["REBALANCE_PRICE_RISE"] = "REBALANCE_PRICE_RISE";
34300
+ CycleType2["WITHDRAWAL"] = "WITHDRAWAL";
34301
+ CycleType2["DELTA_NEUTRAL_ADJUSTMENT"] = "DELTA_NEUTRAL_ADJUSTMENT";
34302
+ return CycleType2;
34303
+ })(CycleType || {});
33756
34304
 
33757
34305
  // src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx
33758
34306
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
@@ -33852,15 +34400,30 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
33852
34400
  const usdceToken = Global.getDefaultTokens().find(
33853
34401
  (token) => token.symbol === "USDCe"
33854
34402
  );
34403
+ const walletBalance = await new ERC20(this.config).balanceOf(
34404
+ usdceToken.address,
34405
+ WALLET_ADDRESS,
34406
+ usdceToken.decimals
34407
+ );
34408
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::moveAssetsToVaultAllocator walletBalance: ${walletBalance}`);
34409
+ const amountToBeTransferred = amount.minimum(walletBalance);
34410
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::moveAssetsToVaultAllocator amountToBeTransferred: ${amountToBeTransferred.toNumber()}`);
34411
+ if (amountToBeTransferred.lessThan(0)) {
34412
+ logger.error(`${_VesuExtendedMultiplierStrategy.name}::moveAssetsToVaultAllocator amountToBeTransferred is less than 0: ${amountToBeTransferred.toNumber()}`);
34413
+ return {
34414
+ calls: [],
34415
+ status: false
34416
+ };
34417
+ }
33855
34418
  const approveCall = new ERC20(this.config).approve(
33856
34419
  usdceToken.address,
33857
34420
  this.metadata.additionalInfo.vaultAllocator,
33858
- amount
34421
+ amountToBeTransferred
33859
34422
  );
33860
34423
  const transferCall = new ERC20(this.config).transfer(
33861
34424
  usdceToken.address,
33862
34425
  this.metadata.additionalInfo.vaultAllocator,
33863
- amount
34426
+ amountToBeTransferred
33864
34427
  );
33865
34428
  const proofsInfo = extendedAdapter.getProofsForFromLegacySwap(
33866
34429
  this.getMerkleTree()
@@ -33868,21 +34431,43 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
33868
34431
  const proofGroups = proofsInfo.proofs;
33869
34432
  const call = this.getManageCall(
33870
34433
  proofGroups,
33871
- await proofsInfo.callConstructor({ amount })
34434
+ await proofsInfo.callConstructor({ amount: amountToBeTransferred })
33872
34435
  );
33873
- return [approveCall, transferCall, call];
34436
+ return {
34437
+ calls: [approveCall, transferCall, call],
34438
+ status: true
34439
+ };
33874
34440
  } catch (err) {
33875
34441
  logger.error(`error moving assets to vault allocator: ${err}`);
33876
- return [];
34442
+ return {
34443
+ calls: [],
34444
+ status: false
34445
+ };
33877
34446
  }
33878
34447
  }
33879
34448
  async shouldInvest() {
33880
34449
  try {
34450
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest starting`);
33881
34451
  const vesuAdapter = await this.getVesuAdapter();
33882
34452
  const extendedAdapter = await this.getExtendedAdapter();
33883
- if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
34453
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest adapters fetched: vesuAdapter=${!!vesuAdapter}, extendedAdapter=${!!extendedAdapter}, extendedAdapter.client=${!!extendedAdapter?.client}`);
34454
+ if (!vesuAdapter) {
33884
34455
  logger.error(
33885
- `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
34456
+ `Vesu adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
34457
+ );
34458
+ return {
34459
+ shouldInvest: false,
34460
+ vesuAmount: new Web3Number(0, 0),
34461
+ extendedAmount: new Web3Number(0, 0),
34462
+ extendedLeverage: 0,
34463
+ collateralPrice: 0,
34464
+ debtPrice: 0,
34465
+ vesuLeverage: 0
34466
+ };
34467
+ }
34468
+ if (!extendedAdapter) {
34469
+ logger.error(
34470
+ `Extended adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
33886
34471
  );
33887
34472
  return {
33888
34473
  shouldInvest: false,
@@ -33894,10 +34479,73 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
33894
34479
  vesuLeverage: 0
33895
34480
  };
33896
34481
  }
34482
+ if (!extendedAdapter.client) {
34483
+ logger.error(
34484
+ `Extended adapter client not initialized. This may be a temporary initialization failure - check network connectivity and API availability.`
34485
+ );
34486
+ return {
34487
+ shouldInvest: false,
34488
+ vesuAmount: new Web3Number(0, 0),
34489
+ extendedAmount: new Web3Number(0, 0),
34490
+ extendedLeverage: 0,
34491
+ collateralPrice: 0,
34492
+ debtPrice: 0,
34493
+ vesuLeverage: 0
34494
+ };
34495
+ }
34496
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest calling getUnusedBalance`);
33897
34497
  const balance = await this.getUnusedBalance();
34498
+ if (!Number.isFinite(balance.usdValue) || balance.usdValue < 0) {
34499
+ logger.error(
34500
+ `Invalid balance.usdValue: ${balance.usdValue}. Expected a finite, non-negative number.`
34501
+ );
34502
+ return {
34503
+ shouldInvest: false,
34504
+ vesuAmount: new Web3Number(0, 0),
34505
+ extendedAmount: new Web3Number(0, 0),
34506
+ extendedLeverage: 0,
34507
+ collateralPrice: 0,
34508
+ debtPrice: 0,
34509
+ vesuLeverage: 0
34510
+ };
34511
+ }
34512
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest balance: ${balance.usdValue}`);
33898
34513
  const usdcBalanceOnExtended = await extendedAdapter.getExtendedDepositAmount();
33899
- const amountToInvest = balance.amount.plus(usdcBalanceOnExtended?.availableForWithdrawal ?? 0).minus(LIMIT_BALANCE);
33900
- if (amountToInvest.lessThan(0)) {
34514
+ if (usdcBalanceOnExtended) {
34515
+ const availableForWithdrawal = parseFloat(usdcBalanceOnExtended.availableForWithdrawal);
34516
+ if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
34517
+ logger.error(
34518
+ `Invalid usdcBalanceOnExtended.availableForWithdrawal: ${usdcBalanceOnExtended.availableForWithdrawal}. Expected a finite, non-negative number.`
34519
+ );
34520
+ return {
34521
+ shouldInvest: false,
34522
+ vesuAmount: new Web3Number(0, 0),
34523
+ extendedAmount: new Web3Number(0, 0),
34524
+ extendedLeverage: 0,
34525
+ collateralPrice: 0,
34526
+ debtPrice: 0,
34527
+ vesuLeverage: 0
34528
+ };
34529
+ }
34530
+ }
34531
+ const amountToInvest = new Web3Number(balance.usdValue, USDC_TOKEN_DECIMALS).plus(usdcBalanceOnExtended?.availableForWithdrawal ?? 0).multipliedBy(1 - LIMIT_BALANCE);
34532
+ const amountToInvestNumber = amountToInvest.toNumber();
34533
+ if (!Number.isFinite(amountToInvestNumber)) {
34534
+ logger.error(
34535
+ `Invalid amountToInvest calculation result: ${amountToInvestNumber}. Calculation may have produced NaN or Infinity.`
34536
+ );
34537
+ return {
34538
+ shouldInvest: false,
34539
+ vesuAmount: new Web3Number(0, 0),
34540
+ extendedAmount: new Web3Number(0, 0),
34541
+ extendedLeverage: 0,
34542
+ collateralPrice: 0,
34543
+ debtPrice: 0,
34544
+ vesuLeverage: 0
34545
+ };
34546
+ }
34547
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvestNumber}`);
34548
+ if (amountToInvest.lessThan(LIMIT_BALANCE_VALUE)) {
33901
34549
  return {
33902
34550
  shouldInvest: false,
33903
34551
  vesuAmount: new Web3Number(0, 0),
@@ -33926,6 +34574,34 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
33926
34574
  collateralPrice,
33927
34575
  debtPrice
33928
34576
  } = await this.getAssetPrices();
34577
+ if (!Number.isFinite(collateralPrice.price) || collateralPrice.price <= 0) {
34578
+ logger.error(
34579
+ `Invalid collateralPrice: ${collateralPrice.price}. Expected a finite, positive number.`
34580
+ );
34581
+ return {
34582
+ shouldInvest: false,
34583
+ vesuAmount: new Web3Number(0, 0),
34584
+ extendedAmount: new Web3Number(0, 0),
34585
+ extendedLeverage: 0,
34586
+ collateralPrice: 0,
34587
+ debtPrice: 0,
34588
+ vesuLeverage: 0
34589
+ };
34590
+ }
34591
+ if (!Number.isFinite(debtPrice.price) || debtPrice.price <= 0) {
34592
+ logger.error(
34593
+ `Invalid debtPrice: ${debtPrice.price}. Expected a finite, positive number.`
34594
+ );
34595
+ return {
34596
+ shouldInvest: false,
34597
+ vesuAmount: new Web3Number(0, 0),
34598
+ extendedAmount: new Web3Number(0, 0),
34599
+ extendedLeverage: 0,
34600
+ collateralPrice: 0,
34601
+ debtPrice: 0,
34602
+ vesuLeverage: 0
34603
+ };
34604
+ }
33929
34605
  const { vesu_amount, extended_amount, extended_leverage, vesu_leverage } = await calculateAmountDistribution(
33930
34606
  amountToInvest.toNumber(),
33931
34607
  extendedAdapter.client,
@@ -33949,6 +34625,7 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
33949
34625
  vesuLeverage: 0
33950
34626
  };
33951
34627
  }
34628
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest vesu_amount: ${vesu_amount.toNumber()}, extended_amount: ${extended_amount.toNumber()}`);
33952
34629
  return {
33953
34630
  shouldInvest: true,
33954
34631
  vesuAmount: vesu_amount,
@@ -33975,111 +34652,251 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
33975
34652
  try {
33976
34653
  const vesuAdapter = await this.getVesuAdapter();
33977
34654
  const extendedAdapter = await this.getExtendedAdapter();
33978
- let calls = [];
33979
34655
  if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client) {
33980
34656
  logger.error(
33981
34657
  `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
33982
34658
  );
33983
- return calls;
34659
+ return [];
34660
+ }
34661
+ const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
34662
+ if (!extendedHoldings) {
34663
+ logger.error(`error getting extended holdings: ${extendedHoldings}`);
34664
+ return [];
33984
34665
  }
33985
- if (extendedAmount.lessThan(0)) {
34666
+ const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
34667
+ const usdcAmountOnExtendedAvailableForWithdrawal = parseFloat(
34668
+ extendedHoldings.availableForWithdrawal
34669
+ );
34670
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::shouldMoveAssets calculating movements - Extended current: ${usdcAmountOnExtendedAvailableForWithdrawal}, Wallet: ${usdcAmountInWallet.toNumber()}, Target Extended: ${extendedAmount.toNumber()}, Target Vesu: ${vesuAmount.toNumber()}`);
34671
+ let totalExtendedWithdrawal = new Web3Number(0, USDC_TOKEN_DECIMALS);
34672
+ let totalExtendedDeposit = new Web3Number(0, USDC_TOKEN_DECIMALS);
34673
+ if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34674
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmount.abs());
34675
+ }
34676
+ const extendedTargetAmount = extendedAmount.abs();
34677
+ let projectedExtendedBalance = usdcAmountOnExtendedAvailableForWithdrawal;
34678
+ if (extendedAmount.isNegative()) {
34679
+ projectedExtendedBalance = projectedExtendedBalance - extendedAmount.abs().toNumber();
34680
+ }
34681
+ const extendedAmountDifference = extendedTargetAmount.minus(projectedExtendedBalance);
34682
+ const extendedAmountDifferenceAbs = extendedAmountDifference.abs();
34683
+ if (extendedAmountDifference.lessThan(0)) {
34684
+ totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmountDifferenceAbs);
34685
+ } else if (extendedAmountDifference.greaterThan(0)) {
34686
+ totalExtendedDeposit = totalExtendedDeposit.plus(extendedAmountDifference);
34687
+ }
34688
+ const vesuTargetAmount = vesuAmount.abs();
34689
+ const projectedWalletBalance = usdcAmountInWallet.plus(totalExtendedWithdrawal).minus(totalExtendedDeposit);
34690
+ let vesuAmountDifference = vesuTargetAmount.minus(projectedWalletBalance);
34691
+ const vesuAmountDifferenceAbs = vesuAmountDifference.abs();
34692
+ 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()}`);
34693
+ let calls = [];
34694
+ let transactionResults = [];
34695
+ if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
33986
34696
  try {
33987
- const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
34697
+ const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
33988
34698
  {
33989
34699
  to: Protocols.VAULT.name,
33990
34700
  from: Protocols.EXTENDED.name,
33991
- amount: extendedAmount.abs()
34701
+ amount: extendedAmount.abs(),
34702
+ cycleType: "INVESTMENT" /* INVESTMENT */
33992
34703
  },
33993
34704
  extendedAdapter,
33994
34705
  vesuAdapter
33995
34706
  );
33996
34707
  if (extendedStatus) {
33997
- calls.push(...extendedCalls);
34708
+ transactionResults.push({
34709
+ status: extendedStatus,
34710
+ calls: extendedCalls,
34711
+ transactionMetadata: {
34712
+ ...extendedTransactionMetadata,
34713
+ transactionType: "DEPOSIT"
34714
+ }
34715
+ });
33998
34716
  } else {
33999
- return [];
34717
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmount.abs() }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34000
34718
  }
34001
34719
  } catch (err) {
34002
34720
  logger.error(`Failed moving assets to vault: ${err}`);
34721
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmount.abs() }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34003
34722
  }
34004
34723
  }
34005
- if (vesuAmount.lessThan(0)) {
34724
+ if (vesuAmount.isNegative() && vesuAmount.abs().greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
34006
34725
  try {
34007
- const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
34726
+ const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
34008
34727
  {
34009
34728
  to: Protocols.EXTENDED.name,
34010
34729
  from: Protocols.VESU.name,
34011
- amount: vesuAmount.abs()
34730
+ amount: vesuAmount.abs(),
34731
+ cycleType: "INVESTMENT" /* INVESTMENT */
34012
34732
  },
34013
34733
  extendedAdapter,
34014
34734
  vesuAdapter
34015
34735
  );
34016
- calls.push(...vesuCalls);
34017
34736
  if (!vesuStatus) {
34018
- return [];
34019
- }
34737
+ return [this.createTransactionResult([], false, { from: Protocols.VESU.name, to: Protocols.EXTENDED.name, amount: vesuAmount.abs() }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34738
+ }
34739
+ transactionResults.push({
34740
+ status: vesuStatus,
34741
+ calls: vesuCalls,
34742
+ transactionMetadata: {
34743
+ ...vesuTransactionMetadata,
34744
+ transactionType: "DEPOSIT"
34745
+ }
34746
+ });
34020
34747
  } catch (err) {
34021
- logger.error(`Failed moving assets to vault: ${err}`);
34748
+ logger.error(`Failed moving assets to extended via vault allocator: ${err}`);
34749
+ return [this.createTransactionResult([], false, { from: Protocols.VESU.name, to: Protocols.EXTENDED.name, amount: vesuAmount.abs() }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34022
34750
  }
34023
34751
  }
34024
- const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
34025
- if (!extendedHoldings) {
34026
- logger.error(`error getting extended holdings: ${extendedHoldings}`);
34027
- return calls;
34028
- }
34029
- const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
34030
- const usdcAmountOnExtended = parseFloat(
34031
- extendedHoldings.availableForWithdrawal
34032
- );
34033
- if (extendedAmount.minus(usdcAmountOnExtended).greaterThan(0)) {
34034
- try {
34035
- const { calls: extendedCalls } = await this.moveAssets(
34036
- {
34037
- to: Protocols.EXTENDED.name,
34038
- from: Protocols.VAULT.name,
34039
- amount: extendedAmount.minus(usdcAmountOnExtended)
34040
- },
34041
- extendedAdapter,
34042
- vesuAdapter
34043
- );
34044
- calls.push(...extendedCalls);
34045
- } catch (err) {
34046
- logger.error(`Failed moving assets to extended: ${err}`);
34752
+ if (extendedAmountDifferenceAbs.greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
34753
+ if (extendedAmountDifference.greaterThan(0)) {
34754
+ try {
34755
+ const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
34756
+ {
34757
+ to: Protocols.EXTENDED.name,
34758
+ from: Protocols.VAULT.name,
34759
+ amount: extendedAmountDifference,
34760
+ cycleType: "INVESTMENT" /* INVESTMENT */
34761
+ },
34762
+ extendedAdapter,
34763
+ vesuAdapter
34764
+ );
34765
+ if (extendedStatus) {
34766
+ transactionResults.push({
34767
+ status: extendedStatus,
34768
+ calls: extendedCalls,
34769
+ transactionMetadata: extendedTransactionMetadata
34770
+ });
34771
+ } else {
34772
+ logger.error(`Failed to move assets to extended - operation returned false status`);
34773
+ return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.EXTENDED.name, amount: extendedAmountDifference }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34774
+ }
34775
+ } catch (err) {
34776
+ logger.error(`Failed moving assets to extended: ${err}`);
34777
+ return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.EXTENDED.name, amount: extendedAmountDifference }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34778
+ }
34779
+ } else if (extendedAmountDifference.lessThan(0)) {
34780
+ try {
34781
+ const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
34782
+ {
34783
+ to: Protocols.VAULT.name,
34784
+ from: Protocols.EXTENDED.name,
34785
+ amount: extendedAmountDifferenceAbs,
34786
+ cycleType: "INVESTMENT" /* INVESTMENT */
34787
+ },
34788
+ extendedAdapter,
34789
+ vesuAdapter
34790
+ );
34791
+ if (extendedStatus) {
34792
+ transactionResults.push({
34793
+ status: extendedStatus,
34794
+ calls: extendedCalls,
34795
+ transactionMetadata: {
34796
+ ...extendedTransactionMetadata,
34797
+ transactionType: "DEPOSIT"
34798
+ }
34799
+ });
34800
+ } else {
34801
+ logger.error(`Failed to withdraw from extended - operation returned false status`);
34802
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmountDifferenceAbs }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34803
+ }
34804
+ } catch (err) {
34805
+ logger.error(`Failed moving assets from extended to vault: ${err}`);
34806
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: extendedAmountDifferenceAbs }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34807
+ }
34047
34808
  }
34048
34809
  }
34049
- if (vesuAmount.minus(usdcAmountInWallet).greaterThan(0)) {
34050
- try {
34051
- const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
34052
- {
34053
- to: Protocols.VAULT.name,
34054
- from: Protocols.EXTENDED.name,
34055
- amount: vesuAmount.minus(usdcAmountInWallet)
34056
- },
34057
- extendedAdapter,
34058
- vesuAdapter
34810
+ if (vesuAmountDifferenceAbs.greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
34811
+ if (vesuAmountDifference.lessThanOrEqualTo(0)) {
34812
+ logger.warn(
34813
+ `Vesu amount difference is negative or zero: ${vesuAmountDifference.toNumber()}. Skipping operation.`
34059
34814
  );
34060
- if (!vesuStatus) {
34061
- return [];
34815
+ } else {
34816
+ try {
34817
+ const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
34818
+ {
34819
+ to: Protocols.VAULT.name,
34820
+ from: Protocols.EXTENDED.name,
34821
+ amount: vesuAmountDifference,
34822
+ cycleType: "INVESTMENT" /* INVESTMENT */
34823
+ },
34824
+ extendedAdapter,
34825
+ vesuAdapter
34826
+ );
34827
+ if (!vesuStatus) {
34828
+ logger.error(`Failed to move assets to vesu - operation returned false status`);
34829
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: vesuAmountDifference }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34830
+ }
34831
+ transactionResults.push({
34832
+ status: vesuStatus,
34833
+ calls: vesuCalls,
34834
+ transactionMetadata: {
34835
+ ...vesuTransactionMetadata,
34836
+ transactionType: "DEPOSIT"
34837
+ }
34838
+ });
34839
+ } catch (err) {
34840
+ logger.error(`Failed moving assets to vault: ${err}`);
34841
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: vesuAmountDifference }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34062
34842
  }
34063
- calls.push(...vesuCalls);
34064
- } catch (err) {
34065
- logger.error(`Failed moving assets to vault: ${err}`);
34066
34843
  }
34067
34844
  }
34068
- return calls;
34845
+ return transactionResults;
34069
34846
  } catch (err) {
34070
34847
  logger.error(`Failed moving assets to vesu: ${err}`);
34071
- return [];
34848
+ return [this.createTransactionResult([], false, { from: Protocols.EXTENDED.name, to: Protocols.VAULT.name, amount: new Web3Number(0, USDC_TOKEN_DECIMALS) }, "NONE", "INVESTMENT" /* INVESTMENT */)];
34072
34849
  }
34073
34850
  }
34851
+ /**
34852
+ * Helper method to create transaction result with metadata
34853
+ */
34854
+ createTransactionResult(calls, status, params, transactionType, cycleType) {
34855
+ if (status) {
34856
+ return {
34857
+ calls,
34858
+ status,
34859
+ transactionMetadata: {
34860
+ protocolFrom: params.from,
34861
+ protocolTo: params.to,
34862
+ transactionType,
34863
+ usdAmount: params.amount.abs().toFixed(),
34864
+ status: "PENDING",
34865
+ cycleType
34866
+ }
34867
+ };
34868
+ }
34869
+ return { calls: [], status: false, transactionMetadata: { protocolFrom: "", protocolTo: "", transactionType: "DEPOSIT", usdAmount: "0", status: "FAILED", cycleType } };
34870
+ }
34074
34871
  async moveAssets(params, extendedAdapter, vesuAdapter) {
34075
34872
  try {
34873
+ if (params.amount.lessThanOrEqualTo(0)) {
34874
+ logger.error(
34875
+ `Invalid amount for moveAssets: ${params.amount.toNumber()}. Amount must be positive.`
34876
+ );
34877
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34878
+ }
34879
+ const amountAbs = params.amount.abs();
34880
+ if (params.from === Protocols.EXTENDED.name || params.to === Protocols.EXTENDED.name) {
34881
+ if (amountAbs.lessThanOrEqualTo(extendedAdapter.minimumExtendedMovementAmount)) {
34882
+ logger.warn(
34883
+ `Amount ${amountAbs.toNumber()} is below minimum Extended movement amount ${extendedAdapter.minimumExtendedMovementAmount}. Skipping operation.`
34884
+ );
34885
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34886
+ }
34887
+ }
34888
+ if (params.from === Protocols.VESU.name || params.to === Protocols.VESU.name) {
34889
+ if (amountAbs.lessThanOrEqualTo(vesuAdapter.minimumVesuMovementAmount)) {
34890
+ logger.warn(
34891
+ `Amount ${amountAbs.toNumber()} is below minimum Vesu movement amount ${vesuAdapter.minimumVesuMovementAmount}. Skipping operation.`
34892
+ );
34893
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34894
+ }
34895
+ }
34076
34896
  const avnuAdapter = await this.getAvnuAdapter();
34077
34897
  if (!avnuAdapter) {
34078
34898
  logger.error(`avnu adapter not found: ${avnuAdapter}`);
34079
- return {
34080
- calls: [],
34081
- status: false
34082
- };
34899
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34083
34900
  }
34084
34901
  logger.info(`moveAssets params, ${JSON.stringify(params)}`);
34085
34902
  const collateralToken = vesuAdapter.config.supportedPositions[0].asset;
@@ -34098,61 +34915,72 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34098
34915
  await proofsInfo.callConstructor({ amount: params.amount })
34099
34916
  );
34100
34917
  calls.push(call);
34101
- return {
34102
- calls: [call],
34103
- status: true
34104
- };
34918
+ return this.createTransactionResult(calls, true, params, "DEPOSIT", params.cycleType);
34105
34919
  } else if (params.to === Protocols.VAULT.name && params.from === Protocols.EXTENDED.name) {
34106
34920
  const extendedLeverage = calculateExtendedLevergae();
34107
34921
  const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
34108
34922
  if (!extendedHoldings) {
34109
34923
  logger.error(`error getting extended holdings: ${extendedHoldings}`);
34110
- return {
34111
- calls: [],
34112
- status: false
34113
- };
34924
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34114
34925
  }
34115
34926
  const extendedHoldingAmount = new Web3Number(
34116
34927
  extendedHoldings.availableForWithdrawal,
34117
34928
  USDC_TOKEN_DECIMALS
34118
34929
  );
34119
- const leftAmountAfterWithdrawalAmountInAccount = params.amount.minus(extendedHoldingAmount);
34120
- const btcAmount = leftAmountAfterWithdrawalAmountInAccount.dividedBy(collateralPrice.price);
34121
- const openLongPosition = await extendedAdapter.createOrder(
34122
- extendedLeverage.toString(),
34123
- btcAmount.toNumber(),
34124
- "BUY" /* BUY */
34125
- );
34126
- if (!openLongPosition) {
34127
- logger.error(`error opening long position: ${openLongPosition}`);
34128
- return {
34129
- calls: [],
34130
- status: false
34131
- };
34930
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::moveAssets extendedHoldingAmount: ${extendedHoldingAmount.toNumber()}`);
34931
+ if (params.amount.abs().greaterThan(extendedHoldingAmount)) {
34932
+ const leftAmountAfterWithdrawalAmountInAccount = params.amount.abs().minus(extendedHoldingAmount);
34933
+ logger.info(`${_VesuExtendedMultiplierStrategy.name}::moveAssets leftAmountAfterWithdrawalAmountInAccount: ${leftAmountAfterWithdrawalAmountInAccount.toNumber()}`);
34934
+ const btcAmount = leftAmountAfterWithdrawalAmountInAccount.dividedBy(collateralPrice.price);
34935
+ const openLongPosition = btcAmount.multipliedBy(3).greaterThan(MINIMUM_EXTENDED_POSITION_SIZE) ? await extendedAdapter.createOrder(
34936
+ extendedLeverage.toString(),
34937
+ btcAmount.toNumber(),
34938
+ "BUY" /* BUY */
34939
+ ) : await extendedAdapter.createOrder(
34940
+ extendedLeverage.toString(),
34941
+ 34e-6,
34942
+ // just in case amount falls short then we need to create a withdrawal
34943
+ "BUY" /* BUY */
34944
+ );
34945
+ if (!openLongPosition) {
34946
+ logger.error(`error opening long position: ${openLongPosition}`);
34947
+ }
34948
+ const updatedHoldings = await extendedAdapter.getExtendedDepositAmount();
34949
+ if (!updatedHoldings || new Web3Number(updatedHoldings.availableForWithdrawal, USDC_TOKEN_DECIMALS).lessThan(params.amount.abs())) {
34950
+ logger.error(`Insufficient balance after opening position. Available: ${updatedHoldings?.availableForWithdrawal}, Needed: ${params.amount.abs()}`);
34951
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34952
+ }
34132
34953
  }
34133
- await new Promise((resolve) => setTimeout(resolve, 5e3));
34134
- const withdrawalFromExtended = await extendedAdapter.withdrawFromExtended(params.amount);
34135
- if (withdrawalFromExtended) {
34954
+ const {
34955
+ status: withdrawalFromExtendedStatus,
34956
+ receivedTxnHash: withdrawalFromExtendedTxnHash
34957
+ } = await extendedAdapter.withdrawFromExtended(params.amount);
34958
+ logger.info(`withdrawalFromExtendedStatus: ${withdrawalFromExtendedStatus}, withdrawalFromExtendedTxnHash: ${withdrawalFromExtendedTxnHash}`);
34959
+ if (withdrawalFromExtendedStatus && withdrawalFromExtendedTxnHash) {
34136
34960
  const extendedHoldings2 = await extendedAdapter.getExtendedDepositAmount();
34137
- logger.info(`extendedHoldings after withdrawal ${extendedHoldings2}`);
34138
- await new Promise((resolve) => setTimeout(resolve, 1e4));
34139
- const calls = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
34140
- if (calls.length > 0) {
34141
- return {
34142
- calls,
34143
- status: true
34144
- };
34961
+ logger.info(`extendedHoldings after withdrawal ${extendedHoldings2?.availableForWithdrawal}`);
34962
+ await new Promise((resolve) => setTimeout(resolve, 5e3));
34963
+ const { calls, status } = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
34964
+ if (calls.length > 0 && status) {
34965
+ return this.createTransactionResult(calls, true, params, "WITHDRAWAL", params.cycleType);
34966
+ } else {
34967
+ return this.createTransactionResult([], true, params, "WITHDRAWAL", params.cycleType);
34145
34968
  }
34969
+ } else if (withdrawalFromExtendedStatus && !withdrawalFromExtendedTxnHash) {
34970
+ logger.error("withdrawal from extended successful, but funds didn't get transferred to the wallet");
34971
+ return this.createTransactionResult([], true, params, "WITHDRAWAL", params.cycleType);
34146
34972
  } else {
34147
34973
  logger.error("withdrawal from extended failed");
34148
- return {
34149
- calls: [],
34150
- status: false
34151
- };
34974
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34152
34975
  }
34153
34976
  } else if (params.to === Protocols.VAULT.name && params.from === Protocols.VESU.name) {
34977
+ const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, "close" /* CLOSE */);
34978
+ if (!isPriceDifferenceBetweenAvnuAndExtended) {
34979
+ logger.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
34980
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34981
+ }
34154
34982
  const vesuAmountInBTC = new Web3Number(
34155
- params.amount.dividedBy(collateralPrice.price).toNumber(),
34983
+ params.amount.dividedBy(collateralPrice.price).toFixed(WBTC_TOKEN_DECIMALS),
34156
34984
  collateralToken.decimals
34157
34985
  );
34158
34986
  const proofsInfo = vesuAdapter.getProofs(false, this.getMerkleTree());
@@ -34170,11 +34998,13 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34170
34998
  await swapProofsInfo.callConstructor({ amount: vesuAmountInBTC })
34171
34999
  );
34172
35000
  calls.push(swapCall);
34173
- return {
34174
- calls,
34175
- status: true
34176
- };
35001
+ return this.createTransactionResult(calls, true, params, "WITHDRAWAL", params.cycleType);
34177
35002
  } else if (params.to === Protocols.EXTENDED.name && params.from === Protocols.VESU.name) {
35003
+ const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, "close" /* CLOSE */);
35004
+ if (!isPriceDifferenceBetweenAvnuAndExtended) {
35005
+ logger.warn(`price difference between avnu and extended doesn't fit the range for close position, ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
35006
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
35007
+ }
34178
35008
  const vesuAmountInBTC = new Web3Number(
34179
35009
  params.amount.dividedBy(collateralPrice.price).toNumber(),
34180
35010
  collateralToken.decimals
@@ -34204,131 +35034,32 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34204
35034
  await proofsInfoDeposit.callConstructor({ amount: params.amount })
34205
35035
  );
34206
35036
  calls.push(callDeposit);
34207
- return {
34208
- calls,
34209
- status: true
34210
- };
35037
+ return this.createTransactionResult(calls, true, params, "DEPOSIT", params.cycleType);
34211
35038
  }
34212
- return {
34213
- calls: [],
34214
- status: false
34215
- };
35039
+ logger.error(`Unsupported assets movement: ${params.from} to ${params.to}`);
35040
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34216
35041
  } catch (err) {
34217
35042
  logger.error(`error moving assets: ${err}`);
34218
- return {
34219
- calls: [],
34220
- status: false
34221
- };
35043
+ return this.createTransactionResult([], false, params, "NONE", params.cycleType);
34222
35044
  }
34223
35045
  }
34224
35046
  async handleDeposit() {
34225
35047
  try {
34226
- const vesuAdapter = await this.getVesuAdapter();
34227
- const extendedAdapter = await this.getExtendedAdapter();
34228
- const avnuAdapter = await this.getAvnuAdapter();
34229
- if (!vesuAdapter || !extendedAdapter || !extendedAdapter.client || !avnuAdapter) {
34230
- logger.error(
34231
- "vesu or extended adapter not found",
34232
- vesuAdapter,
34233
- extendedAdapter
34234
- );
34235
- return {
34236
- extendedAmountInBTC: new Web3Number(0, 0),
34237
- calls: []
34238
- };
34239
- }
34240
- const extendedLeverage = calculateExtendedLevergae();
34241
- const isPriceDifferenceBetweenAvnuAndExtended = await this.checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter);
34242
- if (!isPriceDifferenceBetweenAvnuAndExtended) {
34243
- logger.error("price difference between avnu and extended doesn't fit the range");
34244
- return {
34245
- extendedAmountInBTC: new Web3Number(0, 0),
34246
- calls: []
34247
- };
34248
- }
34249
- const position = await extendedAdapter.getAllOpenPositions();
34250
- if (!position) {
34251
- logger.error("error getting extended position", position);
34252
- return {
34253
- extendedAmountInBTC: new Web3Number(0, 0),
34254
- calls: []
34255
- };
34256
- }
34257
- const extendedPositionValue = position.length > 0 ? parseFloat(position[0].value) : 0;
34258
- const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
34259
- if (!extendedHoldings) {
34260
- logger.error(`error getting extended holdings: ${extendedHoldings}`);
34261
- return {
34262
- extendedAmountInBTC: new Web3Number(0, 0),
34263
- calls: []
34264
- };
34265
- }
34266
- const extendedHoldingAmount = new Web3Number(
34267
- extendedHoldings.availableForWithdrawal,
34268
- USDC_TOKEN_DECIMALS
34269
- );
34270
- const {
34271
- collateralTokenAmount
34272
- } = await vesuAdapter.vesuAdapter.getAssetPrices();
34273
- const { collateralPrice } = await this.getAssetPrices();
34274
- const { vesuAmountInBTC, extendedAmountInBTC } = calculateVesUPositionSizeGivenExtended(
34275
- extendedPositionValue,
34276
- extendedHoldingAmount,
34277
- collateralTokenAmount,
34278
- collateralPrice.price
34279
- );
34280
- logger.info(`vesuAmountInBTC ${vesuAmountInBTC}, extendedAmountInBTC ${extendedAmountInBTC}`);
34281
- let calls = [];
34282
- if (vesuAmountInBTC.greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)) {
34283
- const proofsInfo = vesuAdapter.getProofs(true, this.getMerkleTree());
34284
- const proofGroups = proofsInfo.proofs;
34285
- const call = this.getManageCall(
34286
- proofGroups,
34287
- await proofsInfo.callConstructor({
34288
- amount: vesuAmountInBTC
34289
- })
34290
- );
34291
- const { amount: wbtcAmountInVaultAllocator } = await this.getUnusedBalanceWBTC();
34292
- if (wbtcAmountInVaultAllocator.lessThan(vesuAmountInBTC)) {
34293
- logger.info(`WBTC amount in vault allocator is less than vesu amount required in WBTC thus swapping, wbtcAmountInVaultAllocator: ${wbtcAmountInVaultAllocator}, vesuAmountInBTC: ${vesuAmountInBTC}`);
34294
- const swapProofsInfo = avnuAdapter.getProofs(true, this.getMerkleTree());
34295
- const swapProofGroups = swapProofsInfo.proofs;
34296
- const swapCall = this.getManageCall(
34297
- swapProofGroups,
34298
- await swapProofsInfo.callConstructor({
34299
- amount: vesuAmountInBTC
34300
- })
34301
- );
34302
- calls.push(swapCall);
34303
- }
34304
- calls.push(call);
34305
- }
34306
- const shortPosition = extendedAmountInBTC.multipliedBy(3).abs().greaterThan(MINIMUM_EXTENDED_POSITION_SIZE) ? await extendedAdapter.createOrder(
34307
- extendedLeverage.toString(),
34308
- extendedAmountInBTC.toNumber(),
34309
- "SELL" /* SELL */
34310
- ) : null;
34311
- if (!shortPosition && extendedAmountInBTC.multipliedBy(3).abs().greaterThan(MINIMUM_EXTENDED_POSITION_SIZE)) {
34312
- logger.error(`error creating short position thus no position to be opened on vesu: ${shortPosition}`);
34313
- return {
34314
- extendedAmountInBTC: new Web3Number(0, 0),
34315
- calls: []
34316
- };
34317
- }
34318
- return {
34319
- extendedAmountInBTC,
34320
- calls
34321
- };
35048
+ return this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.VAULT.name, amount: new Web3Number(0, 0) }, "NONE", "INVESTMENT" /* INVESTMENT */);
34322
35049
  } catch (err) {
34323
35050
  logger.error(`error handling deposit: ${err}`);
34324
- return {
34325
- extendedAmountInBTC: new Web3Number(0, 0),
34326
- calls: []
34327
- };
34328
- ;
35051
+ return this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.VAULT.name, amount: new Web3Number(0, 0) }, "NONE", "INVESTMENT" /* INVESTMENT */);
34329
35052
  }
34330
35053
  }
34331
- async checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter) {
35054
+ /**
35055
+ * Check if the price difference between avnu and extended is within the acceptable range to enhance the position size or close the position
35056
+ * @param extendedAdapter - the extended adapter
35057
+ * @param vesuAdapter - the vesu adapter
35058
+ * @param avnuAdapter - the avnu adapter
35059
+ * @param positionType - the position type (open or close)
35060
+ * @returns true if the price difference is within the acceptable range, false otherwise
35061
+ */
35062
+ async checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter, positionType) {
34332
35063
  const {
34333
35064
  ask,
34334
35065
  bid
@@ -34340,13 +35071,30 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34340
35071
  logger.error(`error getting btc price avnu: ${btcPriceAvnu}`);
34341
35072
  return false;
34342
35073
  }
34343
- const priceDifference = price.minus(btcPriceAvnu).toNumber();
34344
- if (priceDifference < MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED && priceDifference > MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED) {
34345
- return true;
35074
+ logger.info(`price: ${price}`);
35075
+ logger.info(`btcPriceAvnu: ${btcPriceAvnu}`);
35076
+ const priceDifference = new Web3Number(price.minus(btcPriceAvnu).toFixed(2), 0);
35077
+ logger.info(`priceDifference: ${priceDifference}`);
35078
+ if (priceDifference.isNegative()) {
35079
+ return false;
35080
+ }
35081
+ if (positionType === "open" /* OPEN */) {
35082
+ logger.info(`price difference between avnu and extended for open position: ${priceDifference.toNumber()}, minimumExtendedPriceDifferenceForSwapOpen: ${avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen}`);
35083
+ const result = priceDifference.greaterThanOrEqualTo(avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen);
35084
+ logger.info(`result: ${result}`);
35085
+ return result;
35086
+ } else {
35087
+ logger.info(`price difference between avnu and extended for close position: ${priceDifference.toNumber()}, maximumExtendedPriceDifferenceForSwapClosing: ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
35088
+ const result = priceDifference.lessThanOrEqualTo(avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing);
35089
+ logger.info(`result: ${result}`);
35090
+ return result;
34346
35091
  }
34347
- logger.error(`price difference between avnu and extended doesn't fit the range, priceDifference: ${priceDifference}`);
34348
- return false;
34349
35092
  }
35093
+ /**
35094
+ * Handle the withdrawal of assets from the vault
35095
+ * @param amount - the amount to withdraw in USDC
35096
+ * @returns the calls to be executed and the status of the calls generated along with the metadata for the calls
35097
+ */
34350
35098
  async handleWithdraw(amount) {
34351
35099
  try {
34352
35100
  const usdcBalanceVaultAllocator = await this.getUnusedBalance();
@@ -34358,12 +35106,8 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34358
35106
  const withdrawCall2 = await this.getBringLiquidityCall({
34359
35107
  amount: usdcBalanceVaultAllocator.amount
34360
35108
  });
34361
- logger.info("withdraw call", withdrawCall2);
34362
35109
  calls.push(withdrawCall2);
34363
- return {
34364
- calls,
34365
- status: true
34366
- };
35110
+ return [this.createTransactionResult(calls, true, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "WITHDRAWAL", "WITHDRAWAL" /* WITHDRAWAL */)];
34367
35111
  }
34368
35112
  const vesuAdapter = await this.getVesuAdapter();
34369
35113
  const extendedAdapter = await this.getExtendedAdapter();
@@ -34372,11 +35116,9 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34372
35116
  logger.error(
34373
35117
  `vesu or extended adapter not found: vesuAdapter=${vesuAdapter}, extendedAdapter=${extendedAdapter}`
34374
35118
  );
34375
- return {
34376
- calls,
34377
- status
34378
- };
35119
+ return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE", "WITHDRAWAL" /* WITHDRAWAL */)];
34379
35120
  }
35121
+ let transactionResults = [];
34380
35122
  const { collateralTokenAmount } = await vesuAdapter.vesuAdapter.getAssetPrices();
34381
35123
  const {
34382
35124
  collateralPrice
@@ -34385,10 +35127,7 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34385
35127
  if (!extendedPositon) {
34386
35128
  status = false;
34387
35129
  logger.error("error getting extended position", extendedPositon);
34388
- return {
34389
- calls,
34390
- status
34391
- };
35130
+ return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE", "WITHDRAWAL" /* WITHDRAWAL */)];
34392
35131
  }
34393
35132
  const amountDistributionForWithdrawal = await calculateAmountDistributionForWithdrawal(
34394
35133
  usdcBalanceDifference,
@@ -34401,61 +35140,70 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34401
35140
  logger.error(
34402
35141
  `error calculating amount distribution for withdrawal: ${amountDistributionForWithdrawal}`
34403
35142
  );
34404
- return {
34405
- calls,
34406
- status
34407
- };
35143
+ return [this.createTransactionResult(calls, status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE", "WITHDRAWAL" /* WITHDRAWAL */)];
34408
35144
  }
34409
35145
  const { vesu_amount, extended_amount } = amountDistributionForWithdrawal;
34410
35146
  if (status && vesu_amount.greaterThan(0)) {
34411
- const { calls: vesuCalls, status: vesuStatus } = await this.moveAssets(
35147
+ const { calls: vesuCalls, status: vesuStatus, transactionMetadata: vesuTransactionMetadata } = await this.moveAssets(
34412
35148
  {
34413
35149
  amount: vesu_amount,
34414
35150
  from: Protocols.VESU.name,
34415
- to: Protocols.VAULT.name
35151
+ to: Protocols.VAULT.name,
35152
+ cycleType: "WITHDRAWAL" /* WITHDRAWAL */
34416
35153
  },
34417
35154
  extendedAdapter,
34418
35155
  vesuAdapter
34419
35156
  );
34420
35157
  status = vesuStatus;
34421
- calls.push(...vesuCalls);
35158
+ transactionResults.push({
35159
+ status: vesuStatus,
35160
+ calls: vesuCalls,
35161
+ transactionMetadata: vesuTransactionMetadata
35162
+ });
34422
35163
  }
34423
35164
  if (status && extended_amount.greaterThan(0)) {
34424
- const { calls: extendedCalls, status: extendedStatus } = await this.moveAssets(
35165
+ const { calls: extendedCalls, status: extendedStatus, transactionMetadata: extendedTransactionMetadata } = await this.moveAssets(
34425
35166
  {
34426
35167
  amount: extended_amount,
34427
35168
  from: Protocols.EXTENDED.name,
34428
- to: Protocols.VAULT.name
35169
+ to: Protocols.VAULT.name,
35170
+ cycleType: "WITHDRAWAL" /* WITHDRAWAL */
34429
35171
  },
34430
35172
  extendedAdapter,
34431
35173
  vesuAdapter
34432
35174
  );
34433
35175
  status = extendedStatus;
34434
35176
  if (status) {
34435
- calls.push(...extendedCalls);
35177
+ transactionResults.push({
35178
+ status: extendedStatus,
35179
+ calls: extendedCalls,
35180
+ transactionMetadata: extendedTransactionMetadata
35181
+ });
34436
35182
  } else {
34437
35183
  logger.error("error moving assets to vault: extendedStatus: ${extendedStatus}");
34438
- return {
34439
- calls: [],
34440
- status
34441
- };
35184
+ return [this.createTransactionResult([], status, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE", "WITHDRAWAL" /* WITHDRAWAL */)];
34442
35185
  }
34443
35186
  }
34444
35187
  const withdrawCall = await this.getBringLiquidityCall({
34445
35188
  amount
34446
35189
  });
34447
35190
  logger.info("withdraw call", withdrawCall);
34448
- calls.push(withdrawCall);
34449
- return {
34450
- calls,
34451
- status
34452
- };
35191
+ transactionResults.push({
35192
+ status,
35193
+ calls: [withdrawCall],
35194
+ transactionMetadata: {
35195
+ protocolFrom: Protocols.VAULT.name,
35196
+ protocolTo: Protocols.NONE.name,
35197
+ transactionType: "WITHDRAWAL",
35198
+ usdAmount: amount.toFixed(),
35199
+ status: "PENDING",
35200
+ cycleType: "WITHDRAWAL" /* WITHDRAWAL */
35201
+ }
35202
+ });
35203
+ return transactionResults;
34453
35204
  } catch (err) {
34454
35205
  logger.error(`error handling withdrawal: ${err}`);
34455
- return {
34456
- calls: [],
34457
- status: false
34458
- };
35206
+ return [this.createTransactionResult([], false, { from: Protocols.VAULT.name, to: Protocols.NONE.name, amount }, "NONE", "WITHDRAWAL" /* WITHDRAWAL */)];
34459
35207
  }
34460
35208
  }
34461
35209
  async getAUM() {
@@ -34502,8 +35250,182 @@ var VesuExtendedMultiplierStrategy = class _VesuExtendedMultiplierStrategy exten
34502
35250
  splits: [realAUM, estimatedAUMDelta]
34503
35251
  };
34504
35252
  }
35253
+ async processTransactionDataFromSDK(txnData) {
35254
+ try {
35255
+ const txnsToBeExecuted = txnData.filter((txn) => {
35256
+ return txn.transactionMetadata.transactionType !== "NONE" && txn.transactionMetadata.protocolFrom !== "" && txn.transactionMetadata.protocolTo !== "";
35257
+ });
35258
+ const callsToBeExecutedFinal = txnsToBeExecuted.flatMap((txn) => txn.calls);
35259
+ const txnMetadata = txnsToBeExecuted.map((txn) => txn.transactionMetadata);
35260
+ return { callsToBeExecutedFinal, txnMetadata };
35261
+ } catch (err) {
35262
+ logger.error(`error processing transaction data from SDK: ${err}`);
35263
+ return null;
35264
+ }
35265
+ }
35266
+ async processTransactionMetadata(txnMetadata, extendedIntentFulfilled) {
35267
+ try {
35268
+ const txnMetadataNew = txnMetadata.map((txn) => {
35269
+ const isExtendedProtocol = txn.protocolFrom === Protocols.EXTENDED.name || txn.protocolTo === Protocols.EXTENDED.name;
35270
+ if (isExtendedProtocol) {
35271
+ txn.status = extendedIntentFulfilled ? "COMPLETED" : "PENDING";
35272
+ } else {
35273
+ txn.status = "COMPLETED";
35274
+ }
35275
+ return txn;
35276
+ });
35277
+ return txnMetadataNew;
35278
+ } catch (err) {
35279
+ logger.error(`error processing transaction data from SDK: ${err}`);
35280
+ return null;
35281
+ }
35282
+ }
35283
+ async getMaxBorrowableAmount() {
35284
+ const vesuAdapter = await this.getVesuAdapter();
35285
+ const extendedAdapter = await this.getExtendedAdapter();
35286
+ if (!vesuAdapter || !extendedAdapter) {
35287
+ return new Web3Number(0, 0);
35288
+ }
35289
+ const extendedFundingRate = new Web3Number((await extendedAdapter.getNetAPY()).toFixed(4), 0);
35290
+ const extendedPositions = await extendedAdapter.getAllOpenPositions();
35291
+ if (!extendedPositions || extendedPositions.length === 0) {
35292
+ logger.info(`no extended positions found`);
35293
+ return new Web3Number(0, 0);
35294
+ }
35295
+ const extendePositionSizeUSD = new Web3Number(extendedPositions[0].value || 0, 0);
35296
+ const vesuPositions = await vesuAdapter.getPositions();
35297
+ const vesuSupplyApy = vesuPositions[0].apy.apy;
35298
+ const vesuCollateralSizeUSD = new Web3Number(vesuPositions[0].usdValue.toFixed(USDC_TOKEN_DECIMALS), USDC_TOKEN_DECIMALS);
35299
+ const vesuDebtSizeUSD = new Web3Number(vesuPositions[1].usdValue.toFixed(USDC_TOKEN_DECIMALS), USDC_TOKEN_DECIMALS);
35300
+ const num1 = extendePositionSizeUSD.multipliedBy(extendedFundingRate);
35301
+ const num22 = vesuCollateralSizeUSD.multipliedBy(vesuSupplyApy);
35302
+ const num32 = vesuDebtSizeUSD.abs();
35303
+ const maxBorrowApy = num1.plus(num22).minus(0.1).dividedBy(num32);
35304
+ const vesuMaxBorrowableAmount = await vesuAdapter.vesuAdapter.getMaxBorrowableByInterestRate(this.config, vesuAdapter.config.debt, maxBorrowApy.toNumber());
35305
+ return new Web3Number(vesuMaxBorrowableAmount.toFixed(USDC_TOKEN_DECIMALS), USDC_TOKEN_DECIMALS);
35306
+ }
35307
+ async getVesuHealthFactors() {
35308
+ const vesuAdapter = await this.getVesuAdapter();
35309
+ const extendedAdapter = await this.getExtendedAdapter();
35310
+ if (!vesuAdapter || !extendedAdapter) {
35311
+ return [0, 0];
35312
+ }
35313
+ const vesuPositions = await vesuAdapter.getPositions();
35314
+ const vesuCollateralSizeUSD = new Web3Number(vesuPositions[0].usdValue.toFixed(USDC_TOKEN_DECIMALS), 0);
35315
+ const vesuDebtSizeUSD = new Web3Number(vesuPositions[1].usdValue.toFixed(USDC_TOKEN_DECIMALS), 0);
35316
+ const actualLtv = vesuDebtSizeUSD.dividedBy(vesuCollateralSizeUSD).abs();
35317
+ logger.info(`actualLtv: ${actualLtv.toNumber()}`);
35318
+ const maxLtv = new Web3Number(await vesuAdapter.vesuAdapter.getLTVConfig(this.config), 4);
35319
+ const healthFactor = new Web3Number(maxLtv.dividedBy(actualLtv).toFixed(4), 4);
35320
+ logger.info(`healthFactor: ${healthFactor.toNumber()}`);
35321
+ const extendedBalance = await extendedAdapter.getExtendedDepositAmount();
35322
+ if (!extendedBalance) {
35323
+ return [0, 0];
35324
+ }
35325
+ const extendedLeverage = new Web3Number((Number(extendedBalance.marginRatio) * 100).toFixed(4), 4);
35326
+ logger.info(`extendedLeverage: ${extendedLeverage.toNumber()}`);
35327
+ return [healthFactor.toNumber(), extendedLeverage.toNumber()];
35328
+ }
35329
+ async netAPY() {
35330
+ const allPositions = [];
35331
+ for (let adapter of this.metadata.additionalInfo.adapters) {
35332
+ if (adapter.adapter.name !== ExtendedAdapter.name) {
35333
+ let positions = await adapter.adapter.getPositions();
35334
+ if (positions.length > 0) {
35335
+ allPositions.push(...positions);
35336
+ }
35337
+ }
35338
+ }
35339
+ const extendedAdapter = await this.getExtendedAdapter();
35340
+ if (!extendedAdapter) {
35341
+ return {
35342
+ net: 0,
35343
+ splits: []
35344
+ };
35345
+ }
35346
+ let vesuPositions = allPositions.filter((item) => item.protocol === Protocols.VESU);
35347
+ vesuPositions.map((item) => {
35348
+ item.apy.apy = item.apy.apy * 0.1;
35349
+ });
35350
+ const extendedPositions = await extendedAdapter.getAllOpenPositions();
35351
+ const usdcToken = Global.getDefaultTokens().find((token) => token.symbol === "USDC");
35352
+ if (!extendedPositions || !usdcToken) {
35353
+ return {
35354
+ net: 0,
35355
+ splits: []
35356
+ };
35357
+ }
35358
+ const extendedPosition = extendedPositions[0] || 0;
35359
+ const extendedEquity = (await extendedAdapter.getExtendedDepositAmount())?.equity || 0;
35360
+ const extendedApy = await extendedAdapter.getNetAPY();
35361
+ const totalHoldingsUSDValue = allPositions.reduce((acc, curr) => acc + curr.usdValue, 0) + Number(extendedEquity);
35362
+ console.log(totalHoldingsUSDValue);
35363
+ const extendedPositionSizeMultipliedByApy = Number(extendedPosition.value) * extendedApy;
35364
+ let weightedAPYs = allPositions.reduce((acc, curr) => acc + curr.apy.apy * curr.usdValue, 0) + extendedPositionSizeMultipliedByApy;
35365
+ console.log(weightedAPYs);
35366
+ const netAPY = weightedAPYs / totalHoldingsUSDValue;
35367
+ console.log(netAPY);
35368
+ allPositions.push({
35369
+ tokenInfo: usdcToken,
35370
+ amount: new Web3Number(extendedPosition.size, 0),
35371
+ usdValue: Number(extendedEquity),
35372
+ apy: { apy: extendedApy, type: "base" /* BASE */ },
35373
+ remarks: "finalised" /* FINALISED */,
35374
+ protocol: Protocols.EXTENDED
35375
+ });
35376
+ return {
35377
+ net: netAPY,
35378
+ splits: allPositions.map((p) => ({ apy: p.apy.apy, id: p.remarks ?? "" }))
35379
+ };
35380
+ }
35381
+ async getWalletHoldings() {
35382
+ const usdceToken = Global.getDefaultTokens().find((token) => token.symbol === "USDCe");
35383
+ const wbtcToken = Global.getDefaultTokens().find((token) => token.symbol === "WBTC");
35384
+ const usdcToken = Global.getDefaultTokens().find((token) => token.symbol === "USDC");
35385
+ if (!usdceToken || !wbtcToken || !usdcToken) {
35386
+ return [];
35387
+ }
35388
+ const walletAddress = this.metadata.additionalInfo.walletAddress;
35389
+ const usdceWalletBalance = await new ERC20(this.config).balanceOf(
35390
+ usdceToken.address,
35391
+ walletAddress,
35392
+ usdceToken.decimals
35393
+ );
35394
+ const usdcWalletBalance = await new ERC20(this.config).balanceOf(
35395
+ usdcToken.address,
35396
+ walletAddress,
35397
+ usdcToken.decimals
35398
+ );
35399
+ const wbtcWalletBalance = await new ERC20(this.config).balanceOf(
35400
+ wbtcToken.address,
35401
+ walletAddress,
35402
+ wbtcToken.decimals
35403
+ );
35404
+ const price = await this.pricer.getPrice(usdceToken.symbol);
35405
+ const wbtcPrice = await this.pricer.getPrice(wbtcToken.symbol);
35406
+ const usdceUsdValue = Number(usdceWalletBalance.toFixed(usdceToken.decimals)) * price.price;
35407
+ const usdcUsdValue = Number(usdcWalletBalance.toFixed(usdcToken.decimals)) * price.price;
35408
+ const wbtcUsdValue = Number(wbtcWalletBalance.toFixed(wbtcToken.decimals)) * wbtcPrice.price;
35409
+ return [
35410
+ {
35411
+ tokenInfo: usdceToken,
35412
+ amount: usdceWalletBalance,
35413
+ usdValue: usdceUsdValue
35414
+ },
35415
+ {
35416
+ tokenInfo: usdcToken,
35417
+ amount: usdcWalletBalance,
35418
+ usdValue: usdcUsdValue
35419
+ },
35420
+ {
35421
+ tokenInfo: wbtcToken,
35422
+ amount: wbtcWalletBalance,
35423
+ usdValue: wbtcUsdValue
35424
+ }
35425
+ ];
35426
+ }
34505
35427
  };
34506
- function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1, extendedBackendUrl, extendedApiKey, vaultIdExtended) {
35428
+ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1, extendedBackendReadUrl, extendedBackendWriteUrl, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing) {
34507
35429
  vaultSettings.leafAdapters = [];
34508
35430
  const wbtcToken = Global.getDefaultTokens().find(
34509
35431
  (token) => token.symbol === lstSymbol
@@ -34527,7 +35449,9 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1, e
34527
35449
  ...baseAdapterConfig,
34528
35450
  avnuContract: AVNU_MIDDLEWARE,
34529
35451
  slippage: 0.01,
34530
- baseUrl: AVNU_QUOTE_URL
35452
+ baseUrl: AVNU_QUOTE_URL,
35453
+ minimumExtendedPriceDifferenceForSwapOpen,
35454
+ maximumExtendedPriceDifferenceForSwapClosing
34531
35455
  });
34532
35456
  const extendedAdapter = new ExtendedAdapter({
34533
35457
  ...baseAdapterConfig,
@@ -34536,14 +35460,17 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1, e
34536
35460
  ],
34537
35461
  vaultIdExtended,
34538
35462
  extendedContract: EXTENDED_CONTRACT,
34539
- extendedBackendUrl,
34540
- extendedApiKey,
35463
+ extendedBackendWriteUrl,
35464
+ extendedBackendReadUrl,
34541
35465
  extendedTimeout: 3e4,
34542
35466
  extendedRetries: 3,
34543
35467
  extendedBaseUrl: "https://api.starknet.extended.exchange",
34544
35468
  extendedMarketName: "BTC-USD",
34545
35469
  extendedPrecision: 5,
34546
- avnuAdapter
35470
+ avnuAdapter,
35471
+ retryDelayForOrderStatus: minimumExtendedRetriesDelayForOrderStatus ?? 3e3,
35472
+ minimumExtendedMovementAmount: minimumExtendedMovementAmount ?? 5
35473
+ //5 usdcs
34547
35474
  });
34548
35475
  const vesuMultiplyAdapter = new VesuMultiplyAdapter({
34549
35476
  poolId: pool1,
@@ -34556,7 +35483,9 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1, e
34556
35483
  supportedPositions: [
34557
35484
  { asset: wbtcToken, isDebt: false },
34558
35485
  { asset: usdcToken, isDebt: true }
34559
- ]
35486
+ ],
35487
+ minimumVesuMovementAmount: minimumVesuMovementAmount ?? 5
35488
+ //5 usdc
34560
35489
  });
34561
35490
  const unusedBalanceAdapter = new UnusedBalanceAdapter({
34562
35491
  ...baseAdapterConfig
@@ -34652,11 +35581,11 @@ function VaultDescription2(lstSymbol, underlyingSymbol) {
34652
35581
  ] });
34653
35582
  }
34654
35583
  var re7UsdcPrimeDevansh = {
34655
- vaultAddress: ContractAddr.from("0x520a2e945dd0762e5284fc1b012f62ca04e238e105eb362d5e0ce208928729d"),
34656
- manager: ContractAddr.from("0x6abe24d31cbc16d7c4acb2421a826f96273e225b4a2d168d91e65123da0bfb9"),
34657
- vaultAllocator: ContractAddr.from("0x6e4f716e22efb164ee4a831233e513f45396ad3be4cff3c07386be0226febed"),
34658
- redeemRequestNFT: ContractAddr.from("0x66060e1874e05506b18e6029188ec49bf231a411ad57642311bbdf3cb22e5f"),
34659
- aumOracle: ContractAddr.from("0x301d883b9b45c76132638e39326b3f464c492599623263d405ec0df991e27ab"),
35584
+ vaultAddress: ContractAddr.from("0x058905be22d6a81792df79425dc9641cf3e1b77f36748631b7d7e5d713a32b55"),
35585
+ manager: ContractAddr.from("0x02648d703783feb2d967cf0520314cb5aa800d69a9426f3e3b317395af44de16"),
35586
+ vaultAllocator: ContractAddr.from("0x07d533c838eab6a4d854dd3aea96a55993fccd35821921970d00bde946b63b6f"),
35587
+ redeemRequestNFT: ContractAddr.from("0x01ef91f08fb99729c00f82fc6e0ece37917bcc43952596c19996259dc8adbbba"),
35588
+ aumOracle: ContractAddr.from("0x030b6acfec162f5d6e72b8a4d2798aedce78fb39de78a8f549f7cd277ae8bc8d"),
34660
35589
  leafAdapters: [],
34661
35590
  adapters: [],
34662
35591
  targetHealthFactor: 1.4,
@@ -34669,14 +35598,15 @@ var re7UsdcPrimeDevansh = {
34669
35598
  Global.getDefaultTokens().find((token) => token.symbol === "WBTC").decimals
34670
35599
  ),
34671
35600
  borrowable_assets: [Global.getDefaultTokens().find((token) => token.symbol === "WBTC")],
34672
- minimumWBTCDifferenceForAvnuSwap: MINIMUM_WBTC_DIFFERENCE_FOR_AVNU_SWAP
35601
+ minimumWBTCDifferenceForAvnuSwap: MINIMUM_WBTC_DIFFERENCE_FOR_AVNU_SWAP,
35602
+ walletAddress: WALLET_ADDRESS
34673
35603
  };
34674
- var VesuExtendedTestStrategies = (extendedBackendUrl, extendedApiKey, vaultIdExtended) => {
35604
+ var VesuExtendedTestStrategies = (extendedBackendReadUrl, extendedBackendWriteUrl, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing) => {
34675
35605
  return [
34676
- getStrategySettingsVesuExtended("WBTC", "USDC", re7UsdcPrimeDevansh, false, false, extendedBackendUrl, extendedApiKey, vaultIdExtended)
35606
+ getStrategySettingsVesuExtended("WBTC", "USDC", re7UsdcPrimeDevansh, false, false, extendedBackendReadUrl, extendedBackendWriteUrl, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing)
34677
35607
  ];
34678
35608
  };
34679
- function getStrategySettingsVesuExtended(lstSymbol, underlyingSymbol, addresses, isPreview = false, isLST, extendedBackendUrl, extendedApiKey, vaultIdExtended) {
35609
+ function getStrategySettingsVesuExtended(lstSymbol, underlyingSymbol, addresses, isPreview = false, isLST, extendedBackendReadUrl, extendedBackendWriteUrl, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing) {
34680
35610
  return {
34681
35611
  name: `Extended Test ${underlyingSymbol}`,
34682
35612
  description: getDescription2(lstSymbol, underlyingSymbol),
@@ -34684,7 +35614,7 @@ function getStrategySettingsVesuExtended(lstSymbol, underlyingSymbol, addresses,
34684
35614
  launchBlock: 0,
34685
35615
  type: "Other",
34686
35616
  depositTokens: [Global.getDefaultTokens().find((token) => token.symbol === underlyingSymbol)],
34687
- additionalInfo: getLooperSettings2(lstSymbol, underlyingSymbol, addresses, VesuPools.Re7USDCPrime, extendedBackendUrl, extendedApiKey, vaultIdExtended),
35617
+ additionalInfo: getLooperSettings2(lstSymbol, underlyingSymbol, addresses, VesuPools.Re7USDCPrime, extendedBackendReadUrl, extendedBackendWriteUrl, vaultIdExtended, minimumExtendedMovementAmount, minimumVesuMovementAmount, minimumExtendedRetriesDelayForOrderStatus, minimumExtendedPriceDifferenceForSwapOpen, maximumExtendedPriceDifferenceForSwapClosing),
34688
35618
  risk: {
34689
35619
  riskFactor: _riskFactor3,
34690
35620
  netRisk: _riskFactor3.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor3.reduce((acc, curr) => acc + curr.weight, 0),
@@ -38927,11 +39857,13 @@ export {
38927
39857
  AssetOperationStatus,
38928
39858
  AssetOperationType,
38929
39859
  AutoCompounderSTRK,
39860
+ AvnuAdapter,
38930
39861
  AvnuWrapper,
38931
39862
  BaseAdapter,
38932
39863
  BaseStrategy,
38933
39864
  CommonAdapter,
38934
39865
  ContractAddr,
39866
+ CycleType,
38935
39867
  deployer_default as Deployer,
38936
39868
  ERC20,
38937
39869
  EXTENDED_CONTRACT,
@@ -38960,6 +39892,7 @@ export {
38960
39892
  PRICE_ROUTER,
38961
39893
  PasswordJsonCryptoUtil,
38962
39894
  PositionSide,
39895
+ PositionTypeAvnuExtended,
38963
39896
  Pragma,
38964
39897
  Pricer,
38965
39898
  PricerBase,
@@ -39009,6 +39942,7 @@ export {
39009
39942
  calculateExtendedLevergae,
39010
39943
  calculateVesUPositionSizeGivenExtended,
39011
39944
  calculateVesuLeverage,
39945
+ calculateWBTCAmountToMaintainLTV,
39012
39946
  extensionMap,
39013
39947
  getAPIUsingHeadlessBrowser,
39014
39948
  getContractDetails,