@strkfarm/sdk 1.1.39 → 1.1.41

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.
@@ -274,6 +274,25 @@ var defaultTokens = [{
274
274
  priceProxySymbol: "WBTC",
275
275
  priceCheckAmount: 1e-4
276
276
  // 112000 * 0.0001 = $11.2
277
+ }, {
278
+ name: "mRe7BTC",
279
+ symbol: "mRe7BTC",
280
+ logo: "https://imagedelivery.net/0xPAQaDtnQhBs8IzYRIlNg/3a62ecee-1e58-45d3-9862-3ce90dff1900/logo",
281
+ address: ContractAddr.from("0x4e4fb1a9ca7e84bae609b9dc0078ad7719e49187ae7e425bb47d131710eddac"),
282
+ decimals: 18,
283
+ coingeckId: void 0,
284
+ displayDecimals: 6,
285
+ priceCheckAmount: 1e-4
286
+ // 112000 * 0.0001 = $11.2
287
+ }, {
288
+ name: "mRe7YIELD",
289
+ symbol: "mRe7YIELD",
290
+ logo: "https://midas.app/assets/mre7-BcOOHm7i.svg",
291
+ address: ContractAddr.from("0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"),
292
+ decimals: 18,
293
+ coingeckId: void 0,
294
+ displayDecimals: 2,
295
+ priceCheckAmount: 100
277
296
  }];
278
297
  var tokens = defaultTokens;
279
298
  var _Global = class _Global {
@@ -2159,16 +2178,16 @@ var AvnuWrapper = class _AvnuWrapper {
2159
2178
  };
2160
2179
  return swapInfo;
2161
2180
  }
