@strkfarm/sdk 1.1.39 → 1.1.40

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 {
@@ -80443,62 +80547,193 @@ spurious results.`);
80443
80547
  logger2.verbose(
80444
80548
  `${_EkuboCLVault.name}: harvest => Processing claim, isToken1: ${isToken1} amount: ${postFeeAmount.toWei()}`
80445
80549
  );
80446
- const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
80447
- const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
80550
+ const isRewardTokenMatch = claim.token.eq(poolKey.token0) || claim.token.eq(poolKey.token1);
80551
+ if (isRewardTokenMatch) {
80552
+ const _callsFinal = await this._handleRewardAndVaultTokenMatchHarvest({
80553
+ acc,
80554
+ claim,
80555
+ isToken1,
80556
+ token0Info,
80557
+ token1Info,
80558
+ postFeeAmount,
80559
+ poolKey,
80560
+ bounds,
80561
+ maxIterations,
80562
+ priceRatioPrecision
80563
+ });
80564
+ calls.push(..._callsFinal);
80565
+ } else {
80566
+ const _callsFinal = await this._handleRewardAndVaultTokenMismatchHarvest({
80567
+ claim,
80568
+ token0Info,
80569
+ token1Info,
80570
+ postFeeAmount,
80571
+ poolKey,
80572
+ bounds,
80573
+ maxIterations,
80574
+ priceRatioPrecision,
80575
+ acc
80576
+ });
80577
+ calls.push(..._callsFinal);
80578
+ }
80579
+ }
80580
+ return calls;
80581
+ }
80582
+ /**
80583
+ * @description This funciton requires atleast one of the pool tokens to be reward token
80584
+ * i.e. STRK.
80585
+ * @param params
80586
+ */
80587
+ async _handleRewardAndVaultTokenMatchHarvest(params) {
80588
+ const { acc, claim, isToken1, token0Info, token1Info, postFeeAmount, poolKey, bounds, maxIterations, priceRatioPrecision } = params;
80589
+ const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
80590
+ const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
80591
+ logger2.verbose(
80592
+ `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
80593
+ );
80594
+ const swapInfo = await this.getSwapInfoGivenAmounts(
80595
+ poolKey,
80596
+ token0Amt,
80597
+ token1Amt,
80598
+ bounds,
80599
+ maxIterations,
80600
+ priceRatioPrecision
80601
+ );
80602
+ swapInfo.token_to_address = token0Info.address.address;
80603
+ logger2.verbose(
80604
+ `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
80605
+ );
80606
+ logger2.verbose(
80607
+ `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
80608
+ );
80609
+ const harvestEstimateCall = async (swapInfo1) => {
80610
+ const swap1Amount = Web3Number.fromWei(
80611
+ uint256_exports.uint256ToBN(swapInfo1.token_from_amount).toString(),
80612
+ 18
80613
+ // cause its always STRK?
80614
+ ).minimum(
80615
+ postFeeAmount.toFixed(18)
80616
+ // cause always strk
80617
+ );
80618
+ swapInfo.token_from_amount = uint256_exports.bnToUint256(swap1Amount.toWei());
80619
+ swapInfo.token_to_min_amount = uint256_exports.bnToUint256(
80620
+ swap1Amount.multipliedBy(0).toWei()
80621
+ // placeholder
80622
+ );
80448
80623
  logger2.verbose(
80449
- `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
80624
+ `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
80450
80625
  );
80451
- const swapInfo = await this.getSwapInfoGivenAmounts(
80452
- poolKey,
80453
- token0Amt,
80454
- token1Amt,
80455
- bounds,
80456
- maxIterations,
80457
- priceRatioPrecision
80626
+ const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
80627
+ logger2.verbose(
80628
+ `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
80458
80629
  );
80459
- swapInfo.token_to_address = token0Info.address.address;
80630
+ const swapInfo2 = {
80631
+ ...swapInfo,
80632
+ token_from_amount: uint256_exports.bnToUint256(remainingAmount.toWei())
80633
+ };
80634
+ swapInfo2.token_to_address = token1Info.address.address;
80460
80635
  logger2.verbose(
80461
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
80636
+ `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
80637
+ swapInfo
80638
+ )}`
80462
80639
  );
80463
80640
  logger2.verbose(
80464
- `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
80641
+ `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
80642
+ swapInfo2
80643
+ )}`
80465
80644
  );
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
- );
80645
+ const calldata = [
80646
+ claim.rewardsContract.address,
80647
+ {
80648
+ id: claim.claim.id,
80649
+ amount: claim.claim.amount.toWei(),
80650
+ claimee: claim.claim.claimee.address
80651
+ },
80652
+ claim.proof.map((p) => num_exports.getDecimalString(p)),
80653
+ swapInfo,
80654
+ swapInfo2
80655
+ ];
80656
+ logger2.verbose(
80657
+ `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
80658
+ calldata
80659
+ )}`
80660
+ );
80661
+ return [this.contract.populate("harvest", calldata)];
80662
+ };
80663
+ const _callsFinal = await this.rebalanceIter(
80664
+ swapInfo,
80665
+ acc,
80666
+ harvestEstimateCall,
80667
+ claim.token.eq(poolKey.token0),
80668
+ 0,
80669
+ 0n,
80670
+ BigInt(postFeeAmount.toWei())
80671
+ // upper limit is the post fee amount
80672
+ );
80673
+ logger2.verbose(
80674
+ `${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
80675
+ _callsFinal
80676
+ )}`
80677
+ );
80678
+ return _callsFinal;
80679
+ }
80680
+ /**
80681
+ * @description This function handles harvesting of reward token that is not the same as any of the vault token
80682
+ * i.e. STRK is not part of vault tokens like BTC/ETH
80683
+ * @param params
80684
+ * @returns
80685
+ */
80686
+ async _handleRewardAndVaultTokenMismatchHarvest(params) {
80687
+ const { acc, claim, token0Info, token1Info, postFeeAmount, poolKey, bounds, maxIterations, priceRatioPrecision } = params;
80688
+ let token0Amt = postFeeAmount;
80689
+ const beneficiary = this.address.address;
80690
+ let harvestCall = null;
80691
+ harvestCall = await this.harvestMismatchEstimateCallFn({
80692
+ postFeeAmount,
80693
+ claim,
80694
+ token0Info,
80695
+ token1Info,
80696
+ acc
80697
+ });
80698
+ if (!harvestCall) {
80699
+ throw new Error("Harvest call not found");
80700
+ }
80701
+ return [harvestCall];
80702
+ }
80703
+ // given an amount (i.e. portion of reward to use to swap to token0), returns info on increasing or decreasing
80704
+ // amount for binary search
80705
+ async harvestMismatchEstimateCallFn(params) {
80706
+ const { postFeeAmount, claim, token0Info, token1Info, acc } = params;
80707
+ let harvestCall = null;
80708
+ const binarySearchCallbackFn = async (mid) => {
80709
+ const rewardPart2 = BigInt(postFeeAmount.toWei()) - mid;
80710
+ const avnuWrapper = new AvnuWrapper();
80711
+ const beneficiary = this.address.address;
80712
+ const quote1 = await avnuWrapper.getQuotes(
80713
+ claim.token.address,
80714
+ token0Info.address.address,
80715
+ mid.toString(),
80716
+ beneficiary
80717
+ );
80718
+ const swapInfo1 = await avnuWrapper.getSwapInfo(
80719
+ quote1,
80720
+ beneficiary,
80721
+ 0,
80722
+ beneficiary
80723
+ );
80724
+ const quote2 = await avnuWrapper.getQuotes(
80725
+ claim.token.address,
80726
+ token1Info.address.address,
80727
+ rewardPart2.toString(),
80728
+ beneficiary
80729
+ );
80730
+ const swapInfo2 = await avnuWrapper.getSwapInfo(
80731
+ quote2,
80732
+ beneficiary,
80733
+ 0,
80734
+ beneficiary
80735
+ );
80736
+ try {
80502
80737
  const calldata = [
80503
80738
  claim.rewardsContract.address,
80504
80739
  {
@@ -80507,34 +80742,24 @@ spurious results.`);
80507
80742
  claimee: claim.claim.claimee.address
80508
80743
  },
80509
80744
  claim.proof.map((p) => num_exports.getDecimalString(p)),
80510
- swapInfo,
80745
+ swapInfo1,
80511
80746
  swapInfo2
80512
80747
  ];
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;
80748
+ harvestCall = this.contract.populate("harvest", calldata);
80749
+ const gas = await acc.estimateInvokeFee(harvestCall);
80750
+ return "found";
80751
+ } catch (err2) {
80752
+ console.error(err2);
80753
+ if (err2.message.includes("invalid token0 amount")) {
80754
+ return "go_low";
80755
+ } else if (err2.message.includes("invalid token1 amount")) {
80756
+ return "go_high";
80757
+ }
80758
+ return "retry";
80759
+ }
80760
+ };
80761
+ await binarySearch(0n, BigInt(postFeeAmount.toWei()), binarySearchCallbackFn);
80762
+ return harvestCall;
80538
80763
  }
80539
80764
  async getInvestmentFlows() {
80540
80765
  const netYield = await this.netAPY();
@@ -83060,7 +83285,58 @@ spurious results.`);
83060
83285
  }
83061
83286
 
83062
83287
  // src/strategies/universal-adapters/baseAdapter.ts
83288
+ var APYType = /* @__PURE__ */ ((APYType2) => {
83289
+ APYType2["BASE"] = "base";
83290
+ APYType2["REWARD"] = "reward";
83291
+ APYType2["LST"] = "lst";
83292
+ return APYType2;
83293
+ })(APYType || {});
83063
83294
  var BaseAdapter = class extends CacheClass {
83295
+ // readonly config: BaseAdapterConfig;
83296
+ // constructor(config: BaseAdapterConfig) {
83297
+ // super();
83298
+ // this.config = config;
83299
+ // }
83300
+ constructor() {
83301
+ super();
83302
+ }
83303
+ // /**
83304
+ // * Loop through all supported positions and return amount, usd value, remarks and apy for each
83305
+ // */
83306
+ // async getPositions(): Promise<PositionInfo[]> {
83307
+ // const results: PositionInfo[] = [];
83308
+ // for (const supported of this.config.supportedPositions) {
83309
+ // const amount = await this.getPosition(supported);
83310
+ // const usdValue = await this.getUSDValue(supported.asset, amount);
83311
+ // const apy = await this.getAPY(supported);
83312
+ // results.push({ amount, usdValue, apy });
83313
+ // }
83314
+ // return results;
83315
+ // }
83316
+ // /**
83317
+ // * Implemented by child adapters to compute APY for a given supported position
83318
+ // */
83319
+ // protected abstract getAPY(supportedPosition: SupportedPosition): Promise<PositionAPY>;
83320
+ // /**
83321
+ // * Implemented by child adapters to fetch amount for a given supported position
83322
+ // */
83323
+ // protected abstract getPosition(supportedPosition: SupportedPosition): Promise<Web3Number>;
83324
+ // /**
83325
+ // * Implemented by child adapters to calculate maximum deposit positions
83326
+ // * @param amount Optional amount in baseToken to deposit
83327
+ // */
83328
+ // protected abstract maxDeposit(amount?: Web3Number): Promise<PositionInfo[]>;
83329
+ // /**
83330
+ // * Implemented by child adapters to calculate maximum withdraw positions
83331
+ // */
83332
+ // protected abstract maxWithdraw(): Promise<PositionInfo[]>;
83333
+ // /**
83334
+ // * Uses pricer to convert an amount of an asset to USD value
83335
+ // */
83336
+ // protected async getUSDValue(asset: TokenInfo, amount: Web3Number): Promise<number> {
83337
+ // const priceInfo = await this.config.pricer.getPrice(asset.symbol);
83338
+ // return amount.toNumber() * priceInfo.price;
83339
+ // }
83064
83340
  constructSimpleLeafData(params, sanitizer = SIMPLE_SANITIZER) {
83065
83341
  const { id, target, method, packedArguments } = params;
83066
83342
  return {
@@ -83078,6 +83354,94 @@ spurious results.`);
83078
83354
  ]
83079
83355
  };
83080
83356
  }
83357
+ // /**
83358
+ // * Implementor must provide target/method/packedArguments/sanitizer for deposit leaf construction
83359
+ // */
83360
+ // protected abstract _getDepositLeaf(): {
83361
+ // target: ContractAddr,
83362
+ // method: string,
83363
+ // packedArguments: bigint[],
83364
+ // sanitizer: ContractAddr,
83365
+ // id: string
83366
+ // }[];
83367
+ // /**
83368
+ // * Implementor must provide target/method/packedArguments/sanitizer for withdraw leaf construction
83369
+ // */
83370
+ // protected abstract _getWithdrawLeaf(): {
83371
+ // target: ContractAddr,
83372
+ // method: string,
83373
+ // packedArguments: bigint[],
83374
+ // sanitizer: ContractAddr,
83375
+ // id: string
83376
+ // }[];
83377
+ // /**
83378
+ // * Returns deposit leaf adapter using configured proof id
83379
+ // */
83380
+ // getDepositLeaf(): AdapterLeafType<T1> {
83381
+ // const leafConfigs = this._getDepositLeaf();
83382
+ // const leaves = leafConfigs.map(config => {
83383
+ // const { target, method, packedArguments, sanitizer, id } = config;
83384
+ // const leaf = this.constructSimpleLeafData({
83385
+ // id: id,
83386
+ // target,
83387
+ // method,
83388
+ // packedArguments
83389
+ // }, sanitizer);
83390
+ // return leaf;
83391
+ // });
83392
+ // return { leaves, callConstructor: this.getDepositCall.bind(this) as unknown as GenerateCallFn<T1> };
83393
+ // }
83394
+ // /**
83395
+ // * Returns withdraw leaf adapter using configured proof id
83396
+ // */
83397
+ // getWithdrawLeaf(): AdapterLeafType<T2> {
83398
+ // const leafConfigs = this._getWithdrawLeaf();
83399
+ // const leaves = leafConfigs.map(config => {
83400
+ // const { target, method, packedArguments, sanitizer, id } = config;
83401
+ // const leaf = this.constructSimpleLeafData({
83402
+ // id: id,
83403
+ // target,
83404
+ // method,
83405
+ // packedArguments
83406
+ // }, sanitizer ?? SIMPLE_SANITIZER);
83407
+ // return leaf;
83408
+ // });
83409
+ // return { leaves, callConstructor: this.getWithdrawCall.bind(this) as unknown as GenerateCallFn<T2> };
83410
+ // }
83411
+ // /**
83412
+ // * Default deposit callConstructor: expects params as calldata (bigint[])
83413
+ // */
83414
+ // protected getDepositCall<T1 = bigint[]>(params: T1): ManageCall[] {
83415
+ // const leafConfigs = this._getDepositLeaf();
83416
+ // return leafConfigs.map(config => {
83417
+ // const { target, method, sanitizer } = config;
83418
+ // return {
83419
+ // sanitizer: sanitizer ?? SIMPLE_SANITIZER,
83420
+ // call: {
83421
+ // contractAddress: target,
83422
+ // selector: hash.getSelectorFromName(method),
83423
+ // calldata: params as unknown as bigint[]
83424
+ // }
83425
+ // };
83426
+ // });
83427
+ // }
83428
+ // /**
83429
+ // * Default withdraw callConstructor: expects params as calldata (bigint[])
83430
+ // */
83431
+ // protected getWithdrawCall<T2 = bigint[]>(params: T2): ManageCall[] {
83432
+ // const leafConfigs = this._getWithdrawLeaf();
83433
+ // return leafConfigs.map(config => {
83434
+ // const { target, method, sanitizer } = config;
83435
+ // return {
83436
+ // sanitizer: sanitizer ?? SIMPLE_SANITIZER,
83437
+ // call: {
83438
+ // contractAddress: target,
83439
+ // selector: hash.getSelectorFromName(method),
83440
+ // calldata: params as unknown as bigint[]
83441
+ // }
83442
+ // };
83443
+ // });
83444
+ // }
83081
83445
  };
83082
83446
 
83083
83447
  // src/strategies/universal-adapters/common-adapter.ts
@@ -90676,7 +91040,20 @@ spurious results.`);
90676
91040
  }
90677
91041
  const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address]);
90678
91042
  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);
91043
+ if (!isV2) {
91044
+ throw new Error("getDebtCap is not supported for v1");
91045
+ }
91046
+ const currentDebt = await this.getCurrentDebtUtilisationAmount(config3);
91047
+ logger2.verbose(`${this.config.debt.symbol}::VesuAdapter::getDebtCap currentDebt: ${currentDebt.toString()}`);
91048
+ return Web3Number.fromWei(output.debt_cap.toString(), this.config.debt.decimals).minus(currentDebt);
91049
+ }
91050
+ async getCurrentDebtUtilisationAmount(config3) {
91051
+ const { contract, isV2 } = await this.getVesuSingletonContract(config3, this.config.poolId);
91052
+ if (!isV2) {
91053
+ throw new Error("getCurrentDebtUtilisationAmount is not supported for v1");
91054
+ }
91055
+ const output = await contract.call("pairs", [this.config.collateral.address.address, this.config.debt.address.address]);
91056
+ return new Web3Number((Number(output.total_nominal_debt) / 1e18).toFixed(9), this.config.debt.decimals);
90680
91057
  }
