@strkfarm/sdk 1.1.39 → 1.1.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -315,6 +315,25 @@ var defaultTokens = [{
315
315
  priceProxySymbol: "WBTC",
316
316
  priceCheckAmount: 1e-4
317
317
  // 112000 * 0.0001 = $11.2
318
+ }, {
319
+ name: "mRe7BTC",
320
+ symbol: "mRe7BTC",
321
+ logo: "https://imagedelivery.net/0xPAQaDtnQhBs8IzYRIlNg/3a62ecee-1e58-45d3-9862-3ce90dff1900/logo",
322
+ address: ContractAddr.from("0x4e4fb1a9ca7e84bae609b9dc0078ad7719e49187ae7e425bb47d131710eddac"),
323
+ decimals: 18,
324
+ coingeckId: void 0,
325
+ displayDecimals: 6,
326
+ priceCheckAmount: 1e-4
327
+ // 112000 * 0.0001 = $11.2
328
+ }, {
329
+ name: "mRe7YIELD",
330
+ symbol: "mRe7YIELD",
331
+ logo: "https://midas.app/assets/mre7-BcOOHm7i.svg",
332
+ address: ContractAddr.from("0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"),
333
+ decimals: 18,
334
+ coingeckId: void 0,
335
+ displayDecimals: 2,
336
+ priceCheckAmount: 100
318
337
  }];
319
338
  var tokens = defaultTokens;
320
339
  var _Global = class _Global {
@@ -2208,16 +2227,16 @@ var AvnuWrapper = class _AvnuWrapper {
2208
2227
  };
2209
2228
  return swapInfo;
2210
2229
  }
