@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.
package/dist/index.js CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ APYType: () => APYType,
33
34
  AUMTypes: () => AUMTypes,
34
35
  AVNU_EXCHANGE: () => AVNU_EXCHANGE,
35
36
  AVNU_MIDDLEWARE: () => AVNU_MIDDLEWARE,
@@ -420,6 +421,25 @@ var defaultTokens = [{
420
421
  priceProxySymbol: "WBTC",
421
422
  priceCheckAmount: 1e-4
422
423
  // 112000 * 0.0001 = $11.2
424
+ }, {
425
+ name: "mRe7BTC",
426
+ symbol: "mRe7BTC",
427
+ logo: "https://imagedelivery.net/0xPAQaDtnQhBs8IzYRIlNg/3a62ecee-1e58-45d3-9862-3ce90dff1900/logo",
428
+ address: ContractAddr.from("0x4e4fb1a9ca7e84bae609b9dc0078ad7719e49187ae7e425bb47d131710eddac"),
429
+ decimals: 18,
430
+ coingeckId: void 0,
431
+ displayDecimals: 6,
432
+ priceCheckAmount: 1e-4
433
+ // 112000 * 0.0001 = $11.2
434
+ }, {
435
+ name: "mRe7YIELD",
436
+ symbol: "mRe7YIELD",
437
+ logo: "https://midas.app/assets/mre7-BcOOHm7i.svg",
438
+ address: ContractAddr.from("0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"),
439
+ decimals: 18,
440
+ coingeckId: void 0,
441
+ displayDecimals: 2,
442
+ priceCheckAmount: 100
423
443
  }];
424
444
  var tokens = defaultTokens;
425
445
  var _Global = class _Global {
@@ -2313,16 +2333,16 @@ var AvnuWrapper = class _AvnuWrapper {
2313
2333
  };
2314
2334
  return swapInfo;
2315
2335
  }