90681
91058
  async getMaxBorrowableByInterestRate(config3, asset, maxBorrowAPY) {
90682
91059
  const { contract, isV2 } = await this.getVesuSingletonContract(config3, this.config.poolId);
@@ -90709,16 +91086,17 @@ spurious results.`);
90709
91086
  const assetConfig = isV2 ? _assetConfig : _assetConfig["0"];
90710
91087
  const timeDelta = assetConfig.last_updated;
90711
91088
  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));
91089
+ const currentDebt = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals);
91090
+ const totalSupply = currentDebt.plus(Web3Number.fromWei(assetConfig.reserve, asset.decimals));
90713
91091
  const ratePerSecond = BigInt(Math.round(maxBorrowAPY / 365 / 24 / 60 / 60 * Number(SCALE)));
90714
91092
  const maxUtilisation = this.getMaxUtilizationGivenRatePerSecond(interestRateConfig, ratePerSecond, timeDelta, lastFullUtilizationRate);
90715
91093
  logger2.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate maxUtilisation: ${Number(maxUtilisation) / 1e18}, totalSupply: ${totalSupply.toString()}`);
90716
91094
  const maxDebtToHave = totalSupply.multipliedBy(Number(maxUtilisation) / 1e18);
90717
- const currentDebt = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals);
91095
+ logger2.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate currentDebt: ${currentDebt.toString()}, maxDebtToHave: ${maxDebtToHave.toString()}`);
90718
91096
  return maxDebtToHave.minus(currentDebt);
90719
91097
  }
90720
- async getLTVConfig(config3) {
90721
- const CACHE_KEY = "ltv_config";
91098
+ async getLTVConfig(config3, blockNumber = "latest") {
91099
+ const CACHE_KEY = `ltv_config_${blockNumber}`;
90722
91100
  const cacheData = this.getCache(CACHE_KEY);
90723
91101
  if (cacheData) {
90724
91102
  return cacheData;
@@ -90726,10 +91104,10 @@ spurious results.`);
90726
91104
  const { contract, isV2 } = await this.getVesuSingletonContract(config3, this.config.poolId);