2211
- static buildZeroSwap(tokenToSell, address) {
2230
+ static buildZeroSwap(tokenToSell, beneficiary, tokenToBuy = tokenToSell) {
2212
2231
  return {
2213
2232
  token_from_address: tokenToSell.address,
2214
2233
  token_from_amount: uint256.bnToUint256(0),
2215
- token_to_address: tokenToSell.address,
2234
+ token_to_address: tokenToBuy.address,
2216
2235
  token_to_amount: uint256.bnToUint256(0),
2217
2236
  token_to_min_amount: uint256.bnToUint256(0),
2218
- beneficiary: address,
2237
+ beneficiary,
2219
2238
  integrator_fee_amount_bps: 0,
2220
- integrator_fee_recipient: address,
2239
+ integrator_fee_recipient: beneficiary,
2221
2240
  routes: []
2222
2241
  };
2223
2242
  }
@@ -4018,21 +4037,20 @@ var Harvests = class _Harvests {
4018
4037
  const rewards = await this.getHarvests(addr);
4019
4038
  if (rewards.length == 0) return [];
4020
4039
  const unClaimed = [];
4021
- const cls = await this.config.provider.getClassAt(rewards[0].rewardsContract.address);
4022
- for (let reward of rewards) {
4023
- const contract = new Contract4({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
4024
- const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
4025
- logger.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}`);
4026
- if (isClaimed) {
4027
- return unClaimed;
4028
- }
4029
- const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
4030
- if (bal.lessThan(reward.claim.amount)) {
4031
- logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
4032
- continue;
4033
- }
4034
- unClaimed.unshift(reward);
4040
+ const reward = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime())[0];
4041
+ const cls = await this.config.provider.getClassAt(reward.rewardsContract.address);
4042
+ const contract = new Contract4({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
4043
+ const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
4044
+ logger.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}`);
4045
+ if (isClaimed) {
4046
+ return unClaimed;
4035
4047
  }
4048
+ const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
4049
+ if (bal.lessThan(reward.claim.amount)) {
4050
+ logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
4051
+ return unClaimed;
4052
+ }
4053
+ unClaimed.unshift(reward);
4036
4054
  return unClaimed;
4037
4055
  }
4038
4056
  };
@@ -15299,6 +15317,91 @@ var apolloClient = new ApolloClient({
15299
15317
  });
15300
15318
  var apollo_client_default = apolloClient;
15301
15319
 
15320
+ // src/utils/math-utils.ts
15321
+ async function binarySearch(lowWei, highWei, callback) {
15322
+ while (lowWei <= highWei) {
15323
+ const diff = highWei - lowWei;
15324
+ const mid = lowWei + diff / 2n;
15325
+ const result = await callback(mid);
15326
+ if (result === "found") {
15327
+ return mid;
15328
+ } else if (result == "retry") {
15329
+ } else if (result === "go_low") {
15330
+ highWei = mid - BigInt(1);
15331
+ } else {
15332
+ lowWei = mid + BigInt(1);
15333
+ }
15334
+ }
15335
+ return null;
15336
+ }
15337
+ async function findMaxInputWithSlippage(options) {
15338
+ const {
15339
+ apiGetOutput,
15340
+ maxInput,
15341
+ maxSlippagePercent,
15342
+ tolerance,
15343
+ minInput = 0,
15344
+ referenceAmountMultiplier = 1e-3,
15345
+ referenceRate = 0
15346
+ } = options;
15347
+ let apiCalls = 0;
15348
+ if (!referenceRate && !referenceAmountMultiplier) {
15349
+ throw new Error("One of referenceRate or referenceAmountMultiplier must be provided");
15350
+ }
15351
+ let _referenceRate = referenceRate;
15352
+ if (!_referenceRate) {
15353
+ const smallAmount = maxInput * referenceAmountMultiplier;
15354
+ const referenceOutput = await apiGetOutput(smallAmount);
15355
+ apiCalls++;
15356
+ _referenceRate = referenceOutput / smallAmount;
15357
+ }
15358
+ async function checkSlippage(inputAmount) {
15359
+ const actualOutput = await apiGetOutput(inputAmount);
15360
+ apiCalls++;
15361
+ const expectedOutput = inputAmount * referenceRate;
15362
+ const slippage = (expectedOutput - actualOutput) / expectedOutput;
15363
+ logger.verbose(`findMaxInputWithSlippage::checkSlippage inputAmount: ${inputAmount}, actualOutput: ${actualOutput}, slippage: ${slippage}, maxSlippagePercent: ${maxSlippagePercent}`);
15364
+ return {
15365
+ acceptable: slippage <= maxSlippagePercent,
15366
+ slippage,
15367
+ output: actualOutput
15368
+ };
15369
+ }
15370
+ const maxCheck = await checkSlippage(maxInput);
15371
+ if (maxCheck.acceptable) {
15372
+ return {
15373
+ optimalInput: maxInput,
15374
+ actualOutput: maxCheck.output,
15375
+ actualSlippage: maxCheck.slippage,
15376
+ apiCallsUsed: apiCalls
15377
+ };
15378
+ }
15379
+ let left = minInput;
15380
+ let right = maxInput;
15381
+ let bestInput = minInput;
15382
+ let bestOutput = 0;
15383
+ let bestSlippage = 0;
15384
+ const convergenceThreshold = tolerance * maxInput;
15385
+ while (right - left > convergenceThreshold) {
15386
+ const mid = (left + right) / 2;
15387
+ const midCheck = await checkSlippage(mid);
15388
+ if (midCheck.acceptable) {
15389
+ bestInput = mid;
15390
+ bestOutput = midCheck.output;
15391
+ bestSlippage = midCheck.slippage;
15392
+ left = mid;
15393
+ } else {
15394
+ right = mid;
15395
+ }
15396
+ }
15397
+ return {
15398
+ optimalInput: bestInput,
15399
+ actualOutput: bestOutput,
15400
+ actualSlippage: bestSlippage,
15401
+ apiCallsUsed: apiCalls
15402
+ };
15403
+ }
15404
+
15302
15405
  // src/strategies/ekubo-cl-vault.tsx
15303
15406
  import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
15304
15407
  var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
@@ -15585,7 +15688,6 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
15585
15688
  for (let i = len - 1; i >= 0; --i) {
15586
15689
  let record = await this.contract.call("get_rewards_info", [i]);
15587
15690
  logger.verbose(`${_EkuboCLVault.name}: getHarvestRewardShares: ${i}`);
15588
- console.log(record);
15589
15691
  const block = Number(record.block_number);
15590
15692
  if (block < fromBlock) {
15591
15693
  return shares;
@@ -15785,16 +15887,10 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
15785
15887
  const sqrtRatio = _EkuboCLVault.div2Power128(
15786
15888
  BigInt(priceInfo.sqrt_ratio.toString())
15787
15889
  );
15788
- console.log(
15789
- `EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, sqrtRatio: ${sqrtRatio}, ${priceInfo.sqrt_ratio.toString()}`
15790
- );
15791
15890
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
15792
15891
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
15793
15892
  const price = sqrtRatio * sqrtRatio * 10 ** token0Info.decimals / 10 ** token1Info.decimals;
15794
15893
  const tick = priceInfo.tick;
15795
- console.log(
15796
- `EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, price: ${price}, tick: ${tick.mag}, ${tick.sign}`
15797
- );
15798
15894
  return {
15799
15895
  price,
15800
15896
  tick: Number(tick.mag) * (tick.sign ? -1 : 1),
@@ -16421,62 +16517,193 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16421
16517
  logger.verbose(
16422
16518
  `${_EkuboCLVault.name}: harvest => Processing claim, isToken1: ${isToken1} amount: ${postFeeAmount.toWei()}`
16423
16519
  );
16424
- const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
16425
- const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
16520
+ const isRewardTokenMatch = claim.token.eq(poolKey.token0) || claim.token.eq(poolKey.token1);
16521
+ if (isRewardTokenMatch) {
16522
+ const _callsFinal = await this._handleRewardAndVaultTokenMatchHarvest({
16523
+ acc,
16524
+ claim,
16525
+ isToken1,
16526
+ token0Info,
16527
+ token1Info,
16528
+ postFeeAmount,
16529
+ poolKey,
16530
+ bounds,
16531
+ maxIterations,
16532
+ priceRatioPrecision
16533
+ });
16534
+ calls.push(..._callsFinal);
16535
+ } else {
16536
+ const _callsFinal = await this._handleRewardAndVaultTokenMismatchHarvest({
16537
+ claim,
16538
+ token0Info,
16539
+ token1Info,
16540
+ postFeeAmount,
16541
+ poolKey,
16542
+ bounds,
16543
+ maxIterations,
16544
+ priceRatioPrecision,
16545
+ acc
16546
+ });
16547
+ calls.push(..._callsFinal);
16548
+ }
16549
+ }
16550
+ return calls;
16551
+ }
16552
+ /**
16553
+ * @description This funciton requires atleast one of the pool tokens to be reward token
16554
+ * i.e. STRK.
16555
+ * @param params
16556
+ */
16557
+ async _handleRewardAndVaultTokenMatchHarvest(params) {
16558
+ const { acc, claim, isToken1, token0Info, token1Info, postFeeAmount, poolKey, bounds, maxIterations, priceRatioPrecision } = params;
16559
+ const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
16560
+ const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
16561
+ logger.verbose(
16562
+ `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
16563
+ );
16564
+ const swapInfo = await this.getSwapInfoGivenAmounts(
16565
+ poolKey,
16566
+ token0Amt,
16567
+ token1Amt,
16568
+ bounds,
16569
+ maxIterations,
16570
+ priceRatioPrecision
16571
+ );
16572
+ swapInfo.token_to_address = token0Info.address.address;
16573
+ logger.verbose(
16574
+ `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
16575
+ );
16576
+ logger.verbose(
16577
+ `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
16578
+ );
16579
+ const harvestEstimateCall = async (swapInfo1) => {
16580
+ const swap1Amount = Web3Number.fromWei(
16581
+ uint2564.uint256ToBN(swapInfo1.token_from_amount).toString(),
16582
+ 18
16583
+ // cause its always STRK?
16584
+ ).minimum(
16585
+ postFeeAmount.toFixed(18)
16586
+ // cause always strk
16587
+ );
16588
+ swapInfo.token_from_amount = uint2564.bnToUint256(swap1Amount.toWei());
16589
+ swapInfo.token_to_min_amount = uint2564.bnToUint256(
16590
+ swap1Amount.multipliedBy(0).toWei()
16591
+ // placeholder
16592
+ );
16426
16593
  logger.verbose(
16427
- `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
16594
+ `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
16428
16595
  );
16429
- const swapInfo = await this.getSwapInfoGivenAmounts(
16430
- poolKey,
16431
- token0Amt,
16432
- token1Amt,
16433
- bounds,
16434
- maxIterations,
16435
- priceRatioPrecision
16596
+ const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
16597
+ logger.verbose(
16598
+ `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
16436
16599
  );
16437
- swapInfo.token_to_address = token0Info.address.address;
16600
+ const swapInfo2 = {
16601
+ ...swapInfo,
16602
+ token_from_amount: uint2564.bnToUint256(remainingAmount.toWei())
16603
+ };
16604
+ swapInfo2.token_to_address = token1Info.address.address;
16438
16605
  logger.verbose(
16439
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
16606
+ `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
16607
+ swapInfo
16608
+ )}`
16440
16609
  );
16441
16610
  logger.verbose(
16442
- `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
16611
+ `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
16612
+ swapInfo2
16613
+ )}`
16443
16614
  );
16444
- const harvestEstimateCall = async (swapInfo1) => {
16445
- const swap1Amount = Web3Number.fromWei(
16446
- uint2564.uint256ToBN(swapInfo1.token_from_amount).toString(),
16447
- 18
16448
- // cause its always STRK?
16449
- ).minimum(
16450
- postFeeAmount.toFixed(18)
16451
- // cause always strk
16452
- );
16453
- swapInfo.token_from_amount = uint2564.bnToUint256(swap1Amount.toWei());
16454
- swapInfo.token_to_min_amount = uint2564.bnToUint256(
16455
- swap1Amount.multipliedBy(0).toWei()
16456
- // placeholder
16457
- );
16458
- logger.verbose(
16459
- `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
16460
- );
16461
- const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
16462
- logger.verbose(
16463
- `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
16464
- );
16465
- const swapInfo2 = {
16466
- ...swapInfo,
16467
- token_from_amount: uint2564.bnToUint256(remainingAmount.toWei())
16468
- };
16469
- swapInfo2.token_to_address = token1Info.address.address;
16470
- logger.verbose(
16471
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
16472
- swapInfo
16473
- )}`
16474
- );
16475
- logger.verbose(
16476
- `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
16477
- swapInfo2
16478
- )}`
16479
- );
16615
+ const calldata = [
16616
+ claim.rewardsContract.address,
16617
+ {
16618
+ id: claim.claim.id,
16619
+ amount: claim.claim.amount.toWei(),
16620
+ claimee: claim.claim.claimee.address
16621
+ },
16622
+ claim.proof.map((p) => num5.getDecimalString(p)),
16623
+ swapInfo,
16624
+ swapInfo2
16625
+ ];
16626
+ logger.verbose(
16627
+ `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
16628
+ calldata
16629
+ )}`
16630
+ );
16631
+ return [this.contract.populate("harvest", calldata)];
16632
+ };
16633
+ const _callsFinal = await this.rebalanceIter(
16634
+ swapInfo,
16635
+ acc,
16636
+ harvestEstimateCall,
16637
+ claim.token.eq(poolKey.token0),
16638
+ 0,
16639
+ 0n,
16640
+ BigInt(postFeeAmount.toWei())
16641
+ // upper limit is the post fee amount
16642
+ );
16643
+ logger.verbose(
16644
+ `${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
16645
+ _callsFinal
16646
+ )}`
16647
+ );
16648
+ return _callsFinal;
16649
+ }
16650
+ /**
16651
+ * @description This function handles harvesting of reward token that is not the same as any of the vault token
16652
+ * i.e. STRK is not part of vault tokens like BTC/ETH
16653
+ * @param params
16654
+ * @returns
16655
+ */
16656
+ async _handleRewardAndVaultTokenMismatchHarvest(params) {
16657
+ const { acc, claim, token0Info, token1Info, postFeeAmount, poolKey, bounds, maxIterations, priceRatioPrecision } = params;
16658
+ let token0Amt = postFeeAmount;
16659
+ const beneficiary = this.address.address;
16660
+ let harvestCall = null;
16661
+ harvestCall = await this.harvestMismatchEstimateCallFn({
16662
+ postFeeAmount,
16663
+ claim,
16664
+ token0Info,
16665
+ token1Info,
16666
+ acc
16667
+ });
16668
+ if (!harvestCall) {
16669
+ throw new Error("Harvest call not found");
16670
+ }
16671
+ return [harvestCall];
16672
+ }
16673
+ // given an amount (i.e. portion of reward to use to swap to token0), returns info on increasing or decreasing
16674
+ // amount for binary search
16675
+ async harvestMismatchEstimateCallFn(params) {
16676
+ const { postFeeAmount, claim, token0Info, token1Info, acc } = params;
16677
+ let harvestCall = null;
16678
+ const binarySearchCallbackFn = async (mid) => {
16679
+ const rewardPart2 = BigInt(postFeeAmount.toWei()) - mid;
16680
+ const avnuWrapper = new AvnuWrapper();
16681
+ const beneficiary = this.address.address;
16682
+ const quote1 = await avnuWrapper.getQuotes(
16683
+ claim.token.address,
16684
+ token0Info.address.address,
16685
+ mid.toString(),
16686
+ beneficiary
16687
+ );
16688
+ const swapInfo1 = await avnuWrapper.getSwapInfo(
16689
+ quote1,
16690
+ beneficiary,
16691
+ 0,
16692
+ beneficiary
16693
+ );
16694
+ const quote2 = await avnuWrapper.getQuotes(
16695
+ claim.token.address,
16696
+ token1Info.address.address,
16697
+ rewardPart2.toString(),
16698
+ beneficiary
16699
+ );
16700
+ const swapInfo2 = await avnuWrapper.getSwapInfo(
16701
+ quote2,
16702
+ beneficiary,
16703
+ 0,
16704
+ beneficiary
16705
+ );
16706
+ try {
16480
16707
  const calldata = [
16481
16708
  claim.rewardsContract.address,
16482
16709
  {
@@ -16485,34 +16712,23 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16485
16712
  claimee: claim.claim.claimee.address
16486
16713
  },
16487
16714
  claim.proof.map((p) => num5.getDecimalString(p)),
16488
- swapInfo,
16715
+ swapInfo1,
16489
16716
  swapInfo2
16490
16717
  ];
16491
- logger.verbose(
16492
- `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
16493
- calldata
16494
- )}`
16495
- );
16496
- return [this.contract.populate("harvest", calldata)];
16497
- };
16498
- const _callsFinal = await this.rebalanceIter(
16499
- swapInfo,
16500
- acc,
16501
- harvestEstimateCall,
16502
- claim.token.eq(poolKey.token0),
16503
- 0,
16504
- 0n,
16505
- BigInt(postFeeAmount.toWei())
16506
- // upper limit is the post fee amount
16507
- );
16508
- logger.verbose(
16509
- `${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
16510
- _callsFinal
16511
- )}`
16512
- );
16513
- calls.push(..._callsFinal);
16514
- }
16515
- return calls;
16718
+ harvestCall = this.contract.populate("harvest", calldata);
16719
+ const gas = await acc.estimateInvokeFee(harvestCall);
16720
+ return "found";
16721
+ } catch (err) {
16722
+ if (err.message.includes("invalid token0 amount")) {
16723
+ return "go_low";
16724
+ } else if (err.message.includes("invalid token1 amount")) {
16725
+ return "go_high";
16726
+ }
16727
+ return "retry";
16728
+ }
16729
+ };
16730
+ await binarySearch(0n, BigInt(postFeeAmount.toWei()), binarySearchCallbackFn);
16731
+ return harvestCall;
16516
16732
  }
