@strkfarm/sdk 1.0.56 → 1.0.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2066,7 +2066,6 @@ var import_bytes = require("@ericnordelo/strk-merkle-tree/dist/bytes");
2066
2066
  var import_core = require("@ericnordelo/strk-merkle-tree/dist/core");
2067
2067
  var import_hashes = require("@ericnordelo/strk-merkle-tree/dist/hashes");
2068
2068
  var import_merkletree = require("@ericnordelo/strk-merkle-tree/dist/merkletree");
2069
- var import_errors = require("@ericnordelo/strk-merkle-tree/src/utils/errors");
2070
2069
  var import_starknet4 = require("starknet");
2071
2070
 
2072
2071
  // ../node_modules/@noble/hashes/esm/_assert.js
@@ -4124,13 +4123,6 @@ var StandardMerkleTree = class _StandardMerkleTree extends import_merkletree.Mer
4124
4123
  });
4125
4124
  return new _StandardMerkleTree(tree, indexedValues, leafEncoding);
4126
4125
  }
4127
- static load(data) {
4128
- (0, import_errors.validateArgument)(data.format === "standard-v1", `Unknown format '${data.format}'`);
4129
- (0, import_errors.validateArgument)(data.leafEncoding !== void 0, "Expected leaf encoding");
4130
- const tree = new _StandardMerkleTree(data.tree, data.values, data.leafEncoding);
4131
- tree.validate();
4132
- return tree;
4133
- }
4134
4126
  static verify(root, leafEncoding, leaf, proof) {
4135
4127
  return (0, import_bytes.toHex)(root) === (0, import_core.processProof)((0, import_hashes.standardLeafHash)(leafEncoding, leaf), proof);
4136
4128
  }
@@ -5888,23 +5880,10 @@ var vesu_rebalance_abi_default = [
5888
5880
  }
5889
5881
  ];
5890
5882
 
