@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.
@@ -20191,7 +20191,7 @@ ${r2}}` : "}", l2;
20191
20191
  toHexString: () => toHexString2,
20192
20192
  toStorageKey: () => toStorageKey2
20193
20193
  });
20194
- var import_utils63 = require_utils2();
20194
+ var import_utils64 = require_utils2();
20195
20195
  function isHex3(hex) {
20196
20196
  return /^0x[0-9a-f]*$/i.test(hex);
20197
20197
  }
@@ -20264,7 +20264,7 @@ ${r2}}` : "}", l2;
20264
20264
  if (adaptedValue.length % 2 !== 0) {
20265
20265
  adaptedValue = `0${adaptedValue}`;
20266
20266
  }
20267
- return (0, import_utils63.hexToBytes)(adaptedValue);
20267
+ return (0, import_utils64.hexToBytes)(adaptedValue);
20268
20268
  }
20269
20269
  function addPercent2(number2, percent) {
20270
20270
  const bigIntNum = BigInt(number2);
@@ -28640,6 +28640,7 @@ ${r2}}` : "}", l2;
28640
28640
  // src/index.browser.ts
28641
28641
  var index_browser_exports = {};
28642
28642
  __export(index_browser_exports, {
28643
+ APYType: () => APYType,
28643
28644
  AUMTypes: () => AUMTypes,
28644
28645
  AVNU_EXCHANGE: () => AVNU_EXCHANGE,
28645
28646
  AVNU_MIDDLEWARE: () => AVNU_MIDDLEWARE,
@@ -49193,6 +49194,25 @@ ${JSON.stringify(data, null, 2)}`;
49193
49194
  priceProxySymbol: "WBTC",
49194
49195
  priceCheckAmount: 1e-4
49195
49196
  // 112000 * 0.0001 = $11.2
49197
+ }, {
49198
+ name: "mRe7BTC",
49199
+ symbol: "mRe7BTC",
49200
+ logo: "https://imagedelivery.net/0xPAQaDtnQhBs8IzYRIlNg/3a62ecee-1e58-45d3-9862-3ce90dff1900/logo",
49201
+ address: ContractAddr.from("0x4e4fb1a9ca7e84bae609b9dc0078ad7719e49187ae7e425bb47d131710eddac"),
49202
+ decimals: 18,
49203
+ coingeckId: void 0,
49204
+ displayDecimals: 6,
49205
+ priceCheckAmount: 1e-4
49206
+ // 112000 * 0.0001 = $11.2
49207
+ }, {
49208
+ name: "mRe7YIELD",
49209
+ symbol: "mRe7YIELD",
49210
+ logo: "https://midas.app/assets/mre7-BcOOHm7i.svg",
49211
+ address: ContractAddr.from("0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"),
49212
+ decimals: 18,
49213
+ coingeckId: void 0,
49214
+ displayDecimals: 2,
49215
+ priceCheckAmount: 100
49196
49216
  }];
49197
49217
  var tokens = defaultTokens;
49198
49218
  var _Global = class _Global {
@@ -53767,16 +53787,16 @@ ${JSON.stringify(data, null, 2)}`;
53767
53787
  };
53768
53788
  return swapInfo;
53769
53789
  }
53770
- static buildZeroSwap(tokenToSell, address) {
53790
+ static buildZeroSwap(tokenToSell, beneficiary, tokenToBuy = tokenToSell) {
53771
53791
  return {
53772
53792
  token_from_address: tokenToSell.address,
53773
53793
  token_from_amount: uint256_exports.bnToUint256(0),
53774
- token_to_address: tokenToSell.address,
53794
+ token_to_address: tokenToBuy.address,
53775
53795
  token_to_amount: uint256_exports.bnToUint256(0),
53776
53796
  token_to_min_amount: uint256_exports.bnToUint256(0),
53777
- beneficiary: address,
53797
+ beneficiary,
53778
53798
  integrator_fee_amount_bps: 0,
53779
- integrator_fee_recipient: address,
53799
+ integrator_fee_recipient: beneficiary,
53780
53800
  routes: []
53781
53801
  };
53782
53802
  }
@@ -55717,21 +55737,20 @@ ${JSON.stringify(data, null, 2)}`;
55717
55737
  const rewards = await this.getHarvests(addr);
55718
55738
  if (rewards.length == 0) return [];
55719
55739
  const unClaimed = [];
55720
- const cls = await this.config.provider.getClassAt(rewards[0].rewardsContract.address);
55721
- for (let reward of rewards) {
55722
- const contract = new Contract({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
55723
- const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
55724
- logger2.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}`);
55725
- if (isClaimed) {
55726
- return unClaimed;
55727
- }
55728
- const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
55729
- if (bal.lessThan(reward.claim.amount)) {
55730
- logger2.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
55731
- continue;
55732
- }
55733
- unClaimed.unshift(reward);
55734
- }
55740
+ const reward = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime())[0];
55741
+ const cls = await this.config.provider.getClassAt(reward.rewardsContract.address);
55742
+ const contract = new Contract({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
55743
+ const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
55744
+ logger2.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}`);
55745
+ if (isClaimed) {
55746
+ return unClaimed;
55747
+ }
55748
+ const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
55749
+ if (bal.lessThan(reward.claim.amount)) {
55750
+ logger2.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
55751
+ return unClaimed;
55752
+ }
55753
+ unClaimed.unshift(reward);
55735
55754
  return unClaimed;
55736
55755
  }
55737
55756
  };