16517
16733
  async getInvestmentFlows() {
16518
16734
  const netYield = await this.netAPY();
@@ -19044,7 +19260,58 @@ function toBigInt(value) {
19044
19260
  }
19045
19261
 
19046
19262
  // src/strategies/universal-adapters/baseAdapter.ts
19263
+ var APYType = /* @__PURE__ */ ((APYType2) => {
19264
+ APYType2["BASE"] = "base";
19265
+ APYType2["REWARD"] = "reward";
19266
+ APYType2["LST"] = "lst";
19267
+ return APYType2;
19268
+ })(APYType || {});
19047
19269
  var BaseAdapter = class extends CacheClass {
19270
+ // readonly config: BaseAdapterConfig;
19271
+ // constructor(config: BaseAdapterConfig) {
19272
+ // super();
19273
+ // this.config = config;
19274
+ // }
19275
+ constructor() {
19276
+ super();
19277
+ }
19278
+ // /**
19279
+ // * Loop through all supported positions and return amount, usd value, remarks and apy for each
19280
+ // */
19281
+ // async getPositions(): Promise<PositionInfo[]> {
19282
+ // const results: PositionInfo[] = [];
19283
+ // for (const supported of this.config.supportedPositions) {
19284
+ // const amount = await this.getPosition(supported);
19285
+ // const usdValue = await this.getUSDValue(supported.asset, amount);
19286
+ // const apy = await this.getAPY(supported);
19287
+ // results.push({ amount, usdValue, apy });
19288
+ // }
19289
+ // return results;
19290
+ // }
19291
+ // /**
19292
+ // * Implemented by child adapters to compute APY for a given supported position
19293
+ // */
19294
+ // protected abstract getAPY(supportedPosition: SupportedPosition): Promise<PositionAPY>;
19295
+ // /**
19296
+ // * Implemented by child adapters to fetch amount for a given supported position
19297
+ // */
19298
+ // protected abstract getPosition(supportedPosition: SupportedPosition): Promise<Web3Number>;
19299
+ // /**
19300
+ // * Implemented by child adapters to calculate maximum deposit positions
19301
+ // * @param amount Optional amount in baseToken to deposit
19302
+ // */
19303
+ // protected abstract maxDeposit(amount?: Web3Number): Promise<PositionInfo[]>;
19304
+ // /**
19305
+ // * Implemented by child adapters to calculate maximum withdraw positions
19306
+ // */
19307
+ // protected abstract maxWithdraw(): Promise<PositionInfo[]>;
19308
+ // /**
19309
+ // * Uses pricer to convert an amount of an asset to USD value
19310
+ // */
19311
+ // protected async getUSDValue(asset: TokenInfo, amount: Web3Number): Promise<number> {
19312
+ // const priceInfo = await this.config.pricer.getPrice(asset.symbol);
19313
+ // return amount.toNumber() * priceInfo.price;
19314
+ // }
19048
19315
  constructSimpleLeafData(params, sanitizer = SIMPLE_SANITIZER) {
19049
19316
  const { id, target, method, packedArguments } = params;
19050
19317
  return {
@@ -19062,6 +19329,94 @@ var BaseAdapter = class extends CacheClass {
19062
19329
  ]
19063
19330
  };
19064
19331
  }
19332
+ // /**
19333
+ // * Implementor must provide target/method/packedArguments/sanitizer for deposit leaf construction
19334
+ // */
19335
+ // protected abstract _getDepositLeaf(): {
19336
+ // target: ContractAddr,
19337
+ // method: string,
19338
+ // packedArguments: bigint[],
19339
+ // sanitizer: ContractAddr,
19340
+ // id: string
19341
+ // }[];
19342
+ // /**
19343
+ // * Implementor must provide target/method/packedArguments/sanitizer for withdraw leaf construction
19344
+ // */
19345
+ // protected abstract _getWithdrawLeaf(): {
19346
+ // target: ContractAddr,
19347
+ // method: string,
19348
+ // packedArguments: bigint[],
19349
+ // sanitizer: ContractAddr,
19350
+ // id: string
19351
+ // }[];
19352
+ // /**
19353
+ // * Returns deposit leaf adapter using configured proof id
19354
+ // */
19355
+ // getDepositLeaf(): AdapterLeafType<T1> {
19356
+ // const leafConfigs = this._getDepositLeaf();
19357
+ // const leaves = leafConfigs.map(config => {
19358
+ // const { target, method, packedArguments, sanitizer, id } = config;
19359
+ // const leaf = this.constructSimpleLeafData({
19360
+ // id: id,
19361
+ // target,
19362
+ // method,
19363
+ // packedArguments
19364
+ // }, sanitizer);
19365
+ // return leaf;
19366
+ // });
19367
+ // return { leaves, callConstructor: this.getDepositCall.bind(this) as unknown as GenerateCallFn<T1> };
19368
+ // }
19369
+ // /**
19370
+ // * Returns withdraw leaf adapter using configured proof id
19371
+ // */
19372
+ // getWithdrawLeaf(): AdapterLeafType<T2> {
19373
+ // const leafConfigs = this._getWithdrawLeaf();
19374
+ // const leaves = leafConfigs.map(config => {
19375
+ // const { target, method, packedArguments, sanitizer, id } = config;
19376
+ // const leaf = this.constructSimpleLeafData({
19377
+ // id: id,
19378
+ // target,
19379
+ // method,
19380
+ // packedArguments
19381
+ // }, sanitizer ?? SIMPLE_SANITIZER);
19382
+ // return leaf;
19383
+ // });
19384
+ // return { leaves, callConstructor: this.getWithdrawCall.bind(this) as unknown as GenerateCallFn<T2> };
19385
+ // }
19386
+ // /**
19387
+ // * Default deposit callConstructor: expects params as calldata (bigint[])
19388
+ // */
19389
+ // protected getDepositCall<T1 = bigint[]>(params: T1): ManageCall[] {
19390
+ // const leafConfigs = this._getDepositLeaf();
19391
+ // return leafConfigs.map(config => {
19392
+ // const { target, method, sanitizer } = config;
19393
+ // return {
19394
+ // sanitizer: sanitizer ?? SIMPLE_SANITIZER,
19395
+ // call: {
19396
+ // contractAddress: target,
19397
+ // selector: hash.getSelectorFromName(method),
19398
+ // calldata: params as unknown as bigint[]
19399
+ // }
19400
+ // };
19401
+ // });
19402
+ // }
19403
+ // /**
19404
+ // * Default withdraw callConstructor: expects params as calldata (bigint[])
19405
+ // */
19406
+ // protected getWithdrawCall<T2 = bigint[]>(params: T2): ManageCall[] {
19407
+ // const leafConfigs = this._getWithdrawLeaf();
19408
+ // return leafConfigs.map(config => {
19409
+ // const { target, method, sanitizer } = config;
19410
+ // return {
19411
+ // sanitizer: sanitizer ?? SIMPLE_SANITIZER,
19412
+ // call: {
19413
+ // contractAddress: target,
19414
+ // selector: hash.getSelectorFromName(method),
19415
+ // calldata: params as unknown as bigint[]
19416
+ // }
19417
+ // };
19418
+ // });
19419
+ // }
19065
19420
  };
19066
19421
 
19067
19422
  // src/strategies/universal-adapters/common-adapter.ts
@@ -26664,7 +27019,20 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26664
27019
  }