90727
91105
  let ltv = 0;
90728
91106
  if (isV2) {
90729
- const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address]);
91107
+ const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address], { blockIdentifier: blockNumber });
90730
91108
  ltv = Number(output.max_ltv) / 1e18;
90731
91109
  } else {
90732
- const output = await contract.call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address]);
91110
+ const output = await contract.call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address], { blockIdentifier: blockNumber });
90733
91111
  ltv = Number(output.max_ltv) / 1e18;
90734
91112
  }
90735
91113
  if (ltv == 0) {
@@ -90738,11 +91116,11 @@ spurious results.`);
90738
91116
  this.setCache(CACHE_KEY, ltv, 3e5);
90739
91117
  return this.getCache(CACHE_KEY);
90740
91118
  }
90741
- async getPositions(config3) {
91119
+ async getPositions(config3, blockNumber = "latest") {
90742
91120
  if (!this.pricer) {
90743
91121
  throw new Error("Pricer is not initialized");
90744
91122
  }
90745
- const CACHE_KEY = "positions";
91123
+ const CACHE_KEY = `positions_${blockNumber}`;
90746
91124
  const cacheData = this.getCache(CACHE_KEY);
90747
91125
  if (cacheData) {
90748
91126
  return cacheData;
@@ -90754,7 +91132,8 @@ spurious results.`);
90754
91132
  this.config.collateral.address.address,
90755
91133
  this.config.debt.address.address,
90756
91134
  this.config.vaultAllocator.address