2316
- static buildZeroSwap(tokenToSell, address) {
2336
+ static buildZeroSwap(tokenToSell, beneficiary, tokenToBuy = tokenToSell) {
2317
2337
  return {
2318
2338
  token_from_address: tokenToSell.address,
2319
2339
  token_from_amount: import_starknet6.uint256.bnToUint256(0),
2320
- token_to_address: tokenToSell.address,
2340
+ token_to_address: tokenToBuy.address,
2321
2341
  token_to_amount: import_starknet6.uint256.bnToUint256(0),
2322
2342
  token_to_min_amount: import_starknet6.uint256.bnToUint256(0),
2323
- beneficiary: address,
2343
+ beneficiary,
2324
2344
  integrator_fee_amount_bps: 0,
2325
- integrator_fee_recipient: address,
2345
+ integrator_fee_recipient: beneficiary,
2326
2346
  routes: []
2327
2347
  };
2328
2348
  }
@@ -4123,21 +4143,20 @@ var Harvests = class _Harvests {
4123
4143
  const rewards = await this.getHarvests(addr);
4124
4144
  if (rewards.length == 0) return [];
4125
4145
  const unClaimed = [];
4126
- const cls = await this.config.provider.getClassAt(rewards[0].rewardsContract.address);
4127
- for (let reward of rewards) {
4128
- const contract = new import_starknet9.Contract({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
4129
- const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
4130
- logger.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}`);
4131
- if (isClaimed) {
4132
- return unClaimed;
4133
- }
4134
- const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
4135
- if (bal.lessThan(reward.claim.amount)) {
4136
- logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
4137
- continue;
4138
- }
4139
- unClaimed.unshift(reward);
4146
+ const reward = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime())[0];
4147
+ const cls = await this.config.provider.getClassAt(reward.rewardsContract.address);
4148
+ const contract = new import_starknet9.Contract({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
4149
+ const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
4150
+ logger.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}`);
4151
+ if (isClaimed) {
4152
+ return unClaimed;
4140
4153
  }
4154
+ const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
4155
+ if (bal.lessThan(reward.claim.amount)) {
4156
+ logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
4157
+ return unClaimed;
4158
+ }
4159
+ unClaimed.unshift(reward);
4141
4160
  return unClaimed;
4142
4161
  }
4143
4162
  };
@@ -15400,6 +15419,91 @@ var apolloClient = new import_client.ApolloClient({
15400
15419
  });
15401
15420
  var apollo_client_default = apolloClient;
15402
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
+
15403
15507
  // src/strategies/ekubo-cl-vault.tsx
15404
15508
  var import_jsx_runtime3 = require("react/jsx-runtime");
15405
15509
  var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
@@ -15686,7 +15790,6 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
15686
15790
  for (let i = len - 1; i >= 0; --i) {
15687
15791
  let record = await this.contract.call("get_rewards_info", [i]);
15688
15792
  logger.verbose(`${_EkuboCLVault.name}: getHarvestRewardShares: ${i}`);
15689
- console.log(record);
15690
15793
  const block = Number(record.block_number);
15691
15794
  if (block < fromBlock) {
15692
15795
  return shares;
@@ -15886,16 +15989,10 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
15886
15989
  const sqrtRatio = _EkuboCLVault.div2Power128(
15887
15990
  BigInt(priceInfo.sqrt_ratio.toString())
15888
15991
  );
15889
- console.log(
15890
- `EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, sqrtRatio: ${sqrtRatio}, ${priceInfo.sqrt_ratio.toString()}`
15891
- );
15892
15992
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
15893
15993
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
15894
15994
  const price = sqrtRatio * sqrtRatio * 10 ** token0Info.decimals / 10 ** token1Info.decimals;
15895
15995
  const tick = priceInfo.tick;
15896
- console.log(
15897
- `EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, price: ${price}, tick: ${tick.mag}, ${tick.sign}`
15898
- );
15899
15996
  return {
15900
15997
  price,
15901
15998
  tick: Number(tick.mag) * (tick.sign ? -1 : 1),
@@ -16522,62 +16619,193 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16522
16619
  logger.verbose(
16523
16620
  `${_EkuboCLVault.name}: harvest => Processing claim, isToken1: ${isToken1} amount: ${postFeeAmount.toWei()}`
16524
16621
  );
16525
- const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
16526
- 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
+ import_starknet11.uint256.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 = import_starknet11.uint256.bnToUint256(swap1Amount.toWei());
16691
+ swapInfo.token_to_min_amount = import_starknet11.uint256.bnToUint256(
16692
+ swap1Amount.multipliedBy(0).toWei()
16693
+ // placeholder
16694
+ );
16527
16695
  logger.verbose(
16528
- `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
16696
+ `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
16529
16697
  );
16530
- const swapInfo = await this.getSwapInfoGivenAmounts(
16531
- poolKey,
16532
- token0Amt,
16533
- token1Amt,
16534
- bounds,
16535
- maxIterations,
16536
- priceRatioPrecision
16698
+ const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
16699
+ logger.verbose(
16700
+ `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
16537
16701
  );
16538
- swapInfo.token_to_address = token0Info.address.address;
16702
+ const swapInfo2 = {
16703
+ ...swapInfo,
16704
+ token_from_amount: import_starknet11.uint256.bnToUint256(remainingAmount.toWei())
16705
+ };
16706
+ swapInfo2.token_to_address = token1Info.address.address;
16539
16707
  logger.verbose(
16540
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
16708
+ `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
16709
+ swapInfo
16710
+ )}`
16541
16711
  );
16542
16712
  logger.verbose(
16543
- `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
16713
+ `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
16714
+ swapInfo2
16715
+ )}`
16544
16716
  );
16545
- const harvestEstimateCall = async (swapInfo1) => {
16546
- const swap1Amount = Web3Number.fromWei(
16547
- import_starknet11.uint256.uint256ToBN(swapInfo1.token_from_amount).toString(),
16548
- 18
16549
- // cause its always STRK?
16550
- ).minimum(
16551
- postFeeAmount.toFixed(18)
16552
- // cause always strk
16553
- );
16554
- swapInfo.token_from_amount = import_starknet11.uint256.bnToUint256(swap1Amount.toWei());
16555
- swapInfo.token_to_min_amount = import_starknet11.uint256.bnToUint256(
16556
- swap1Amount.multipliedBy(0).toWei()
16557
- // placeholder
16558
- );
16559
- logger.verbose(
16560
- `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
16561
- );
16562
- const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
16563
- logger.verbose(
16564
- `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
16565
- );
16566
- const swapInfo2 = {
16567
- ...swapInfo,
16568
- token_from_amount: import_starknet11.uint256.bnToUint256(remainingAmount.toWei())
16569
- };
16570
- swapInfo2.token_to_address = token1Info.address.address;
16571
- logger.verbose(
16572
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
16573
- swapInfo
16574
- )}`
16575
- );
16576
- logger.verbose(
16577
- `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
16578
- swapInfo2
16579
- )}`
16580
- );
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) => import_starknet11.num.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 {
16581
16809
  const calldata = [
16582
16810
  claim.rewardsContract.address,
16583
16811
  {
@@ -16586,34 +16814,23 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16586
16814
  claimee: claim.claim.claimee.address
16587
16815
  },
16588
16816
  claim.proof.map((p) => import_starknet11.num.getDecimalString(p)),
16589
- swapInfo,
16817
+ swapInfo1,
16590
16818
  swapInfo2
16591
16819
  ];
16592
- logger.verbose(
16593
- `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
16594
- calldata
16595
- )}`
16596
- );
16597
- return [this.contract.populate("harvest", calldata)];
16598
- };
16599
- const _callsFinal = await this.rebalanceIter(
16600
- swapInfo,
16601
- acc,
16602
- harvestEstimateCall,
16603
- claim.token.eq(poolKey.token0),
16604
- 0,
16605
- 0n,
16606
- BigInt(postFeeAmount.toWei())
16607
- // upper limit is the post fee amount
16608
- );
16609
- logger.verbose(
16610
- `${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
16611
- _callsFinal
16612
- )}`
16613
- );
16614
- calls.push(..._callsFinal);
16615
- }
16616
- 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;
16617
16834
  }
16618
16835
  async getInvestmentFlows() {
16619
16836
  const netYield = await this.netAPY();
@@ -19145,7 +19362,58 @@ function toBigInt(value) {
19145
19362
  }
19146
19363
 
19147
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 || {});
19148
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
+ // }
19149
19417
  constructSimpleLeafData(params, sanitizer = SIMPLE_SANITIZER) {
19150
19418
  const { id, target, method, packedArguments } = params;
19151
19419
  return {
@@ -19163,6 +19431,94 @@ var BaseAdapter = class extends CacheClass {
19163
19431
  ]
19164
19432
  };
19165
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
+ // }
19166
19522
  };
19167
19523
 
19168
19524
  // src/strategies/universal-adapters/common-adapter.ts
@@ -26765,7 +27121,20 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26765
27121
  }
26766
27122
  const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address]);
26767
27123
  logger.verbose(`${this.config.debt.symbol}::VesuAdapter::getDebtCap debt_cap: ${output.debt_cap.toString()}`);
26768
- 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);
26769
27138
  }
26770
27139
  async getMaxBorrowableByInterestRate(config, asset, maxBorrowAPY) {
26771
27140
  const { contract, isV2 } = await this.getVesuSingletonContract(config, this.config.poolId);
@@ -26798,16 +27167,17 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26798
27167
  const assetConfig = isV2 ? _assetConfig : _assetConfig["0"];
26799
27168
  const timeDelta = assetConfig.last_updated;
26800
27169
  const lastFullUtilizationRate = assetConfig.last_full_utilization_rate;
26801
- 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));
26802
27172
  const ratePerSecond = BigInt(Math.round(maxBorrowAPY / 365 / 24 / 60 / 60 * Number(SCALE)));
26803
27173
  const maxUtilisation = this.getMaxUtilizationGivenRatePerSecond(interestRateConfig, ratePerSecond, timeDelta, lastFullUtilizationRate);
26804
27174
  logger.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate maxUtilisation: ${Number(maxUtilisation) / 1e18}, totalSupply: ${totalSupply.toString()}`);