26665
27020
  const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address]);
26666
27021
  logger.verbose(`${this.config.debt.symbol}::VesuAdapter::getDebtCap debt_cap: ${output.debt_cap.toString()}`);
26667
- return Web3Number.fromWei(output.debt_cap.toString(), this.config.debt.decimals);
27022
+ if (!isV2) {
27023
+ throw new Error("getDebtCap is not supported for v1");
27024
+ }
27025
+ const currentDebt = await this.getCurrentDebtUtilisationAmount(config);
27026
+ logger.verbose(`${this.config.debt.symbol}::VesuAdapter::getDebtCap currentDebt: ${currentDebt.toString()}`);
27027
+ return Web3Number.fromWei(output.debt_cap.toString(), this.config.debt.decimals).minus(currentDebt);
27028
+ }
27029
+ async getCurrentDebtUtilisationAmount(config) {
27030
+ const { contract, isV2 } = await this.getVesuSingletonContract(config, this.config.poolId);
27031
+ if (!isV2) {
27032
+ throw new Error("getCurrentDebtUtilisationAmount is not supported for v1");
27033
+ }
27034
+ const output = await contract.call("pairs", [this.config.collateral.address.address, this.config.debt.address.address]);
27035
+ return new Web3Number((Number(output.total_nominal_debt) / 1e18).toFixed(9), this.config.debt.decimals);
26668
27036
  }
26669
27037
  async getMaxBorrowableByInterestRate(config, asset, maxBorrowAPY) {
26670
27038
  const { contract, isV2 } = await this.getVesuSingletonContract(config, this.config.poolId);
@@ -26697,16 +27065,17 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26697
27065
  const assetConfig = isV2 ? _assetConfig : _assetConfig["0"];
26698
27066
  const timeDelta = assetConfig.last_updated;
26699
27067
  const lastFullUtilizationRate = assetConfig.last_full_utilization_rate;
26700
- const totalSupply = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals).plus(Web3Number.fromWei(assetConfig.reserve, asset.decimals));
27068
+ const currentDebt = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals);
27069
+ const totalSupply = currentDebt.plus(Web3Number.fromWei(assetConfig.reserve, asset.decimals));
26701
27070
  const ratePerSecond = BigInt(Math.round(maxBorrowAPY / 365 / 24 / 60 / 60 * Number(SCALE)));
26702
27071
  const maxUtilisation = this.getMaxUtilizationGivenRatePerSecond(interestRateConfig, ratePerSecond, timeDelta, lastFullUtilizationRate);
26703
27072
  logger.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate maxUtilisation: ${Number(maxUtilisation) / 1e18}, totalSupply: ${totalSupply.toString()}`);
26704
27073
  const maxDebtToHave = totalSupply.multipliedBy(Number(maxUtilisation) / 1e18);
26705
- const currentDebt = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals);
27074
+ logger.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate currentDebt: ${currentDebt.toString()}, maxDebtToHave: ${maxDebtToHave.toString()}`);
26706
27075
  return maxDebtToHave.minus(currentDebt);
26707
27076
  }
26708
- async getLTVConfig(config) {
26709
- const CACHE_KEY = "ltv_config";
27077
+ async getLTVConfig(config, blockNumber = "latest") {
27078
+ const CACHE_KEY = `ltv_config_${blockNumber}`;
26710
27079
  const cacheData = this.getCache(CACHE_KEY);
26711
27080
  if (cacheData) {
26712
27081
  return cacheData;
@@ -26714,10 +27083,10 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26714
27083
  const { contract, isV2 } = await this.getVesuSingletonContract(config, this.config.poolId);
26715
27084
  let ltv = 0;
26716
27085
  if (isV2) {
26717
- const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address]);
27086
+ const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address], { blockIdentifier: blockNumber });
26718
27087
  ltv = Number(output.max_ltv) / 1e18;
26719
27088
  } else {
26720
- const output = await contract.call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address]);
27089
+ const output = await contract.call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address], { blockIdentifier: blockNumber });
26721
27090
  ltv = Number(output.max_ltv) / 1e18;
26722
27091
  }
26723
27092
  if (ltv == 0) {
@@ -26726,11 +27095,11 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26726
27095
  this.setCache(CACHE_KEY, ltv, 3e5);
26727
27096
  return this.getCache(CACHE_KEY);
26728
27097
  }
26729
- async getPositions(config) {
27098
+ async getPositions(config, blockNumber = "latest") {
26730
27099
  if (!this.pricer) {
26731
27100
  throw new Error("Pricer is not initialized");
26732
27101
  }
26733
- const CACHE_KEY = "positions";
27102
+ const CACHE_KEY = `positions_${blockNumber}`;
26734
27103
  const cacheData = this.getCache(CACHE_KEY);
26735
27104
  if (cacheData) {
26736
27105
  return cacheData;
@@ -26742,7 +27111,8 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26742
27111
  this.config.collateral.address.address,
26743
27112
  this.config.debt.address.address,
26744
27113
  this.config.vaultAllocator.address
26745
- ]);
27114
+ ], { blockIdentifier: blockNumber });
27115
+ console.log(output);
26746
27116
  const token1Price = await this.pricer.getPrice(this.config.collateral.symbol);
26747
27117
  const token2Price = await this.pricer.getPrice(this.config.debt.symbol);
26748
27118
  logger.verbose(`VesuAdapter::getPositions token1Price: ${token1Price.price}, token2Price: ${token2Price.price}`);
@@ -26762,11 +27132,11 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26762
27132
  this.setCache(CACHE_KEY, value, 6e4);
26763
27133
  return value;
26764
27134
  }
26765
- async getCollateralization(config) {
27135
+ async getCollateralization(config, blockNumber = "latest") {
26766
27136
  if (!this.pricer) {
26767
27137
  throw new Error("Pricer is not initialized");
26768
27138
  }
26769
- const CACHE_KEY = "collateralization";
27139
+ const CACHE_KEY = `collateralization_${blockNumber}`;
26770
27140
  const cacheData = this.getCache(CACHE_KEY);
26771
27141
  if (cacheData) {
26772
27142
  return cacheData;
@@ -26778,7 +27148,7 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26778
27148
  this.config.collateral.address.address,
26779
27149
  this.config.debt.address.address,
26780
27150
  this.config.vaultAllocator.address
26781
- ]);
27151
+ ], { blockIdentifier: blockNumber });
26782
27152
  const collateralAmount = Web3Number.fromWei(output["1"].toString(), 18);
26783
27153
  const debtAmount = Web3Number.fromWei(output["2"].toString(), 18);
26784
27154
  const value = [{
@@ -26815,9 +27185,9 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
26815
27185
  ltv
26816
27186
  };
26817
27187
  }
26818
- async getHealthFactor() {
26819
- const ltv = await this.getLTVConfig(this.networkConfig);
26820
- const collateralisation = await this.getCollateralization(this.networkConfig);
27188
+ async getHealthFactor(blockNumber = "latest") {
27189
+ const ltv = await this.getLTVConfig(this.networkConfig, blockNumber);
27190
+ const collateralisation = await this.getCollateralization(this.networkConfig, blockNumber);
26821
27191
  return collateralisation[0].usdValue * ltv / collateralisation[1].usdValue;
26822
27192
  }
26823
27193
  static async getVesuPools(retry = 0) {
@@ -29479,11 +29849,11 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
29479
29849
  vesuAdapter2.networkConfig = this.config;
29480
29850
  return [vesuAdapter1, vesuAdapter2];
29481
29851
  }
29482
- async getVesuPositions() {
29852
+ async getVesuPositions(blockNumber = "latest") {
29483
29853
  const adapters = this.getVesuAdapters();
29484
29854
  const positions = [];
29485
29855
  for (const adapter of adapters) {
29486
- positions.push(...await adapter.getPositions(this.config));
29856
+ positions.push(...await adapter.getPositions(this.config, blockNumber));
29487
29857
  }
29488
29858
  return positions;
29489
29859
  }
@@ -29552,8 +29922,8 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
29552
29922
  async getLSTAPR(address) {
29553
29923
  return 0;
29554
29924
  }
29555
- async getVesuHealthFactors() {
29556
- return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor()));
29925
+ async getVesuHealthFactors(blockNumber = "latest") {
29926
+ return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor(blockNumber)));
29557
29927
  }