2162
- static buildZeroSwap(tokenToSell, address) {
2181
+ static buildZeroSwap(tokenToSell, beneficiary, tokenToBuy = tokenToSell) {
2163
2182
  return {
2164
2183
  token_from_address: tokenToSell.address,
2165
2184
  token_from_amount: uint256.bnToUint256(0),
2166
- token_to_address: tokenToSell.address,
2185
+ token_to_address: tokenToBuy.address,
2167
2186
  token_to_amount: uint256.bnToUint256(0),
2168
2187
  token_to_min_amount: uint256.bnToUint256(0),
2169
- beneficiary: address,
2188
+ beneficiary,
2170
2189
  integrator_fee_amount_bps: 0,
2171
- integrator_fee_recipient: address,
2190
+ integrator_fee_recipient: beneficiary,
2172
2191
  routes: []
2173
2192
  };
2174
2193
  }
@@ -4120,21 +4139,20 @@ var Harvests = class _Harvests {
4120
4139
  const rewards = await this.getHarvests(addr);
4121
4140
  if (rewards.length == 0) return [];
4122
4141
  const unClaimed = [];
4123
- const cls = await this.config.provider.getClassAt(rewards[0].rewardsContract.address);
4124
- for (let reward of rewards) {
4125
- const contract = new Contract4({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
4126
- const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
4127
- logger.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}`);
4128
- if (isClaimed) {
4129
- return unClaimed;
4130
- }
4131
- const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
4132
- if (bal.lessThan(reward.claim.amount)) {
4133
- logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
4134
- continue;
4135
- }
4136
- unClaimed.unshift(reward);
4142
+ const reward = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime())[0];
4143
+ const cls = await this.config.provider.getClassAt(reward.rewardsContract.address);
4144
+ const contract = new Contract4({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
4145
+ const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
4146
+ logger.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}`);
4147
+ if (isClaimed) {
4148
+ return unClaimed;
4137
4149
  }
4150
+ const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
4151
+ if (bal.lessThan(reward.claim.amount)) {
4152
+ logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
4153
+ return unClaimed;
4154
+ }
4155
+ unClaimed.unshift(reward);
4138
4156
  return unClaimed;
4139
4157
  }
4140
4158
  };
@@ -15401,6 +15419,91 @@ var apolloClient = new ApolloClient({
15401
15419
  });
15402
15420
  var apollo_client_default = apolloClient;
15403
15421
 
15422
+ // src/utils/math-utils.ts
15423
+ async function binarySearch(lowWei, highWei, callback) {
15424
+ while (lowWei <= highWei) {
15425
+ const diff = highWei - lowWei;
15426
+ const mid = lowWei + diff / 2n;
15427
+ const result = await callback(mid);
15428
+ if (result === "found") {
15429
+ return mid;
15430
+ } else if (result == "retry") {
15431
+ } else if (result === "go_low") {
15432
+ highWei = mid - BigInt(1);
15433
+ } else {
15434
+ lowWei = mid + BigInt(1);
15435
+ }
15436
+ }
15437
+ return null;
15438
+ }
15439
+ async function findMaxInputWithSlippage(options) {
15440
+ const {
15441
+ apiGetOutput,
15442
+ maxInput,
15443
+ maxSlippagePercent,
15444
+ tolerance,
15445
+ minInput = 0,
15446
+ referenceAmountMultiplier = 1e-3,
15447
+ referenceRate = 0
15448
+ } = options;
15449
+ let apiCalls = 0;
15450
+ if (!referenceRate && !referenceAmountMultiplier) {
15451
+ throw new Error("One of referenceRate or referenceAmountMultiplier must be provided");
15452
+ }
15453
+ let _referenceRate = referenceRate;
15454
+ if (!_referenceRate) {
15455
+ const smallAmount = maxInput * referenceAmountMultiplier;
15456
+ const referenceOutput = await apiGetOutput(smallAmount);
15457
+ apiCalls++;
15458
+ _referenceRate = referenceOutput / smallAmount;
15459
+ }
15460
+ async function checkSlippage(inputAmount) {
15461
+ const actualOutput = await apiGetOutput(inputAmount);
15462
+ apiCalls++;
15463
+ const expectedOutput = inputAmount * referenceRate;
15464
+ const slippage = (expectedOutput - actualOutput) / expectedOutput;
15465
+ logger.verbose(`findMaxInputWithSlippage::checkSlippage inputAmount: ${inputAmount}, actualOutput: ${actualOutput}, slippage: ${slippage}, maxSlippagePercent: ${maxSlippagePercent}`);
15466
+ return {
15467
+ acceptable: slippage <= maxSlippagePercent,
15468
+ slippage,
15469
+ output: actualOutput
15470
+ };
15471
+ }
15472
+ const maxCheck = await checkSlippage(maxInput);
15473
+ if (maxCheck.acceptable) {
15474
+ return {
15475
+ optimalInput: maxInput,
15476
+ actualOutput: maxCheck.output,
15477
+ actualSlippage: maxCheck.slippage,
15478
+ apiCallsUsed: apiCalls
15479
+ };
15480
+ }
15481
+ let left = minInput;
15482
+ let right = maxInput;
15483
+ let bestInput = minInput;
15484
+ let bestOutput = 0;
15485
+ let bestSlippage = 0;
15486
+ const convergenceThreshold = tolerance * maxInput;
15487
+ while (right - left > convergenceThreshold) {
15488
+ const mid = (left + right) / 2;
15489
+ const midCheck = await checkSlippage(mid);
15490
+ if (midCheck.acceptable) {
15491
+ bestInput = mid;
15492
+ bestOutput = midCheck.output;
15493
+ bestSlippage = midCheck.slippage;
15494
+ left = mid;
15495
+ } else {
15496
+ right = mid;
15497
+ }
15498
+ }
15499
+ return {
15500
+ optimalInput: bestInput,
15501
+ actualOutput: bestOutput,
15502
+ actualSlippage: bestSlippage,
15503
+ apiCallsUsed: apiCalls
15504
+ };
15505
+ }
15506
+
15404
15507
  // src/strategies/ekubo-cl-vault.tsx
15405
15508
  import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
15406
15509
  var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
@@ -15687,7 +15790,6 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
15687
15790
  for (let i = len - 1; i >= 0; --i) {
15688
15791
  let record = await this.contract.call("get_rewards_info", [i]);
15689
15792
  logger.verbose(`${_EkuboCLVault.name}: getHarvestRewardShares: ${i}`);
15690
- console.log(record);
15691
15793
  const block = Number(record.block_number);
15692
15794
  if (block < fromBlock) {
15693
15795
  return shares;
@@ -15887,16 +15989,10 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
15887
15989
  const sqrtRatio = _EkuboCLVault.div2Power128(
15888
15990
  BigInt(priceInfo.sqrt_ratio.toString())
15889
15991
  );
15890
- console.log(
15891
- `EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, sqrtRatio: ${sqrtRatio}, ${priceInfo.sqrt_ratio.toString()}`
15892
- );
15893
15992
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
15894
15993
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
15895
15994
  const price = sqrtRatio * sqrtRatio * 10 ** token0Info.decimals / 10 ** token1Info.decimals;
15896
15995
  const tick = priceInfo.tick;
15897
- console.log(
15898
- `EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, price: ${price}, tick: ${tick.mag}, ${tick.sign}`
15899
- );
15900
15996
  return {
15901
15997
  price,
15902
15998
  tick: Number(tick.mag) * (tick.sign ? -1 : 1),
@@ -16523,62 +16619,193 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16523
16619
  logger.verbose(
16524
16620
  `${_EkuboCLVault.name}: harvest => Processing claim, isToken1: ${isToken1} amount: ${postFeeAmount.toWei()}`
16525
16621
  );
16526
- const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
16527
- const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
16622
+ const isRewardTokenMatch = claim.token.eq(poolKey.token0) || claim.token.eq(poolKey.token1);
16623
+ if (isRewardTokenMatch) {
16624
+ const _callsFinal = await this._handleRewardAndVaultTokenMatchHarvest({
16625
+ acc,
16626
+ claim,
16627
+ isToken1,
16628
+ token0Info,
16629
+ token1Info,
16630
+ postFeeAmount,
16631
+ poolKey,
16632
+ bounds,
16633
+ maxIterations,
16634
+ priceRatioPrecision
16635
+ });
16636
+ calls.push(..._callsFinal);
16637
+ } else {
16638
+ const _callsFinal = await this._handleRewardAndVaultTokenMismatchHarvest({
16639
+ claim,
16640
+ token0Info,
16641
+ token1Info,
16642
+ postFeeAmount,
16643
+ poolKey,
16644
+ bounds,
16645
+ maxIterations,
16646
+ priceRatioPrecision,
16647
+ acc
16648
+ });
16649
+ calls.push(..._callsFinal);
16650
+ }
16651
+ }
16652
+ return calls;
16653
+ }
16654
+ /**
16655
+ * @description This funciton requires atleast one of the pool tokens to be reward token
16656
+ * i.e. STRK.
16657
+ * @param params
16658
+ */
16659
+ async _handleRewardAndVaultTokenMatchHarvest(params) {
16660
+ const { acc, claim, isToken1, token0Info, token1Info, postFeeAmount, poolKey, bounds, maxIterations, priceRatioPrecision } = params;
16661
+ const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
16662
+ const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
16663
+ logger.verbose(
16664
+ `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
16665
+ );
16666
+ const swapInfo = await this.getSwapInfoGivenAmounts(
16667
+ poolKey,
16668
+ token0Amt,
16669
+ token1Amt,
16670
+ bounds,
16671
+ maxIterations,
16672
+ priceRatioPrecision
16673
+ );
16674
+ swapInfo.token_to_address = token0Info.address.address;
16675
+ logger.verbose(
16676
+ `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
16677
+ );
16678
+ logger.verbose(
16679
+ `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
16680
+ );
16681
+ const harvestEstimateCall = async (swapInfo1) => {
16682
+ const swap1Amount = Web3Number.fromWei(
16683
+ uint2564.uint256ToBN(swapInfo1.token_from_amount).toString(),
16684
+ 18
16685
+ // cause its always STRK?
16686
+ ).minimum(
16687
+ postFeeAmount.toFixed(18)
16688
+ // cause always strk
16689
+ );
16690
+ swapInfo.token_from_amount = uint2564.bnToUint256(swap1Amount.toWei());
16691
+ swapInfo.token_to_min_amount = uint2564.bnToUint256(
16692
+ swap1Amount.multipliedBy(0).toWei()
16693
+ // placeholder
16694
+ );
16528
16695
  logger.verbose(
16529
- `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
16696
+ `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
16530
16697
  );
16531
- const swapInfo = await this.getSwapInfoGivenAmounts(
16532
- poolKey,
16533
- token0Amt,
16534
- token1Amt,
16535
- bounds,
16536
- maxIterations,
16537
- priceRatioPrecision
16698
+ const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
16699
+ logger.verbose(
16700
+ `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
16538
16701
  );
16539
- swapInfo.token_to_address = token0Info.address.address;
16702
+ const swapInfo2 = {
16703
+ ...swapInfo,
16704
+ token_from_amount: uint2564.bnToUint256(remainingAmount.toWei())
16705
+ };
16706
+ swapInfo2.token_to_address = token1Info.address.address;
16540
16707
  logger.verbose(
16541
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
16708
+ `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
16709
+ swapInfo
16710
+ )}`
16542
16711
  );
16543
16712
  logger.verbose(
16544
- `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
16713
+ `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
16714
+ swapInfo2
16715
+ )}`
16545
16716
  );
16546
- const harvestEstimateCall = async (swapInfo1) => {
16547
- const swap1Amount = Web3Number.fromWei(
16548
- uint2564.uint256ToBN(swapInfo1.token_from_amount).toString(),
16549
- 18
16550
- // cause its always STRK?
16551
- ).minimum(
16552
- postFeeAmount.toFixed(18)
16553
- // cause always strk
16554
- );
16555
- swapInfo.token_from_amount = uint2564.bnToUint256(swap1Amount.toWei());
16556
- swapInfo.token_to_min_amount = uint2564.bnToUint256(
16557
- swap1Amount.multipliedBy(0).toWei()
16558
- // placeholder
16559
- );
16560
- logger.verbose(
16561
- `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
16562
- );
16563
- const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
16564
- logger.verbose(
16565
- `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
16566
- );
16567
- const swapInfo2 = {
16568
- ...swapInfo,
16569
- token_from_amount: uint2564.bnToUint256(remainingAmount.toWei())
16570
- };
16571
- swapInfo2.token_to_address = token1Info.address.address;
16572
- logger.verbose(
16573
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
16574
- swapInfo
16575
- )}`
16576
- );
16577
- logger.verbose(
16578
- `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
16579
- swapInfo2
16580
- )}`
16581
- );
16717
+ const calldata = [
16718
+ claim.rewardsContract.address,
16719
+ {
16720
+ id: claim.claim.id,
16721
+ amount: claim.claim.amount.toWei(),
16722
+ claimee: claim.claim.claimee.address
16723
+ },
16724
+ claim.proof.map((p) => num5.getDecimalString(p)),
16725
+ swapInfo,
16726
+ swapInfo2
16727
+ ];
16728
+ logger.verbose(
16729
+ `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
16730
+ calldata
16731
+ )}`
16732
+ );
16733
+ return [this.contract.populate("harvest", calldata)];
16734
+ };
16735
+ const _callsFinal = await this.rebalanceIter(
16736
+ swapInfo,
16737
+ acc,
16738
+ harvestEstimateCall,
16739
+ claim.token.eq(poolKey.token0),
16740
+ 0,
16741
+ 0n,
16742
+ BigInt(postFeeAmount.toWei())
16743
+ // upper limit is the post fee amount
16744
+ );
16745
+ logger.verbose(
16746
+ `${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
16747
+ _callsFinal
16748
+ )}`
16749
+ );
16750
+ return _callsFinal;
16751
+ }
16752
+ /**
16753
+ * @description This function handles harvesting of reward token that is not the same as any of the vault token
16754
+ * i.e. STRK is not part of vault tokens like BTC/ETH
16755
+ * @param params
16756
+ * @returns
16757
+ */
16758
+ async _handleRewardAndVaultTokenMismatchHarvest(params) {
16759
+ const { acc, claim, token0Info, token1Info, postFeeAmount, poolKey, bounds, maxIterations, priceRatioPrecision } = params;
16760
+ let token0Amt = postFeeAmount;
16761
+ const beneficiary = this.address.address;
16762
+ let harvestCall = null;
16763
+ harvestCall = await this.harvestMismatchEstimateCallFn({
16764
+ postFeeAmount,
16765
+ claim,
16766
+ token0Info,
16767
+ token1Info,
16768
+ acc
16769
+ });
16770
+ if (!harvestCall) {
16771
+ throw new Error("Harvest call not found");
16772
+ }
16773
+ return [harvestCall];
16774
+ }
16775
+ // given an amount (i.e. portion of reward to use to swap to token0), returns info on increasing or decreasing
16776
+ // amount for binary search
16777
+ async harvestMismatchEstimateCallFn(params) {
16778
+ const { postFeeAmount, claim, token0Info, token1Info, acc } = params;
16779
+ let harvestCall = null;
16780
+ const binarySearchCallbackFn = async (mid) => {
16781
+ const rewardPart2 = BigInt(postFeeAmount.toWei()) - mid;
16782
+ const avnuWrapper = new AvnuWrapper();
16783
+ const beneficiary = this.address.address;
16784
+ const quote1 = await avnuWrapper.getQuotes(
16785
+ claim.token.address,
16786
+ token0Info.address.address,
16787
+ mid.toString(),
16788
+ beneficiary
16789
+ );
16790
+ const swapInfo1 = await avnuWrapper.getSwapInfo(
16791
+ quote1,
16792
+ beneficiary,
16793
+ 0,
16794
+ beneficiary
16795
+ );
16796
+ const quote2 = await avnuWrapper.getQuotes(
16797
+ claim.token.address,
16798
+ token1Info.address.address,
16799
+ rewardPart2.toString(),
16800
+ beneficiary
16801
+ );
16802
+ const swapInfo2 = await avnuWrapper.getSwapInfo(
16803
+ quote2,
16804
+ beneficiary,
16805
+ 0,
16806
+ beneficiary
16807
+ );
16808
+ try {
16582
16809
  const calldata = [
16583
16810
  claim.rewardsContract.address,
16584
16811
  {
@@ -16587,34 +16814,23 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16587
16814
  claimee: claim.claim.claimee.address
16588
16815
  },
16589
16816
  claim.proof.map((p) => num5.getDecimalString(p)),
16590
- swapInfo,
16817
+ swapInfo1,
16591
16818
  swapInfo2
16592
16819
  ];
16593
- logger.verbose(
16594
- `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
16595
- calldata
16596
- )}`
16597
- );
16598
- return [this.contract.populate("harvest", calldata)];
16599
- };
16600
- const _callsFinal = await this.rebalanceIter(
16601
- swapInfo,
16602
- acc,
16603
- harvestEstimateCall,
16604
- claim.token.eq(poolKey.token0),
16605
- 0,
16606
- 0n,
16607
- BigInt(postFeeAmount.toWei())
16608
- // upper limit is the post fee amount
16609
- );
16610
- logger.verbose(
16611
- `${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
16612
- _callsFinal
16613
- )}`
16614
- );
16615
- calls.push(..._callsFinal);
16616
- }
16617
- return calls;
16820
+ harvestCall = this.contract.populate("harvest", calldata);
16821
+ const gas = await acc.estimateInvokeFee(harvestCall);
16822
+ return "found";
16823
+ } catch (err) {
16824
+ if (err.message.includes("invalid token0 amount")) {
16825
+ return "go_low";
16826
+ } else if (err.message.includes("invalid token1 amount")) {
16827
+ return "go_high";
16828
+ }
16829
+ return "retry";
16830
+ }
16831
+ };
16832
+ await binarySearch(0n, BigInt(postFeeAmount.toWei()), binarySearchCallbackFn);
16833
+ return harvestCall;
16618
16834
  }