26805
27175
  const maxDebtToHave = totalSupply.multipliedBy(Number(maxUtilisation) / 1e18);
26806
- 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()}`);
26807
27177
  return maxDebtToHave.minus(currentDebt);
26808
27178
  }
26809
- async getLTVConfig(config) {
26810
- const CACHE_KEY = "ltv_config";
27179
+ async getLTVConfig(config, blockNumber = "latest") {
27180
+ const CACHE_KEY = `ltv_config_${blockNumber}`;
26811
27181
  const cacheData = this.getCache(CACHE_KEY);
26812
27182
  if (cacheData) {
26813
27183
  return cacheData;
@@ -26815,10 +27185,10 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26815
27185
  const { contract, isV2 } = await this.getVesuSingletonContract(config, this.config.poolId);
26816
27186
  let ltv = 0;
26817
27187
  if (isV2) {
26818
- 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 });
26819
27189
  ltv = Number(output.max_ltv) / 1e18;
26820
27190
  } else {
26821
- 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 });
26822
27192
  ltv = Number(output.max_ltv) / 1e18;
26823
27193
  }
26824
27194
  if (ltv == 0) {
@@ -26827,11 +27197,11 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26827
27197
  this.setCache(CACHE_KEY, ltv, 3e5);
26828
27198
  return this.getCache(CACHE_KEY);
26829
27199
  }
26830
- async getPositions(config) {
27200
+ async getPositions(config, blockNumber = "latest") {
26831
27201
  if (!this.pricer) {
26832
27202
  throw new Error("Pricer is not initialized");
26833
27203
  }
26834
- const CACHE_KEY = "positions";
27204
+ const CACHE_KEY = `positions_${blockNumber}`;
26835
27205
  const cacheData = this.getCache(CACHE_KEY);
26836
27206
  if (cacheData) {
26837
27207
  return cacheData;
@@ -26843,7 +27213,8 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26843
27213
  this.config.collateral.address.address,
26844
27214
  this.config.debt.address.address,
26845
27215
  this.config.vaultAllocator.address
26846
- ]);
27216
+ ], { blockIdentifier: blockNumber });
27217
+ console.log(output);
26847
27218
  const token1Price = await this.pricer.getPrice(this.config.collateral.symbol);
26848
27219
  const token2Price = await this.pricer.getPrice(this.config.debt.symbol);
26849
27220
  logger.verbose(`VesuAdapter::getPositions token1Price: ${token1Price.price}, token2Price: ${token2Price.price}`);
@@ -26863,11 +27234,11 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26863
27234
  this.setCache(CACHE_KEY, value, 6e4);
26864
27235
  return value;
26865
27236
  }
26866
- async getCollateralization(config) {
27237
+ async getCollateralization(config, blockNumber = "latest") {
26867
27238
  if (!this.pricer) {
26868
27239
  throw new Error("Pricer is not initialized");
26869
27240
  }
26870
- const CACHE_KEY = "collateralization";
27241
+ const CACHE_KEY = `collateralization_${blockNumber}`;
26871
27242
  const cacheData = this.getCache(CACHE_KEY);
26872
27243
  if (cacheData) {
26873
27244
  return cacheData;
@@ -26879,7 +27250,7 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26879
27250
  this.config.collateral.address.address,
26880
27251
  this.config.debt.address.address,
26881
27252
  this.config.vaultAllocator.address
26882
- ]);
27253
+ ], { blockIdentifier: blockNumber });
26883
27254
  const collateralAmount = Web3Number.fromWei(output["1"].toString(), 18);
26884
27255
  const debtAmount = Web3Number.fromWei(output["2"].toString(), 18);
26885
27256
  const value = [{
@@ -26916,9 +27287,9 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26916
27287
  ltv
26917
27288
  };
26918
27289
  }
26919
- async getHealthFactor() {
26920
- const ltv = await this.getLTVConfig(this.networkConfig);
26921
- 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);
26922
27293
  return collateralisation[0].usdValue * ltv / collateralisation[1].usdValue;
26923
27294
  }
26924
27295
  static async getVesuPools(retry = 0) {
@@ -29580,11 +29951,11 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
29580
29951
  vesuAdapter2.networkConfig = this.config;
29581
29952
  return [vesuAdapter1, vesuAdapter2];
29582
29953
  }
29583
- async getVesuPositions() {
29954
+ async getVesuPositions(blockNumber = "latest") {
29584
29955
  const adapters = this.getVesuAdapters();
29585
29956
  const positions = [];
29586
29957
  for (const adapter of adapters) {
29587
- positions.push(...await adapter.getPositions(this.config));
29958
+ positions.push(...await adapter.getPositions(this.config, blockNumber));
29588
29959
  }
29589
29960
  return positions;
29590
29961
  }
@@ -29653,8 +30024,8 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
29653
30024
  async getLSTAPR(address) {
29654
30025
  return 0;
29655
30026
  }
29656
- async getVesuHealthFactors() {
29657
- 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)));
29658
30029
  }
29659
30030
  async computeRebalanceConditionAndReturnCalls() {
29660
30031
  const vesuAdapters = this.getVesuAdapters();
@@ -30250,6 +30621,42 @@ var UniversalStrategies = [
30250
30621
 
30251
30622
  // src/strategies/universal-lst-muliplier-strategy.tsx
30252
30623
  var import_starknet17 = require("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
30253
30660
  var import_jsx_runtime5 = require("react/jsx-runtime");
30254
30661
  var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy extends UniversalStrategy {
30255
30662
  constructor(config, pricer, metadata) {
@@ -30264,15 +30671,14 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30264
30671
  }
30265
30672
  }
30266
30673
  asset() {
30267
- const vesuAdapter1 = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
30268
- return vesuAdapter1.config.collateral;
30674
+ return this.getVesuSameTokenAdapter().config.collateral;
30269
30675
  }
30270
30676
  getTag() {
30271
30677
  return `${_UniversalLstMultiplierStrategy.name}:${this.metadata.name}`;
30272
30678
  }
30273
30679
  // Vesu adapter with LST and base token match
30274
30680
  getVesuSameTokenAdapter() {
30275
- const baseAdapter = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
30681
+ const baseAdapter = this.getAdapter(getVesuLegId("vesu_leg1" /* VESU_LEG1 */, this.metadata.additionalInfo.underlyingToken.symbol));
30276
30682
  baseAdapter.networkConfig = this.config;
30277
30683
  baseAdapter.pricer = this.pricer;
30278
30684
  return baseAdapter;
@@ -30320,20 +30726,52 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30320
30726
  return price;
30321
30727
  }
30322
30728
  async getAvnuSwapMultiplyCall(params) {
30323
- return this._getAvnuDepositSwapLegCall({
30324
- ...params,
30325
- minHF: 1.1
30326
- // undo
30327
- });
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`);
30328
30766
  }