@@ -79321,6 +79340,91 @@ spurious results.`);
79321
79340
  });
79322
79341
  var apollo_client_default = apolloClient;
79323
79342
 
79343
+ // src/utils/math-utils.ts
79344
+ async function binarySearch(lowWei, highWei, callback) {
79345
+ while (lowWei <= highWei) {
79346
+ const diff = highWei - lowWei;
79347
+ const mid = lowWei + diff / 2n;
79348
+ const result2 = await callback(mid);
79349
+ if (result2 === "found") {
79350
+ return mid;
79351
+ } else if (result2 == "retry") {
79352
+ } else if (result2 === "go_low") {
79353
+ highWei = mid - BigInt(1);
79354
+ } else {
79355
+ lowWei = mid + BigInt(1);
79356
+ }
79357
+ }
79358
+ return null;
79359
+ }
79360
+ async function findMaxInputWithSlippage(options) {
79361
+ const {
79362
+ apiGetOutput,
79363
+ maxInput,
79364
+ maxSlippagePercent,
79365
+ tolerance,
79366
+ minInput = 0,
79367
+ referenceAmountMultiplier = 1e-3,
79368
+ referenceRate = 0
79369
+ } = options;
79370
+ let apiCalls = 0;
79371
+ if (!referenceRate && !referenceAmountMultiplier) {
79372
+ throw new Error("One of referenceRate or referenceAmountMultiplier must be provided");
79373
+ }
79374
+ let _referenceRate = referenceRate;
79375
+ if (!_referenceRate) {
79376
+ const smallAmount = maxInput * referenceAmountMultiplier;
79377
+ const referenceOutput = await apiGetOutput(smallAmount);
79378
+ apiCalls++;
79379
+ _referenceRate = referenceOutput / smallAmount;
79380
+ }
79381
+ async function checkSlippage(inputAmount) {
79382
+ const actualOutput = await apiGetOutput(inputAmount);
79383
+ apiCalls++;
79384
+ const expectedOutput = inputAmount * referenceRate;
79385
+ const slippage = (expectedOutput - actualOutput) / expectedOutput;
79386
+ logger2.verbose(`findMaxInputWithSlippage::checkSlippage inputAmount: ${inputAmount}, actualOutput: ${actualOutput}, slippage: ${slippage}, maxSlippagePercent: ${maxSlippagePercent}`);
79387
+ return {
79388
+ acceptable: slippage <= maxSlippagePercent,
79389
+ slippage,
79390
+ output: actualOutput
79391
+ };
79392
+ }
79393
+ const maxCheck = await checkSlippage(maxInput);
79394
+ if (maxCheck.acceptable) {
79395
+ return {
79396
+ optimalInput: maxInput,
79397
+ actualOutput: maxCheck.output,
79398
+ actualSlippage: maxCheck.slippage,
79399
+ apiCallsUsed: apiCalls
79400
+ };
79401
+ }
79402
+ let left = minInput;
79403
+ let right = maxInput;
79404
+ let bestInput = minInput;
79405
+ let bestOutput = 0;
79406
+ let bestSlippage = 0;
79407
+ const convergenceThreshold = tolerance * maxInput;
79408
+ while (right - left > convergenceThreshold) {
79409
+ const mid = (left + right) / 2;
79410
+ const midCheck = await checkSlippage(mid);
79411
+ if (midCheck.acceptable) {
79412
+ bestInput = mid;
79413
+ bestOutput = midCheck.output;
79414
+ bestSlippage = midCheck.slippage;
79415
+ left = mid;
79416
+ } else {
79417
+ right = mid;
79418
+ }
79419
+ }
79420
+ return {
79421
+ optimalInput: bestInput,
79422
+ actualOutput: bestOutput,
79423
+ actualSlippage: bestSlippage,
79424
+ apiCallsUsed: apiCalls
79425
+ };
79426
+ }
79427
+
79324
79428
  // src/strategies/ekubo-cl-vault.tsx
79325
79429
  var import_jsx_runtime3 = __toESM(require_jsx_runtime());
79326
79430
  var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
@@ -79607,7 +79711,6 @@ spurious results.`);
79607
79711
  for (let i = len - 1; i >= 0; --i) {
79608
79712
  let record = await this.contract.call("get_rewards_info", [i]);
79609
79713
  logger2.verbose(`${_EkuboCLVault.name}: getHarvestRewardShares: ${i}`);
79610
- console.log(record);
79611
79714
  const block2 = Number(record.block_number);
79612
79715
  if (block2 < fromBlock) {
79613
79716
  return shares;
@@ -79807,16 +79910,10 @@ spurious results.`);
79807
79910
  const sqrtRatio = _EkuboCLVault.div2Power128(
79808
79911
  BigInt(priceInfo.sqrt_ratio.toString())
79809
79912
  );
79810
- console.log(
79811
- `EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, sqrtRatio: ${sqrtRatio}, ${priceInfo.sqrt_ratio.toString()}`
79812
- );
79813
79913
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
79814
79914
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
79815
79915
  const price = sqrtRatio * sqrtRatio * 10 ** token0Info.decimals / 10 ** token1Info.decimals;
79816
79916
  const tick = priceInfo.tick;
79817
- console.log(
79818
- `EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, price: ${price}, tick: ${tick.mag}, ${tick.sign}`
79819
- );
79820
79917
  return {
79821
79918
  price,
79822
79919
  tick: Number(tick.mag) * (tick.sign ? -1 : 1),
@@ -80443,62 +80540,193 @@ spurious results.`);
80443
80540
  logger2.verbose(
80444
80541
  `${_EkuboCLVault.name}: harvest => Processing claim, isToken1: ${isToken1} amount: ${postFeeAmount.toWei()}`
80445
80542
  );
80446
- const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
80447
- const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
80543
+ const isRewardTokenMatch = claim.token.eq(poolKey.token0) || claim.token.eq(poolKey.token1);
80544
+ if (isRewardTokenMatch) {
80545
+ const _callsFinal = await this._handleRewardAndVaultTokenMatchHarvest({
80546
+ acc,
80547
+ claim,
80548
+ isToken1,
80549
+ token0Info,
80550
+ token1Info,
80551
+ postFeeAmount,
80552
+ poolKey,
80553
+ bounds,
80554
+ maxIterations,
80555
+ priceRatioPrecision
80556
+ });
80557
+ calls.push(..._callsFinal);
80558
+ } else {
80559
+ const _callsFinal = await this._handleRewardAndVaultTokenMismatchHarvest({
80560
+ claim,
80561
+ token0Info,
80562
+ token1Info,
80563
+ postFeeAmount,
80564
+ poolKey,
80565
+ bounds,
80566
+ maxIterations,
80567
+ priceRatioPrecision,
80568
+ acc
80569
+ });
80570
+ calls.push(..._callsFinal);
80571
+ }
80572
+ }
80573
+ return calls;
80574
+ }
80575
+ /**
80576
+ * @description This funciton requires atleast one of the pool tokens to be reward token
80577
+ * i.e. STRK.
80578
+ * @param params
80579
+ */
80580
+ async _handleRewardAndVaultTokenMatchHarvest(params) {
80581
+ const { acc, claim, isToken1, token0Info, token1Info, postFeeAmount, poolKey, bounds, maxIterations, priceRatioPrecision } = params;
80582
+ const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
80583
+ const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
80584
+ logger2.verbose(
80585
+ `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
80586
+ );
80587
+ const swapInfo = await this.getSwapInfoGivenAmounts(
80588
+ poolKey,
80589
+ token0Amt,
80590
+ token1Amt,
80591
+ bounds,
80592
+ maxIterations,
80593
+ priceRatioPrecision
80594
+ );
80595
+ swapInfo.token_to_address = token0Info.address.address;
80596
+ logger2.verbose(
80597
+ `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
80598
+ );
80599
+ logger2.verbose(
80600
+ `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
80601
+ );
80602
+ const harvestEstimateCall = async (swapInfo1) => {
80603
+ const swap1Amount = Web3Number.fromWei(
80604
+ uint256_exports.uint256ToBN(swapInfo1.token_from_amount).toString(),
80605
+ 18
80606
+ // cause its always STRK?
80607
+ ).minimum(
80608
+ postFeeAmount.toFixed(18)
80609
+ // cause always strk
80610
+ );
80611
+ swapInfo.token_from_amount = uint256_exports.bnToUint256(swap1Amount.toWei());
80612
+ swapInfo.token_to_min_amount = uint256_exports.bnToUint256(
80613
+ swap1Amount.multipliedBy(0).toWei()
80614
+ // placeholder
80615
+ );
80448
80616
  logger2.verbose(
80449
- `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
80617
+ `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
80450
80618
  );
80451
- const swapInfo = await this.getSwapInfoGivenAmounts(
80452
- poolKey,
80453
- token0Amt,
80454
- token1Amt,
80455
- bounds,
80456
- maxIterations,
80457
- priceRatioPrecision
80619
+ const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
80620
+ logger2.verbose(
80621
+ `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
80458
80622
  );
80459
- swapInfo.token_to_address = token0Info.address.address;
80623
+ const swapInfo2 = {
80624
+ ...swapInfo,
80625
+ token_from_amount: uint256_exports.bnToUint256(remainingAmount.toWei())
80626
+ };
80627
+ swapInfo2.token_to_address = token1Info.address.address;
80460
80628
  logger2.verbose(
80461
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
80629
+ `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
80630
+ swapInfo
80631
+ )}`
80462
80632
  );
80463
80633
  logger2.verbose(
80464
- `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
80634
+ `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
80635
+ swapInfo2
80636
+ )}`
80465
80637
  );
80466
- const harvestEstimateCall = async (swapInfo1) => {
80467
- const swap1Amount = Web3Number.fromWei(
80468
- uint256_exports.uint256ToBN(swapInfo1.token_from_amount).toString(),
80469
- 18
80470
- // cause its always STRK?
80471
- ).minimum(
80472
- postFeeAmount.toFixed(18)
80473
- // cause always strk
80474
- );
80475
- swapInfo.token_from_amount = uint256_exports.bnToUint256(swap1Amount.toWei());
80476
- swapInfo.token_to_min_amount = uint256_exports.bnToUint256(
80477
- swap1Amount.multipliedBy(0).toWei()
80478
- // placeholder
80479
- );
80480
- logger2.verbose(
80481
- `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
80482
- );
80483
- const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
80484
- logger2.verbose(
80485
- `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
80486
- );
80487
- const swapInfo2 = {
80488
- ...swapInfo,
80489
- token_from_amount: uint256_exports.bnToUint256(remainingAmount.toWei())
80490
- };
80491
- swapInfo2.token_to_address = token1Info.address.address;
80492
- logger2.verbose(
80493
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
80494
- swapInfo
80495
- )}`
80496
- );
80497
- logger2.verbose(
80498
- `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
80499
- swapInfo2
80500
- )}`
80501
- );
80638
+ const calldata = [
80639
+ claim.rewardsContract.address,
80640
+ {
80641
+ id: claim.claim.id,
80642
+ amount: claim.claim.amount.toWei(),
80643
+ claimee: claim.claim.claimee.address
80644
+ },
80645
+ claim.proof.map((p) => num_exports.getDecimalString(p)),
80646
+ swapInfo,
80647
+ swapInfo2
80648
+ ];
80649
+ logger2.verbose(
80650
+ `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
80651
+ calldata
80652
+ )}`
80653
+ );
80654
+ return [this.contract.populate("harvest", calldata)];
80655
+ };
80656
+ const _callsFinal = await this.rebalanceIter(
80657
+ swapInfo,
80658
+ acc,
80659
+ harvestEstimateCall,
80660
+ claim.token.eq(poolKey.token0),
80661
+ 0,
80662
+ 0n,
80663
+ BigInt(postFeeAmount.toWei())
80664
+ // upper limit is the post fee amount
80665
+ );
80666
+ logger2.verbose(
80667
+ `${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
80668
+ _callsFinal
80669
+ )}`
80670
+ );
80671
+ return _callsFinal;
80672
+ }
80673
+ /**
80674
+ * @description This function handles harvesting of reward token that is not the same as any of the vault token
80675
+ * i.e. STRK is not part of vault tokens like BTC/ETH
80676
+ * @param params
80677
+ * @returns
80678
+ */
80679
+ async _handleRewardAndVaultTokenMismatchHarvest(params) {
80680
+ const { acc, claim, token0Info, token1Info, postFeeAmount, poolKey, bounds, maxIterations, priceRatioPrecision } = params;
80681
+ let token0Amt = postFeeAmount;
80682
+ const beneficiary = this.address.address;
80683
+ let harvestCall = null;
80684
+ harvestCall = await this.harvestMismatchEstimateCallFn({
80685
+ postFeeAmount,
80686
+ claim,
80687
+ token0Info,
80688
+ token1Info,
80689
+ acc
80690
+ });
80691
+ if (!harvestCall) {
80692
+ throw new Error("Harvest call not found");
80693
+ }
80694
+ return [harvestCall];
80695
+ }
80696
+ // given an amount (i.e. portion of reward to use to swap to token0), returns info on increasing or decreasing
80697
+ // amount for binary search
80698
+ async harvestMismatchEstimateCallFn(params) {
80699
+ const { postFeeAmount, claim, token0Info, token1Info, acc } = params;
80700
+ let harvestCall = null;
80701
+ const binarySearchCallbackFn = async (mid) => {
80702
+ const rewardPart2 = BigInt(postFeeAmount.toWei()) - mid;
80703
+ const avnuWrapper = new AvnuWrapper();
80704
+ const beneficiary = this.address.address;
80705
+ const quote1 = await avnuWrapper.getQuotes(
80706
+ claim.token.address,
80707
+ token0Info.address.address,
80708
+ mid.toString(),
80709
+ beneficiary
80710
+ );
80711
+ const swapInfo1 = await avnuWrapper.getSwapInfo(
80712
+ quote1,
80713
+ beneficiary,
80714
+ 0,
80715
+ beneficiary
80716
+ );
80717
+ const quote2 = await avnuWrapper.getQuotes(
80718
+ claim.token.address,
80719
+ token1Info.address.address,
80720
+ rewardPart2.toString(),
80721
+ beneficiary
80722
+ );
80723
+ const swapInfo2 = await avnuWrapper.getSwapInfo(
80724
+ quote2,
80725
+ beneficiary,
80726
+ 0,
80727
+ beneficiary
80728
+ );
80729
+ try {
80502
80730
  const calldata = [
80503
80731
  claim.rewardsContract.address,
80504
80732
  {
@@ -80507,34 +80735,23 @@ spurious results.`);
80507
80735
  claimee: claim.claim.claimee.address
80508
80736
  },
80509
80737
  claim.proof.map((p) => num_exports.getDecimalString(p)),
80510
- swapInfo,
80738
+ swapInfo1,
80511
80739
  swapInfo2
80512
80740
  ];
80513
- logger2.verbose(
80514
- `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
80515
- calldata
80516
- )}`
80517
- );
80518
- return [this.contract.populate("harvest", calldata)];
80519
- };
80520
- const _callsFinal = await this.rebalanceIter(
80521
- swapInfo,
80522
- acc,
80523
- harvestEstimateCall,
80524
- claim.token.eq(poolKey.token0),
80525
- 0,
80526
- 0n,
80527
- BigInt(postFeeAmount.toWei())
80528
- // upper limit is the post fee amount
80529
- );
80530
- logger2.verbose(
80531
- `${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
80532
- _callsFinal
80533
- )}`
80534
- );
80535
- calls.push(..._callsFinal);
80536
- }
80537
- return calls;
80741
+ harvestCall = this.contract.populate("harvest", calldata);
80742
+ const gas = await acc.estimateInvokeFee(harvestCall);
80743
+ return "found";
80744
+ } catch (err2) {
80745
+ if (err2.message.includes("invalid token0 amount")) {
80746
+ return "go_low";
80747
+ } else if (err2.message.includes("invalid token1 amount")) {
80748
+ return "go_high";
80749
+ }
80750
+ return "retry";
80751
+ }
80752
+ };
80753
+ await binarySearch(0n, BigInt(postFeeAmount.toWei()), binarySearchCallbackFn);
80754
+ return harvestCall;
80538
80755
  }
80539
80756
  async getInvestmentFlows() {
80540
80757
  const netYield = await this.netAPY();
@@ -83060,7 +83277,58 @@ spurious results.`);
83060
83277
  }