29558
29928
  async computeRebalanceConditionAndReturnCalls() {
29559
29929
  const vesuAdapters = this.getVesuAdapters();
@@ -30149,6 +30519,42 @@ var UniversalStrategies = [
30149
30519
 
30150
30520
  // src/strategies/universal-lst-muliplier-strategy.tsx
30151
30521
  import { Contract as Contract10, uint256 as uint2569 } from "starknet";
30522
+
30523
+ // src/utils/health-factor-math.ts
30524
+ var HealthFactorMath = class {
30525
+ static getCollateralRequired(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo) {
30526
+ const numerator = debtAmount.multipliedBy(debtPrice).multipliedBy(targetHF);
30527
+ const denominator = collateralPrice * maxLTV;
30528
+ const collateralAmount = numerator.dividedBy(denominator);
30529
+ const netCollateral = new Web3Number(collateralAmount.toString(), collateralTokenInfo.decimals);
30530
+ return netCollateral;
30531
+ }
30532
+ static getMinCollateralRequiredOnLooping(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo) {
30533
+ const netCollateral = this.getCollateralRequired(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo);
30534
+ const collateralFromDebt = new Web3Number(debtAmount.multipliedBy(debtPrice).dividedBy(collateralPrice).toString(), collateralTokenInfo.decimals);
30535
+ return netCollateral.minus(collateralFromDebt);
30536
+ }
30537
+ static getHealthFactor(collateralAmount, collateralPrice, maxLTV, debtAmount, debtPrice) {
30538
+ const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
30539
+ const denominator = debtAmount.multipliedBy(debtPrice);
30540
+ const healthFactor = numerator.dividedBy(denominator);
30541
+ return healthFactor.toNumber();
30542
+ }
30543
+ static getMaxDebtAmountOnLooping(collateralAmount, collateralPrice, maxLTV, targetHF, debtPrice, debtTokenInfo) {
30544
+ const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
30545
+ const denominator = targetHF - maxLTV;
30546
+ const debtAmount = numerator.dividedBy(denominator);
30547
+ return new Web3Number(debtAmount.toString(), debtTokenInfo.decimals);
30548
+ }
30549
+ static getMaxDebtAmount(collateralAmount, collateralPrice, maxLTV, targetHF, debtPrice, debtTokenInfo) {
30550
+ const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
30551
+ const denominator = targetHF * debtPrice;
30552
+ const debtAmount = numerator.dividedBy(denominator);
30553
+ return new Web3Number(debtAmount.toString(), debtTokenInfo.decimals);
30554
+ }
30555
+ };
30556
+
30557
+ // src/strategies/universal-lst-muliplier-strategy.tsx
30152
30558
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
30153
30559
  var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy extends UniversalStrategy {
30154
30560
  constructor(config, pricer, metadata) {
@@ -30163,15 +30569,14 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30163
30569
  }
30164
30570
  }
30165
30571
  asset() {
30166
- const vesuAdapter1 = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
30167
- return vesuAdapter1.config.collateral;
30572
+ return this.getVesuSameTokenAdapter().config.collateral;
30168
30573
  }
30169
30574
  getTag() {
30170
30575
  return `${_UniversalLstMultiplierStrategy.name}:${this.metadata.name}`;
30171
30576
  }
30172
30577
  // Vesu adapter with LST and base token match
30173
30578
  getVesuSameTokenAdapter() {
30174
- const baseAdapter = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
30579
+ const baseAdapter = this.getAdapter(getVesuLegId("vesu_leg1" /* VESU_LEG1 */, this.metadata.additionalInfo.underlyingToken.symbol));
30175
30580
  baseAdapter.networkConfig = this.config;
30176
30581
  baseAdapter.pricer = this.pricer;
30177
30582
  return baseAdapter;
@@ -30219,20 +30624,52 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30219
30624
  return price;
30220
30625
  }
30221
30626
  async getAvnuSwapMultiplyCall(params) {
30222
- return this._getAvnuDepositSwapLegCall({
30223
- ...params,
30224
- minHF: 1.1
30225
- // undo
30226
- });
30627
+ assert(params.isDeposit, "Only deposit is supported in getAvnuSwapMultiplyCall");
30628
+ const maxBorrowableAmounts = await this.getMaxBorrowableAmount({ isAPYComputation: false });
30629
+ const allVesuAdapters = this.getVesuAdapters();
30630
+ let remainingAmount = params.leg1DepositAmount;
30631
+ const lstExRate = await this.getLSTExchangeRate();
30632
+ const baseAssetPrice = await this.pricer.getPrice(this.getLSTUnderlyingTokenInfo().symbol);
30633
+ const lstPrice = baseAssetPrice.price * lstExRate;
30634
+ for (let i = 0; i < maxBorrowableAmounts.maxBorrowables.length; i++) {
30635
+ const maxBorrowable = maxBorrowableAmounts.maxBorrowables[i];
30636
+ const vesuAdapter = allVesuAdapters.find((adapter) => adapter.config.debt.address.eq(maxBorrowable.borrowableAsset.address));
30637
+ if (!vesuAdapter) {
30638
+ throw new Error(`${this.getTag()}::getAvnuSwapMultiplyCall: vesuAdapter not found for borrowable asset: ${maxBorrowable.borrowableAsset.symbol}`);
30639
+ }
30640
+ const maxLTV = await vesuAdapter.getLTVConfig(this.config);
30641
+ const debtPrice = await this.pricer.getPrice(maxBorrowable.borrowableAsset.symbol);
30642
+ const maxAmountToDeposit = HealthFactorMath.getMinCollateralRequiredOnLooping(
30643
+ maxBorrowable.amount,
30644
+ debtPrice.price,
30645
+ this.metadata.additionalInfo.targetHealthFactor,
30646
+ maxLTV,
30647
+ lstPrice,
30648
+ this.asset()
30649
+ );
30650
+ const amountToDeposit = remainingAmount.minimum(maxAmountToDeposit);
30651
+ logger.verbose(`${this.getTag()}::getAvnuSwapMultiplyCall::${vesuAdapter.config.debt.symbol}:: remainingAmount: ${remainingAmount}, amountToDeposit: ${amountToDeposit}, depositAmount: ${amountToDeposit}, maxBorrowable: ${maxBorrowable.amount}`);
30652
+ const call = await this._getAvnuDepositSwapLegCall({
30653
+ isDeposit: params.isDeposit,
30654
+ // adjust decimals of debt asset
30655
+ leg1DepositAmount: amountToDeposit,
30656
+ minHF: 1.1,
30657
+ // undo
30658
+ vesuAdapter
30659
+ });
30660
+ remainingAmount = remainingAmount.minus(amountToDeposit);
30661
+ return { call, vesuAdapter };
30662
+ }
30663
+ throw new Error(`${this.getTag()}::getAvnuSwapMultiplyCall: no calls found`);
30227
30664
  }
30228
30665
  async _getAvnuDepositSwapLegCall(params) {
30666
+ const { vesuAdapter } = params;
30229
30667
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall params: ${JSON.stringify(params)}`);
30230
30668
  assert(params.isDeposit, "Only deposit is supported in _getAvnuDepositSwapLegCall");
30231
- const [vesuAdapter1] = this.getVesuAdapters();
30232
- const legLTV = await vesuAdapter1.getLTVConfig(this.config);
30669
+ const legLTV = await vesuAdapter.getLTVConfig(this.config);
30233
30670
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall legLTV: ${legLTV}`);
30234
- const existingPositions = await vesuAdapter1.getPositions(this.config);
30235
- const collateralisation = await vesuAdapter1.getCollateralization(this.config);
30671
+ const existingPositions = await vesuAdapter.getPositions(this.config);
30672
+ const collateralisation = await vesuAdapter.getCollateralization(this.config);
30236
30673
  const existingCollateralInfo = existingPositions[0];
30237
30674
  const existingDebtInfo = existingPositions[1];
30238
30675
  logger.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
@@ -30240,11 +30677,40 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30240
30677
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
30241
30678
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
30242
30679
  logger.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
30680
+ const debtTokenInfo = vesuAdapter.config.debt;
30681
+ let newDepositAmount = params.leg1DepositAmount;
30243
30682
  const totalCollateral = existingCollateralInfo.amount.plus(params.leg1DepositAmount);
30244
30683
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalCollateral: ${totalCollateral}`);
30245
- const totalDebtAmount = totalCollateral.multipliedBy(collateralPrice).multipliedBy(legLTV).dividedBy(debtPrice).dividedBy(params.minHF);
30246
- logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalDebtAmount: ${totalDebtAmount}`);
30247
- const debtAmount = totalDebtAmount.minus(existingDebtInfo.amount);
30684
+ const totalDebtAmount = new Web3Number(
30685
+ totalCollateral.multipliedBy(collateralPrice).multipliedBy(legLTV).dividedBy(debtPrice).dividedBy(params.minHF).toString(),
30686
+ debtTokenInfo.decimals
30687
+ );
30688
+ let debtAmount = totalDebtAmount.minus(existingDebtInfo.amount);
30689
+ logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalDebtAmount: ${totalDebtAmount}, initial computed debt: ${debtAmount}`);
30690
+ const maxBorrowable = await this.getMaxBorrowableAmountByVesuAdapter(vesuAdapter, false);
30691
+ if (debtAmount.gt(0) && maxBorrowable.amount.eq(0)) {
30692
+ logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall maxBorrowable is 0, skipping`);
30693
+ return void 0;
30694
+ } else if (debtAmount.gt(0) && maxBorrowable.amount.gt(0)) {
30695
+ debtAmount = maxBorrowable.amount.minimum(debtAmount);
30696
+ const newDebtUSDValue = debtAmount.multipliedBy(debtPrice);
30697
+ const totalCollateralRequired = HealthFactorMath.getCollateralRequired(
30698
+ debtAmount.plus(existingDebtInfo.amount),
30699
+ debtPrice,
30700
+ params.minHF,
30701
+ legLTV,
30702
+ collateralPrice,
30703
+ this.asset()
30704
+ );
30705
+ newDepositAmount = totalCollateralRequired.minus(existingCollateralInfo.amount);
30706
+ if (newDepositAmount.lt(0)) {
30707
+ throw new Error(`${this.getTag()}::_getAvnuDepositSwapLegCall newDepositAmount is less than 0, newDepositAmount: ${newDepositAmount}, totalCollateralRequired: ${totalCollateralRequired}, existingCollateralInfo.amount: ${existingCollateralInfo.amount}`);
30708
+ }
30709
+ if (newDebtUSDValue.toNumber() < 100) {
30710
+ logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall newDebtUSDValue is less than 100, skipping`);
30711
+ return void 0;
30712
+ }
30713
+ }
30248
30714
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall debtAmount: ${debtAmount}`);
30249
30715
  if (debtAmount.lt(0)) {
30250
30716
  const lstDEXPrice = await this.getLSTDexPrice();
@@ -30256,32 +30722,34 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30256
30722
  assert(calls.length == 1, `Expected 1 call for unwind, got ${calls.length}`);
30257
30723
  return calls[0];
30258
30724
  }
30725
+ console.log(`debtAmount`, debtAmount.toWei(), params.leg1DepositAmount.toWei());
30259
30726
  const STEP0 = "approve_token1" /* APPROVE_TOKEN1 */;
30260
30727
  const manage0Info = this.getProofs(STEP0);
30261
30728
  const manageCall0 = manage0Info.callConstructor({
30262
- amount: params.leg1DepositAmount
30729
+ amount: newDepositAmount
30263
30730
  });
30264
- const STEP1 = "vesu_leg1" /* VESU_LEG1 */;
30731
+ const STEP1 = getVesuLegId("vesu_leg1" /* VESU_LEG1 */, vesuAdapter.config.debt.symbol);
30265
30732
  const manage1Info = this.getProofs(STEP1);
30266
30733
  const manageCall1 = manage1Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
30267
- collateralAmount: params.leg1DepositAmount,
30734
+ collateralAmount: newDepositAmount,
30268
30735
  isAddCollateral: params.isDeposit,
30269
30736
  debtAmount,
30270
30737
  isBorrow: params.isDeposit
30271
30738
  }));