30329
30767
  async _getAvnuDepositSwapLegCall(params) {
30768
+ const { vesuAdapter } = params;
30330
30769
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall params: ${JSON.stringify(params)}`);
30331
30770
  assert(params.isDeposit, "Only deposit is supported in _getAvnuDepositSwapLegCall");
30332
- const [vesuAdapter1] = this.getVesuAdapters();
30333
- const legLTV = await vesuAdapter1.getLTVConfig(this.config);
30771
+ const legLTV = await vesuAdapter.getLTVConfig(this.config);
30334
30772
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall legLTV: ${legLTV}`);
30335
- const existingPositions = await vesuAdapter1.getPositions(this.config);
30336
- const collateralisation = await vesuAdapter1.getCollateralization(this.config);
30773
+ const existingPositions = await vesuAdapter.getPositions(this.config);
30774
+ const collateralisation = await vesuAdapter.getCollateralization(this.config);
30337
30775
  const existingCollateralInfo = existingPositions[0];
30338
30776
  const existingDebtInfo = existingPositions[1];
30339
30777
  logger.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
@@ -30341,11 +30779,40 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30341
30779
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
30342
30780
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
30343
30781
  logger.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
30782
+ const debtTokenInfo = vesuAdapter.config.debt;
30783
+ let newDepositAmount = params.leg1DepositAmount;
30344
30784
  const totalCollateral = existingCollateralInfo.amount.plus(params.leg1DepositAmount);