83061
83278
 
83062
83279
  // src/strategies/universal-adapters/baseAdapter.ts
83280
+ var APYType = /* @__PURE__ */ ((APYType2) => {
83281
+ APYType2["BASE"] = "base";
83282
+ APYType2["REWARD"] = "reward";
83283
+ APYType2["LST"] = "lst";
83284
+ return APYType2;
83285
+ })(APYType || {});
83063
83286
  var BaseAdapter = class extends CacheClass {
83287
+ // readonly config: BaseAdapterConfig;
83288
+ // constructor(config: BaseAdapterConfig) {
83289
+ // super();
83290
+ // this.config = config;
83291
+ // }
83292
+ constructor() {
83293
+ super();
83294
+ }
83295
+ // /**
83296
+ // * Loop through all supported positions and return amount, usd value, remarks and apy for each
83297
+ // */
83298
+ // async getPositions(): Promise<PositionInfo[]> {
83299
+ // const results: PositionInfo[] = [];
83300
+ // for (const supported of this.config.supportedPositions) {
83301
+ // const amount = await this.getPosition(supported);
83302
+ // const usdValue = await this.getUSDValue(supported.asset, amount);
83303
+ // const apy = await this.getAPY(supported);
83304
+ // results.push({ amount, usdValue, apy });
83305
+ // }
83306
+ // return results;
83307
+ // }
83308
+ // /**
83309
+ // * Implemented by child adapters to compute APY for a given supported position
83310
+ // */
83311
+ // protected abstract getAPY(supportedPosition: SupportedPosition): Promise<PositionAPY>;
83312
+ // /**
83313
+ // * Implemented by child adapters to fetch amount for a given supported position
83314
+ // */
83315
+ // protected abstract getPosition(supportedPosition: SupportedPosition): Promise<Web3Number>;
83316
+ // /**
83317
+ // * Implemented by child adapters to calculate maximum deposit positions
83318
+ // * @param amount Optional amount in baseToken to deposit
83319
+ // */
83320
+ // protected abstract maxDeposit(amount?: Web3Number): Promise<PositionInfo[]>;
83321
+ // /**
83322
+ // * Implemented by child adapters to calculate maximum withdraw positions
83323
+ // */
83324
+ // protected abstract maxWithdraw(): Promise<PositionInfo[]>;
83325
+ // /**
83326
+ // * Uses pricer to convert an amount of an asset to USD value
83327
+ // */
83328
+ // protected async getUSDValue(asset: TokenInfo, amount: Web3Number): Promise<number> {
83329
+ // const priceInfo = await this.config.pricer.getPrice(asset.symbol);
83330
+ // return amount.toNumber() * priceInfo.price;
83331
+ // }
83064
83332
  constructSimpleLeafData(params, sanitizer = SIMPLE_SANITIZER) {
83065
83333
  const { id, target, method, packedArguments } = params;
83066
83334
  return {
@@ -83078,6 +83346,94 @@ spurious results.`);
83078
83346
  ]
83079
83347
  };
83080
83348
  }
83349
+ // /**
83350
+ // * Implementor must provide target/method/packedArguments/sanitizer for deposit leaf construction
83351
+ // */
83352
+ // protected abstract _getDepositLeaf(): {
83353
+ // target: ContractAddr,
83354
+ // method: string,
83355
+ // packedArguments: bigint[],
83356
+ // sanitizer: ContractAddr,
83357
+ // id: string
83358
+ // }[];
83359
+ // /**
83360
+ // * Implementor must provide target/method/packedArguments/sanitizer for withdraw leaf construction
83361
+ // */
83362
+ // protected abstract _getWithdrawLeaf(): {
83363
+ // target: ContractAddr,
83364
+ // method: string,
83365
+ // packedArguments: bigint[],
83366
+ // sanitizer: ContractAddr,
83367
+ // id: string
83368
+ // }[];
83369
+ // /**
83370
+ // * Returns deposit leaf adapter using configured proof id
83371
+ // */
83372
+ // getDepositLeaf(): AdapterLeafType<T1> {
83373
+ // const leafConfigs = this._getDepositLeaf();
83374
+ // const leaves = leafConfigs.map(config => {
83375
+ // const { target, method, packedArguments, sanitizer, id } = config;
83376
+ // const leaf = this.constructSimpleLeafData({
83377
+ // id: id,
83378
+ // target,
83379
+ // method,
83380
+ // packedArguments
83381
+ // }, sanitizer);
83382
+ // return leaf;
83383
+ // });
83384
+ // return { leaves, callConstructor: this.getDepositCall.bind(this) as unknown as GenerateCallFn<T1> };
83385
+ // }
83386
+ // /**
83387
+ // * Returns withdraw leaf adapter using configured proof id
83388
+ // */
83389
+ // getWithdrawLeaf(): AdapterLeafType<T2> {
83390
+ // const leafConfigs = this._getWithdrawLeaf();
83391
+ // const leaves = leafConfigs.map(config => {
83392
+ // const { target, method, packedArguments, sanitizer, id } = config;
83393
+ // const leaf = this.constructSimpleLeafData({
83394
+ // id: id,
83395
+ // target,
83396
+ // method,
83397
+ // packedArguments
83398
+ // }, sanitizer ?? SIMPLE_SANITIZER);
83399
+ // return leaf;
83400
+ // });
83401
+ // return { leaves, callConstructor: this.getWithdrawCall.bind(this) as unknown as GenerateCallFn<T2> };
83402
+ // }
83403
+ // /**
83404
+ // * Default deposit callConstructor: expects params as calldata (bigint[])
83405
+ // */
83406
+ // protected getDepositCall<T1 = bigint[]>(params: T1): ManageCall[] {
83407
+ // const leafConfigs = this._getDepositLeaf();
83408
+ // return leafConfigs.map(config => {
83409
+ // const { target, method, sanitizer } = config;
83410
+ // return {
83411
+ // sanitizer: sanitizer ?? SIMPLE_SANITIZER,
83412
+ // call: {
83413
+ // contractAddress: target,
83414
+ // selector: hash.getSelectorFromName(method),
83415
+ // calldata: params as unknown as bigint[]
83416
+ // }
83417
+ // };
83418
+ // });
83419
+ // }
83420
+ // /**
83421
+ // * Default withdraw callConstructor: expects params as calldata (bigint[])
83422
+ // */
83423
+ // protected getWithdrawCall<T2 = bigint[]>(params: T2): ManageCall[] {
83424
+ // const leafConfigs = this._getWithdrawLeaf();
83425
+ // return leafConfigs.map(config => {
83426
+ // const { target, method, sanitizer } = config;
83427
+ // return {
83428
+ // sanitizer: sanitizer ?? SIMPLE_SANITIZER,
83429
+ // call: {
83430
+ // contractAddress: target,
83431
+ // selector: hash.getSelectorFromName(method),
83432
+ // calldata: params as unknown as bigint[]
83433
+ // }
83434
+ // };
83435
+ // });
83436
+ // }
83081
83437
  };
83082
83438
 
83083
83439
  // src/strategies/universal-adapters/common-adapter.ts
@@ -90676,7 +91032,20 @@ spurious results.`);
90676
91032
  }
90677
91033
  const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address]);