16619
16835
  async getInvestmentFlows() {
16620
16836
  const netYield = await this.netAPY();
@@ -19146,7 +19362,58 @@ function toBigInt(value) {
19146
19362
  }
19147
19363
 
19148
19364
  // src/strategies/universal-adapters/baseAdapter.ts
19365
+ var APYType = /* @__PURE__ */ ((APYType2) => {
19366
+ APYType2["BASE"] = "base";
19367
+ APYType2["REWARD"] = "reward";
19368
+ APYType2["LST"] = "lst";
19369
+ return APYType2;
19370
+ })(APYType || {});
19149
19371
  var BaseAdapter = class extends CacheClass {
19372
+ // readonly config: BaseAdapterConfig;
19373
+ // constructor(config: BaseAdapterConfig) {
19374
+ // super();
19375
+ // this.config = config;
19376
+ // }
19377
+ constructor() {
19378
+ super();
19379
+ }
19380
+ // /**
19381
+ // * Loop through all supported positions and return amount, usd value, remarks and apy for each
19382
+ // */
19383
+ // async getPositions(): Promise<PositionInfo[]> {
19384
+ // const results: PositionInfo[] = [];
19385
+ // for (const supported of this.config.supportedPositions) {
19386
+ // const amount = await this.getPosition(supported);
19387
+ // const usdValue = await this.getUSDValue(supported.asset, amount);
19388
+ // const apy = await this.getAPY(supported);
19389
+ // results.push({ amount, usdValue, apy });
19390
+ // }
19391
+ // return results;
19392
+ // }
19393
+ // /**
19394
+ // * Implemented by child adapters to compute APY for a given supported position
19395
+ // */
19396
+ // protected abstract getAPY(supportedPosition: SupportedPosition): Promise<PositionAPY>;
19397
+ // /**
19398
+ // * Implemented by child adapters to fetch amount for a given supported position
19399
+ // */
19400
+ // protected abstract getPosition(supportedPosition: SupportedPosition): Promise<Web3Number>;
19401
+ // /**
19402
+ // * Implemented by child adapters to calculate maximum deposit positions
19403
+ // * @param amount Optional amount in baseToken to deposit
19404
+ // */
19405
+ // protected abstract maxDeposit(amount?: Web3Number): Promise<PositionInfo[]>;
19406
+ // /**
19407
+ // * Implemented by child adapters to calculate maximum withdraw positions
19408
+ // */
19409
+ // protected abstract maxWithdraw(): Promise<PositionInfo[]>;
19410
+ // /**
19411
+ // * Uses pricer to convert an amount of an asset to USD value
19412
+ // */
19413
+ // protected async getUSDValue(asset: TokenInfo, amount: Web3Number): Promise<number> {
19414
+ // const priceInfo = await this.config.pricer.getPrice(asset.symbol);
19415
+ // return amount.toNumber() * priceInfo.price;
19416
+ // }
19150
19417
  constructSimpleLeafData(params, sanitizer = SIMPLE_SANITIZER) {
19151
19418
  const { id, target, method, packedArguments } = params;
19152
19419
  return {
@@ -19164,6 +19431,94 @@ var BaseAdapter = class extends CacheClass {
19164
19431
  ]
19165
19432
  };
19166
19433
  }
19434
+ // /**
19435
+ // * Implementor must provide target/method/packedArguments/sanitizer for deposit leaf construction
19436
+ // */
19437
+ // protected abstract _getDepositLeaf(): {
19438
+ // target: ContractAddr,
19439
+ // method: string,
19440
+ // packedArguments: bigint[],
19441
+ // sanitizer: ContractAddr,
19442
+ // id: string
19443
+ // }[];
19444
+ // /**
19445
+ // * Implementor must provide target/method/packedArguments/sanitizer for withdraw leaf construction
19446
+ // */
19447
+ // protected abstract _getWithdrawLeaf(): {
19448
+ // target: ContractAddr,
19449
+ // method: string,
19450
+ // packedArguments: bigint[],
19451
+ // sanitizer: ContractAddr,
19452
+ // id: string
19453
+ // }[];
19454
+ // /**
19455
+ // * Returns deposit leaf adapter using configured proof id
19456
+ // */
19457
+ // getDepositLeaf(): AdapterLeafType<T1> {
19458
+ // const leafConfigs = this._getDepositLeaf();
19459
+ // const leaves = leafConfigs.map(config => {
19460
+ // const { target, method, packedArguments, sanitizer, id } = config;
19461
+ // const leaf = this.constructSimpleLeafData({
19462
+ // id: id,
19463
+ // target,
19464
+ // method,
19465
+ // packedArguments
19466
+ // }, sanitizer);
19467
+ // return leaf;
19468
+ // });
19469
+ // return { leaves, callConstructor: this.getDepositCall.bind(this) as unknown as GenerateCallFn<T1> };
19470
+ // }
19471
+ // /**
19472
+ // * Returns withdraw leaf adapter using configured proof id
19473
+ // */
19474
+ // getWithdrawLeaf(): AdapterLeafType<T2> {
19475
+ // const leafConfigs = this._getWithdrawLeaf();
19476
+ // const leaves = leafConfigs.map(config => {
19477
+ // const { target, method, packedArguments, sanitizer, id } = config;
19478
+ // const leaf = this.constructSimpleLeafData({
19479
+ // id: id,
19480
+ // target,
19481
+ // method,
19482
+ // packedArguments
19483
+ // }, sanitizer ?? SIMPLE_SANITIZER);
19484
+ // return leaf;
19485
+ // });
19486
+ // return { leaves, callConstructor: this.getWithdrawCall.bind(this) as unknown as GenerateCallFn<T2> };
19487
+ // }
19488
+ // /**
19489
+ // * Default deposit callConstructor: expects params as calldata (bigint[])
19490
+ // */
19491
+ // protected getDepositCall<T1 = bigint[]>(params: T1): ManageCall[] {
19492
+ // const leafConfigs = this._getDepositLeaf();
19493
+ // return leafConfigs.map(config => {
19494
+ // const { target, method, sanitizer } = config;
19495
+ // return {
19496
+ // sanitizer: sanitizer ?? SIMPLE_SANITIZER,
19497
+ // call: {
19498
+ // contractAddress: target,
19499
+ // selector: hash.getSelectorFromName(method),
19500
+ // calldata: params as unknown as bigint[]
19501
+ // }
19502
+ // };
19503
+ // });
19504
+ // }
19505
+ // /**
19506
+ // * Default withdraw callConstructor: expects params as calldata (bigint[])
19507
+ // */
19508
+ // protected getWithdrawCall<T2 = bigint[]>(params: T2): ManageCall[] {
19509
+ // const leafConfigs = this._getWithdrawLeaf();
19510
+ // return leafConfigs.map(config => {
19511
+ // const { target, method, sanitizer } = config;
19512
+ // return {
19513
+ // sanitizer: sanitizer ?? SIMPLE_SANITIZER,
19514
+ // call: {
19515
+ // contractAddress: target,
19516
+ // selector: hash.getSelectorFromName(method),
19517
+ // calldata: params as unknown as bigint[]
19518
+ // }
19519
+ // };
19520
+ // });
19521
+ // }
19167
19522
  };
19168
19523
 
19169
19524
  // src/strategies/universal-adapters/common-adapter.ts
@@ -26766,7 +27121,20 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26766
27121
  }