90757
- ]);
91135
+ ], { blockIdentifier: blockNumber });
91136
+ console.log(output);
90758
91137
  const token1Price = await this.pricer.getPrice(this.config.collateral.symbol);
90759
91138
  const token2Price = await this.pricer.getPrice(this.config.debt.symbol);
90760
91139
  logger2.verbose(`VesuAdapter::getPositions token1Price: ${token1Price.price}, token2Price: ${token2Price.price}`);
@@ -90774,11 +91153,11 @@ spurious results.`);
90774
91153
  this.setCache(CACHE_KEY, value, 6e4);
90775
91154
  return value;
90776
91155
  }
90777
- async getCollateralization(config3) {
91156
+ async getCollateralization(config3, blockNumber = "latest") {
90778
91157
  if (!this.pricer) {
90779
91158
  throw new Error("Pricer is not initialized");
90780
91159
  }
90781
- const CACHE_KEY = "collateralization";
91160
+ const CACHE_KEY = `collateralization_${blockNumber}`;
90782
91161
  const cacheData = this.getCache(CACHE_KEY);
90783
91162
  if (cacheData) {
90784
91163
  return cacheData;
@@ -90790,7 +91169,7 @@ spurious results.`);
90790
91169
  this.config.collateral.address.address,
90791
91170
  this.config.debt.address.address,
90792
91171
  this.config.vaultAllocator.address
90793
- ]);
91172
+ ], { blockIdentifier: blockNumber });
90794
91173
  const collateralAmount = Web3Number.fromWei(output["1"].toString(), 18);
90795
91174
  const debtAmount = Web3Number.fromWei(output["2"].toString(), 18);
90796
91175
  const value = [{
@@ -90827,9 +91206,9 @@ spurious results.`);
90827
91206
  ltv
90828
91207
  };
90829
91208
  }
90830
- async getHealthFactor() {
90831
- const ltv = await this.getLTVConfig(this.networkConfig);
90832
- const collateralisation = await this.getCollateralization(this.networkConfig);
91209
+ async getHealthFactor(blockNumber = "latest") {
91210
+ const ltv = await this.getLTVConfig(this.networkConfig, blockNumber);
91211
+ const collateralisation = await this.getCollateralization(this.networkConfig, blockNumber);
90833
91212
  return collateralisation[0].usdValue * ltv / collateralisation[1].usdValue;
90834
91213
  }
90835
91214
  static async getVesuPools(retry = 0) {
@@ -93488,11 +93867,11 @@ spurious results.`);
93488
93867
  vesuAdapter2.networkConfig = this.config;
93489
93868
  return [vesuAdapter1, vesuAdapter2];
93490
93869
  }
93491
- async getVesuPositions() {
93870
+ async getVesuPositions(blockNumber = "latest") {
93492
93871
  const adapters = this.getVesuAdapters();
93493
93872
  const positions = [];
93494
93873
  for (const adapter of adapters) {
93495
- positions.push(...await adapter.getPositions(this.config));
93874
+ positions.push(...await adapter.getPositions(this.config, blockNumber));
93496
93875
  }
93497
93876
  return positions;
93498
93877
  }
@@ -93561,8 +93940,8 @@ spurious results.`);
93561
93940
  async getLSTAPR(address) {
93562
93941
  return 0;
93563
93942
  }
93564
- async getVesuHealthFactors() {
93565
- return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor()));
93943
+ async getVesuHealthFactors(blockNumber = "latest") {
93944
+ return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor(blockNumber)));
93566
93945
  }
93567
93946
  async computeRebalanceConditionAndReturnCalls() {
93568
93947
  const vesuAdapters = this.getVesuAdapters();
@@ -94156,6 +94535,40 @@ spurious results.`);
94156
94535
  }
94157
94536
  ];
94158
94537
 
94538
+ // src/utils/health-factor-math.ts
94539
+ var HealthFactorMath = class {
94540
+ static getCollateralRequired(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo) {
94541
+ const numerator = debtAmount.multipliedBy(debtPrice).multipliedBy(targetHF);
94542
+ const denominator = collateralPrice * maxLTV;
94543
+ const collateralAmount = numerator.dividedBy(denominator);
94544
+ const netCollateral = new Web3Number(collateralAmount.toString(), collateralTokenInfo.decimals);
94545
+ return netCollateral;
94546
+ }
94547
+ static getMinCollateralRequiredOnLooping(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo) {
94548
+ const netCollateral = this.getCollateralRequired(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo);
94549
+ const collateralFromDebt = new Web3Number(debtAmount.multipliedBy(debtPrice).dividedBy(collateralPrice).toString(), collateralTokenInfo.decimals);
94550
+ return netCollateral.minus(collateralFromDebt);
94551
+ }
94552
+ static getHealthFactor(collateralAmount, collateralPrice, maxLTV, debtAmount, debtPrice) {
94553
+ const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
94554
+ const denominator = debtAmount.multipliedBy(debtPrice);
94555
+ const healthFactor = numerator.dividedBy(denominator);
94556
+ return healthFactor.toNumber();
94557
+ }
94558
+ static getMaxDebtAmountOnLooping(collateralAmount, collateralPrice, maxLTV, targetHF, debtPrice, debtTokenInfo) {
94559
+ const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
94560
+ const denominator = targetHF - maxLTV;
94561
+ const debtAmount = numerator.dividedBy(denominator);
94562
+ return new Web3Number(debtAmount.toString(), debtTokenInfo.decimals);
94563
+ }
94564
+ static getMaxDebtAmount(collateralAmount, collateralPrice, maxLTV, targetHF, debtPrice, debtTokenInfo) {
94565
+ const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
94566
+ const denominator = targetHF * debtPrice;
94567
+ const debtAmount = numerator.dividedBy(denominator);
94568
+ return new Web3Number(debtAmount.toString(), debtTokenInfo.decimals);
94569
+ }
94570
+ };
94571
+
94159
94572
  // src/strategies/universal-lst-muliplier-strategy.tsx
94160
94573
  var import_jsx_runtime5 = __toESM(require_jsx_runtime());
94161
94574
  var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy extends UniversalStrategy {
@@ -94171,15 +94584,14 @@ spurious results.`);
94171
94584
  }
94172
94585
  }
94173
94586
  asset() {
94174
- const vesuAdapter1 = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
94175
- return vesuAdapter1.config.collateral;
94587
+ return this.getVesuSameTokenAdapter().config.collateral;
94176
94588
  }
94177
94589
  getTag() {
94178
94590
  return `${_UniversalLstMultiplierStrategy.name}:${this.metadata.name}`;
94179
94591
  }
94180
94592
  // Vesu adapter with LST and base token match
94181
94593
  getVesuSameTokenAdapter() {
94182
- const baseAdapter = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
94594
+ const baseAdapter = this.getAdapter(getVesuLegId("vesu_leg1" /* VESU_LEG1 */, this.metadata.additionalInfo.underlyingToken.symbol));
94183
94595
  baseAdapter.networkConfig = this.config;
94184
94596
  baseAdapter.pricer = this.pricer;
94185
94597
  return baseAdapter;
@@ -94227,20 +94639,52 @@ spurious results.`);
94227
94639
  return price;