90678
91034
  logger2.verbose(`${this.config.debt.symbol}::VesuAdapter::getDebtCap debt_cap: ${output.debt_cap.toString()}`);
90679
- return Web3Number.fromWei(output.debt_cap.toString(), this.config.debt.decimals);
91035
+ if (!isV2) {
91036
+ throw new Error("getDebtCap is not supported for v1");
91037
+ }
91038
+ const currentDebt = await this.getCurrentDebtUtilisationAmount(config3);
91039
+ logger2.verbose(`${this.config.debt.symbol}::VesuAdapter::getDebtCap currentDebt: ${currentDebt.toString()}`);
91040
+ return Web3Number.fromWei(output.debt_cap.toString(), this.config.debt.decimals).minus(currentDebt);
91041
+ }
91042
+ async getCurrentDebtUtilisationAmount(config3) {
91043
+ const { contract, isV2 } = await this.getVesuSingletonContract(config3, this.config.poolId);
91044
+ if (!isV2) {
91045
+ throw new Error("getCurrentDebtUtilisationAmount is not supported for v1");
91046
+ }
91047
+ const output = await contract.call("pairs", [this.config.collateral.address.address, this.config.debt.address.address]);
91048
+ return new Web3Number((Number(output.total_nominal_debt) / 1e18).toFixed(9), this.config.debt.decimals);
90680
91049
  }
90681
91050
  async getMaxBorrowableByInterestRate(config3, asset, maxBorrowAPY) {
90682
91051
  const { contract, isV2 } = await this.getVesuSingletonContract(config3, this.config.poolId);
@@ -90709,16 +91078,17 @@ spurious results.`);
90709
91078
  const assetConfig = isV2 ? _assetConfig : _assetConfig["0"];
90710
91079
  const timeDelta = assetConfig.last_updated;
90711
91080
  const lastFullUtilizationRate = assetConfig.last_full_utilization_rate;
90712
- const totalSupply = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals).plus(Web3Number.fromWei(assetConfig.reserve, asset.decimals));
91081
+ const currentDebt = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals);
91082
+ const totalSupply = currentDebt.plus(Web3Number.fromWei(assetConfig.reserve, asset.decimals));
90713
91083
  const ratePerSecond = BigInt(Math.round(maxBorrowAPY / 365 / 24 / 60 / 60 * Number(SCALE)));
90714
91084
  const maxUtilisation = this.getMaxUtilizationGivenRatePerSecond(interestRateConfig, ratePerSecond, timeDelta, lastFullUtilizationRate);
90715
91085
  logger2.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate maxUtilisation: ${Number(maxUtilisation) / 1e18}, totalSupply: ${totalSupply.toString()}`);
90716
91086
  const maxDebtToHave = totalSupply.multipliedBy(Number(maxUtilisation) / 1e18);
90717
- const currentDebt = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals);
91087
+ logger2.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate currentDebt: ${currentDebt.toString()}, maxDebtToHave: ${maxDebtToHave.toString()}`);
90718
91088
  return maxDebtToHave.minus(currentDebt);
90719
91089
  }
90720
- async getLTVConfig(config3) {
90721
- const CACHE_KEY = "ltv_config";
91090
+ async getLTVConfig(config3, blockNumber = "latest") {
91091
+ const CACHE_KEY = `ltv_config_${blockNumber}`;
90722
91092
  const cacheData = this.getCache(CACHE_KEY);
90723
91093
  if (cacheData) {
90724
91094
  return cacheData;
@@ -90726,10 +91096,10 @@ spurious results.`);
90726
91096
  const { contract, isV2 } = await this.getVesuSingletonContract(config3, this.config.poolId);
90727
91097
  let ltv = 0;
90728
91098
  if (isV2) {
90729
- const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address]);
91099
+ const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address], { blockIdentifier: blockNumber });
90730
91100
  ltv = Number(output.max_ltv) / 1e18;
90731
91101
  } else {
90732
- const output = await contract.call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address]);
91102
+ const output = await contract.call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address], { blockIdentifier: blockNumber });
90733
91103
  ltv = Number(output.max_ltv) / 1e18;
90734
91104
  }
90735
91105
  if (ltv == 0) {
@@ -90738,11 +91108,11 @@ spurious results.`);
90738
91108
  this.setCache(CACHE_KEY, ltv, 3e5);
90739
91109
  return this.getCache(CACHE_KEY);
90740
91110
  }
90741
- async getPositions(config3) {
91111
+ async getPositions(config3, blockNumber = "latest") {
90742
91112
  if (!this.pricer) {
90743
91113
  throw new Error("Pricer is not initialized");
90744
91114
  }
90745
- const CACHE_KEY = "positions";
91115
+ const CACHE_KEY = `positions_${blockNumber}`;
90746
91116
  const cacheData = this.getCache(CACHE_KEY);
90747
91117
  if (cacheData) {
90748
91118
  return cacheData;
@@ -90754,7 +91124,8 @@ spurious results.`);
90754
91124
  this.config.collateral.address.address,
90755
91125
  this.config.debt.address.address,
90756
91126
  this.config.vaultAllocator.address
90757
- ]);
91127
+ ], { blockIdentifier: blockNumber });
91128
+ console.log(output);
90758
91129
  const token1Price = await this.pricer.getPrice(this.config.collateral.symbol);
90759
91130
  const token2Price = await this.pricer.getPrice(this.config.debt.symbol);
90760
91131
  logger2.verbose(`VesuAdapter::getPositions token1Price: ${token1Price.price}, token2Price: ${token2Price.price}`);
@@ -90774,11 +91145,11 @@ spurious results.`);
90774
91145
  this.setCache(CACHE_KEY, value, 6e4);
90775
91146
  return value;
90776
91147
  }
90777
- async getCollateralization(config3) {
91148
+ async getCollateralization(config3, blockNumber = "latest") {
90778
91149
  if (!this.pricer) {
90779
91150
  throw new Error("Pricer is not initialized");
90780
91151
  }
90781
- const CACHE_KEY = "collateralization";
91152
+ const CACHE_KEY = `collateralization_${blockNumber}`;
90782
91153
  const cacheData = this.getCache(CACHE_KEY);
90783
91154
  if (cacheData) {
90784
91155
  return cacheData;
@@ -90790,7 +91161,7 @@ spurious results.`);
90790
91161
  this.config.collateral.address.address,
90791
91162
  this.config.debt.address.address,
90792
91163
  this.config.vaultAllocator.address
90793
- ]);
91164
+ ], { blockIdentifier: blockNumber });
90794
91165
  const collateralAmount = Web3Number.fromWei(output["1"].toString(), 18);
90795
91166
  const debtAmount = Web3Number.fromWei(output["2"].toString(), 18);