30739
+ console.log(`manageCall1`, manageCall1.call, debtAmount.toWei(), newDepositAmount.toWei());
30272
30740
  const proofIds = [STEP0, STEP1];
30273
30741
  const manageCalls = [manageCall0, manageCall1];
30274
30742
  if (debtAmount.gt(0)) {
30275
- const STEP2 = "avnu_multiply_approve_deposit" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */;
30743
+ const STEP2 = getAvnuManageIDs("avnu_mul_approve_dep" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */, vesuAdapter.config.debt.symbol);
30276
30744
  const manage2Info = this.getProofs(STEP2);
30277
30745
  const manageCall2 = manage2Info.callConstructor({
30278
30746
  amount: debtAmount
30279
30747
  });
30280
- const debtTokenInfo = vesuAdapter1.config.debt;
30748
+ const debtTokenInfo2 = vesuAdapter.config.debt;
30281
30749
  const lstTokenInfo = this.asset();
30282
30750
  const avnuModule = new AvnuWrapper();
30283
30751
  const quote = await avnuModule.getQuotes(
30284
- debtTokenInfo.address.address,
30752
+ debtTokenInfo2.address.address,
30285
30753
  lstTokenInfo.address.address,
30286
30754
  debtAmount.toWei(),
30287
30755
  this.metadata.additionalInfo.vaultAllocator.address
@@ -30297,7 +30765,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30297
30765
  minAmountWei
30298
30766
  );
30299
30767
  logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall swapInfo: ${JSON.stringify(swapInfo)}`);
30300
- const STEP3 = "avnu_multiply_swap_deposit" /* AVNU_MULTIPLY_SWAP_DEPOSIT */;
30768
+ const STEP3 = getAvnuManageIDs("avnu_mul_swap_dep" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, vesuAdapter.config.debt.symbol);
30301
30769
  const manage3Info = this.getProofs(STEP3);
30302
30770
  const manageCall3 = manage3Info.callConstructor({
30303
30771
  props: swapInfo
@@ -30315,7 +30783,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30315
30783
  const manageCall4 = manage4Info.callConstructor({
30316
30784
  amount: minAmount
30317
30785
  });
30318
- const STEP5 = "vesu_leg1" /* VESU_LEG1 */;
30786
+ const STEP5 = getVesuLegId("vesu_leg1" /* VESU_LEG1 */, vesuAdapter.config.debt.symbol);
30319
30787
  const manage5Info = this.getProofs(STEP5);
30320
30788
  const manageCall5 = manage5Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
30321
30789
  collateralAmount: minAmount,
@@ -30332,28 +30800,41 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30332
30800
  }
30333
30801
  // todo unwind or not deposit when the yield is bad.
30334
30802
  async getLSTMultiplierRebalanceCall() {
30335
- const positions = await this.getVaultPositions();
30336
- assert(positions.length == 3, "Rebalance call is only supported for 3 positions");
30803
+ let shouldRebalance = false;
30804
+ const calls = [];
30805
+ const allVesuAdapters = this.getVesuAdapters().filter((vesuAdapter) => vesuAdapter.config.debt.symbol === "LBTC");
30806
+ for (const vesuAdapter of allVesuAdapters) {
30807
+ const call = await this._getLSTMultiplierRebalanceCall(vesuAdapter);
30808
+ if (call.shouldRebalance && call.manageCall) {
30809
+ shouldRebalance = true;
30810
+ calls.push({ vesuAdapter, manageCall: call.manageCall });
30811
+ }
30812
+ }
30813
+ return { shouldRebalance, manageCalls: calls };
30814
+ }
30815
+ async _getLSTMultiplierRebalanceCall(vesuAdapter) {
30816
+ const positions = await vesuAdapter.getPositions(this.config);
30817
+ assert(positions.length == 2, "Rebalance call is only supported for 2 positions");
30337
30818
  const existingCollateralInfo = positions[0];
30338
30819
  const existingDebtInfo = positions[1];
30339
- const unusedBalance = positions[2];
30340
- const [healthFactor] = await this.getVesuHealthFactors();
30341
- const [vesuAdapter1] = this.getVesuAdapters();
30342
- const legLTV = await vesuAdapter1.getLTVConfig(this.config);
30343
- const collateralisation = await vesuAdapter1.getCollateralization(this.config);
30344
- logger.debug(`${this.getTag()}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
30820
+ const unusedBalance = await this.getUnusedBalance();
30821
+ const healthFactor = await vesuAdapter.getHealthFactor();
30822
+ const collateralisation = await vesuAdapter.getCollateralization(this.config);
30823
+ logger.debug(`${this.getTag()}::getVesuMultiplyCall::${vesuAdapter.config.debt.symbol} existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
30345
30824
  existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
30346
30825
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
30347
30826
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
30348
30827
  logger.debug(`${this.getTag()}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
30828
+ logger.debug(`${this.getTag()}::getVesuMultiplyCall healthFactor: ${healthFactor}`);
30349
30829
  const isHFTooLow = healthFactor < this.metadata.additionalInfo.minHealthFactor;
30350
30830
  const isHFTooHigh = healthFactor > this.metadata.additionalInfo.targetHealthFactor + 0.05;
30351
- if (isHFTooLow || isHFTooHigh) {
30831
+ if (isHFTooLow || isHFTooHigh || 1) {
30352
30832
  const manageCall = await this._getAvnuDepositSwapLegCall({
30353
30833
  isDeposit: true,
30354
30834
  leg1DepositAmount: unusedBalance.amount,
30355
- minHF: 1.02
30835
+ minHF: 1.02,
30356
30836
  // todo, shouldnt use this 1.02 HF, if there isn;t more looping left.
30837
+ vesuAdapter
30357
30838
  });
30358
30839
  return { shouldRebalance: true, manageCall };
30359
30840
  } else {
@@ -30386,7 +30867,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30386
30867
  async _getMinOutputAmountLSTBuy(amountInUnderlying) {
30387
30868
  const lstTruePrice = await this.getLSTExchangeRate();
30388
30869
  const minOutputAmount = amountInUnderlying.dividedBy(lstTruePrice).multipliedBy(0.99979);
30389
- return minOutputAmount;
30870
+ return new Web3Number(minOutputAmount.toString(), this.asset().decimals);
30390
30871
  }
30391
30872
  async _getMinOutputAmountLSTSell(amountInLST) {
30392
30873
  const lstTruePrice = await this.getLSTExchangeRate();
@@ -30443,21 +30924,52 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30443
30924
  const vesuAdapter1 = this.getVesuSameTokenAdapter();
30444
30925
  return vesuAdapter1.config.debt;
30445
30926
  }
30446
- async getMaxBorrowableAmount() {
30927
+ async getMaxBorrowableAmount(params = { isAPYComputation: false }) {
30447
30928
  const vesuAdapters = this.getVesuAdapters();
30448
30929
  let netMaxBorrowableAmount = Web3Number.fromWei("0", this.getLSTUnderlyingTokenInfo().decimals);
30449
30930
  const maxBorrowables = [];
30450
- const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
30451
- const maxInterestRate = lstAPY * 0.8;
30452
30931
  for (const vesuAdapter of vesuAdapters) {
30453
- const maxBorrowableAmount = await vesuAdapter.getMaxBorrowableByInterestRate(this.config, vesuAdapter.config.debt, maxInterestRate);
30454
- const debtCap = await vesuAdapter.getDebtCap(this.config);
30455
- maxBorrowables.push({ amount: maxBorrowableAmount.minimum(debtCap), borrowableAsset: vesuAdapter.config.debt });
30932
+ maxBorrowables.push(await this.getMaxBorrowableAmountByVesuAdapter(vesuAdapter, params.isAPYComputation));
30456
30933
  }
30457
30934
  maxBorrowables.sort((a, b) => b.amount.toNumber() - a.amount.toNumber());
30458
30935
  netMaxBorrowableAmount = maxBorrowables.reduce((acc, curr) => acc.plus(curr.amount), Web3Number.fromWei("0", this.getLSTUnderlyingTokenInfo().decimals));
30459
30936
  return { netMaxBorrowableAmount, maxBorrowables };
30460
30937
  }
30938
+ // recursively, using binary search computes max swappable.
30939
+ // @dev assumes 1 token of from == 1 token of to
30940
+ async getMaxSwappableWithMaxSlippage(fromToken, toToken, maxSlippage, maxAmount) {
30941
+ const output = await findMaxInputWithSlippage({
30942
+ apiGetOutput: async (inputAmount) => {
30943
+ const ekuboQuoter = new EkuboQuoter(this.config);
30944
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
30945
+ const quote = await ekuboQuoter.getQuote(fromToken.address.address, toToken.address.address, new Web3Number(inputAmount.toFixed(9), fromToken.decimals));
30946
+ return Web3Number.fromWei(quote.total_calculated.toString(), toToken.decimals).toNumber();
30947
+ },
30948
+ maxInput: maxAmount.toNumber(),
30949
+ maxSlippagePercent: maxSlippage,
30950
+ tolerance: 1e-3,
30951
+ referenceRate: 1
30952
+ });
30953
+ return new Web3Number(output.optimalInput, fromToken.decimals);
30954
+ }
30955
+ async getMaxBorrowableAmountByVesuAdapter(vesuAdapter, isAPYComputation) {
30956
+ const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
30957
+ const maxInterestRate = lstAPY * 0.8;
30958
+ const maxBorrowableAmount = await vesuAdapter.getMaxBorrowableByInterestRate(this.config, vesuAdapter.config.debt, maxInterestRate);
30959
+ const debtCap = await vesuAdapter.getDebtCap(this.config);
30960
+ const maxBorrowable = maxBorrowableAmount.minimum(debtCap).multipliedBy(0.999);
30961
+ if (vesuAdapter.config.debt.address.eq(this.getLSTUnderlyingTokenInfo().address) || isAPYComputation) {
30962
+ return { amount: maxBorrowable, dexSwappableAmount: maxBorrowable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
30963
+ }
30964
+ try {
30965
+ const maxSwappable = await this.getMaxSwappableWithMaxSlippage(vesuAdapter.config.debt, this.getLSTUnderlyingTokenInfo(), 2e-4, maxBorrowable);
30966
+ return { amount: maxBorrowable.minimum(maxSwappable), dexSwappableAmount: maxSwappable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
30967
+ } catch (error) {
30968
+ logger.warn(`${this.getTag()}: Failed to get max swappable: ${error}`);
30969
+ const maxSwappable = Web3Number.fromWei("0", vesuAdapter.config.debt.decimals);
30970
+ return { amount: maxBorrowable.minimum(maxSwappable), dexSwappableAmount: maxSwappable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
30971
+ }
30972
+ }
30461
30973
  // todo how much to unwind to get back healthy APY zone again
30462
30974
  // if net APY < LST APR + 0.5%, we need to unwind to get back to LST APR + 1% atleast or 0 vesu position
30463
30975
  // For xSTRK, simply deposit in Vesu if looping is not viable
@@ -30481,7 +30993,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30481
30993
  // todo undo this
30482
30994
  async netAPY() {
30483
30995
  const unusedBalance = await this.getUnusedBalance();
30484
- const maxNewDeposits = await this.maxNewDeposits();
30996
+ const maxNewDeposits = await this.maxNewDeposits({ isAPYComputation: true });
30485
30997
  const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
30486
30998
  if (maxNewDeposits * 1.5 < unusedBalance.amount.toNumber()) {
30487
30999
  logger.verbose(`${this.getTag()}::netAPY: unused balance is > max servicable from loan, lstAPY: ${lstAPY}`);
@@ -30498,8 +31010,8 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30498
31010
  return output;
30499
31011
  }
30500
31012
  }
30501
- async maxNewDeposits() {
30502
- const maxBorrowableAmounts = await this.getMaxBorrowableAmount();
31013
+ async maxNewDeposits(params = { isAPYComputation: false }) {
31014
+ const maxBorrowableAmounts = await this.getMaxBorrowableAmount(params);
30503
31015
  let ltv = void 0;
30504
31016
  for (let adapter of this.getVesuAdapters()) {
30505
31017
  const maxBorrowableAmount = maxBorrowableAmounts.maxBorrowables.find((b) => b.borrowableAsset.address.eq(adapter.config.debt.address))?.amount;
@@ -30602,7 +31114,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
30602
31114
  const manageCall2 = manage2Info.callConstructor({
30603
31115
  delegation: true
30604
31116
  });
30605
- const STEP3_ID = "multiply_vesu" /* MULTIPLY_VESU */;
31117
+ const STEP3_ID = getVesuLegId("multiply_vesu" /* MULTIPLY_VESU */, vesuAdapter1.config.debt.symbol);
30606
31118
  const manage3Info = this.getProofs(STEP3_ID);
30607
31119
  const multiplyParams = params.isIncrease ? {
30608
31120
  isIncrease: true,
@@ -30686,6 +31198,12 @@ function VaultDescription(lstSymbol, underlyingSymbol) {
30686
31198
  function getDescription2(tokenSymbol, underlyingSymbol) {
30687
31199
  return VaultDescription(tokenSymbol, underlyingSymbol);
30688
31200
  }
31201
+ function getAvnuManageIDs(baseID, debtTokenSymbol) {
31202
+ return `${baseID}_${debtTokenSymbol.toLowerCase()}`;
31203
+ }
31204
+ function getVesuLegId(baseID, debtTokenSymbol) {
31205
+ return `${baseID}_${debtTokenSymbol.toLowerCase()}`;
31206
+ }
30689
31207
  function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
30690
31208
  vaultSettings.leafAdapters = [];
30691
31209
  const lstToken = Global.getDefaultTokens().find((token) => token.symbol === lstSymbol);
@@ -30695,7 +31213,7 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
30695
31213
  collateral: lstToken,
30696
31214
  debt: underlyingToken,
30697
31215
  vaultAllocator: vaultSettings.vaultAllocator,
30698
- id: "vesu_leg1" /* VESU_LEG1 */
31216
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, underlyingToken.symbol)
30699
31217
  });
30700
31218
  const commonAdapter = new CommonAdapter({
30701
31219
  manager: vaultSettings.manager,
@@ -30704,25 +31222,39 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
30704
31222
  vaultAddress: vaultSettings.vaultAddress,
30705
31223
  vaultAllocator: vaultSettings.vaultAllocator
30706
31224
  });
30707
- const { isV2, addr: poolAddr } = getVesuSingletonAddress(pool1);
30708
- const VESU_MULTIPLY = isV2 ? vesuAdapterLST.VESU_MULTIPLY : vesuAdapterLST.VESU_MULTIPLY_V1;
30709
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, VESU_MULTIPLY, "multiple_approve" /* MULTIPLE_APPROVE */).bind(commonAdapter));
30710
- vaultSettings.leafAdapters.push(vesuAdapterLST.getMultiplyAdapter("multiply_vesu" /* MULTIPLY_VESU */).bind(vesuAdapterLST));
30711
- vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_on" /* SWITCH_DELEGATION_ON */).bind(vesuAdapterLST));
30712
- vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_off" /* SWITCH_DELEGATION_OFF */).bind(vesuAdapterLST));
30713
31225
  vaultSettings.adapters.push(...[{
30714
- id: "vesu_leg1_adapter" /* VESU_LEG1 */,
31226
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, underlyingToken.symbol),
30715
31227
  adapter: vesuAdapterLST
30716
31228
  }, {
30717
31229
  id: "common_adapter" /* COMMON */,
30718
31230
  adapter: commonAdapter
30719
31231
  }]);
30720
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(underlyingToken.address, AVNU_EXCHANGE, "avnu_multiply_approve_deposit" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */).bind(commonAdapter));
30721
- vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(underlyingToken.address, lstToken.address, "avnu_multiply_swap_deposit" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, false).bind(commonAdapter));
30722
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, AVNU_EXCHANGE, "avnu_multiply_approve_withdraw" /* AVNU_MULTIPLY_APPROVE_WITHDRAW */).bind(commonAdapter));
30723
- vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(lstToken.address, underlyingToken.address, "avnu_multiply_swap_withdraw" /* AVNU_MULTIPLY_SWAP_WITHDRAW */, false).bind(commonAdapter));
30724
- vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, poolAddr, "approve_token1" /* APPROVE_TOKEN1 */).bind(commonAdapter));
30725
- vaultSettings.leafAdapters.push(vesuAdapterLST.getModifyPosition.bind(vesuAdapterLST));
31232
+ const { isV2, addr: poolAddr } = getVesuSingletonAddress(pool1);
31233
+ const VESU_MULTIPLY = isV2 ? vesuAdapterLST.VESU_MULTIPLY : vesuAdapterLST.VESU_MULTIPLY_V1;
31234
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, VESU_MULTIPLY, "multiple_approve" /* MULTIPLE_APPROVE */).bind(commonAdapter));
31235
+ vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_on" /* SWITCH_DELEGATION_ON */).bind(vesuAdapterLST));
31236
+ vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_off" /* SWITCH_DELEGATION_OFF */).bind(vesuAdapterLST));
31237
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, AVNU_EXCHANGE, "avnu_mul_approve_withdr" /* AVNU_MULTIPLY_APPROVE_WITHDRAW */).bind(commonAdapter));
31238
+ for (let borrowableAsset of vaultSettings.borrowable_assets) {
31239
+ const debtAsset = borrowableAsset;
31240
+ const approve_debt_token_id = getAvnuManageIDs("avnu_mul_approve_dep" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */, debtAsset.symbol);
31241
+ const swap_debt_token_id = getAvnuManageIDs("avnu_mul_swap_dep" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, debtAsset.symbol);
31242
+ const swap_lst_token_id = getAvnuManageIDs("avnu_mul_swap_withdr" /* AVNU_MULTIPLY_SWAP_WITHDRAW */, debtAsset.symbol);
31243
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(debtAsset.address, AVNU_EXCHANGE, approve_debt_token_id).bind(commonAdapter));
31244
+ vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(debtAsset.address, lstToken.address, swap_debt_token_id, false).bind(commonAdapter));
31245
+ vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(lstToken.address, debtAsset.address, swap_lst_token_id, false).bind(commonAdapter));
31246
+ const vesuAdapter = new VesuAdapter({
31247
+ poolId: pool1,
31248
+ collateral: lstToken,
31249
+ debt: debtAsset,
31250
+ vaultAllocator: vaultSettings.vaultAllocator,
31251
+ id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, debtAsset.symbol)
31252
+ });
31253
+ vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, poolAddr, "approve_token1" /* APPROVE_TOKEN1 */).bind(commonAdapter));
31254
+ vaultSettings.leafAdapters.push(vesuAdapter.getModifyPosition.bind(vesuAdapter));
31255
+ const multiplID = getVesuLegId("multiply_vesu" /* MULTIPLY_VESU */, debtAsset.symbol);
31256
+ vaultSettings.leafAdapters.push(vesuAdapter.getMultiplyAdapter(multiplID).bind(vesuAdapter));
31257
+ }
30726
31258
  vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, vaultSettings.vaultAddress, "approve_bring_liquidity" /* APPROVE_BRING_LIQUIDITY */).bind(commonAdapter));