30345
30785
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalCollateral: ${totalCollateral}`);
30346
- const totalDebtAmount = totalCollateral.multipliedBy(collateralPrice).multipliedBy(legLTV).dividedBy(debtPrice).dividedBy(params.minHF);
30347
- logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalDebtAmount: ${totalDebtAmount}`);
30348
- 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
+ }
30349
30816
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall debtAmount: ${debtAmount}`);
30350
30817
  if (debtAmount.lt(0)) {
30351
30818
  const lstDEXPrice = await this.getLSTDexPrice();
@@ -30357,32 +30824,34 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30357
30824
  assert(calls.length == 1, `Expected 1 call for unwind, got ${calls.length}`);
30358
30825
  return calls[0];
30359
30826
  }
30827
+ console.log(`debtAmount`, debtAmount.toWei(), params.leg1DepositAmount.toWei());
30360
30828
  const STEP0 = "approve_token1" /* APPROVE_TOKEN1 */;
30361
30829
  const manage0Info = this.getProofs(STEP0);
30362
30830
  const manageCall0 = manage0Info.callConstructor({
30363
- amount: params.leg1DepositAmount
30831
+ amount: newDepositAmount
30364
30832
  });
30365
- const STEP1 = "vesu_leg1" /* VESU_LEG1 */;
30833
+ const STEP1 = getVesuLegId("vesu_leg1" /* VESU_LEG1 */, vesuAdapter.config.debt.symbol);
30366
30834
  const manage1Info = this.getProofs(STEP1);
30367
30835
  const manageCall1 = manage1Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
30368
- collateralAmount: params.leg1DepositAmount,
30836
+ collateralAmount: newDepositAmount,
30369
30837
  isAddCollateral: params.isDeposit,
30370
30838
  debtAmount,
30371
30839
  isBorrow: params.isDeposit
30372
30840
  }));
30841
+ console.log(`manageCall1`, manageCall1.call, debtAmount.toWei(), newDepositAmount.toWei());
30373
30842
  const proofIds = [STEP0, STEP1];
30374
30843
  const manageCalls = [manageCall0, manageCall1];
30375
30844
  if (debtAmount.gt(0)) {
30376
- 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);
30377
30846
  const manage2Info = this.getProofs(STEP2);
30378
30847
  const manageCall2 = manage2Info.callConstructor({
30379
30848
  amount: debtAmount
30380
30849
  });
30381
- const debtTokenInfo = vesuAdapter1.config.debt;
30850
+ const debtTokenInfo2 = vesuAdapter.config.debt;
30382
30851
  const lstTokenInfo = this.asset();
30383
30852
  const avnuModule = new AvnuWrapper();
30384
30853
  const quote = await avnuModule.getQuotes(
30385
- debtTokenInfo.address.address,
30854
+ debtTokenInfo2.address.address,
30386
30855
  lstTokenInfo.address.address,
30387
30856
  debtAmount.toWei(),
30388
30857
  this.metadata.additionalInfo.vaultAllocator.address
@@ -30398,7 +30867,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30398
30867
  minAmountWei
30399
30868
  );
30400
30869
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall swapInfo: ${JSON.stringify(swapInfo)}`);
30401
- 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);
30402
30871
  const manage3Info = this.getProofs(STEP3);