90796
91167
  const value = [{
@@ -90827,9 +91198,9 @@ spurious results.`);
90827
91198
  ltv
90828
91199
  };
90829
91200
  }
90830
- async getHealthFactor() {
90831
- const ltv = await this.getLTVConfig(this.networkConfig);
90832
- const collateralisation = await this.getCollateralization(this.networkConfig);
91201
+ async getHealthFactor(blockNumber = "latest") {
91202
+ const ltv = await this.getLTVConfig(this.networkConfig, blockNumber);
91203
+ const collateralisation = await this.getCollateralization(this.networkConfig, blockNumber);
90833
91204
  return collateralisation[0].usdValue * ltv / collateralisation[1].usdValue;
90834
91205
  }
90835
91206
  static async getVesuPools(retry = 0) {
@@ -93488,11 +93859,11 @@ spurious results.`);
93488
93859
  vesuAdapter2.networkConfig = this.config;
93489
93860
  return [vesuAdapter1, vesuAdapter2];
93490
93861
  }
93491
- async getVesuPositions() {
93862
+ async getVesuPositions(blockNumber = "latest") {
93492
93863
  const adapters = this.getVesuAdapters();
93493
93864
  const positions = [];
93494
93865
  for (const adapter of adapters) {
93495
- positions.push(...await adapter.getPositions(this.config));
93866
+ positions.push(...await adapter.getPositions(this.config, blockNumber));
93496
93867
  }
93497
93868
  return positions;
93498
93869
  }
@@ -93561,8 +93932,8 @@ spurious results.`);
93561
93932
  async getLSTAPR(address) {
93562
93933
  return 0;
93563
93934
  }
93564
- async getVesuHealthFactors() {
93565
- return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor()));
93935
+ async getVesuHealthFactors(blockNumber = "latest") {
93936
+ return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor(blockNumber)));
93566
93937
  }
93567
93938
  async computeRebalanceConditionAndReturnCalls() {
93568
93939
  const vesuAdapters = this.getVesuAdapters();
@@ -94156,6 +94527,40 @@ spurious results.`);
94156
94527
  }
94157
94528
  ];
94158
94529
 
94530
+ // src/utils/health-factor-math.ts
94531
+ var HealthFactorMath = class {
94532
+ static getCollateralRequired(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo) {
94533
+ const numerator = debtAmount.multipliedBy(debtPrice).multipliedBy(targetHF);
94534
+ const denominator = collateralPrice * maxLTV;
94535
+ const collateralAmount = numerator.dividedBy(denominator);
94536
+ const netCollateral = new Web3Number(collateralAmount.toString(), collateralTokenInfo.decimals);
94537
+ return netCollateral;
94538
+ }
94539
+ static getMinCollateralRequiredOnLooping(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo) {
94540
+ const netCollateral = this.getCollateralRequired(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo);
94541
+ const collateralFromDebt = new Web3Number(debtAmount.multipliedBy(debtPrice).dividedBy(collateralPrice).toString(), collateralTokenInfo.decimals);
94542
+ return netCollateral.minus(collateralFromDebt);
94543
+ }
94544
+ static getHealthFactor(collateralAmount, collateralPrice, maxLTV, debtAmount, debtPrice) {
94545
+ const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
94546
+ const denominator = debtAmount.multipliedBy(debtPrice);
94547
+ const healthFactor = numerator.dividedBy(denominator);
94548
+ return healthFactor.toNumber();
94549
+ }
94550
+ static getMaxDebtAmountOnLooping(collateralAmount, collateralPrice, maxLTV, targetHF, debtPrice, debtTokenInfo) {
94551
+ const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
94552
+ const denominator = targetHF - maxLTV;
94553
+ const debtAmount = numerator.dividedBy(denominator);
94554
+ return new Web3Number(debtAmount.toString(), debtTokenInfo.decimals);
94555
+ }
94556
+ static getMaxDebtAmount(collateralAmount, collateralPrice, maxLTV, targetHF, debtPrice, debtTokenInfo) {
94557
+ const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
94558
+ const denominator = targetHF * debtPrice;
94559
+ const debtAmount = numerator.dividedBy(denominator);
94560
+ return new Web3Number(debtAmount.toString(), debtTokenInfo.decimals);
94561
+ }
94562
+ };
94563
+
94159
94564
  // src/strategies/universal-lst-muliplier-strategy.tsx
94160
94565
  var import_jsx_runtime5 = __toESM(require_jsx_runtime());
94161
94566
  var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy extends UniversalStrategy {
@@ -94171,15 +94576,14 @@ spurious results.`);
94171
94576
  }
94172
94577
  }
94173
94578
  asset() {
94174
- const vesuAdapter1 = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
94175
- return vesuAdapter1.config.collateral;
94579
+ return this.getVesuSameTokenAdapter().config.collateral;
94176
94580
  }
94177
94581
  getTag() {
94178
94582
  return `${_UniversalLstMultiplierStrategy.name}:${this.metadata.name}`;
94179
94583
  }
94180
94584
  // Vesu adapter with LST and base token match
94181
94585
  getVesuSameTokenAdapter() {
94182
- const baseAdapter = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
94586
+ const baseAdapter = this.getAdapter(getVesuLegId("vesu_leg1" /* VESU_LEG1 */, this.metadata.additionalInfo.underlyingToken.symbol));
94183
94587
  baseAdapter.networkConfig = this.config;
94184
94588
  baseAdapter.pricer = this.pricer;
94185
94589
  return baseAdapter;
@@ -94227,20 +94631,52 @@ spurious results.`);
94227
94631
  return price;
94228
94632
  }
94229
94633
  async getAvnuSwapMultiplyCall(params) {
94230
- return this._getAvnuDepositSwapLegCall({
94231
- ...params,
94232
- minHF: 1.1
94233
- // undo
94234
- });
94634
+ assert3(params.isDeposit, "Only deposit is supported in getAvnuSwapMultiplyCall");
94635
+ const maxBorrowableAmounts = await this.getMaxBorrowableAmount({ isAPYComputation: false });
94636
+ const allVesuAdapters = this.getVesuAdapters();
94637
+ let remainingAmount = params.leg1DepositAmount;
94638
+ const lstExRate = await this.getLSTExchangeRate();
94639
+ const baseAssetPrice = await this.pricer.getPrice(this.getLSTUnderlyingTokenInfo().symbol);
94640
+ const lstPrice = baseAssetPrice.price * lstExRate;
94641
+ for (let i = 0; i < maxBorrowableAmounts.maxBorrowables.length; i++) {
94642
+ const maxBorrowable = maxBorrowableAmounts.maxBorrowables[i];
94643
+ const vesuAdapter = allVesuAdapters.find((adapter) => adapter.config.debt.address.eq(maxBorrowable.borrowableAsset.address));
94644
+ if (!vesuAdapter) {
94645
+ throw new Error(`${this.getTag()}::getAvnuSwapMultiplyCall: vesuAdapter not found for borrowable asset: ${maxBorrowable.borrowableAsset.symbol}`);
94646
+ }
94647
+ const maxLTV = await vesuAdapter.getLTVConfig(this.config);
94648
+ const debtPrice = await this.pricer.getPrice(maxBorrowable.borrowableAsset.symbol);
94649
+ const maxAmountToDeposit = HealthFactorMath.getMinCollateralRequiredOnLooping(
94650
+ maxBorrowable.amount,
94651
+ debtPrice.price,
94652
+ this.metadata.additionalInfo.targetHealthFactor,
94653
+ maxLTV,
94654
+ lstPrice,
94655
+ this.asset()
94656
+ );
94657
+ const amountToDeposit = remainingAmount.minimum(maxAmountToDeposit);
94658
+ logger2.verbose(`${this.getTag()}::getAvnuSwapMultiplyCall::${vesuAdapter.config.debt.symbol}:: remainingAmount: ${remainingAmount}, amountToDeposit: ${amountToDeposit}, depositAmount: ${amountToDeposit}, maxBorrowable: ${maxBorrowable.amount}`);
94659
+ const call = await this._getAvnuDepositSwapLegCall({
94660
+ isDeposit: params.isDeposit,
94661
+ // adjust decimals of debt asset
94662
+ leg1DepositAmount: amountToDeposit,
94663
+ minHF: 1.1,
94664
+ // undo
94665
+ vesuAdapter
94666
+ });
94667
+ remainingAmount = remainingAmount.minus(amountToDeposit);
94668
+ return { call, vesuAdapter };
94669
+ }
94670
+ throw new Error(`${this.getTag()}::getAvnuSwapMultiplyCall: no calls found`);
94235
94671
  }
94236
94672
  async _getAvnuDepositSwapLegCall(params) {
94673
+ const { vesuAdapter } = params;
94237
94674
  logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall params: ${JSON.stringify(params)}`);
94238
94675
  assert3(params.isDeposit, "Only deposit is supported in _getAvnuDepositSwapLegCall");
94239
- const [vesuAdapter1] = this.getVesuAdapters();
94240
- const legLTV = await vesuAdapter1.getLTVConfig(this.config);
94676
+ const legLTV = await vesuAdapter.getLTVConfig(this.config);
94241
94677
  logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall legLTV: ${legLTV}`);
94242
- const existingPositions = await vesuAdapter1.getPositions(this.config);
94243
- const collateralisation = await vesuAdapter1.getCollateralization(this.config);
94678
+ const existingPositions = await vesuAdapter.getPositions(this.config);
94679
+ const collateralisation = await vesuAdapter.getCollateralization(this.config);
94244
94680
  const existingCollateralInfo = existingPositions[0];