30727
31259
  vaultSettings.leafAdapters.push(commonAdapter.getBringLiquidityAdapter("bring_liquidity" /* BRING_LIQUIDITY */).bind(commonAdapter));
30728
31260
  vaultSettings.leafAdapters.push(vesuAdapterLST.getDefispringRewardsAdapter("defispring_rewards" /* DEFISPRING_REWARDS */).bind(vesuAdapterLST));
@@ -30800,7 +31332,8 @@ var hyperxSTRK = {
30800
31332
  adapters: [],
30801
31333
  targetHealthFactor: 1.1,
30802
31334
  minHealthFactor: 1.05,
30803
- borrowable_assets: Global.getDefaultTokens().filter((token) => token.symbol === "STRK")
31335
+ borrowable_assets: Global.getDefaultTokens().filter((token) => token.symbol === "STRK"),
31336
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "STRK")
30804
31337
  };
30805
31338
  var hyperxWBTC = {
30806
31339
  vaultAddress: ContractAddr.from("0x2da9d0f96a46b453f55604313785dc866424240b1c6811d13bef594343db818"),
@@ -30812,7 +31345,8 @@ var hyperxWBTC = {
30812
31345
  adapters: [],
30813
31346
  targetHealthFactor: 1.1,
30814
31347
  minHealthFactor: 1.05,
30815
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
31348
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
31349
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "WBTC")
30816
31350
  };