30403
30872
  const manageCall3 = manage3Info.callConstructor({
30404
30873
  props: swapInfo
@@ -30416,7 +30885,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30416
30885
  const manageCall4 = manage4Info.callConstructor({
30417
30886
  amount: minAmount
30418
30887
  });
30419
- const STEP5 = "vesu_leg1" /* VESU_LEG1 */;
30888
+ const STEP5 = getVesuLegId("vesu_leg1" /* VESU_LEG1 */, vesuAdapter.config.debt.symbol);
30420
30889
  const manage5Info = this.getProofs(STEP5);
30421
30890
  const manageCall5 = manage5Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
30422
30891
  collateralAmount: minAmount,
@@ -30433,28 +30902,41 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30433
30902
  }
30434
30903
  // todo unwind or not deposit when the yield is bad.
30435
30904
  async getLSTMultiplierRebalanceCall() {
30436
- const positions = await this.getVaultPositions();
30437
- 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");
30438
30920
  const existingCollateralInfo = positions[0];
30439
30921
  const existingDebtInfo = positions[1];
30440
- const unusedBalance = positions[2];
30441
- const [healthFactor] = await this.getVesuHealthFactors();
30442
- const [vesuAdapter1] = this.getVesuAdapters();
30443
- const legLTV = await vesuAdapter1.getLTVConfig(this.config);
30444
- const collateralisation = await vesuAdapter1.getCollateralization(this.config);
30445
- 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)},
30446
30926
  existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