26767
27122
  const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address]);
26768
27123
  logger.verbose(`${this.config.debt.symbol}::VesuAdapter::getDebtCap debt_cap: ${output.debt_cap.toString()}`);
26769
- return Web3Number.fromWei(output.debt_cap.toString(), this.config.debt.decimals);
27124
+ if (!isV2) {
27125
+ throw new Error("getDebtCap is not supported for v1");
27126
+ }
27127
+ const currentDebt = await this.getCurrentDebtUtilisationAmount(config);
27128
+ logger.verbose(`${this.config.debt.symbol}::VesuAdapter::getDebtCap currentDebt: ${currentDebt.toString()}`);
27129
+ return Web3Number.fromWei(output.debt_cap.toString(), this.config.debt.decimals).minus(currentDebt);
27130
+ }
27131
+ async getCurrentDebtUtilisationAmount(config) {
27132
+ const { contract, isV2 } = await this.getVesuSingletonContract(config, this.config.poolId);
27133
+ if (!isV2) {
27134
+ throw new Error("getCurrentDebtUtilisationAmount is not supported for v1");
27135
+ }
27136
+ const output = await contract.call("pairs", [this.config.collateral.address.address, this.config.debt.address.address]);
27137
+ return new Web3Number((Number(output.total_nominal_debt) / 1e18).toFixed(9), this.config.debt.decimals);
26770
27138
  }
26771
27139
  async getMaxBorrowableByInterestRate(config, asset, maxBorrowAPY) {
26772
27140
  const { contract, isV2 } = await this.getVesuSingletonContract(config, this.config.poolId);
@@ -26799,16 +27167,17 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26799
27167
  const assetConfig = isV2 ? _assetConfig : _assetConfig["0"];
26800
27168
  const timeDelta = assetConfig.last_updated;
26801
27169
  const lastFullUtilizationRate = assetConfig.last_full_utilization_rate;
26802
- const totalSupply = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals).plus(Web3Number.fromWei(assetConfig.reserve, asset.decimals));
27170
+ const currentDebt = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals);
27171
+ const totalSupply = currentDebt.plus(Web3Number.fromWei(assetConfig.reserve, asset.decimals));
26803
27172
  const ratePerSecond = BigInt(Math.round(maxBorrowAPY / 365 / 24 / 60 / 60 * Number(SCALE)));
26804
27173
  const maxUtilisation = this.getMaxUtilizationGivenRatePerSecond(interestRateConfig, ratePerSecond, timeDelta, lastFullUtilizationRate);
26805
27174
  logger.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate maxUtilisation: ${Number(maxUtilisation) / 1e18}, totalSupply: ${totalSupply.toString()}`);
26806
27175
  const maxDebtToHave = totalSupply.multipliedBy(Number(maxUtilisation) / 1e18);
26807
- const currentDebt = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals);
27176
+ logger.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate currentDebt: ${currentDebt.toString()}, maxDebtToHave: ${maxDebtToHave.toString()}`);
26808
27177
  return maxDebtToHave.minus(currentDebt);
26809
27178
  }
26810
- async getLTVConfig(config) {
26811
- const CACHE_KEY = "ltv_config";
27179
+ async getLTVConfig(config, blockNumber = "latest") {
27180
+ const CACHE_KEY = `ltv_config_${blockNumber}`;
26812
27181
  const cacheData = this.getCache(CACHE_KEY);
26813
27182
  if (cacheData) {
26814
27183
  return cacheData;
@@ -26816,10 +27185,10 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26816
27185
  const { contract, isV2 } = await this.getVesuSingletonContract(config, this.config.poolId);
26817
27186
  let ltv = 0;
26818
27187
  if (isV2) {
26819
- const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address]);
27188
+ const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address], { blockIdentifier: blockNumber });
26820
27189
  ltv = Number(output.max_ltv) / 1e18;
26821
27190
  } else {
26822
- const output = await contract.call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address]);
27191
+ const output = await contract.call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address], { blockIdentifier: blockNumber });
26823
27192
  ltv = Number(output.max_ltv) / 1e18;
26824
27193
  }
26825
27194
  if (ltv == 0) {
@@ -26828,11 +27197,11 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26828
27197
  this.setCache(CACHE_KEY, ltv, 3e5);
26829
27198
  return this.getCache(CACHE_KEY);
26830
27199
  }
26831
- async getPositions(config) {
27200
+ async getPositions(config, blockNumber = "latest") {
26832
27201
  if (!this.pricer) {
26833
27202
  throw new Error("Pricer is not initialized");
26834
27203
  }
26835
- const CACHE_KEY = "positions";
27204
+ const CACHE_KEY = `positions_${blockNumber}`;
26836
27205
  const cacheData = this.getCache(CACHE_KEY);
26837
27206
  if (cacheData) {
26838
27207
  return cacheData;
@@ -26844,7 +27213,8 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26844
27213
  this.config.collateral.address.address,
26845
27214
  this.config.debt.address.address,
26846
27215
  this.config.vaultAllocator.address
26847
- ]);
27216
+ ], { blockIdentifier: blockNumber });
27217
+ console.log(output);
26848
27218
  const token1Price = await this.pricer.getPrice(this.config.collateral.symbol);
26849
27219
  const token2Price = await this.pricer.getPrice(this.config.debt.symbol);
26850
27220
  logger.verbose(`VesuAdapter::getPositions token1Price: ${token1Price.price}, token2Price: ${token2Price.price}`);
@@ -26864,11 +27234,11 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26864
27234
  this.setCache(CACHE_KEY, value, 6e4);
26865
27235
  return value;
26866
27236
  }
26867
- async getCollateralization(config) {
27237
+ async getCollateralization(config, blockNumber = "latest") {
26868
27238
  if (!this.pricer) {
26869
27239
  throw new Error("Pricer is not initialized");
26870
27240
  }
26871
- const CACHE_KEY = "collateralization";
27241
+ const CACHE_KEY = `collateralization_${blockNumber}`;
26872
27242
  const cacheData = this.getCache(CACHE_KEY);
26873
27243
  if (cacheData) {
26874
27244
  return cacheData;
@@ -26880,7 +27250,7 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26880
27250
  this.config.collateral.address.address,
26881
27251
  this.config.debt.address.address,
26882
27252
  this.config.vaultAllocator.address
26883
- ]);
27253
+ ], { blockIdentifier: blockNumber });
26884
27254
  const collateralAmount = Web3Number.fromWei(output["1"].toString(), 18);
26885
27255
  const debtAmount = Web3Number.fromWei(output["2"].toString(), 18);
26886
27256
  const value = [{
@@ -26917,9 +27287,9 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26917
27287
  ltv
26918
27288
  };
26919
27289
  }
26920
- async getHealthFactor() {
26921
- const ltv = await this.getLTVConfig(this.networkConfig);
26922
- const collateralisation = await this.getCollateralization(this.networkConfig);
27290
+ async getHealthFactor(blockNumber = "latest") {
27291
+ const ltv = await this.getLTVConfig(this.networkConfig, blockNumber);
27292
+ const collateralisation = await this.getCollateralization(this.networkConfig, blockNumber);
26923
27293
  return collateralisation[0].usdValue * ltv / collateralisation[1].usdValue;
26924
27294
  }
26925
27295
  static async getVesuPools(retry = 0) {
@@ -29581,11 +29951,11 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
29581
29951
  vesuAdapter2.networkConfig = this.config;
29582
29952
  return [vesuAdapter1, vesuAdapter2];
29583
29953
  }
29584
- async getVesuPositions() {
29954
+ async getVesuPositions(blockNumber = "latest") {
29585
29955
  const adapters = this.getVesuAdapters();
29586
29956
  const positions = [];
29587
29957
  for (const adapter of adapters) {
29588
- positions.push(...await adapter.getPositions(this.config));
29958
+ positions.push(...await adapter.getPositions(this.config, blockNumber));
29589
29959
  }
29590
29960
  return positions;
29591
29961
  }
@@ -29654,8 +30024,8 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
29654
30024
  async getLSTAPR(address) {
29655
30025
  return 0;
29656
30026
  }
29657
- async getVesuHealthFactors() {
29658
- return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor()));
30027
+ async getVesuHealthFactors(blockNumber = "latest") {
30028
+ return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor(blockNumber)));
29659
30029
  }