94228
94640
  }
94229
94641
  async getAvnuSwapMultiplyCall(params) {
94230
- return this._getAvnuDepositSwapLegCall({
94231
- ...params,
94232
- minHF: 1.1
94233
- // undo
94234
- });
94642
+ assert3(params.isDeposit, "Only deposit is supported in getAvnuSwapMultiplyCall");
94643
+ const maxBorrowableAmounts = await this.getMaxBorrowableAmount({ isAPYComputation: false });
94644
+ const allVesuAdapters = this.getVesuAdapters();
94645
+ let remainingAmount = params.leg1DepositAmount;
94646
+ const lstExRate = await this.getLSTExchangeRate();
94647
+ const baseAssetPrice = await this.pricer.getPrice(this.getLSTUnderlyingTokenInfo().symbol);
94648
+ const lstPrice = baseAssetPrice.price * lstExRate;
94649
+ for (let i = 0; i < maxBorrowableAmounts.maxBorrowables.length; i++) {
94650
+ const maxBorrowable = maxBorrowableAmounts.maxBorrowables[i];
94651
+ const vesuAdapter = allVesuAdapters.find((adapter) => adapter.config.debt.address.eq(maxBorrowable.borrowableAsset.address));
94652
+ if (!vesuAdapter) {
94653
+ throw new Error(`${this.getTag()}::getAvnuSwapMultiplyCall: vesuAdapter not found for borrowable asset: ${maxBorrowable.borrowableAsset.symbol}`);
94654
+ }
94655
+ const maxLTV = await vesuAdapter.getLTVConfig(this.config);
94656
+ const debtPrice = await this.pricer.getPrice(maxBorrowable.borrowableAsset.symbol);
94657
+ const maxAmountToDeposit = HealthFactorMath.getMinCollateralRequiredOnLooping(
94658
+ maxBorrowable.amount,
94659
+ debtPrice.price,
94660
+ this.metadata.additionalInfo.targetHealthFactor,
94661
+ maxLTV,
94662
+ lstPrice,
94663
+ this.asset()
94664
+ );
94665
+ const amountToDeposit = remainingAmount.minimum(maxAmountToDeposit);
94666
+ logger2.verbose(`${this.getTag()}::getAvnuSwapMultiplyCall::${vesuAdapter.config.debt.symbol}:: remainingAmount: ${remainingAmount}, amountToDeposit: ${amountToDeposit}, depositAmount: ${amountToDeposit}, maxBorrowable: ${maxBorrowable.amount}`);
94667
+ const call = await this._getAvnuDepositSwapLegCall({
94668
+ isDeposit: params.isDeposit,
94669
+ // adjust decimals of debt asset
94670
+ leg1DepositAmount: amountToDeposit,
94671
+ minHF: 1.1,
94672
+ // undo
94673
+ vesuAdapter
94674
+ });
94675
+ remainingAmount = remainingAmount.minus(amountToDeposit);
94676
+ return { call, vesuAdapter };
94677
+ }
94678
+ throw new Error(`${this.getTag()}::getAvnuSwapMultiplyCall: no calls found`);
94235
94679
  }
94236
94680
  async _getAvnuDepositSwapLegCall(params) {
94681
+ const { vesuAdapter } = params;
94237
94682
  logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall params: ${JSON.stringify(params)}`);
94238
94683
  assert3(params.isDeposit, "Only deposit is supported in _getAvnuDepositSwapLegCall");
94239
- const [vesuAdapter1] = this.getVesuAdapters();
94240
- const legLTV = await vesuAdapter1.getLTVConfig(this.config);
94684
+ const legLTV = await vesuAdapter.getLTVConfig(this.config);
94241
94685
  logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall legLTV: ${legLTV}`);
94242
- const existingPositions = await vesuAdapter1.getPositions(this.config);
94243
- const collateralisation = await vesuAdapter1.getCollateralization(this.config);
94686
+ const existingPositions = await vesuAdapter.getPositions(this.config);
94687
+ const collateralisation = await vesuAdapter.getCollateralization(this.config);
94244
94688
  const existingCollateralInfo = existingPositions[0];
94245
94689
  const existingDebtInfo = existingPositions[1];
94246
94690
  logger2.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
@@ -94248,11 +94692,40 @@ spurious results.`);
94248
94692
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
94249
94693
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
94250
94694
  logger2.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
94695
+ const debtTokenInfo = vesuAdapter.config.debt;
94696
+ let newDepositAmount = params.leg1DepositAmount;
94251
94697
  const totalCollateral = existingCollateralInfo.amount.plus(params.leg1DepositAmount);
94252
94698
  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);
94699
+ const totalDebtAmount = new Web3Number(
94700
+ totalCollateral.multipliedBy(collateralPrice).multipliedBy(legLTV).dividedBy(debtPrice).dividedBy(params.minHF).toString(),
94701
+ debtTokenInfo.decimals
94702
+ );
94703
+ let debtAmount = totalDebtAmount.minus(existingDebtInfo.amount);
94704
+ logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalDebtAmount: ${totalDebtAmount}, initial computed debt: ${debtAmount}`);
94705
+ const maxBorrowable = await this.getMaxBorrowableAmountByVesuAdapter(vesuAdapter, false);
94706
+ if (debtAmount.gt(0) && maxBorrowable.amount.eq(0)) {
94707
+ logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall maxBorrowable is 0, skipping`);
94708
+ return void 0;
94709
+ } else if (debtAmount.gt(0) && maxBorrowable.amount.gt(0)) {
94710
+ debtAmount = maxBorrowable.amount.minimum(debtAmount);
94711
+ const newDebtUSDValue = debtAmount.multipliedBy(debtPrice);
94712
+ const totalCollateralRequired = HealthFactorMath.getCollateralRequired(
94713
+ debtAmount.plus(existingDebtInfo.amount),
94714
+ debtPrice,
94715
+ params.minHF,
94716
+ legLTV,
94717
+ collateralPrice,
94718
+ this.asset()
94719
+ );
94720
+ newDepositAmount = totalCollateralRequired.minus(existingCollateralInfo.amount);
94721
+ if (newDepositAmount.lt(0)) {
94722
+ throw new Error(`${this.getTag()}::_getAvnuDepositSwapLegCall newDepositAmount is less than 0, newDepositAmount: ${newDepositAmount}, totalCollateralRequired: ${totalCollateralRequired}, existingCollateralInfo.amount: ${existingCollateralInfo.amount}`);
94723
+ }
94724
+ if (newDebtUSDValue.toNumber() < 100) {
94725
+ logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall newDebtUSDValue is less than 100, skipping`);
94726
+ return void 0;
94727
+ }
94728
+ }
94256
94729
  logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall debtAmount: ${debtAmount}`);
94257
94730
  if (debtAmount.lt(0)) {
94258
94731
  const lstDEXPrice = await this.getLSTDexPrice();
@@ -94264,32 +94737,34 @@ spurious results.`);
94264
94737
  assert3(calls.length == 1, `Expected 1 call for unwind, got ${calls.length}`);