5891
- // src/strategies/base-strategy.ts
5892
- var BaseStrategy = class {
5893
- constructor(config) {
5883
+ // src/utils/cacheClass.ts
5884
+ var CacheClass = class {
5885
+ constructor() {
5894
5886
  this.cache = /* @__PURE__ */ new Map();
5895
- this.config = config;
5896
- }
5897
- async getUserTVL(user) {
5898
- throw new Error("Not implemented");
5899
- }
5900
- async getTVL() {
5901
- throw new Error("Not implemented");
5902
- }
5903
- async depositCall(amountInfo, receiver) {
5904
- throw new Error("Not implemented");
5905
- }
5906
- async withdrawCall(amountInfo, receiver, owner) {
5907
- throw new Error("Not implemented");
5908
5887
  }
5909
5888
  setCache(key, data, ttl = 6e4) {
5910
5889
  const timestamp = Date.now();
@@ -5925,6 +5904,27 @@ var BaseStrategy = class {
5925
5904
  }
5926
5905
  };
5927
5906
 
5907
+ // src/strategies/base-strategy.ts
5908
+ var BaseStrategy = class extends CacheClass {
5909
+ constructor(config) {
5910
+ super();
5911
+ this.cache = /* @__PURE__ */ new Map();
5912
+ this.config = config;
5913
+ }
5914
+ async getUserTVL(user) {
5915
+ throw new Error("Not implemented");
5916
+ }
5917
+ async getTVL() {
5918
+ throw new Error("Not implemented");
5919
+ }
5920
+ async depositCall(amountInfo, receiver) {
5921
+ throw new Error("Not implemented");
5922
+ }
5923
+ async withdrawCall(amountInfo, receiver, owner) {
5924
+ throw new Error("Not implemented");
5925
+ }
5926
+ };
5927
+
5928
5928
  // src/node/headless.browser.ts
5929
5929
  var import_axios5 = __toESM(require("axios"));
5930
5930
  async function getAPIUsingHeadlessBrowser(url) {
@@ -20394,9 +20394,8 @@ var SenseiVault = class extends BaseStrategy {
20394
20394
  }
20395
20395
  async getPositionInfo() {
20396
20396
  const CACHE_KEY = "positionInfo";
20397
- if (this.isCacheValid(CACHE_KEY)) {
20398
- return this.getCache(CACHE_KEY);
20399
- }
20397
+ const existingCacheData = this.getCache(CACHE_KEY);
20398
+ if (existingCacheData) return existingCacheData;
20400
20399
  const resp = await fetch(
20401
20400
  `${getTrovesEndpoint()}/vesu/positions?walletAddress=${this.address.address}`
20402
20401
  );
@@ -20440,9 +20439,8 @@ var SenseiVault = class extends BaseStrategy {
20440
20439
  }
20441
20440
  async getSecondaryTokenPriceRelativeToMain(retry = 0) {
20442
20441
  const CACHE_KEY = "xSTRKPrice";
20443
- if (this.isCacheValid(CACHE_KEY)) {
20444
- return this.getCache(CACHE_KEY);
20445
- }
20442
+ const existingCacheData = this.getCache(CACHE_KEY);
20443
+ if (existingCacheData) return existingCacheData;
20446
20444
  const params = {
20447
20445
  sellTokenAddress: this.metadata.additionalInfo.secondaryToken.address.address,
20448
20446
  buyTokenAddress: this.metadata.additionalInfo.mainToken.address.address,
@@ -20596,7 +20594,7 @@ function toBigInt(value) {
20596
20594
  }
20597
20595
 
20598
20596
  // src/strategies/universal-adapters/baseAdapter.ts
20599
- var BaseAdapter = class {
20597
+ var BaseAdapter = class extends CacheClass {
20600
20598
  constructSimpleLeafData(params) {
20601
20599
  const { id, target, method, packedArguments } = params;
20602
20600
  return {
@@ -22971,7 +22969,6 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
22971
22969
  constructor(config) {
22972
22970
  super();
22973
22971
  this.VESU_SINGLETON = ContractAddr.from("0x000d8d6dfec4d33bfb6895de9f3852143a17c6f92fd2a21da3d6924d34870160");
22974
- this.cache = {};
22975
22972
  this.getModifyPosition = () => {
22976
22973
  const positionData = [0n];
22977
22974
  const packedArguments = [
@@ -23000,17 +22997,19 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
23000
22997
  denomination: this.formatAmountDenominationEnum(params.collateralAmount.denomination),
23001
22998
  value: {
23002
22999
  abs: import_starknet14.uint256.bnToUint256(params.collateralAmount.value.abs.toWei()),
23003
- is_negative: params.collateralAmount.value.is_negative
23000
+ is_negative: params.collateralAmount.value.abs.isZero() ? false : params.collateralAmount.value.is_negative
23004
23001
  }
23005
23002
  };
23003
+ logger.verbose(`VesuAdapter::ConstructingModify::Collateral::${JSON.stringify(_collateral)}`);
23006
23004
  const _debt = {
23007
23005
  amount_type: this.formatAmountTypeEnum(params.debtAmount.amount_type),
23008
23006
  denomination: this.formatAmountDenominationEnum(params.debtAmount.denomination),
23009
23007
  value: {
23010
23008
  abs: import_starknet14.uint256.bnToUint256(params.debtAmount.value.abs.toWei()),
23011
- is_negative: params.debtAmount.value.is_negative
23009
+ is_negative: params.debtAmount.value.abs.isZero() ? false : params.debtAmount.value.is_negative
23012
23010
  }
23013
23011
  };
23012
+ logger.verbose(`VesuAdapter::ConstructingModify::Debt::${JSON.stringify(_debt)}`);
23014
23013
  const singletonContract = new import_starknet14.Contract(vesu_singleton_abi_default, this.VESU_SINGLETON.toString(), new import_starknet14.RpcProvider({ nodeUrl: "" }));
23015
23014
  const call = singletonContract.populate("modify_position", {
23016
23015
  params: {
@@ -23079,20 +23078,22 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
23079
23078
  }
23080
23079
  async getLTVConfig(config) {
23081
23080
  const CACHE_KEY = "ltv_config";
23082
- if (this.cache[CACHE_KEY]) {
23083
- return this.cache[CACHE_KEY];
23081
+ const cacheData = this.getCache(CACHE_KEY);
23082
+ if (cacheData) {
23083
+ return cacheData;
23084
23084
  }
23085
23085
  const output2 = await this.getVesuSingletonContract(config).call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address]);
23086
- this.cache[CACHE_KEY] = Number(output2.max_ltv) / 1e18;
23087
- return this.cache[CACHE_KEY];
23086
+ this.setCache(CACHE_KEY, Number(output2.max_ltv) / 1e18, 3e5);
23087
+ return this.getCache(CACHE_KEY);
23088
23088
  }
23089
23089
  async getPositions(config) {
23090
23090
  if (!this.pricer) {
23091
23091
  throw new Error("Pricer is not initialized");
23092
23092
  }
23093
23093
  const CACHE_KEY = "positions";
23094
- if (this.cache[CACHE_KEY]) {
23095
- return this.cache[CACHE_KEY];
23094
+ const cacheData = this.getCache(CACHE_KEY);
23095
+ if (cacheData) {
23096
+ return cacheData;
23096
23097
  }
23097
23098
  const output2 = await this.getVesuSingletonContract(config).call("position_unsafe", [
23098
23099
  this.config.poolId.address,
@@ -23115,9 +23116,65 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
23115
23116
  usdValue: debtAmount.multipliedBy(token2Price.price).toNumber(),
23116
23117
  remarks: "Debt"
23117
23118
  }];
23118
- this.cache[CACHE_KEY] = value;
23119
+ this.setCache(CACHE_KEY, value, 6e4);
23120
+ return value;
23121
+ }
23122
+ async getCollateralization(config) {
23123
+ if (!this.pricer) {
23124
+ throw new Error("Pricer is not initialized");
23125
+ }
23126
+ const CACHE_KEY = "collateralization";
23127
+ const cacheData = this.getCache(CACHE_KEY);
23128
+ if (cacheData) {
23129
+ return cacheData;
23130
+ }
23131
+ const output2 = await this.getVesuSingletonContract(config).call("check_collateralization_unsafe", [
23132
+ this.config.poolId.address,
23133
+ this.config.collateral.address.address,
23134
+ this.config.debt.address.address,
23135
+ this.config.vaultAllocator.address
23136
+ ]);
23137
+ const collateralAmount = Web3Number.fromWei(output2["1"].toString(), 18);
23138
+ const debtAmount = Web3Number.fromWei(output2["2"].toString(), 18);
23139
+ const value = [{
23140
+ token: this.config.collateral,
23141
+ usdValue: collateralAmount.toNumber(),
23142
+ remarks: "Collateral"
23143
+ }, {
23144
+ token: this.config.debt,
23145
+ usdValue: debtAmount.toNumber(),
23146
+ remarks: "Debt"
23147
+ }];
23148
+ this.setCache(CACHE_KEY, value, 6e4);
23119
23149
  return value;
23120
23150
  }
23151
+ async getAssetPrices() {
23152
+ const collateralizationProm = this.getCollateralization(this.networkConfig);
23153
+ const positionsProm = this.getPositions(this.networkConfig);
23154
+ const ltvProm = this.getLTVConfig(this.networkConfig);
23155
+ const output2 = await Promise.all([collateralizationProm, positionsProm, ltvProm]);
23156
+ const [collateralization, positions, ltv] = output2;
23157
+ const collateralTokenAmount = positions[0].amount;
23158
+ const collateralUSDAmount = collateralization[0].usdValue;
23159
+ const collateralPrice = collateralUSDAmount / collateralTokenAmount.toNumber();
23160
+ const debtTokenAmount = positions[1].amount;
23161
+ const debtUSDAmount = collateralization[1].usdValue;
23162
+ const debtPrice = debtUSDAmount / debtTokenAmount.toNumber();
23163
+ return {
23164
+ collateralTokenAmount,
23165
+ collateralUSDAmount,
23166
+ collateralPrice,
23167
+ debtTokenAmount,
23168
+ debtUSDAmount,
23169
+ debtPrice,
23170
+ ltv
23171
+ };
23172
+ }
23173
+ async getHealthFactor() {
23174
+ const ltv = await this.getLTVConfig(this.networkConfig);
23175
+ const collateralisation = await this.getCollateralization(this.networkConfig);
23176
+ return collateralisation[0].usdValue * ltv / collateralisation[1].usdValue;
23177
+ }
23121
23178
  static async getVesuPools(retry = 0) {
23122
23179
  const CACHE_KEY = "VESU_POOLS";
23123
23180
  const cacheValue = Global.getGlobalCache(CACHE_KEY);
@@ -25489,19 +25546,32 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
25489
25546
  const debtAsset1 = pool1.assets.find((a) => a.symbol === vesuAdapter1.config.debt.symbol)?.stats;
25490
25547
  const collateralAsset2 = pool2.assets.find((a) => a.symbol === vesuAdapter2.config.collateral.symbol)?.stats;
25491
25548
  const debtAsset2 = pool2.assets.find((a) => a.symbol === vesuAdapter2.config.debt.symbol)?.stats;
25492
- const collateral1APY = Number(collateralAsset1.supplyApy.value) / 1e18 + Number(collateralAsset1.defiSpringSupplyApr.value) / 1e18;
25549
+ const collateral1APY = Number(collateralAsset1.supplyApy.value) / 1e18;
25493
25550
  const debt1APY = Number(debtAsset1.borrowApr.value) / 1e18;
25494
- const collateral2APY = Number(collateralAsset2.supplyApy.value) / 1e18 + Number(collateralAsset2.defiSpringSupplyApr.value) / 1e18;
25551
+ const collateral2APY = Number(collateralAsset2.supplyApy.value) / 1e18;
25495
25552
  const debt2APY = Number(debtAsset2.borrowApr.value) / 1e18;
25496
- const apys = [collateral1APY, debt1APY, collateral2APY, debt2APY];
25497
25553
  const positions = await this.getVaultPositions();
25498
- assert(positions.length == apys.length, "Positions and APYs length mismatch");
25499
- const weightedAPYs = positions.map((pos, i) => {
25500
- return pos.usdValue * apys[i] * (i % 2 == 0 ? 1 : -1);
25501
- });
25502
- const netPosition = positions.reduce((acc, val, index) => acc + val.usdValue * (index % 2 == 0 ? 1 : -1), 0);
25503
- const apy = weightedAPYs.reduce((acc, val) => acc + val, 0) / netPosition;
25504
- return apy;
25554
+ const weights = positions.map((p, index) => p.usdValue * (index % 2 == 0 ? 1 : -1));
25555
+ const baseAPYs = [collateral1APY, debt1APY, collateral2APY, debt2APY];
25556
+ assert(positions.length == baseAPYs.length, "Positions and APYs length mismatch");
25557
+ const rewardAPYs = [Number(collateralAsset1.defiSpringSupplyApr.value) / 1e18, 0, Number(collateralAsset2.defiSpringSupplyApr.value) / 1e18, 0];
25558
+ const baseAPY = this.computeAPY(baseAPYs, weights);
25559
+ const rewardAPY = this.computeAPY(rewardAPYs, weights);
25560
+ const apys = [...baseAPYs, ...rewardAPYs];
25561
+ const netAPY = baseAPY + rewardAPY;
25562
+ return { net: netAPY, splits: [{
25563
+ apy: baseAPY,
25564
+ id: "base"
25565
+ }, {
25566
+ apy: rewardAPY,
25567
+ id: "defispring"
25568
+ }] };
25569
+ }
25570
+ computeAPY(apys, weights) {
25571
+ assert(apys.length === weights.length, "APYs and weights length mismatch");
25572
+ const weightedSum = apys.reduce((acc, apy, i) => acc + apy * weights[i], 0);
25573
+ const totalWeight = weights.reduce((acc, weight) => acc + weight, 0);
25574
+ return weightedSum / totalWeight;
25505
25575
  }
25506
25576
  /**
25507
25577
  * Calculates the total TVL of the strategy.
@@ -25524,22 +25594,48 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
25524
25594
  };
25525
25595
  }
25526
25596
  async getAUM() {
25597
+ const currentAUM = await this.contract.call("aum", []);
25598
+ const lastReportTime = await this.contract.call("last_report_timestamp", []);
25599
+ const token1Price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
25527
25600
  const [vesuAdapter1, vesuAdapter2] = this.getVesuAdapters();
25528
25601
  const leg1AUM = await vesuAdapter1.getPositions(this.config);
25529
25602
  const leg2AUM = await vesuAdapter2.getPositions(this.config);
25530
- const token1Price = await this.pricer.getPrice(vesuAdapter1.config.collateral.symbol);
25531
25603
  const aumToken = leg1AUM[0].amount.plus(leg2AUM[0].usdValue / token1Price.price).minus(leg1AUM[1].usdValue / token1Price.price).minus(leg2AUM[1].amount);
25532
- return {
25604
+ logger.verbose(`${this.getTag()} Actual AUM: ${aumToken}`);
25605
+ const netAPY = await this.netAPY();
25606
+ const defispringAPY = netAPY.splits.find((s) => s.id === "defispring")?.apy || 0;
25607
+ if (!defispringAPY) throw new Error("DefiSpring APY not found");
25608
+ const timeDiff = Math.round(Date.now() / 1e3) - Number(lastReportTime);
25609
+ const growthRate = timeDiff * defispringAPY / (365 * 24 * 60 * 60);
25610
+ const prevAum = Web3Number.fromWei(currentAUM.toString(), this.asset().decimals);
25611
+ const rewardAssets = prevAum.multipliedBy(growthRate);
25612
+ logger.verbose(`${this.getTag()} DefiSpring AUM time difference: ${timeDiff}`);
25613
+ logger.verbose(`${this.getTag()} Current AUM: ${currentAUM}`);
25614
+ logger.verbose(`${this.getTag()} Net APY: ${JSON.stringify(netAPY)}`);
25615
+ logger.verbose(`${this.getTag()} rewards AUM: ${rewardAssets}`);
25616
+ const newAUM = aumToken.plus(rewardAssets);
25617
+ logger.verbose(`${this.getTag()} New AUM: ${newAUM}`);
25618
+ const net = {
25533
25619
  tokenInfo: this.asset(),
25534
- amount: aumToken,
25535
- usdValue: aumToken.multipliedBy(token1Price.price).toNumber()
25620
+ amount: newAUM,
25621
+ usdValue: newAUM.multipliedBy(token1Price.price).toNumber()
25536
25622
  };
25623
+ const splits = [{
25624
+ id: "finalised",
25625
+ aum: aumToken
25626
+ }, {
25627
+ id: "defispring",
25628
+ aum: rewardAssets
25629
+ }];
25630
+ return { net, splits, prevAum };
25537
25631
  }
25538
25632
  getVesuAdapters() {
25539
25633
  const vesuAdapter1 = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
25540
25634
  const vesuAdapter2 = this.getAdapter("vesu_leg2_adapter" /* VESU_LEG2 */);
25541
25635
  vesuAdapter1.pricer = this.pricer;
25542
25636
  vesuAdapter2.pricer = this.pricer;
25637
+ vesuAdapter1.networkConfig = this.config;
25638
+ vesuAdapter2.networkConfig = this.config;
25543
25639
  return [vesuAdapter1, vesuAdapter2];
25544
25640
  }
25545
25641
  async getVaultPositions() {
@@ -25581,12 +25677,14 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
25581
25677
  }));
25582
25678
  const output2 = [{
25583
25679
  proofs: manage5Info.proofs,
25584
- manageCall: manageCall5
25680
+ manageCall: manageCall5,
25681
+ step: STEP2_ID
25585
25682
  }];
25586
25683
  if (approveAmount.gt(0)) {
25587
25684
  output2.unshift({
25588
25685
  proofs: manage4Info.proofs,
25589
- manageCall: manageCall4
25686
+ manageCall: manageCall4,
25687
+ step: STEP1_ID
25590
25688
  });
25591
25689
  }
25592
25690
  return output2;
@@ -25594,9 +25692,96 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
25594
25692
  getTag() {
25595
25693
  return `${_UniversalStrategy.name}:${this.metadata.name}`;
25596
25694
  }
25695
+ async getVesuHealthFactors() {
25696
+ return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor()));
25697
+ }
25698
+ async computeRebalanceConditionAndReturnCalls() {
25699
+ const vesuAdapters = this.getVesuAdapters();
25700
+ const healthFactors = await this.getVesuHealthFactors();
25701
+ const leg1HealthFactor = healthFactors[0];
25702
+ const leg2HealthFactor = healthFactors[1];
25703
+ logger.verbose(`${this.getTag()}: HealthFactorLeg1: ${leg1HealthFactor}`);
25704
+ logger.verbose(`${this.getTag()}: HealthFactorLeg2: ${leg2HealthFactor}`);
25705
+ const minHf = this.metadata.additionalInfo.minHealthFactor;
25706
+ const isRebalanceNeeded1 = leg1HealthFactor < minHf;
25707
+ const isRebalanceNeeded2 = leg2HealthFactor < minHf;
25708
+ if (!isRebalanceNeeded1 && !isRebalanceNeeded2) {
25709
+ return [];
25710
+ }
25711
+ if (isRebalanceNeeded1) {
25712
+ const amount = await this.getLegRebalanceAmount(vesuAdapters[0], leg1HealthFactor, false);
25713
+ const leg2HF = await this.getNewHealthFactor(vesuAdapters[1], amount, true);
25714
+ assert(leg2HF > minHf, `Rebalance Leg1 failed: Leg2 HF after rebalance would be too low: ${leg2HF}`);
25715
+ return [await this.getRebalanceCall({
25716
+ isLeg1toLeg2: false,
25717
+ amount
25718
+ })];
25719
+ } else {
25720
+ const amount = await this.getLegRebalanceAmount(vesuAdapters[1], leg2HealthFactor, true);
25721
+ const leg1HF = await this.getNewHealthFactor(vesuAdapters[0], amount, false);
25722
+ assert(leg1HF > minHf, `Rebalance Leg2 failed: Leg1 HF after rebalance would be too low: ${leg1HF}`);
25723
+ return [await this.getRebalanceCall({
25724
+ isLeg1toLeg2: true,
25725
+ amount
25726
+ })];
25727
+ }
25728
+ }
25729
+ async getNewHealthFactor(vesuAdapter, newAmount, isWithdraw) {
25730
+ const {
25731
+ collateralTokenAmount,
25732
+ collateralUSDAmount,
25733
+ collateralPrice,
25734
+ debtTokenAmount,
25735
+ debtUSDAmount,
25736
+ debtPrice,
25737
+ ltv
25738
+ } = await vesuAdapter.getAssetPrices();
25739
+ if (isWithdraw) {
25740
+ const newHF = (collateralTokenAmount.toNumber() - newAmount.toNumber()) * collateralPrice * ltv / debtUSDAmount;
25741
+ logger.verbose(`getNewHealthFactor:: HF: ${newHF}, amoutn: ${newAmount.toNumber()}, isDeposit`);
25742
+ return newHF;
25743
+ } else {
25744
+ const newHF = collateralUSDAmount * ltv / ((debtTokenAmount.toNumber() + newAmount.toNumber()) * debtPrice);
25745
+ logger.verbose(`getNewHealthFactor:: HF: ${newHF}, amoutn: ${newAmount.toNumber()}, isRepay`);
25746
+ return newHF;
25747
+ }
25748
+ }
25749
+ /**
25750
+ *
25751
+ * @param vesuAdapter
25752
+ * @param currentHf
25753
+ * @param isDeposit if true, attempt by adding collateral, else by repaying
25754
+ * @returns
25755
+ */
25756
+ async getLegRebalanceAmount(vesuAdapter, currentHf, isDeposit) {
25757
+ const {
25758
+ collateralTokenAmount,
25759
+ collateralUSDAmount,
25760
+ collateralPrice,
25761
+ debtTokenAmount,
25762
+ debtUSDAmount,
25763
+ debtPrice,
25764
+ ltv
25765
+ } = await vesuAdapter.getAssetPrices();
25766
+ if (debtTokenAmount.isZero()) {
25767
+ return Web3Number.fromWei(0, 0);
25768
+ }
25769
+ assert(collateralPrice > 0 && debtPrice > 0, "getRebalanceAmount: Invalid price");
25770
+ const targetHF = this.metadata.additionalInfo.targetHealthFactor;
25771
+ if (currentHf > targetHF - 0.01)
25772
+ throw new Error("getLegRebalanceAmount: Current health factor is healthy");
25773
+ if (isDeposit) {
25774
+ const newAmount = targetHF * debtUSDAmount / (collateralPrice * ltv) - collateralTokenAmount.toNumber();
25775
+ logger.verbose(`${this.getTag()}:: getLegRebalanceAmount: addCollateral, currentHf: ${currentHf}, targetHF: ${targetHF}, collAmount: ${collateralTokenAmount.toString()}, collUSD: ${collateralUSDAmount}, collPrice: ${collateralPrice}, debtAmount: ${debtTokenAmount.toString()}, debtUSD: ${debtUSDAmount}, debtPrice: ${debtPrice}, ltv: ${ltv}, newAmount: ${newAmount}`);
25776
+ return new Web3Number(newAmount.toFixed(8), collateralTokenAmount.decimals);
25777
+ } else {
25778
+ const newAmount = debtTokenAmount.toNumber() - collateralUSDAmount * ltv / (targetHF * debtPrice);
25779
+ logger.verbose(`${this.getTag()}:: getLegRebalanceAmount: repayDebt, currentHf: ${currentHf}, targetHF: ${targetHF}, collAmount: ${collateralTokenAmount.toString()}, collUSD: ${collateralUSDAmount}, collPrice: ${collateralPrice}, debtAmount: ${debtTokenAmount.toString()}, debtUSD: ${debtUSDAmount}, debtPrice: ${debtPrice}, ltv: ${ltv}, newAmount: ${newAmount}`);
25780
+ return new Web3Number(newAmount.toFixed(8), debtTokenAmount.decimals);
25781
+ }
25782
+ }
25597
25783
  async getVesuMultiplyCall(params) {
25598
- const vesuAdapter1 = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
25599
- const vesuAdapter2 = this.getAdapter("vesu_leg2_adapter" /* VESU_LEG2 */);
25784
+ const [vesuAdapter1, vesuAdapter2] = this.getVesuAdapters();
25600
25785
  const leg1LTV = await vesuAdapter1.getLTVConfig(this.config);
25601
25786
  const leg2LTV = await vesuAdapter2.getLTVConfig(this.config);
25602
25787
  logger.verbose(`${this.getTag()}: LTVLeg1: ${leg1LTV}`);
@@ -25605,7 +25790,7 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
25605
25790
  const token2Price = await this.pricer.getPrice(vesuAdapter2.config.collateral.symbol);
25606
25791
  logger.verbose(`${this.getTag()}: Price${vesuAdapter1.config.collateral.symbol}: ${token1Price.price}`);
25607
25792
  logger.verbose(`${this.getTag()}: Price${vesuAdapter2.config.collateral.symbol}: ${token2Price.price}`);
25608
- const TARGET_HF = 1.3;
25793
+ const TARGET_HF = this.metadata.additionalInfo.targetHealthFactor;
25609
25794
  const k1 = token1Price.price * leg1LTV / token2Price.price / TARGET_HF;
25610
25795
  const k2 = token1Price.price * TARGET_HF / token2Price.price / leg2LTV;
25611
25796
  const borrow2Amount = new Web3Number(
@@ -25663,14 +25848,14 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
25663
25848
  });
25664
25849
  if (params.isLeg1toLeg2) {
25665
25850
  const manageCall = this.getManageCall([
25666
- "vesu_leg1" /* VESU_LEG1 */,
25667
- "vesu_leg2" /* VESU_LEG2 */
25851
+ ...callSet1.map((i) => i.step),
25852
+ ...callSet2.map((i) => i.step)
25668
25853
  ], [...callSet1.map((i) => i.manageCall), ...callSet2.map((i) => i.manageCall)]);
25669
25854
  return manageCall;
25670
25855
  } else {
25671
25856
  const manageCall = this.getManageCall([
25672
- "vesu_leg2" /* VESU_LEG2 */,
25673
- "vesu_leg1" /* VESU_LEG1 */
25857
+ ...callSet2.map((i) => i.step),
25858
+ ...callSet1.map((i) => i.step)
25674
25859
  ], [...callSet2.map((i) => i.manageCall), ...callSet1.map((i) => i.manageCall)]);
25675
25860
  return manageCall;
25676
25861
  }
@@ -25738,14 +25923,18 @@ var usdcVaultSettings = {
25738
25923
  vaultAllocator: ContractAddr.from("0x228cca1005d3f2b55cbaba27cb291dacf1b9a92d1d6b1638195fbd3d0c1e3ba"),
25739
25924
  redeemRequestNFT: ContractAddr.from("0x906d03590010868cbf7590ad47043959d7af8e782089a605d9b22567b64fda"),
25740
25925
  leafAdapters: [],
25741
- adapters: []
25926
+ adapters: [],
25927
+ targetHealthFactor: 1.3,
25928
+ minHealthFactor: 1.25
25742
25929
  };
25743
25930
  var wbtcVaultSettings = {
25744
25931
  manager: ContractAddr.from("0xef8a664ffcfe46a6af550766d27c28937bf1b77fb4ab54d8553e92bca5ba34"),
25745
25932
  vaultAllocator: ContractAddr.from("0x1e01c25f0d9494570226ad28a7fa856c0640505e809c366a9fab4903320e735"),
25746
25933
  redeemRequestNFT: ContractAddr.from("0x4fec59a12f8424281c1e65a80b5de51b4e754625c60cddfcd00d46941ec37b2"),
25747
25934
  leafAdapters: [],
25748
- adapters: []
25935
+ adapters: [],
25936
+ targetHealthFactor: 1.3,
25937
+ minHealthFactor: 1.25
25749
25938
  };
25750
25939
  var UniversalStrategies = [
25751
25940
  {
@@ -25795,13 +25984,10 @@ var TelegramNotif = class {
25795
25984
  this.subscribers = [
25796
25985
  // '6820228303',
25797
25986
  "1505578076",
25798
- // '5434736198', // maaza
25799
25987
  "1356705582",
25800
25988
  // langs
25801
25989
  "1388729514",
25802
25990
  // hwashere
25803
- "6020162572",
25804
- //minato
25805
25991
  "985902592"
25806
25992
  ];
25807
25993
  this.bot = new import_node_telegram_bot_api.default(token, { polling: shouldPoll });