29660
30030
  async computeRebalanceConditionAndReturnCalls() {
29661
30031
  const vesuAdapters = this.getVesuAdapters();
@@ -30251,6 +30621,42 @@ var UniversalStrategies = [
30251
30621
 
30252
30622
  // src/strategies/universal-lst-muliplier-strategy.tsx
30253
30623
  import { Contract as Contract10, uint256 as uint2569 } from "starknet";
30624
+
30625
+ // src/utils/health-factor-math.ts
30626
+ var HealthFactorMath = class {
30627
+ static getCollateralRequired(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo) {
30628
+ const numerator = debtAmount.multipliedBy(debtPrice).multipliedBy(targetHF);
30629
+ const denominator = collateralPrice * maxLTV;
30630
+ const collateralAmount = numerator.dividedBy(denominator);
30631
+ const netCollateral = new Web3Number(collateralAmount.toString(), collateralTokenInfo.decimals);
30632
+ return netCollateral;
30633
+ }
30634
+ static getMinCollateralRequiredOnLooping(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo) {
30635
+ const netCollateral = this.getCollateralRequired(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo);
30636
+ const collateralFromDebt = new Web3Number(debtAmount.multipliedBy(debtPrice).dividedBy(collateralPrice).toString(), collateralTokenInfo.decimals);
30637
+ return netCollateral.minus(collateralFromDebt);
30638
+ }
30639
+ static getHealthFactor(collateralAmount, collateralPrice, maxLTV, debtAmount, debtPrice) {
30640
+ const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
30641
+ const denominator = debtAmount.multipliedBy(debtPrice);
30642
+ const healthFactor = numerator.dividedBy(denominator);
30643
+ return healthFactor.toNumber();
30644
+ }
30645
+ static getMaxDebtAmountOnLooping(collateralAmount, collateralPrice, maxLTV, targetHF, debtPrice, debtTokenInfo) {
30646
+ const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
30647
+ const denominator = targetHF - maxLTV;
30648
+ const debtAmount = numerator.dividedBy(denominator);
30649
+ return new Web3Number(debtAmount.toString(), debtTokenInfo.decimals);
30650
+ }
30651
+ static getMaxDebtAmount(collateralAmount, collateralPrice, maxLTV, targetHF, debtPrice, debtTokenInfo) {
30652
+ const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
30653
+ const denominator = targetHF * debtPrice;
30654
+ const debtAmount = numerator.dividedBy(denominator);
30655
+ return new Web3Number(debtAmount.toString(), debtTokenInfo.decimals);
30656
+ }
30657
+ };
30658
+
30659
+ // src/strategies/universal-lst-muliplier-strategy.tsx
30254
30660
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
30255
30661
  var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy extends UniversalStrategy {
30256
30662
  constructor(config, pricer, metadata) {
@@ -30265,15 +30671,14 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30265
30671
  }
30266
30672
  }
30267
30673
  asset() {
30268
- const vesuAdapter1 = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
30269
- return vesuAdapter1.config.collateral;
30674
+ return this.getVesuSameTokenAdapter().config.collateral;
30270
30675
  }
30271
30676
  getTag() {
30272
30677
  return `${_UniversalLstMultiplierStrategy.name}:${this.metadata.name}`;
30273
30678
  }
30274
30679
  // Vesu adapter with LST and base token match
30275
30680
  getVesuSameTokenAdapter() {
30276
- const baseAdapter = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
30681
+ const baseAdapter = this.getAdapter(getVesuLegId("vesu_leg1" /* VESU_LEG1 */, this.metadata.additionalInfo.underlyingToken.symbol));
30277
30682
  baseAdapter.networkConfig = this.config;
30278
30683
  baseAdapter.pricer = this.pricer;
30279
30684
  return baseAdapter;
@@ -30321,20 +30726,52 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30321
30726
  return price;
30322
30727
  }
30323
30728
  async getAvnuSwapMultiplyCall(params) {
30324
- return this._getAvnuDepositSwapLegCall({
30325
- ...params,
30326
- minHF: 1.1
30327
- // undo
30328
- });
30729
+ assert(params.isDeposit, "Only deposit is supported in getAvnuSwapMultiplyCall");
30730
+ const maxBorrowableAmounts = await this.getMaxBorrowableAmount({ isAPYComputation: false });
30731
+ const allVesuAdapters = this.getVesuAdapters();
30732
+ let remainingAmount = params.leg1DepositAmount;
30733
+ const lstExRate = await this.getLSTExchangeRate();
30734
+ const baseAssetPrice = await this.pricer.getPrice(this.getLSTUnderlyingTokenInfo().symbol);
30735
+ const lstPrice = baseAssetPrice.price * lstExRate;
30736
+ for (let i = 0; i < maxBorrowableAmounts.maxBorrowables.length; i++) {
30737
+ const maxBorrowable = maxBorrowableAmounts.maxBorrowables[i];
30738
+ const vesuAdapter = allVesuAdapters.find((adapter) => adapter.config.debt.address.eq(maxBorrowable.borrowableAsset.address));
30739
+ if (!vesuAdapter) {
30740
+ throw new Error(`${this.getTag()}::getAvnuSwapMultiplyCall: vesuAdapter not found for borrowable asset: ${maxBorrowable.borrowableAsset.symbol}`);
30741
+ }
30742
+ const maxLTV = await vesuAdapter.getLTVConfig(this.config);
30743
+ const debtPrice = await this.pricer.getPrice(maxBorrowable.borrowableAsset.symbol);
30744
+ const maxAmountToDeposit = HealthFactorMath.getMinCollateralRequiredOnLooping(
30745
+ maxBorrowable.amount,
30746
+ debtPrice.price,
30747
+ this.metadata.additionalInfo.targetHealthFactor,
30748
+ maxLTV,
30749
+ lstPrice,
30750
+ this.asset()
30751
+ );
30752
+ const amountToDeposit = remainingAmount.minimum(maxAmountToDeposit);
30753
+ logger.verbose(`${this.getTag()}::getAvnuSwapMultiplyCall::${vesuAdapter.config.debt.symbol}:: remainingAmount: ${remainingAmount}, amountToDeposit: ${amountToDeposit}, depositAmount: ${amountToDeposit}, maxBorrowable: ${maxBorrowable.amount}`);
30754
+ const call = await this._getAvnuDepositSwapLegCall({
30755
+ isDeposit: params.isDeposit,
30756
+ // adjust decimals of debt asset
30757
+ leg1DepositAmount: amountToDeposit,
30758
+ minHF: 1.1,
30759
+ // undo
30760
+ vesuAdapter
30761
+ });
30762
+ remainingAmount = remainingAmount.minus(amountToDeposit);
30763
+ return { call, vesuAdapter };
30764
+ }
30765
+ throw new Error(`${this.getTag()}::getAvnuSwapMultiplyCall: no calls found`);
30329
30766
  }
30330
30767
  async _getAvnuDepositSwapLegCall(params) {
30768
+ const { vesuAdapter } = params;
30331
30769
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall params: ${JSON.stringify(params)}`);
30332
30770
  assert(params.isDeposit, "Only deposit is supported in _getAvnuDepositSwapLegCall");
30333
- const [vesuAdapter1] = this.getVesuAdapters();
30334
- const legLTV = await vesuAdapter1.getLTVConfig(this.config);
30771
+ const legLTV = await vesuAdapter.getLTVConfig(this.config);
30335
30772
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall legLTV: ${legLTV}`);
30336
- const existingPositions = await vesuAdapter1.getPositions(this.config);
30337
- const collateralisation = await vesuAdapter1.getCollateralization(this.config);
30773
+ const existingPositions = await vesuAdapter.getPositions(this.config);
30774
+ const collateralisation = await vesuAdapter.getCollateralization(this.config);
30338
30775
  const existingCollateralInfo = existingPositions[0];
30339
30776
  const existingDebtInfo = existingPositions[1];
30340
30777
  logger.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
@@ -30342,11 +30779,40 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30342
30779
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
30343
30780
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
30344
30781
  logger.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
30782
+ const debtTokenInfo = vesuAdapter.config.debt;
30783
+ let newDepositAmount = params.leg1DepositAmount;
30345
30784
  const totalCollateral = existingCollateralInfo.amount.plus(params.leg1DepositAmount);
30346
30785
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalCollateral: ${totalCollateral}`);
30347
- const totalDebtAmount = totalCollateral.multipliedBy(collateralPrice).multipliedBy(legLTV).dividedBy(debtPrice).dividedBy(params.minHF);
30348
- logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalDebtAmount: ${totalDebtAmount}`);
30349
- const debtAmount = totalDebtAmount.minus(existingDebtInfo.amount);
30786
+ const totalDebtAmount = new Web3Number(
30787
+ totalCollateral.multipliedBy(collateralPrice).multipliedBy(legLTV).dividedBy(debtPrice).dividedBy(params.minHF).toString(),
30788
+ debtTokenInfo.decimals
30789
+ );
30790
+ let debtAmount = totalDebtAmount.minus(existingDebtInfo.amount);
30791
+ logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalDebtAmount: ${totalDebtAmount}, initial computed debt: ${debtAmount}`);
30792
+ const maxBorrowable = await this.getMaxBorrowableAmountByVesuAdapter(vesuAdapter, false);
30793
+ if (debtAmount.gt(0) && maxBorrowable.amount.eq(0)) {
30794
+ logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall maxBorrowable is 0, skipping`);
30795
+ return void 0;
30796
+ } else if (debtAmount.gt(0) && maxBorrowable.amount.gt(0)) {
30797
+ debtAmount = maxBorrowable.amount.minimum(debtAmount);
30798
+ const newDebtUSDValue = debtAmount.multipliedBy(debtPrice);
30799
+ const totalCollateralRequired = HealthFactorMath.getCollateralRequired(
30800
+ debtAmount.plus(existingDebtInfo.amount),
30801
+ debtPrice,
30802
+ params.minHF,
30803
+ legLTV,
30804
+ collateralPrice,
30805
+ this.asset()
30806
+ );
30807
+ newDepositAmount = totalCollateralRequired.minus(existingCollateralInfo.amount);
30808
+ if (newDepositAmount.lt(0)) {
30809
+ throw new Error(`${this.getTag()}::_getAvnuDepositSwapLegCall newDepositAmount is less than 0, newDepositAmount: ${newDepositAmount}, totalCollateralRequired: ${totalCollateralRequired}, existingCollateralInfo.amount: ${existingCollateralInfo.amount}`);
30810
+ }
30811
+ if (newDebtUSDValue.toNumber() < 100) {
30812
+ logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall newDebtUSDValue is less than 100, skipping`);
30813
+ return void 0;
30814
+ }
30815
+ }
30350
30816
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall debtAmount: ${debtAmount}`);
30351
30817
  if (debtAmount.lt(0)) {
30352
30818
  const lstDEXPrice = await this.getLSTDexPrice();
@@ -30358,32 +30824,34 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30358
30824
  assert(calls.length == 1, `Expected 1 call for unwind, got ${calls.length}`);
30359
30825
  return calls[0];
30360
30826
  }
30827
+ console.log(`debtAmount`, debtAmount.toWei(), params.leg1DepositAmount.toWei());
30361
30828
  const STEP0 = "approve_token1" /* APPROVE_TOKEN1 */;
30362
30829
  const manage0Info = this.getProofs(STEP0);
30363
30830
  const manageCall0 = manage0Info.callConstructor({
30364
- amount: params.leg1DepositAmount
30831
+ amount: newDepositAmount
30365
30832
  });
30366
- const STEP1 = "vesu_leg1" /* VESU_LEG1 */;
30833
+ const STEP1 = getVesuLegId("vesu_leg1" /* VESU_LEG1 */, vesuAdapter.config.debt.symbol);
30367
30834
  const manage1Info = this.getProofs(STEP1);
30368
30835
  const manageCall1 = manage1Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
30369
- collateralAmount: params.leg1DepositAmount,
30836
+ collateralAmount: newDepositAmount,
30370
30837
  isAddCollateral: params.isDeposit,
30371
30838
  debtAmount,
30372
30839
  isBorrow: params.isDeposit
30373
30840
  }));