94265
94738
  return calls[0];
94266
94739
  }
94740
+ console.log(`debtAmount`, debtAmount.toWei(), params.leg1DepositAmount.toWei());
94267
94741
  const STEP0 = "approve_token1" /* APPROVE_TOKEN1 */;
94268
94742
  const manage0Info = this.getProofs(STEP0);
94269
94743
  const manageCall0 = manage0Info.callConstructor({
94270
- amount: params.leg1DepositAmount
94744
+ amount: newDepositAmount
94271
94745
  });
94272
- const STEP1 = "vesu_leg1" /* VESU_LEG1 */;
94746
+ const STEP1 = getVesuLegId("vesu_leg1" /* VESU_LEG1 */, vesuAdapter.config.debt.symbol);
94273
94747
  const manage1Info = this.getProofs(STEP1);
94274
94748
  const manageCall1 = manage1Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
94275
- collateralAmount: params.leg1DepositAmount,
94749
+ collateralAmount: newDepositAmount,
94276
94750
  isAddCollateral: params.isDeposit,
94277
94751
  debtAmount,
94278
94752
  isBorrow: params.isDeposit
94279
94753
  }));
94754
+ console.log(`manageCall1`, manageCall1.call, debtAmount.toWei(), newDepositAmount.toWei());
94280
94755
  const proofIds = [STEP0, STEP1];
94281
94756
  const manageCalls = [manageCall0, manageCall1];
94282
94757
  if (debtAmount.gt(0)) {
94283
- const STEP2 = "avnu_multiply_approve_deposit" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */;
94758
+ const STEP2 = getAvnuManageIDs("avnu_mul_approve_dep" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */, vesuAdapter.config.debt.symbol);
94284
94759
  const manage2Info = this.getProofs(STEP2);
94285
94760
  const manageCall2 = manage2Info.callConstructor({
94286
94761
  amount: debtAmount
94287
94762
  });
94288
- const debtTokenInfo = vesuAdapter1.config.debt;
94763
+ const debtTokenInfo2 = vesuAdapter.config.debt;
94289
94764
  const lstTokenInfo = this.asset();
94290
94765
  const avnuModule = new AvnuWrapper();
94291
94766
  const quote = await avnuModule.getQuotes(
94292
- debtTokenInfo.address.address,
94767
+ debtTokenInfo2.address.address,
94293
94768
  lstTokenInfo.address.address,
94294
94769
  debtAmount.toWei(),
94295
94770
  this.metadata.additionalInfo.vaultAllocator.address
@@ -94305,7 +94780,7 @@ spurious results.`);
94305
94780
  minAmountWei
94306
94781
  );
94307
94782
  logger2.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall swapInfo: ${JSON.stringify(swapInfo)}`);
94308
- const STEP3 = "avnu_multiply_swap_deposit" /* AVNU_MULTIPLY_SWAP_DEPOSIT */;
94783
+ const STEP3 = getAvnuManageIDs("avnu_mul_swap_dep" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, vesuAdapter.config.debt.symbol);
94309
94784
  const manage3Info = this.getProofs(STEP3);
94310
94785
  const manageCall3 = manage3Info.callConstructor({
94311
94786
  props: swapInfo
@@ -94323,7 +94798,7 @@ spurious results.`);
94323
94798
  const manageCall4 = manage4Info.callConstructor({
94324
94799
  amount: minAmount
94325
94800
  });
94326
- const STEP5 = "vesu_leg1" /* VESU_LEG1 */;
94801
+ const STEP5 = getVesuLegId("vesu_leg1" /* VESU_LEG1 */, vesuAdapter.config.debt.symbol);
94327
94802
  const manage5Info = this.getProofs(STEP5);
94328
94803
  const manageCall5 = manage5Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
94329
94804
  collateralAmount: minAmount,
@@ -94340,28 +94815,41 @@ spurious results.`);
94340
94815
  }
94341
94816
  // todo unwind or not deposit when the yield is bad.
94342
94817
  async getLSTMultiplierRebalanceCall() {
94343
- const positions = await this.getVaultPositions();
94344
- assert3(positions.length == 3, "Rebalance call is only supported for 3 positions");
94818
+ let shouldRebalance = false;
94819
+ const calls = [];
94820
+ const allVesuAdapters = this.getVesuAdapters().filter((vesuAdapter) => vesuAdapter.config.debt.symbol === "LBTC");
94821
+ for (const vesuAdapter of allVesuAdapters) {
94822
+ const call = await this._getLSTMultiplierRebalanceCall(vesuAdapter);
94823
+ if (call.shouldRebalance && call.manageCall) {
94824
+ shouldRebalance = true;
94825
+ calls.push({ vesuAdapter, manageCall: call.manageCall });
94826
+ }
94827
+ }
94828
+ return { shouldRebalance, manageCalls: calls };
94829
+ }
94830
+ async _getLSTMultiplierRebalanceCall(vesuAdapter) {
94831
+ const positions = await vesuAdapter.getPositions(this.config);
94832
+ assert3(positions.length == 2, "Rebalance call is only supported for 2 positions");
94345
94833
  const existingCollateralInfo = positions[0];
94346
94834
  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)},
94835
+ const unusedBalance = await this.getUnusedBalance();
94836
+ const healthFactor = await vesuAdapter.getHealthFactor();
94837
+ const collateralisation = await vesuAdapter.getCollateralization(this.config);
94838
+ logger2.debug(`${this.getTag()}::getVesuMultiplyCall::${vesuAdapter.config.debt.symbol} existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
94353
94839
  existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
94354
94840
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
94355
94841
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
94356
94842
  logger2.debug(`${this.getTag()}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
94843
+ logger2.debug(`${this.getTag()}::getVesuMultiplyCall healthFactor: ${healthFactor}`);
94357
94844
  const isHFTooLow = healthFactor < this.metadata.additionalInfo.minHealthFactor;
94358
94845
  const isHFTooHigh = healthFactor > this.metadata.additionalInfo.targetHealthFactor + 0.05;
94359
- if (isHFTooLow || isHFTooHigh) {
94846
+ if (isHFTooLow || isHFTooHigh || 1) {
94360
94847
  const manageCall = await this._getAvnuDepositSwapLegCall({
94361
94848
  isDeposit: true,
94362
94849
  leg1DepositAmount: unusedBalance.amount,
94363
- minHF: 1.02
94850
+ minHF: 1.02,
94364
94851
  // todo, shouldnt use this 1.02 HF, if there isn;t more looping left.
94852
+ vesuAdapter
94365
94853
  });
94366
94854
  return { shouldRebalance: true, manageCall };
94367
94855
  } else {
@@ -94394,7 +94882,7 @@ spurious results.`);
94394
94882
  async _getMinOutputAmountLSTBuy(amountInUnderlying) {
94395
94883
  const lstTruePrice = await this.getLSTExchangeRate();
94396
94884
  const minOutputAmount = amountInUnderlying.dividedBy(lstTruePrice).multipliedBy(0.99979);
94397
- return minOutputAmount;
94885
+ return new Web3Number(minOutputAmount.toString(), this.asset().decimals);
94398
94886
  }
94399
94887
  async _getMinOutputAmountLSTSell(amountInLST) {
94400
94888
  const lstTruePrice = await this.getLSTExchangeRate();
@@ -94451,21 +94939,52 @@ spurious results.`);
94451
94939
  const vesuAdapter1 = this.getVesuSameTokenAdapter();
94452
94940
  return vesuAdapter1.config.debt;
94453
94941
  }
94454
- async getMaxBorrowableAmount() {
94942
+ async getMaxBorrowableAmount(params = { isAPYComputation: false }) {
94455
94943
  const vesuAdapters = this.getVesuAdapters();
94456
94944
  let netMaxBorrowableAmount = Web3Number.fromWei("0", this.getLSTUnderlyingTokenInfo().decimals);
94457
94945
  const maxBorrowables = [];
94458
- const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
94459
- const maxInterestRate = lstAPY * 0.8;
94460
94946
  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 });
94947
+ maxBorrowables.push(await this.getMaxBorrowableAmountByVesuAdapter(vesuAdapter, params.isAPYComputation));
94464
94948
  }