94245
94681
  const existingDebtInfo = existingPositions[1];
94246
94682
  logger2.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
@@ -94248,11 +94684,40 @@ spurious results.`);
94248
94684
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
94249
94685
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
94250
94686
  logger2.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
94687
+ const debtTokenInfo = vesuAdapter.config.debt;
94688
+ let newDepositAmount = params.leg1DepositAmount;
94251
94689
  const totalCollateral = existingCollateralInfo.amount.plus(params.leg1DepositAmount);
94252
94690
  logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalCollateral: ${totalCollateral}`);
94253
- const totalDebtAmount = totalCollateral.multipliedBy(collateralPrice).multipliedBy(legLTV).dividedBy(debtPrice).dividedBy(params.minHF);
94254
- logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalDebtAmount: ${totalDebtAmount}`);
94255
- const debtAmount = totalDebtAmount.minus(existingDebtInfo.amount);
94691
+ const totalDebtAmount = new Web3Number(
94692
+ totalCollateral.multipliedBy(collateralPrice).multipliedBy(legLTV).dividedBy(debtPrice).dividedBy(params.minHF).toString(),
94693
+ debtTokenInfo.decimals
94694
+ );
94695
+ let debtAmount = totalDebtAmount.minus(existingDebtInfo.amount);
94696
+ logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalDebtAmount: ${totalDebtAmount}, initial computed debt: ${debtAmount}`);
94697
+ const maxBorrowable = await this.getMaxBorrowableAmountByVesuAdapter(vesuAdapter, false);
94698
+ if (debtAmount.gt(0) && maxBorrowable.amount.eq(0)) {
94699
+ logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall maxBorrowable is 0, skipping`);
94700
+ return void 0;
94701
+ } else if (debtAmount.gt(0) && maxBorrowable.amount.gt(0)) {
94702
+ debtAmount = maxBorrowable.amount.minimum(debtAmount);
94703
+ const newDebtUSDValue = debtAmount.multipliedBy(debtPrice);
94704
+ const totalCollateralRequired = HealthFactorMath.getCollateralRequired(
94705
+ debtAmount.plus(existingDebtInfo.amount),
94706
+ debtPrice,
94707
+ params.minHF,
94708
+ legLTV,
94709
+ collateralPrice,
94710
+ this.asset()
94711
+ );
94712
+ newDepositAmount = totalCollateralRequired.minus(existingCollateralInfo.amount);
94713
+ if (newDepositAmount.lt(0)) {
94714
+ throw new Error(`${this.getTag()}::_getAvnuDepositSwapLegCall newDepositAmount is less than 0, newDepositAmount: ${newDepositAmount}, totalCollateralRequired: ${totalCollateralRequired}, existingCollateralInfo.amount: ${existingCollateralInfo.amount}`);
94715
+ }
94716
+ if (newDebtUSDValue.toNumber() < 100) {
94717
+ logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall newDebtUSDValue is less than 100, skipping`);
94718
+ return void 0;
94719
+ }
94720
+ }
94256
94721
  logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall debtAmount: ${debtAmount}`);
94257
94722
  if (debtAmount.lt(0)) {
94258
94723
  const lstDEXPrice = await this.getLSTDexPrice();
@@ -94264,32 +94729,34 @@ spurious results.`);
94264
94729
  assert3(calls.length == 1, `Expected 1 call for unwind, got ${calls.length}`);
94265
94730
  return calls[0];
94266
94731
  }
94732
+ console.log(`debtAmount`, debtAmount.toWei(), params.leg1DepositAmount.toWei());
94267
94733
  const STEP0 = "approve_token1" /* APPROVE_TOKEN1 */;
94268
94734
  const manage0Info = this.getProofs(STEP0);
94269
94735
  const manageCall0 = manage0Info.callConstructor({
94270
- amount: params.leg1DepositAmount
94736
+ amount: newDepositAmount
94271
94737
  });
94272
- const STEP1 = "vesu_leg1" /* VESU_LEG1 */;
94738
+ const STEP1 = getVesuLegId("vesu_leg1" /* VESU_LEG1 */, vesuAdapter.config.debt.symbol);
94273
94739
  const manage1Info = this.getProofs(STEP1);
94274
94740
  const manageCall1 = manage1Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
94275
- collateralAmount: params.leg1DepositAmount,
94741
+ collateralAmount: newDepositAmount,
94276
94742
  isAddCollateral: params.isDeposit,
94277
94743
  debtAmount,
94278
94744
  isBorrow: params.isDeposit
94279
94745
  }));
94746
+ console.log(`manageCall1`, manageCall1.call, debtAmount.toWei(), newDepositAmount.toWei());
94280
94747
  const proofIds = [STEP0, STEP1];
94281
94748
  const manageCalls = [manageCall0, manageCall1];