30841
+ console.log(`manageCall1`, manageCall1.call, debtAmount.toWei(), newDepositAmount.toWei());
30374
30842
  const proofIds = [STEP0, STEP1];
30375
30843
  const manageCalls = [manageCall0, manageCall1];
30376
30844
  if (debtAmount.gt(0)) {
30377
- const STEP2 = "avnu_multiply_approve_deposit" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */;
30845
+ const STEP2 = getAvnuManageIDs("avnu_mul_approve_dep" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */, vesuAdapter.config.debt.symbol);
30378
30846
  const manage2Info = this.getProofs(STEP2);
30379
30847
  const manageCall2 = manage2Info.callConstructor({
30380
30848
  amount: debtAmount
30381
30849
  });
30382
- const debtTokenInfo = vesuAdapter1.config.debt;
30850
+ const debtTokenInfo2 = vesuAdapter.config.debt;
30383
30851
  const lstTokenInfo = this.asset();
30384
30852
  const avnuModule = new AvnuWrapper();
30385
30853
  const quote = await avnuModule.getQuotes(
30386
- debtTokenInfo.address.address,
30854
+ debtTokenInfo2.address.address,
30387
30855
  lstTokenInfo.address.address,
30388
30856
  debtAmount.toWei(),
30389
30857
  this.metadata.additionalInfo.vaultAllocator.address
@@ -30399,7 +30867,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30399
30867
  minAmountWei
30400
30868
  );
30401
30869
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall swapInfo: ${JSON.stringify(swapInfo)}`);
30402
- const STEP3 = "avnu_multiply_swap_deposit" /* AVNU_MULTIPLY_SWAP_DEPOSIT */;
30870
+ const STEP3 = getAvnuManageIDs("avnu_mul_swap_dep" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, vesuAdapter.config.debt.symbol);
30403
30871
  const manage3Info = this.getProofs(STEP3);
30404
30872
  const manageCall3 = manage3Info.callConstructor({
30405
30873
  props: swapInfo
@@ -30417,7 +30885,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30417
30885
  const manageCall4 = manage4Info.callConstructor({
30418
30886
  amount: minAmount
30419
30887
  });
30420
- const STEP5 = "vesu_leg1" /* VESU_LEG1 */;
30888
+ const STEP5 = getVesuLegId("vesu_leg1" /* VESU_LEG1 */, vesuAdapter.config.debt.symbol);
30421
30889
  const manage5Info = this.getProofs(STEP5);
30422
30890
  const manageCall5 = manage5Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
30423
30891
  collateralAmount: minAmount,
@@ -30434,28 +30902,41 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30434
30902
  }
30435
30903
  // todo unwind or not deposit when the yield is bad.
30436
30904
  async getLSTMultiplierRebalanceCall() {
30437
- const positions = await this.getVaultPositions();
30438
- assert(positions.length == 3, "Rebalance call is only supported for 3 positions");
30905
+ let shouldRebalance = false;
30906
+ const calls = [];
30907
+ const allVesuAdapters = this.getVesuAdapters().filter((vesuAdapter) => vesuAdapter.config.debt.symbol === "LBTC");
30908
+ for (const vesuAdapter of allVesuAdapters) {
30909
+ const call = await this._getLSTMultiplierRebalanceCall(vesuAdapter);
30910
+ if (call.shouldRebalance && call.manageCall) {
30911
+ shouldRebalance = true;
30912
+ calls.push({ vesuAdapter, manageCall: call.manageCall });
30913
+ }
30914
+ }
30915
+ return { shouldRebalance, manageCalls: calls };
30916
+ }
30917
+ async _getLSTMultiplierRebalanceCall(vesuAdapter) {
30918
+ const positions = await vesuAdapter.getPositions(this.config);
30919
+ assert(positions.length == 2, "Rebalance call is only supported for 2 positions");
30439
30920
  const existingCollateralInfo = positions[0];
30440
30921
  const existingDebtInfo = positions[1];
30441
- const unusedBalance = positions[2];
30442
- const [healthFactor] = await this.getVesuHealthFactors();
30443
- const [vesuAdapter1] = this.getVesuAdapters();
30444
- const legLTV = await vesuAdapter1.getLTVConfig(this.config);
30445
- const collateralisation = await vesuAdapter1.getCollateralization(this.config);
30446
- logger.debug(`${this.getTag()}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
30922
+ const unusedBalance = await this.getUnusedBalance();
30923
+ const healthFactor = await vesuAdapter.getHealthFactor();
30924
+ const collateralisation = await vesuAdapter.getCollateralization(this.config);
30925
+ logger.debug(`${this.getTag()}::getVesuMultiplyCall::${vesuAdapter.config.debt.symbol} existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
30447
30926
  existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
30448
30927
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
30449
30928
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
30450
30929
  logger.debug(`${this.getTag()}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
30930
+ logger.debug(`${this.getTag()}::getVesuMultiplyCall healthFactor: ${healthFactor}`);
30451
30931
  const isHFTooLow = healthFactor < this.metadata.additionalInfo.minHealthFactor;
30452
30932
  const isHFTooHigh = healthFactor > this.metadata.additionalInfo.targetHealthFactor + 0.05;
30453
- if (isHFTooLow || isHFTooHigh) {
30933
+ if (isHFTooLow || isHFTooHigh || 1) {
30454
30934
  const manageCall = await this._getAvnuDepositSwapLegCall({
30455
30935
  isDeposit: true,
30456
30936
  leg1DepositAmount: unusedBalance.amount,
30457
- minHF: 1.02
30937
+ minHF: 1.02,
30458
30938
  // todo, shouldnt use this 1.02 HF, if there isn;t more looping left.
30939
+ vesuAdapter
30459
30940
  });
30460
30941
  return { shouldRebalance: true, manageCall };
30461
30942
  } else {
@@ -30488,7 +30969,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30488
30969
  async _getMinOutputAmountLSTBuy(amountInUnderlying) {
30489
30970
  const lstTruePrice = await this.getLSTExchangeRate();
30490
30971
  const minOutputAmount = amountInUnderlying.dividedBy(lstTruePrice).multipliedBy(0.99979);
30491
- return minOutputAmount;
30972
+ return new Web3Number(minOutputAmount.toString(), this.asset().decimals);
30492
30973
  }
30493
30974
  async _getMinOutputAmountLSTSell(amountInLST) {
30494
30975
  const lstTruePrice = await this.getLSTExchangeRate();
@@ -30545,21 +31026,52 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30545
31026
  const vesuAdapter1 = this.getVesuSameTokenAdapter();
30546
31027
  return vesuAdapter1.config.debt;
30547
31028
  }
30548
- async getMaxBorrowableAmount() {
31029
+ async getMaxBorrowableAmount(params = { isAPYComputation: false }) {
30549
31030
  const vesuAdapters = this.getVesuAdapters();
30550
31031
  let netMaxBorrowableAmount = Web3Number.fromWei("0", this.getLSTUnderlyingTokenInfo().decimals);
30551
31032
  const maxBorrowables = [];
30552
- const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
30553
- const maxInterestRate = lstAPY * 0.8;
30554
31033
  for (const vesuAdapter of vesuAdapters) {
30555
- const maxBorrowableAmount = await vesuAdapter.getMaxBorrowableByInterestRate(this.config, vesuAdapter.config.debt, maxInterestRate);
30556
- const debtCap = await vesuAdapter.getDebtCap(this.config);
30557
- maxBorrowables.push({ amount: maxBorrowableAmount.minimum(debtCap), borrowableAsset: vesuAdapter.config.debt });
31034
+ maxBorrowables.push(await this.getMaxBorrowableAmountByVesuAdapter(vesuAdapter, params.isAPYComputation));
30558
31035
  }
30559
31036
  maxBorrowables.sort((a, b) => b.amount.toNumber() - a.amount.toNumber());
30560
31037
  netMaxBorrowableAmount = maxBorrowables.reduce((acc, curr) => acc.plus(curr.amount), Web3Number.fromWei("0", this.getLSTUnderlyingTokenInfo().decimals));
30561
31038
  return { netMaxBorrowableAmount, maxBorrowables };
30562
31039
  }
31040
+ // recursively, using binary search computes max swappable.
31041
+ // @dev assumes 1 token of from == 1 token of to
31042
+ async getMaxSwappableWithMaxSlippage(fromToken, toToken, maxSlippage, maxAmount) {
31043
+ const output = await findMaxInputWithSlippage({
31044
+ apiGetOutput: async (inputAmount) => {
31045
+ const ekuboQuoter = new EkuboQuoter(this.config);
31046
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
31047
+ const quote = await ekuboQuoter.getQuote(fromToken.address.address, toToken.address.address, new Web3Number(inputAmount.toFixed(9), fromToken.decimals));
31048
+ return Web3Number.fromWei(quote.total_calculated.toString(), toToken.decimals).toNumber();
31049
+ },
31050
+ maxInput: maxAmount.toNumber(),
31051
+ maxSlippagePercent: maxSlippage,
31052
+ tolerance: 1e-3,
31053
+ referenceRate: 1
31054
+ });
31055
+ return new Web3Number(output.optimalInput, fromToken.decimals);
31056
+ }
31057
+ async getMaxBorrowableAmountByVesuAdapter(vesuAdapter, isAPYComputation) {
31058
+ const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
31059
+ const maxInterestRate = lstAPY * 0.8;
31060
+ const maxBorrowableAmount = await vesuAdapter.getMaxBorrowableByInterestRate(this.config, vesuAdapter.config.debt, maxInterestRate);
31061
+ const debtCap = await vesuAdapter.getDebtCap(this.config);
31062
+ const maxBorrowable = maxBorrowableAmount.minimum(debtCap).multipliedBy(0.999);
31063
+ if (vesuAdapter.config.debt.address.eq(this.getLSTUnderlyingTokenInfo().address) || isAPYComputation) {
31064
+ return { amount: maxBorrowable, dexSwappableAmount: maxBorrowable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
31065
+ }
31066
+ try {
31067
+ const maxSwappable = await this.getMaxSwappableWithMaxSlippage(vesuAdapter.config.debt, this.getLSTUnderlyingTokenInfo(), 2e-4, maxBorrowable);
31068
+ return { amount: maxBorrowable.minimum(maxSwappable), dexSwappableAmount: maxSwappable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
31069
+ } catch (error) {
31070
+ logger.warn(`${this.getTag()}: Failed to get max swappable: ${error}`);
31071
+ const maxSwappable = Web3Number.fromWei("0", vesuAdapter.config.debt.decimals);
31072
+ return { amount: maxBorrowable.minimum(maxSwappable), dexSwappableAmount: maxSwappable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
31073
+ }
31074
+ }
30563
31075
  // todo how much to unwind to get back healthy APY zone again
30564
31076
  // if net APY < LST APR + 0.5%, we need to unwind to get back to LST APR + 1% atleast or 0 vesu position
30565
31077
  // For xSTRK, simply deposit in Vesu if looping is not viable
@@ -30583,7 +31095,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30583
31095
  // todo undo this
30584
31096
  async netAPY() {
30585
31097
  const unusedBalance = await this.getUnusedBalance();
30586
- const maxNewDeposits = await this.maxNewDeposits();
31098
+ const maxNewDeposits = await this.maxNewDeposits({ isAPYComputation: true });
30587
31099
  const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
30588
31100
  if (maxNewDeposits * 1.5 < unusedBalance.amount.toNumber()) {
30589
31101
  logger.verbose(`${this.getTag()}::netAPY: unused balance is > max servicable from loan, lstAPY: ${lstAPY}`);
@@ -30600,8 +31112,8 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30600
31112
  return output;
30601
31113
  }
30602
31114
  }
30603
- async maxNewDeposits() {
30604
- const maxBorrowableAmounts = await this.getMaxBorrowableAmount();
31115
+ async maxNewDeposits(params = { isAPYComputation: false }) {
31116
+ const maxBorrowableAmounts = await this.getMaxBorrowableAmount(params);
30605
31117
  let ltv = void 0;
30606
31118
  for (let adapter of this.getVesuAdapters()) {
30607
31119
  const maxBorrowableAmount = maxBorrowableAmounts.maxBorrowables.find((b) => b.borrowableAsset.address.eq(adapter.config.debt.address))?.amount;
@@ -30704,7 +31216,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30704
31216
  const manageCall2 = manage2Info.callConstructor({
30705
31217
  delegation: true
30706
31218
  });
30707
- const STEP3_ID = "multiply_vesu" /* MULTIPLY_VESU */;
31219
+ const STEP3_ID = getVesuLegId("multiply_vesu" /* MULTIPLY_VESU */, vesuAdapter1.config.debt.symbol);
30708
31220
  const manage3Info = this.getProofs(STEP3_ID);
30709
31221
  const multiplyParams = params.isIncrease ? {
30710
31222
  isIncrease: true,
@@ -30788,6 +31300,12 @@ function VaultDescription(lstSymbol, underlyingSymbol) {
30788
31300
  function getDescription2(tokenSymbol, underlyingSymbol) {
30789
31301
  return VaultDescription(tokenSymbol, underlyingSymbol);
30790
31302
  }
31303
+ function getAvnuManageIDs(baseID, debtTokenSymbol) {
31304
+ return `${baseID}_${debtTokenSymbol.toLowerCase()}`;
31305
+ }
31306
+ function getVesuLegId(baseID, debtTokenSymbol) {
31307
+ return `${baseID}_${debtTokenSymbol.toLowerCase()}`;
31308
+ }
30791
31309
  function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
30792
31310
  vaultSettings.leafAdapters = [];
30793
31311
  const lstToken = Global.getDefaultTokens().find((token) => token.symbol === lstSymbol);
@@ -30797,7 +31315,7 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
30797
31315
  collateral: lstToken,
30798
31316
  debt: underlyingToken,
30799
31317
  vaultAllocator: vaultSettings.vaultAllocator,
30800
- id: "vesu_leg1" /* VESU_LEG1 */
31318
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, underlyingToken.symbol)
30801
31319
  });
30802
31320
  const commonAdapter = new CommonAdapter({
30803
31321
  manager: vaultSettings.manager,
@@ -30806,25 +31324,39 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
30806
31324
  vaultAddress: vaultSettings.vaultAddress,
30807
31325
  vaultAllocator: vaultSettings.vaultAllocator
30808
31326
  });
30809
- const { isV2, addr: poolAddr } = getVesuSingletonAddress(pool1);
30810
- const VESU_MULTIPLY = isV2 ? vesuAdapterLST.VESU_MULTIPLY : vesuAdapterLST.VESU_MULTIPLY_V1;
30811
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, VESU_MULTIPLY, "multiple_approve" /* MULTIPLE_APPROVE */).bind(commonAdapter));
30812
- vaultSettings.leafAdapters.push(vesuAdapterLST.getMultiplyAdapter("multiply_vesu" /* MULTIPLY_VESU */).bind(vesuAdapterLST));
30813
- vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_on" /* SWITCH_DELEGATION_ON */).bind(vesuAdapterLST));
30814
- vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_off" /* SWITCH_DELEGATION_OFF */).bind(vesuAdapterLST));
30815
31327
  vaultSettings.adapters.push(...[{
30816
- id: "vesu_leg1_adapter" /* VESU_LEG1 */,
31328
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, underlyingToken.symbol),
30817
31329
  adapter: vesuAdapterLST
30818
31330
  }, {
30819
31331
  id: "common_adapter" /* COMMON */,
30820
31332
  adapter: commonAdapter
30821
31333
  }]);
30822
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(underlyingToken.address, AVNU_EXCHANGE, "avnu_multiply_approve_deposit" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */).bind(commonAdapter));
30823
- vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(underlyingToken.address, lstToken.address, "avnu_multiply_swap_deposit" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, false).bind(commonAdapter));
30824
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, AVNU_EXCHANGE, "avnu_multiply_approve_withdraw" /* AVNU_MULTIPLY_APPROVE_WITHDRAW */).bind(commonAdapter));
30825
- vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(lstToken.address, underlyingToken.address, "avnu_multiply_swap_withdraw" /* AVNU_MULTIPLY_SWAP_WITHDRAW */, false).bind(commonAdapter));
30826
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, poolAddr, "approve_token1" /* APPROVE_TOKEN1 */).bind(commonAdapter));
30827
- vaultSettings.leafAdapters.push(vesuAdapterLST.getModifyPosition.bind(vesuAdapterLST));
31334
+ const { isV2, addr: poolAddr } = getVesuSingletonAddress(pool1);
31335
+ const VESU_MULTIPLY = isV2 ? vesuAdapterLST.VESU_MULTIPLY : vesuAdapterLST.VESU_MULTIPLY_V1;
31336
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, VESU_MULTIPLY, "multiple_approve" /* MULTIPLE_APPROVE */).bind(commonAdapter));
31337
+ vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_on" /* SWITCH_DELEGATION_ON */).bind(vesuAdapterLST));
31338
+ vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_off" /* SWITCH_DELEGATION_OFF */).bind(vesuAdapterLST));
31339
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, AVNU_EXCHANGE, "avnu_mul_approve_withdr" /* AVNU_MULTIPLY_APPROVE_WITHDRAW */).bind(commonAdapter));
31340
+ for (let borrowableAsset of vaultSettings.borrowable_assets) {
31341
+ const debtAsset = borrowableAsset;
31342
+ const approve_debt_token_id = getAvnuManageIDs("avnu_mul_approve_dep" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */, debtAsset.symbol);
31343
+ const swap_debt_token_id = getAvnuManageIDs("avnu_mul_swap_dep" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, debtAsset.symbol);
31344
+ const swap_lst_token_id = getAvnuManageIDs("avnu_mul_swap_withdr" /* AVNU_MULTIPLY_SWAP_WITHDRAW */, debtAsset.symbol);
31345
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(debtAsset.address, AVNU_EXCHANGE, approve_debt_token_id).bind(commonAdapter));
31346
+ vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(debtAsset.address, lstToken.address, swap_debt_token_id, false).bind(commonAdapter));
31347
+ vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(lstToken.address, debtAsset.address, swap_lst_token_id, false).bind(commonAdapter));
31348
+ const vesuAdapter = new VesuAdapter({
31349
+ poolId: pool1,
31350
+ collateral: lstToken,
31351
+ debt: debtAsset,
31352
+ vaultAllocator: vaultSettings.vaultAllocator,
31353
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, debtAsset.symbol)
31354
+ });
31355
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, poolAddr, "approve_token1" /* APPROVE_TOKEN1 */).bind(commonAdapter));
31356
+ vaultSettings.leafAdapters.push(vesuAdapter.getModifyPosition.bind(vesuAdapter));
31357
+ const multiplID = getVesuLegId("multiply_vesu" /* MULTIPLY_VESU */, debtAsset.symbol);
31358
+ vaultSettings.leafAdapters.push(vesuAdapter.getMultiplyAdapter(multiplID).bind(vesuAdapter));
31359
+ }
30828
31360
  vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, vaultSettings.vaultAddress, "approve_bring_liquidity" /* APPROVE_BRING_LIQUIDITY */).bind(commonAdapter));