94465
94949
  maxBorrowables.sort((a, b) => b.amount.toNumber() - a.amount.toNumber());
94466
94950
  netMaxBorrowableAmount = maxBorrowables.reduce((acc, curr) => acc.plus(curr.amount), Web3Number.fromWei("0", this.getLSTUnderlyingTokenInfo().decimals));
94467
94951
  return { netMaxBorrowableAmount, maxBorrowables };
94468
94952
  }
94953
+ // recursively, using binary search computes max swappable.
94954
+ // @dev assumes 1 token of from == 1 token of to
94955
+ async getMaxSwappableWithMaxSlippage(fromToken, toToken, maxSlippage, maxAmount) {
94956
+ const output = await findMaxInputWithSlippage({
94957
+ apiGetOutput: async (inputAmount) => {
94958
+ const ekuboQuoter = new EkuboQuoter(this.config);
94959
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
94960
+ const quote = await ekuboQuoter.getQuote(fromToken.address.address, toToken.address.address, new Web3Number(inputAmount.toFixed(9), fromToken.decimals));
94961
+ return Web3Number.fromWei(quote.total_calculated.toString(), toToken.decimals).toNumber();
94962
+ },
94963
+ maxInput: maxAmount.toNumber(),
94964
+ maxSlippagePercent: maxSlippage,
94965
+ tolerance: 1e-3,
94966
+ referenceRate: 1
94967
+ });
94968
+ return new Web3Number(output.optimalInput, fromToken.decimals);
94969
+ }
94970
+ async getMaxBorrowableAmountByVesuAdapter(vesuAdapter, isAPYComputation) {
94971
+ const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
94972
+ const maxInterestRate = lstAPY * 0.8;
94973
+ const maxBorrowableAmount = await vesuAdapter.getMaxBorrowableByInterestRate(this.config, vesuAdapter.config.debt, maxInterestRate);
94974
+ const debtCap = await vesuAdapter.getDebtCap(this.config);
94975
+ const maxBorrowable = maxBorrowableAmount.minimum(debtCap).multipliedBy(0.999);
94976
+ if (vesuAdapter.config.debt.address.eq(this.getLSTUnderlyingTokenInfo().address) || isAPYComputation) {
94977
+ return { amount: maxBorrowable, dexSwappableAmount: maxBorrowable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
94978
+ }
94979
+ try {
94980
+ const maxSwappable = await this.getMaxSwappableWithMaxSlippage(vesuAdapter.config.debt, this.getLSTUnderlyingTokenInfo(), 2e-4, maxBorrowable);
94981
+ return { amount: maxBorrowable.minimum(maxSwappable), dexSwappableAmount: maxSwappable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
94982
+ } catch (error2) {
94983
+ logger2.warn(`${this.getTag()}: Failed to get max swappable: ${error2}`);
94984
+ const maxSwappable = Web3Number.fromWei("0", vesuAdapter.config.debt.decimals);
94985
+ return { amount: maxBorrowable.minimum(maxSwappable), dexSwappableAmount: maxSwappable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
94986
+ }
94987
+ }
94469
94988
  // todo how much to unwind to get back healthy APY zone again
94470
94989
  // if net APY < LST APR + 0.5%, we need to unwind to get back to LST APR + 1% atleast or 0 vesu position
94471
94990
  // For xSTRK, simply deposit in Vesu if looping is not viable
@@ -94489,7 +95008,7 @@ spurious results.`);
94489
95008
  // todo undo this
94490
95009
  async netAPY() {
94491
95010
  const unusedBalance = await this.getUnusedBalance();
94492
- const maxNewDeposits = await this.maxNewDeposits();
95011
+ const maxNewDeposits = await this.maxNewDeposits({ isAPYComputation: true });
94493
95012
  const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
94494
95013
  if (maxNewDeposits * 1.5 < unusedBalance.amount.toNumber()) {
94495
95014
  logger2.verbose(`${this.getTag()}::netAPY: unused balance is > max servicable from loan, lstAPY: ${lstAPY}`);
@@ -94506,8 +95025,8 @@ spurious results.`);
94506
95025
  return output;
94507
95026
  }
94508
95027
  }