94282
94749
  if (debtAmount.gt(0)) {
94283
- const STEP2 = "avnu_multiply_approve_deposit" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */;
94750
+ const STEP2 = getAvnuManageIDs("avnu_mul_approve_dep" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */, vesuAdapter.config.debt.symbol);
94284
94751
  const manage2Info = this.getProofs(STEP2);
94285
94752
  const manageCall2 = manage2Info.callConstructor({
94286
94753
  amount: debtAmount
94287
94754
  });
94288
- const debtTokenInfo = vesuAdapter1.config.debt;
94755
+ const debtTokenInfo2 = vesuAdapter.config.debt;
94289
94756
  const lstTokenInfo = this.asset();
94290
94757
  const avnuModule = new AvnuWrapper();
94291
94758
  const quote = await avnuModule.getQuotes(
94292
- debtTokenInfo.address.address,
94759
+ debtTokenInfo2.address.address,
94293
94760
  lstTokenInfo.address.address,
94294
94761
  debtAmount.toWei(),
94295
94762
  this.metadata.additionalInfo.vaultAllocator.address
@@ -94305,7 +94772,7 @@ spurious results.`);
94305
94772
  minAmountWei
94306
94773
  );
94307
94774
  logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall swapInfo: ${JSON.stringify(swapInfo)}`);
94308
- const STEP3 = "avnu_multiply_swap_deposit" /* AVNU_MULTIPLY_SWAP_DEPOSIT */;
94775
+ const STEP3 = getAvnuManageIDs("avnu_mul_swap_dep" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, vesuAdapter.config.debt.symbol);
94309
94776
  const manage3Info = this.getProofs(STEP3);
94310
94777
  const manageCall3 = manage3Info.callConstructor({
94311
94778
  props: swapInfo
@@ -94323,7 +94790,7 @@ spurious results.`);
94323
94790
  const manageCall4 = manage4Info.callConstructor({
94324
94791
  amount: minAmount
94325
94792
  });
94326
- const STEP5 = "vesu_leg1" /* VESU_LEG1 */;
94793
+ const STEP5 = getVesuLegId("vesu_leg1" /* VESU_LEG1 */, vesuAdapter.config.debt.symbol);
94327
94794
  const manage5Info = this.getProofs(STEP5);
94328
94795
  const manageCall5 = manage5Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
94329
94796
  collateralAmount: minAmount,
@@ -94340,28 +94807,41 @@ spurious results.`);
94340
94807
  }
94341
94808
  // todo unwind or not deposit when the yield is bad.
94342
94809
  async getLSTMultiplierRebalanceCall() {
94343
- const positions = await this.getVaultPositions();
94344
- assert3(positions.length == 3, "Rebalance call is only supported for 3 positions");
94810
+ let shouldRebalance = false;
94811
+ const calls = [];
94812
+ const allVesuAdapters = this.getVesuAdapters().filter((vesuAdapter) => vesuAdapter.config.debt.symbol === "LBTC");
94813
+ for (const vesuAdapter of allVesuAdapters) {
94814
+ const call = await this._getLSTMultiplierRebalanceCall(vesuAdapter);
94815
+ if (call.shouldRebalance && call.manageCall) {
94816
+ shouldRebalance = true;
94817
+ calls.push({ vesuAdapter, manageCall: call.manageCall });
94818
+ }
94819
+ }
94820
+ return { shouldRebalance, manageCalls: calls };
94821
+ }
94822
+ async _getLSTMultiplierRebalanceCall(vesuAdapter) {
94823
+ const positions = await vesuAdapter.getPositions(this.config);
94824
+ assert3(positions.length == 2, "Rebalance call is only supported for 2 positions");
94345
94825
  const existingCollateralInfo = positions[0];
94346
94826
  const existingDebtInfo = positions[1];
94347
- const unusedBalance = positions[2];
94348
- const [healthFactor] = await this.getVesuHealthFactors();
94349
- const [vesuAdapter1] = this.getVesuAdapters();
94350
- const legLTV = await vesuAdapter1.getLTVConfig(this.config);
94351
- const collateralisation = await vesuAdapter1.getCollateralization(this.config);
94352
- logger2.debug(`${this.getTag()}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
94827
+ const unusedBalance = await this.getUnusedBalance();
94828
+ const healthFactor = await vesuAdapter.getHealthFactor();
94829
+ const collateralisation = await vesuAdapter.getCollateralization(this.config);
94830
+ logger2.debug(`${this.getTag()}::getVesuMultiplyCall::${vesuAdapter.config.debt.symbol} existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
94353
94831
  existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
94354
94832
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
94355
94833
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
94356
94834
  logger2.debug(`${this.getTag()}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
94835
+ logger2.debug(`${this.getTag()}::getVesuMultiplyCall healthFactor: ${healthFactor}`);
94357
94836
  const isHFTooLow = healthFactor < this.metadata.additionalInfo.minHealthFactor;
94358
94837
  const isHFTooHigh = healthFactor > this.metadata.additionalInfo.targetHealthFactor + 0.05;
94359
- if (isHFTooLow || isHFTooHigh) {
94838
+ if (isHFTooLow || isHFTooHigh || 1) {
94360
94839
  const manageCall = await this._getAvnuDepositSwapLegCall({
94361
94840
  isDeposit: true,
94362
94841
  leg1DepositAmount: unusedBalance.amount,
94363
- minHF: 1.02
94842
+ minHF: 1.02,
94364
94843
  // todo, shouldnt use this 1.02 HF, if there isn;t more looping left.
94844
+ vesuAdapter
94365
94845
  });
94366
94846
  return { shouldRebalance: true, manageCall };
94367
94847
  } else {
@@ -94394,7 +94874,7 @@ spurious results.`);
94394
94874
  async _getMinOutputAmountLSTBuy(amountInUnderlying) {
94395
94875
  const lstTruePrice = await this.getLSTExchangeRate();
94396
94876
  const minOutputAmount = amountInUnderlying.dividedBy(lstTruePrice).multipliedBy(0.99979);
94397
- return minOutputAmount;
94877
+ return new Web3Number(minOutputAmount.toString(), this.asset().decimals);
94398
94878
  }
94399
94879
  async _getMinOutputAmountLSTSell(amountInLST) {
94400
94880
  const lstTruePrice = await this.getLSTExchangeRate();
@@ -94451,21 +94931,52 @@ spurious results.`);
94451
94931
  const vesuAdapter1 = this.getVesuSameTokenAdapter();
94452
94932
  return vesuAdapter1.config.debt;
94453
94933
  }
94454
- async getMaxBorrowableAmount() {
94934
+ async getMaxBorrowableAmount(params = { isAPYComputation: false }) {
94455
94935
  const vesuAdapters = this.getVesuAdapters();
94456
94936
  let netMaxBorrowableAmount = Web3Number.fromWei("0", this.getLSTUnderlyingTokenInfo().decimals);
94457
94937
  const maxBorrowables = [];
94458
- const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
94459
- const maxInterestRate = lstAPY * 0.8;
94460
94938
  for (const vesuAdapter of vesuAdapters) {
94461
- const maxBorrowableAmount = await vesuAdapter.getMaxBorrowableByInterestRate(this.config, vesuAdapter.config.debt, maxInterestRate);
94462
- const debtCap = await vesuAdapter.getDebtCap(this.config);
94463
- maxBorrowables.push({ amount: maxBorrowableAmount.minimum(debtCap), borrowableAsset: vesuAdapter.config.debt });
94939
+ maxBorrowables.push(await this.getMaxBorrowableAmountByVesuAdapter(vesuAdapter, params.isAPYComputation));
94464
94940
  }
94465
94941
  maxBorrowables.sort((a, b) => b.amount.toNumber() - a.amount.toNumber());
94466
94942
  netMaxBorrowableAmount = maxBorrowables.reduce((acc, curr) => acc.plus(curr.amount), Web3Number.fromWei("0", this.getLSTUnderlyingTokenInfo().decimals));
94467
94943
  return { netMaxBorrowableAmount, maxBorrowables };
94468
94944
  }
94945
+ // recursively, using binary search computes max swappable.
94946
+ // @dev assumes 1 token of from == 1 token of to
94947
+ async getMaxSwappableWithMaxSlippage(fromToken, toToken, maxSlippage, maxAmount) {
94948
+ const output = await findMaxInputWithSlippage({
94949
+ apiGetOutput: async (inputAmount) => {
94950
+ const ekuboQuoter = new EkuboQuoter(this.config);
94951
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
94952
+ const quote = await ekuboQuoter.getQuote(fromToken.address.address, toToken.address.address, new Web3Number(inputAmount.toFixed(9), fromToken.decimals));
94953
+ return Web3Number.fromWei(quote.total_calculated.toString(), toToken.decimals).toNumber();
94954
+ },
94955
+ maxInput: maxAmount.toNumber(),
94956
+ maxSlippagePercent: maxSlippage,
94957
+ tolerance: 1e-3,
94958
+ referenceRate: 1
94959
+ });
94960
+ return new Web3Number(output.optimalInput, fromToken.decimals);
94961
+ }
94962
+ async getMaxBorrowableAmountByVesuAdapter(vesuAdapter, isAPYComputation) {
94963
+ const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
94964
+ const maxInterestRate = lstAPY * 0.8;
94965
+ const maxBorrowableAmount = await vesuAdapter.getMaxBorrowableByInterestRate(this.config, vesuAdapter.config.debt, maxInterestRate);
94966
+ const debtCap = await vesuAdapter.getDebtCap(this.config);
94967
+ const maxBorrowable = maxBorrowableAmount.minimum(debtCap).multipliedBy(0.999);
94968
+ if (vesuAdapter.config.debt.address.eq(this.getLSTUnderlyingTokenInfo().address) || isAPYComputation) {
94969
+ return { amount: maxBorrowable, dexSwappableAmount: maxBorrowable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
94970
+ }
94971
+ try {
94972
+ const maxSwappable = await this.getMaxSwappableWithMaxSlippage(vesuAdapter.config.debt, this.getLSTUnderlyingTokenInfo(), 2e-4, maxBorrowable);
94973
+ return { amount: maxBorrowable.minimum(maxSwappable), dexSwappableAmount: maxSwappable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
94974
+ } catch (error2) {
94975
+ logger2.warn(`${this.getTag()}: Failed to get max swappable: ${error2}`);
94976
+ const maxSwappable = Web3Number.fromWei("0", vesuAdapter.config.debt.decimals);
94977
+ return { amount: maxBorrowable.minimum(maxSwappable), dexSwappableAmount: maxSwappable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
94978
+ }
94979
+ }
94469
94980
  // todo how much to unwind to get back healthy APY zone again
94470
94981
  // if net APY < LST APR + 0.5%, we need to unwind to get back to LST APR + 1% atleast or 0 vesu position
94471
94982
  // For xSTRK, simply deposit in Vesu if looping is not viable
@@ -94489,7 +95000,7 @@ spurious results.`);
94489
95000
  // todo undo this
94490
95001
  async netAPY() {
94491
95002
  const unusedBalance = await this.getUnusedBalance();
94492
- const maxNewDeposits = await this.maxNewDeposits();
95003
+ const maxNewDeposits = await this.maxNewDeposits({ isAPYComputation: true });
94493
95004
  const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
94494
95005
  if (maxNewDeposits * 1.5 < unusedBalance.amount.toNumber()) {
94495
95006
  logger2.verbose(`${this.getTag()}::netAPY: unused balance is > max servicable from loan, lstAPY: ${lstAPY}`);
@@ -94506,8 +95017,8 @@ spurious results.`);
94506
95017
  return output;
94507
95018
  }
94508
95019
  }
94509
- async maxNewDeposits() {
94510
- const maxBorrowableAmounts = await this.getMaxBorrowableAmount();
95020
+ async maxNewDeposits(params = { isAPYComputation: false }) {
95021
+ const maxBorrowableAmounts = await this.getMaxBorrowableAmount(params);
94511
95022
  let ltv = void 0;
94512
95023
  for (let adapter of this.getVesuAdapters()) {
94513
95024
  const maxBorrowableAmount = maxBorrowableAmounts.maxBorrowables.find((b) => b.borrowableAsset.address.eq(adapter.config.debt.address))?.amount;
@@ -94610,7 +95121,7 @@ spurious results.`);
94610
95121
  const manageCall2 = manage2Info.callConstructor({
94611
95122
  delegation: true
94612
95123
  });
94613
- const STEP3_ID = "multiply_vesu" /* MULTIPLY_VESU */;
95124
+ const STEP3_ID = getVesuLegId("multiply_vesu" /* MULTIPLY_VESU */, vesuAdapter1.config.debt.symbol);
94614
95125
  const manage3Info = this.getProofs(STEP3_ID);
94615
95126
  const multiplyParams = params.isIncrease ? {
94616
95127
  isIncrease: true,
@@ -94694,6 +95205,12 @@ spurious results.`);
94694
95205
  function getDescription2(tokenSymbol, underlyingSymbol) {
94695
95206
  return VaultDescription(tokenSymbol, underlyingSymbol);
94696
95207
  }
95208
+ function getAvnuManageIDs(baseID, debtTokenSymbol) {
95209
+ return `${baseID}_${debtTokenSymbol.toLowerCase()}`;
95210
+ }
95211
+ function getVesuLegId(baseID, debtTokenSymbol) {
95212
+ return `${baseID}_${debtTokenSymbol.toLowerCase()}`;
95213
+ }
94697
95214
  function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
94698
95215
  vaultSettings.leafAdapters = [];
94699
95216
  const lstToken = Global.getDefaultTokens().find((token) => token.symbol === lstSymbol);
@@ -94703,7 +95220,7 @@ spurious results.`);
94703
95220
  collateral: lstToken,
94704
95221
  debt: underlyingToken,
94705
95222
  vaultAllocator: vaultSettings.vaultAllocator,
94706
- id: "vesu_leg1" /* VESU_LEG1 */
95223
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, underlyingToken.symbol)
94707
95224
  });
94708
95225
  const commonAdapter = new CommonAdapter({
94709
95226
  manager: vaultSettings.manager,
@@ -94712,25 +95229,39 @@ spurious results.`);
94712
95229
  vaultAddress: vaultSettings.vaultAddress,
94713
95230
  vaultAllocator: vaultSettings.vaultAllocator
94714
95231
  });
94715
- const { isV2, addr: poolAddr } = getVesuSingletonAddress(pool1);
94716
- const VESU_MULTIPLY = isV2 ? vesuAdapterLST.VESU_MULTIPLY : vesuAdapterLST.VESU_MULTIPLY_V1;
94717
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, VESU_MULTIPLY, "multiple_approve" /* MULTIPLE_APPROVE */).bind(commonAdapter));
94718
- vaultSettings.leafAdapters.push(vesuAdapterLST.getMultiplyAdapter("multiply_vesu" /* MULTIPLY_VESU */).bind(vesuAdapterLST));
94719
- vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_on" /* SWITCH_DELEGATION_ON */).bind(vesuAdapterLST));
94720
- vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_off" /* SWITCH_DELEGATION_OFF */).bind(vesuAdapterLST));
94721
95232
  vaultSettings.adapters.push(...[{
94722
- id: "vesu_leg1_adapter" /* VESU_LEG1 */,
95233
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, underlyingToken.symbol),
94723
95234
  adapter: vesuAdapterLST
94724
95235
  }, {
94725
95236
  id: "common_adapter" /* COMMON */,
94726
95237
  adapter: commonAdapter
94727
95238
  }]);
94728
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(underlyingToken.address, AVNU_EXCHANGE, "avnu_multiply_approve_deposit" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */).bind(commonAdapter));
94729
- vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(underlyingToken.address, lstToken.address, "avnu_multiply_swap_deposit" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, false).bind(commonAdapter));
94730
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, AVNU_EXCHANGE, "avnu_multiply_approve_withdraw" /* AVNU_MULTIPLY_APPROVE_WITHDRAW */).bind(commonAdapter));
94731
- vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(lstToken.address, underlyingToken.address, "avnu_multiply_swap_withdraw" /* AVNU_MULTIPLY_SWAP_WITHDRAW */, false).bind(commonAdapter));
94732
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, poolAddr, "approve_token1" /* APPROVE_TOKEN1 */).bind(commonAdapter));
94733
- vaultSettings.leafAdapters.push(vesuAdapterLST.getModifyPosition.bind(vesuAdapterLST));
95239
+ const { isV2, addr: poolAddr } = getVesuSingletonAddress(pool1);
95240
+ const VESU_MULTIPLY = isV2 ? vesuAdapterLST.VESU_MULTIPLY : vesuAdapterLST.VESU_MULTIPLY_V1;
95241
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, VESU_MULTIPLY, "multiple_approve" /* MULTIPLE_APPROVE */).bind(commonAdapter));
95242
+ vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_on" /* SWITCH_DELEGATION_ON */).bind(vesuAdapterLST));
95243
+ vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_off" /* SWITCH_DELEGATION_OFF */).bind(vesuAdapterLST));
95244
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, AVNU_EXCHANGE, "avnu_mul_approve_withdr" /* AVNU_MULTIPLY_APPROVE_WITHDRAW */).bind(commonAdapter));
95245
+ for (let borrowableAsset of vaultSettings.borrowable_assets) {
95246
+ const debtAsset = borrowableAsset;
95247
+ const approve_debt_token_id = getAvnuManageIDs("avnu_mul_approve_dep" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */, debtAsset.symbol);
95248
+ const swap_debt_token_id = getAvnuManageIDs("avnu_mul_swap_dep" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, debtAsset.symbol);
95249
+ const swap_lst_token_id = getAvnuManageIDs("avnu_mul_swap_withdr" /* AVNU_MULTIPLY_SWAP_WITHDRAW */, debtAsset.symbol);
95250
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(debtAsset.address, AVNU_EXCHANGE, approve_debt_token_id).bind(commonAdapter));
95251
+ vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(debtAsset.address, lstToken.address, swap_debt_token_id, false).bind(commonAdapter));
95252
+ vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(lstToken.address, debtAsset.address, swap_lst_token_id, false).bind(commonAdapter));
95253
+ const vesuAdapter = new VesuAdapter({
95254
+ poolId: pool1,
95255
+ collateral: lstToken,
95256
+ debt: debtAsset,
95257
+ vaultAllocator: vaultSettings.vaultAllocator,
95258
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, debtAsset.symbol)
95259
+ });
95260
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, poolAddr, "approve_token1" /* APPROVE_TOKEN1 */).bind(commonAdapter));
95261
+ vaultSettings.leafAdapters.push(vesuAdapter.getModifyPosition.bind(vesuAdapter));
95262
+ const multiplID = getVesuLegId("multiply_vesu" /* MULTIPLY_VESU */, debtAsset.symbol);
95263
+ vaultSettings.leafAdapters.push(vesuAdapter.getMultiplyAdapter(multiplID).bind(vesuAdapter));
95264
+ }
94734
95265
  vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, vaultSettings.vaultAddress, "approve_bring_liquidity" /* APPROVE_BRING_LIQUIDITY */).bind(commonAdapter));
94735
95266
  vaultSettings.leafAdapters.push(commonAdapter.getBringLiquidityAdapter("bring_liquidity" /* BRING_LIQUIDITY */).bind(commonAdapter));
94736
95267
  vaultSettings.leafAdapters.push(vesuAdapterLST.getDefispringRewardsAdapter("defispring_rewards" /* DEFISPRING_REWARDS */).bind(vesuAdapterLST));
@@ -94808,7 +95339,8 @@ spurious results.`);
94808
95339
  adapters: [],
94809
95340
  targetHealthFactor: 1.1,
94810
95341
  minHealthFactor: 1.05,
94811
- borrowable_assets: Global.getDefaultTokens().filter((token) => token.symbol === "STRK")
95342
+ borrowable_assets: Global.getDefaultTokens().filter((token) => token.symbol === "STRK"),
95343
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "STRK")
94812
95344
  };