30447
30927
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
30448
30928
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
30449
30929
  logger.debug(`${this.getTag()}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
30930
+ logger.debug(`${this.getTag()}::getVesuMultiplyCall healthFactor: ${healthFactor}`);
30450
30931
  const isHFTooLow = healthFactor < this.metadata.additionalInfo.minHealthFactor;
30451
30932
  const isHFTooHigh = healthFactor > this.metadata.additionalInfo.targetHealthFactor + 0.05;
30452
- if (isHFTooLow || isHFTooHigh) {
30933
+ if (isHFTooLow || isHFTooHigh || 1) {
30453
30934
  const manageCall = await this._getAvnuDepositSwapLegCall({
30454
30935
  isDeposit: true,
30455
30936
  leg1DepositAmount: unusedBalance.amount,
30456
- minHF: 1.02
30937
+ minHF: 1.02,
30457
30938
  // todo, shouldnt use this 1.02 HF, if there isn;t more looping left.
30939
+ vesuAdapter
30458
30940
  });
30459
30941
  return { shouldRebalance: true, manageCall };
30460
30942
  } else {
@@ -30487,7 +30969,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30487
30969
  async _getMinOutputAmountLSTBuy(amountInUnderlying) {
30488
30970
  const lstTruePrice = await this.getLSTExchangeRate();
30489
30971
  const minOutputAmount = amountInUnderlying.dividedBy(lstTruePrice).multipliedBy(0.99979);
30490
- return minOutputAmount;
30972
+ return new Web3Number(minOutputAmount.toString(), this.asset().decimals);
30491
30973
  }
30492
30974
  async _getMinOutputAmountLSTSell(amountInLST) {
30493
30975
  const lstTruePrice = await this.getLSTExchangeRate();
@@ -30544,21 +31026,52 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30544
31026
  const vesuAdapter1 = this.getVesuSameTokenAdapter();
30545
31027
  return vesuAdapter1.config.debt;
30546
31028
  }
30547
- async getMaxBorrowableAmount() {
31029
+ async getMaxBorrowableAmount(params = { isAPYComputation: false }) {
30548
31030
  const vesuAdapters = this.getVesuAdapters();
30549
31031
  let netMaxBorrowableAmount = Web3Number.fromWei("0", this.getLSTUnderlyingTokenInfo().decimals);
30550
31032
  const maxBorrowables = [];
30551
- const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
30552
- const maxInterestRate = lstAPY * 0.8;
30553
31033
  for (const vesuAdapter of vesuAdapters) {
30554
- const maxBorrowableAmount = await vesuAdapter.getMaxBorrowableByInterestRate(this.config, vesuAdapter.config.debt, maxInterestRate);
30555
- const debtCap = await vesuAdapter.getDebtCap(this.config);
30556
- maxBorrowables.push({ amount: maxBorrowableAmount.minimum(debtCap), borrowableAsset: vesuAdapter.config.debt });
31034
+ maxBorrowables.push(await this.getMaxBorrowableAmountByVesuAdapter(vesuAdapter, params.isAPYComputation));
30557
31035
  }
30558
31036
  maxBorrowables.sort((a, b) => b.amount.toNumber() - a.amount.toNumber());
30559
31037
  netMaxBorrowableAmount = maxBorrowables.reduce((acc, curr) => acc.plus(curr.amount), Web3Number.fromWei("0", this.getLSTUnderlyingTokenInfo().decimals));
30560
31038
  return { netMaxBorrowableAmount, maxBorrowables };
30561
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
+ }
30562
31075
  // todo how much to unwind to get back healthy APY zone again
30563
31076
  // if net APY < LST APR + 0.5%, we need to unwind to get back to LST APR + 1% atleast or 0 vesu position
30564
31077
  // For xSTRK, simply deposit in Vesu if looping is not viable
@@ -30582,7 +31095,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30582
31095
  // todo undo this
30583
31096
  async netAPY() {
30584
31097
  const unusedBalance = await this.getUnusedBalance();
30585
- const maxNewDeposits = await this.maxNewDeposits();
31098
+ const maxNewDeposits = await this.maxNewDeposits({ isAPYComputation: true });
30586
31099
  const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
30587
31100
  if (maxNewDeposits * 1.5 < unusedBalance.amount.toNumber()) {
30588
31101
  logger.verbose(`${this.getTag()}::netAPY: unused balance is > max servicable from loan, lstAPY: ${lstAPY}`);
@@ -30599,8 +31112,8 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30599
31112
  return output;
30600
31113
  }
30601
31114
  }
30602
- async maxNewDeposits() {
30603
- const maxBorrowableAmounts = await this.getMaxBorrowableAmount();
31115
+ async maxNewDeposits(params = { isAPYComputation: false }) {
31116
+ const maxBorrowableAmounts = await this.getMaxBorrowableAmount(params);
30604
31117
  let ltv = void 0;
30605
31118
  for (let adapter of this.getVesuAdapters()) {
30606
31119
  const maxBorrowableAmount = maxBorrowableAmounts.maxBorrowables.find((b) => b.borrowableAsset.address.eq(adapter.config.debt.address))?.amount;
@@ -30703,7 +31216,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30703
31216
  const manageCall2 = manage2Info.callConstructor({
30704
31217
  delegation: true
30705
31218
  });
30706
- const STEP3_ID = "multiply_vesu" /* MULTIPLY_VESU */;
31219
+ const STEP3_ID = getVesuLegId("multiply_vesu" /* MULTIPLY_VESU */, vesuAdapter1.config.debt.symbol);
30707
31220
  const manage3Info = this.getProofs(STEP3_ID);
30708
31221
  const multiplyParams = params.isIncrease ? {
30709
31222
  isIncrease: true,
@@ -30787,6 +31300,12 @@ function VaultDescription(lstSymbol, underlyingSymbol) {
30787
31300
  function getDescription2(tokenSymbol, underlyingSymbol) {
30788
31301
  return VaultDescription(tokenSymbol, underlyingSymbol);
30789
31302
  }
31303
+ function getAvnuManageIDs(baseID, debtTokenSymbol) {
31304
+ return `${baseID}_${debtTokenSymbol.toLowerCase()}`;
31305
+ }
31306
+ function getVesuLegId(baseID, debtTokenSymbol) {
31307
+ return `${baseID}_${debtTokenSymbol.toLowerCase()}`;
31308
+ }
30790
31309
  function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
30791
31310
  vaultSettings.leafAdapters = [];
30792
31311
  const lstToken = Global.getDefaultTokens().find((token) => token.symbol === lstSymbol);
@@ -30796,7 +31315,7 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
30796
31315
  collateral: lstToken,
30797
31316
  debt: underlyingToken,
30798
31317
  vaultAllocator: vaultSettings.vaultAllocator,
30799
- id: "vesu_leg1" /* VESU_LEG1 */
31318
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, underlyingToken.symbol)
30800
31319
  });
30801
31320
  const commonAdapter = new CommonAdapter({
30802
31321
  manager: vaultSettings.manager,
@@ -30805,25 +31324,39 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
30805
31324
  vaultAddress: vaultSettings.vaultAddress,
30806
31325
  vaultAllocator: vaultSettings.vaultAllocator
30807
31326
  });
30808
- const { isV2, addr: poolAddr } = getVesuSingletonAddress(pool1);
30809
- const VESU_MULTIPLY = isV2 ? vesuAdapterLST.VESU_MULTIPLY : vesuAdapterLST.VESU_MULTIPLY_V1;
30810
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, VESU_MULTIPLY, "multiple_approve" /* MULTIPLE_APPROVE */).bind(commonAdapter));
30811
- vaultSettings.leafAdapters.push(vesuAdapterLST.getMultiplyAdapter("multiply_vesu" /* MULTIPLY_VESU */).bind(vesuAdapterLST));
30812
- vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_on" /* SWITCH_DELEGATION_ON */).bind(vesuAdapterLST));
30813
- vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_off" /* SWITCH_DELEGATION_OFF */).bind(vesuAdapterLST));
30814
31327
  vaultSettings.adapters.push(...[{
30815
- id: "vesu_leg1_adapter" /* VESU_LEG1 */,
31328
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, underlyingToken.symbol),
30816
31329
  adapter: vesuAdapterLST
30817
31330
  }, {
30818
31331
  id: "common_adapter" /* COMMON */,
30819
31332
  adapter: commonAdapter
30820
31333
  }]);
30821
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(underlyingToken.address, AVNU_EXCHANGE, "avnu_multiply_approve_deposit" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */).bind(commonAdapter));
30822
- vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(underlyingToken.address, lstToken.address, "avnu_multiply_swap_deposit" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, false).bind(commonAdapter));
30823
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, AVNU_EXCHANGE, "avnu_multiply_approve_withdraw" /* AVNU_MULTIPLY_APPROVE_WITHDRAW */).bind(commonAdapter));
30824
- vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(lstToken.address, underlyingToken.address, "avnu_multiply_swap_withdraw" /* AVNU_MULTIPLY_SWAP_WITHDRAW */, false).bind(commonAdapter));
30825
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, poolAddr, "approve_token1" /* APPROVE_TOKEN1 */).bind(commonAdapter));
30826
- 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
+ }
30827
31360
  vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, vaultSettings.vaultAddress, "approve_bring_liquidity" /* APPROVE_BRING_LIQUIDITY */).bind(commonAdapter));
30828
31361
  vaultSettings.leafAdapters.push(commonAdapter.getBringLiquidityAdapter("bring_liquidity" /* BRING_LIQUIDITY */).bind(commonAdapter));
30829
31362
  vaultSettings.leafAdapters.push(vesuAdapterLST.getDefispringRewardsAdapter("defispring_rewards" /* DEFISPRING_REWARDS */).bind(vesuAdapterLST));
@@ -30901,7 +31434,8 @@ var hyperxSTRK = {
30901
31434
  adapters: [],
30902
31435
  targetHealthFactor: 1.1,
30903
31436
  minHealthFactor: 1.05,
30904
- 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")
30905
31439
  };
30906
31440
  var hyperxWBTC = {
30907
31441
  vaultAddress: ContractAddr.from("0x2da9d0f96a46b453f55604313785dc866424240b1c6811d13bef594343db818"),
@@ -30913,7 +31447,8 @@ var hyperxWBTC = {
30913
31447
  adapters: [],
30914
31448
  targetHealthFactor: 1.1,
30915
31449
  minHealthFactor: 1.05,
30916
- 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")
30917
31452
  };
30918
31453
  var hyperxtBTC = {
30919
31454
  vaultAddress: ContractAddr.from("0x47d5f68477e5637ce0e56436c6b5eee5a354e6828995dae106b11a48679328"),
@@ -30925,7 +31460,8 @@ var hyperxtBTC = {
30925
31460
  adapters: [],
30926
31461
  targetHealthFactor: 1.1,
30927
31462
  minHealthFactor: 1.05,
30928
- 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")
30929
31465
  };
30930
31466
  var hyperxsBTC = {
30931
31467
  vaultAddress: ContractAddr.from("0x437ef1e7d0f100b2e070b7a65cafec0b2be31b0290776da8b4112f5473d8d9"),
@@ -30937,7 +31473,8 @@ var hyperxsBTC = {
30937
31473
  adapters: [],
30938
31474
  targetHealthFactor: 1.1,
30939
31475
  minHealthFactor: 1.05,
30940
- 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")
30941
31478
  };
30942
31479
  var hyperxLBTC = {
30943
31480
  vaultAddress: ContractAddr.from("0x64cf24d4883fe569926419a0569ab34497c6956a1a308fa883257f7486d7030"),
@@ -30949,7 +31486,8 @@ var hyperxLBTC = {
30949
31486
  adapters: [],
30950
31487
  targetHealthFactor: 1.1,
30951
31488
  minHealthFactor: 1.05,
30952
- 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")
30953
31491
  };
30954
31492
  function getInvestmentSteps(lstSymbol, underlyingSymbol) {
30955
31493
  return [
@@ -31652,6 +32190,7 @@ var Deployer = {
31652
32190
  var deployer_default = Deployer;
31653
32191
  // Annotate the CommonJS export names for ESM import in node:
31654
32192
  0 && (module.exports = {
32193
+ APYType,
31655
32194
  AUMTypes,
31656
32195
  AVNU_EXCHANGE,
31657
32196
  AVNU_MIDDLEWARE,