94509
- async maxNewDeposits() {
94510
- const maxBorrowableAmounts = await this.getMaxBorrowableAmount();
95028
+ async maxNewDeposits(params = { isAPYComputation: false }) {
95029
+ const maxBorrowableAmounts = await this.getMaxBorrowableAmount(params);
94511
95030
  let ltv = void 0;
94512
95031
  for (let adapter of this.getVesuAdapters()) {
94513
95032
  const maxBorrowableAmount = maxBorrowableAmounts.maxBorrowables.find((b) => b.borrowableAsset.address.eq(adapter.config.debt.address))?.amount;
@@ -94610,7 +95129,7 @@ spurious results.`);
94610
95129
  const manageCall2 = manage2Info.callConstructor({
94611
95130
  delegation: true
94612
95131
  });
94613
- const STEP3_ID = "multiply_vesu" /* MULTIPLY_VESU */;
95132
+ const STEP3_ID = getVesuLegId("multiply_vesu" /* MULTIPLY_VESU */, vesuAdapter1.config.debt.symbol);
94614
95133
  const manage3Info = this.getProofs(STEP3_ID);
94615
95134
  const multiplyParams = params.isIncrease ? {
94616
95135
  isIncrease: true,
@@ -94694,6 +95213,12 @@ spurious results.`);
94694
95213
  function getDescription2(tokenSymbol, underlyingSymbol) {
94695
95214
  return VaultDescription(tokenSymbol, underlyingSymbol);
94696
95215
  }
95216
+ function getAvnuManageIDs(baseID, debtTokenSymbol) {
95217
+ return `${baseID}_${debtTokenSymbol.toLowerCase()}`;
95218
+ }
95219
+ function getVesuLegId(baseID, debtTokenSymbol) {
95220
+ return `${baseID}_${debtTokenSymbol.toLowerCase()}`;
95221
+ }
94697
95222
  function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
94698
95223
  vaultSettings.leafAdapters = [];
94699
95224
  const lstToken = Global.getDefaultTokens().find((token) => token.symbol === lstSymbol);
@@ -94703,7 +95228,7 @@ spurious results.`);
94703
95228
  collateral: lstToken,
94704
95229
  debt: underlyingToken,
94705
95230
  vaultAllocator: vaultSettings.vaultAllocator,
94706
- id: "vesu_leg1" /* VESU_LEG1 */
95231
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, underlyingToken.symbol)
94707
95232
  });
94708
95233
  const commonAdapter = new CommonAdapter({
94709
95234
  manager: vaultSettings.manager,
@@ -94712,25 +95237,39 @@ spurious results.`);
94712
95237
  vaultAddress: vaultSettings.vaultAddress,
94713
95238
  vaultAllocator: vaultSettings.vaultAllocator
94714
95239
  });
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
95240
  vaultSettings.adapters.push(...[{
94722
- id: "vesu_leg1_adapter" /* VESU_LEG1 */,
95241
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, underlyingToken.symbol),
94723
95242
  adapter: vesuAdapterLST
94724
95243
  }, {
94725
95244
  id: "common_adapter" /* COMMON */,
94726
95245
  adapter: commonAdapter
94727
95246
  }]);
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));
95247
+ const { isV2, addr: poolAddr } = getVesuSingletonAddress(pool1);
95248
+ const VESU_MULTIPLY = isV2 ? vesuAdapterLST.VESU_MULTIPLY : vesuAdapterLST.VESU_MULTIPLY_V1;
95249
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, VESU_MULTIPLY, "multiple_approve" /* MULTIPLE_APPROVE */).bind(commonAdapter));
95250
+ vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_on" /* SWITCH_DELEGATION_ON */).bind(vesuAdapterLST));
95251
+ vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_off" /* SWITCH_DELEGATION_OFF */).bind(vesuAdapterLST));
95252
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, AVNU_EXCHANGE, "avnu_mul_approve_withdr" /* AVNU_MULTIPLY_APPROVE_WITHDRAW */).bind(commonAdapter));
95253
+ for (let borrowableAsset of vaultSettings.borrowable_assets) {
95254
+ const debtAsset = borrowableAsset;
95255
+ const approve_debt_token_id = getAvnuManageIDs("avnu_mul_approve_dep" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */, debtAsset.symbol);
95256
+ const swap_debt_token_id = getAvnuManageIDs("avnu_mul_swap_dep" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, debtAsset.symbol);
95257
+ const swap_lst_token_id = getAvnuManageIDs("avnu_mul_swap_withdr" /* AVNU_MULTIPLY_SWAP_WITHDRAW */, debtAsset.symbol);
95258
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(debtAsset.address, AVNU_EXCHANGE, approve_debt_token_id).bind(commonAdapter));
95259
+ vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(debtAsset.address, lstToken.address, swap_debt_token_id, false).bind(commonAdapter));
95260
+ vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(lstToken.address, debtAsset.address, swap_lst_token_id, false).bind(commonAdapter));
95261
+ const vesuAdapter = new VesuAdapter({
95262
+ poolId: pool1,
95263
+ collateral: lstToken,
95264
+ debt: debtAsset,
95265
+ vaultAllocator: vaultSettings.vaultAllocator,
95266
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, debtAsset.symbol)
95267
+ });
95268
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, poolAddr, "approve_token1" /* APPROVE_TOKEN1 */).bind(commonAdapter));
95269
+ vaultSettings.leafAdapters.push(vesuAdapter.getModifyPosition.bind(vesuAdapter));
95270
+ const multiplID = getVesuLegId("multiply_vesu" /* MULTIPLY_VESU */, debtAsset.symbol);
95271
+ vaultSettings.leafAdapters.push(vesuAdapter.getMultiplyAdapter(multiplID).bind(vesuAdapter));
95272
+ }
94734
95273
  vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, vaultSettings.vaultAddress, "approve_bring_liquidity" /* APPROVE_BRING_LIQUIDITY */).bind(commonAdapter));
94735
95274
  vaultSettings.leafAdapters.push(commonAdapter.getBringLiquidityAdapter("bring_liquidity" /* BRING_LIQUIDITY */).bind(commonAdapter));
94736
95275
  vaultSettings.leafAdapters.push(vesuAdapterLST.getDefispringRewardsAdapter("defispring_rewards" /* DEFISPRING_REWARDS */).bind(vesuAdapterLST));
@@ -94808,7 +95347,8 @@ spurious results.`);
94808
95347
  adapters: [],
94809
95348
  targetHealthFactor: 1.1,
94810
95349
  minHealthFactor: 1.05,
94811
- borrowable_assets: Global.getDefaultTokens().filter((token) => token.symbol === "STRK")
95350
+ borrowable_assets: Global.getDefaultTokens().filter((token) => token.symbol === "STRK"),
95351
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "STRK")
94812
95352
  };
94813
95353
  var hyperxWBTC = {
94814
95354
  vaultAddress: ContractAddr.from("0x2da9d0f96a46b453f55604313785dc866424240b1c6811d13bef594343db818"),
@@ -94820,7 +95360,8 @@ spurious results.`);
94820
95360
  adapters: [],
94821
95361
  targetHealthFactor: 1.1,
94822
95362
  minHealthFactor: 1.05,
94823
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
95363
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
95364
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "WBTC")
94824
95365
  };
94825
95366
  var hyperxtBTC = {
94826
95367
  vaultAddress: ContractAddr.from("0x47d5f68477e5637ce0e56436c6b5eee5a354e6828995dae106b11a48679328"),
@@ -94832,7 +95373,8 @@ spurious results.`);
94832
95373
  adapters: [],
94833
95374
  targetHealthFactor: 1.1,
94834
95375
  minHealthFactor: 1.05,
94835
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
95376
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
95377
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "tBTC")
94836
95378
  };
94837
95379
  var hyperxsBTC = {
94838
95380
  vaultAddress: ContractAddr.from("0x437ef1e7d0f100b2e070b7a65cafec0b2be31b0290776da8b4112f5473d8d9"),
@@ -94844,7 +95386,8 @@ spurious results.`);
94844
95386
  adapters: [],
94845
95387
  targetHealthFactor: 1.1,
94846
95388
  minHealthFactor: 1.05,
94847
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
95389
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
95390
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "solvBTC")
94848
95391
  };
94849
95392
  var hyperxLBTC = {
94850
95393
  vaultAddress: ContractAddr.from("0x64cf24d4883fe569926419a0569ab34497c6956a1a308fa883257f7486d7030"),
@@ -94856,7 +95399,8 @@ spurious results.`);
94856
95399
  adapters: [],
94857
95400
  targetHealthFactor: 1.1,
94858
95401
  minHealthFactor: 1.05,
94859
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
95402
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
95403
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "LBTC")
94860
95404
  };
94861
95405
  function getInvestmentSteps(lstSymbol, underlyingSymbol) {
94862
95406
  return [