94813
95345
  var hyperxWBTC = {
94814
95346
  vaultAddress: ContractAddr.from("0x2da9d0f96a46b453f55604313785dc866424240b1c6811d13bef594343db818"),
@@ -94820,7 +95352,8 @@ spurious results.`);
94820
95352
  adapters: [],
94821
95353
  targetHealthFactor: 1.1,
94822
95354
  minHealthFactor: 1.05,
94823
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
95355
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
95356
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "WBTC")
94824
95357
  };
94825
95358
  var hyperxtBTC = {
94826
95359
  vaultAddress: ContractAddr.from("0x47d5f68477e5637ce0e56436c6b5eee5a354e6828995dae106b11a48679328"),
@@ -94832,7 +95365,8 @@ spurious results.`);
94832
95365
  adapters: [],
94833
95366
  targetHealthFactor: 1.1,
94834
95367
  minHealthFactor: 1.05,
94835
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
95368
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
95369
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "tBTC")
94836
95370
  };
94837
95371
  var hyperxsBTC = {
94838
95372
  vaultAddress: ContractAddr.from("0x437ef1e7d0f100b2e070b7a65cafec0b2be31b0290776da8b4112f5473d8d9"),
@@ -94844,7 +95378,8 @@ spurious results.`);
94844
95378
  adapters: [],
94845
95379
  targetHealthFactor: 1.1,
94846
95380
  minHealthFactor: 1.05,
94847
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
95381
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
95382
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "solvBTC")
94848
95383
  };
94849
95384
  var hyperxLBTC = {
94850
95385
  vaultAddress: ContractAddr.from("0x64cf24d4883fe569926419a0569ab34497c6956a1a308fa883257f7486d7030"),
@@ -94856,7 +95391,8 @@ spurious results.`);
94856
95391
  adapters: [],
94857
95392
  targetHealthFactor: 1.1,
94858
95393
  minHealthFactor: 1.05,
94859
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
95394
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
95395
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "LBTC")
94860
95396
  };
94861
95397
  function getInvestmentSteps(lstSymbol, underlyingSymbol) {
94862
95398
  return [