30829
31361
  vaultSettings.leafAdapters.push(commonAdapter.getBringLiquidityAdapter("bring_liquidity" /* BRING_LIQUIDITY */).bind(commonAdapter));
30830
31362
  vaultSettings.leafAdapters.push(vesuAdapterLST.getDefispringRewardsAdapter("defispring_rewards" /* DEFISPRING_REWARDS */).bind(vesuAdapterLST));
@@ -30902,7 +31434,8 @@ var hyperxSTRK = {
30902
31434
  adapters: [],
30903
31435
  targetHealthFactor: 1.1,
30904
31436
  minHealthFactor: 1.05,
30905
- borrowable_assets: Global.getDefaultTokens().filter((token) => token.symbol === "STRK")
31437
+ borrowable_assets: Global.getDefaultTokens().filter((token) => token.symbol === "STRK"),
31438
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "STRK")
30906
31439
  };
30907
31440
  var hyperxWBTC = {
30908
31441
  vaultAddress: ContractAddr.from("0x2da9d0f96a46b453f55604313785dc866424240b1c6811d13bef594343db818"),
@@ -30914,7 +31447,8 @@ var hyperxWBTC = {
30914
31447
  adapters: [],
30915
31448
  targetHealthFactor: 1.1,
30916
31449
  minHealthFactor: 1.05,
30917
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
31450
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
31451
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "WBTC")
30918
31452
  };