30817
31351
  var hyperxtBTC = {
30818
31352
  vaultAddress: ContractAddr.from("0x47d5f68477e5637ce0e56436c6b5eee5a354e6828995dae106b11a48679328"),
@@ -30824,7 +31358,8 @@ var hyperxtBTC = {
30824
31358
  adapters: [],
30825
31359
  targetHealthFactor: 1.1,
30826
31360
  minHealthFactor: 1.05,
30827
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
31361
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
31362
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "tBTC")
30828
31363
  };
30829
31364
  var hyperxsBTC = {
30830
31365
  vaultAddress: ContractAddr.from("0x437ef1e7d0f100b2e070b7a65cafec0b2be31b0290776da8b4112f5473d8d9"),
@@ -30836,7 +31371,8 @@ var hyperxsBTC = {
30836
31371
  adapters: [],
30837
31372
  targetHealthFactor: 1.1,
30838
31373
  minHealthFactor: 1.05,
30839
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
31374
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
31375
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "solvBTC")
30840
31376
  };
30841
31377
  var hyperxLBTC = {
30842
31378
  vaultAddress: ContractAddr.from("0x64cf24d4883fe569926419a0569ab34497c6956a1a308fa883257f7486d7030"),
@@ -30848,7 +31384,8 @@ var hyperxLBTC = {
30848
31384
  adapters: [],
30849
31385
  targetHealthFactor: 1.1,
30850
31386
  minHealthFactor: 1.05,
30851
- borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
31387
+ borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
31388
+ underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "LBTC")
30852
31389
  };
30853
31390
  function getInvestmentSteps(lstSymbol, underlyingSymbol) {
30854
31391
  return [
@@ -31550,6 +32087,7 @@ var Deployer = {
31550
32087
  };
31551
32088
  var deployer_default = Deployer;
31552
32089
  export {
32090
+ APYType,
31553
32091
  AUMTypes,
31554
32092
  AVNU_EXCHANGE,
31555
32093
  AVNU_MIDDLEWARE,