30919
31453
  var hyperxtBTC = {
30920
31454
  vaultAddress: ContractAddr.from("0x47d5f68477e5637ce0e56436c6b5eee5a354e6828995dae106b11a48679328"),
@@ -30926,7 +31460,8 @@ var hyperxtBTC = {
30926
31460
  adapters: [],
30927
31461
  targetHealthFactor: 1.1,
30928
31462
  minHealthFactor: 1.05,
30929
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
31463
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
31464
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "tBTC")
30930
31465
  };
30931
31466
  var hyperxsBTC = {
30932
31467
  vaultAddress: ContractAddr.from("0x437ef1e7d0f100b2e070b7a65cafec0b2be31b0290776da8b4112f5473d8d9"),
@@ -30938,7 +31473,8 @@ var hyperxsBTC = {
30938
31473
  adapters: [],
30939
31474
  targetHealthFactor: 1.1,
30940
31475
  minHealthFactor: 1.05,
30941
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
31476
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
31477
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "solvBTC")
30942
31478
  };
30943
31479
  var hyperxLBTC = {
30944
31480
  vaultAddress: ContractAddr.from("0x64cf24d4883fe569926419a0569ab34497c6956a1a308fa883257f7486d7030"),
@@ -30950,7 +31486,8 @@ var hyperxLBTC = {
30950
31486
  adapters: [],
30951
31487
  targetHealthFactor: 1.1,
30952
31488
  minHealthFactor: 1.05,
30953
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
31489
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
31490
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "LBTC")
30954
31491
  };
30955
31492
  function getInvestmentSteps(lstSymbol, underlyingSymbol) {
30956
31493
  return [
@@ -30993,6 +31530,7 @@ var HyperLSTStrategies = [
30993
31530
  getStrategySettings("xLBTC", "LBTC", hyperxLBTC, false)
30994
31531
  ];
30995
31532
  export {
31533
+ APYType,
30996
31534
  AUMTypes,
30997
31535
  AVNU_EXCHANGE,
30998
31536
  AVNU_MIDDLEWARE,