@strkfarm/sdk 1.0.37 → 1.0.39

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
@@ -7,6 +7,43 @@ import axios from "axios";
7
7
  // src/dataTypes/bignumber.node.ts
8
8
  import util from "util";
9
9
 
10
+ // src/utils/logger.node.ts
11
+ import winston, { format } from "winston";
12
+ var colors = {
13
+ error: "red",
14
+ warn: "yellow",
15
+ info: "blue",
16
+ verbose: "white",
17
+ debug: "white"
18
+ };
19
+ winston.addColors(colors);
20
+ var logger = winston.createLogger({
21
+ level: "verbose",
22
+ // Set the minimum logging level
23
+ format: format.combine(
24
+ format.colorize({ all: true }),
25
+ // Apply custom colors
26
+ format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
27
+ // Add timestamp to log messages
28
+ format.printf(({ timestamp, level, message, ...meta }) => {
29
+ let msg = `${timestamp} ${level}: ${message}`;
30
+ if (meta && meta[Symbol.for("splat")]) {
31
+ for (const arg of meta[Symbol.for("splat")]) {
32
+ if (arg instanceof Error) {
33
+ msg += `
34
+ ${arg.stack}`;
35
+ }
36
+ }
37
+ }
38
+ return msg;
39
+ })
40
+ ),
41
+ transports: [
42
+ new winston.transports.Console()
43
+ // Output logs to the console
44
+ ]
45
+ });
46
+
10
47
  // src/dataTypes/_bignumber.ts
11
48
  import BigNumber from "bignumber.js";
12
49
  var _Web3Number = class extends BigNumber {
@@ -23,6 +60,7 @@ var _Web3Number = class extends BigNumber {
23
60
  }
24
61
  dividedBy(value) {
25
62
  const _value = this.getStandardString(value);
63
+ console.log("dividedBy", _value);
26
64
  return this.construct(this.div(_value).toString(), this.decimals);
27
65
  }
28
66
  plus(value) {
@@ -36,13 +74,15 @@ var _Web3Number = class extends BigNumber {
36
74
  construct(value, decimals) {
37
75
  return new this.constructor(value, decimals);
38
76
  }
39
- toString(decimals = this.maxToFixedDecimals()) {
40
- return super.toFixed(decimals);
77
+ toString() {
78
+ return super.toString();
41
79
  }
42
80
  toJSON() {
81
+ logger.verbose(`converting to json with decimals`);
43
82
  return this.toString();
44
83
  }
45
84
  valueOf() {
85
+ logger.verbose(`converting to valueOf with decimals`);
46
86
  return this.toString();
47
87
  }
48
88
  maxToFixedDecimals() {
@@ -107,12 +147,6 @@ var ContractAddr = class _ContractAddr {
107
147
  };
108
148
 
109
149
  // src/global.ts
110
- var logger = {
111
- ...console,
112
- verbose(message) {
113
- console.log(`[VERBOSE] ${message}`);
114
- }
115
- };
116
150
  var FatalError = class extends Error {
117
151
  constructor(message, err) {
118
152
  super(message);
@@ -706,7 +740,7 @@ var PricerFromApi = class extends PricerBase {
706
740
  } catch (e) {
707
741
  logger.warn("getPriceFromMyAPI error", JSON.stringify(e.message || e));
708
742
  }
709
- logger.log("getPrice coinbase", tokenSymbol);
743
+ logger.info("getPrice coinbase", tokenSymbol);
710
744
  let retry = 0;
711
745
  const MAX_RETRIES = 5;
712
746
  for (retry = 1; retry < MAX_RETRIES + 1; retry++) {
@@ -1887,6 +1921,11 @@ var ERC20 = class {
1887
1921
  const balance = await contract.call("balanceOf", [address.toString()]);
1888
1922
  return Web3Number.fromWei(balance.toString(), tokenDecimals);
1889
1923
  }
1924
+ async allowance(token, owner, spender, tokenDecimals) {
1925
+ const contract = this.contract(token);
1926
+ const allowance = await contract.call("allowance", [owner.toString(), spender.toString()]);
1927
+ return Web3Number.fromWei(allowance.toString(), tokenDecimals);
1928
+ }
1890
1929
  };
1891
1930
 
1892
1931
  // src/modules/avnu.ts
@@ -2026,7 +2065,9 @@ var getRiskColor = (risk) => {
2026
2065
  };
2027
2066
  var getNoRiskTags = (risks) => {
2028
2067
  const noRisks1 = risks.filter((risk) => risk.value === 0).map((risk) => risk.type);
2029
- const noRisks2 = Object.values(RiskType).filter((risk) => !risks.map((risk2) => risk2.type).includes(risk));
2068
+ const noRisks2 = Object.values(RiskType).filter(
2069
+ (risk) => !risks.map((risk2) => risk2.type).includes(risk)
2070
+ );
2030
2071
  const mergedUnique = [.../* @__PURE__ */ new Set([...noRisks1, ...noRisks2])];
2031
2072
  return mergedUnique.map((risk) => `No ${risk}`);
2032
2073
  };
@@ -12718,6 +12759,7 @@ var vesu_pools_default = {
12718
12759
  };
12719
12760
 
12720
12761
  // src/strategies/vesu-rebalance.tsx
12762
+ import { jsx, jsxs } from "react/jsx-runtime";
12721
12763
  var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12722
12764
  // 10000 bps = 100%
12723
12765
  /**
@@ -12731,10 +12773,17 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12731
12773
  super(config);
12732
12774
  this.BASE_WEIGHT = 1e4;
12733
12775
  this.pricer = pricer;
12734
- assert(metadata.depositTokens.length === 1, "VesuRebalance only supports 1 deposit token");
12776
+ assert(
12777
+ metadata.depositTokens.length === 1,
12778
+ "VesuRebalance only supports 1 deposit token"
12779
+ );
12735
12780
  this.metadata = metadata;
12736
12781
  this.address = metadata.address;
12737
- this.contract = new Contract5(vesu_rebalance_abi_default, this.address.address, this.config.provider);
12782
+ this.contract = new Contract5(
12783
+ vesu_rebalance_abi_default,
12784
+ this.address.address,
12785
+ this.config.provider
12786
+ );
12738
12787
  }
12739
12788
  /**
12740
12789
  * Creates a deposit call to the strategy contract.
@@ -12743,10 +12792,23 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12743
12792
  * @returns Populated contract call for deposit
12744
12793
  */
12745
12794
  async depositCall(amountInfo, receiver) {
12746
- assert(amountInfo.tokenInfo.address.eq(this.asset().address), "Deposit token mismatch");
12747
- const assetContract = new Contract5(vesu_rebalance_abi_default, this.asset().address.address, this.config.provider);
12748
- const call1 = assetContract.populate("approve", [this.address.address, uint2563.bnToUint256(amountInfo.amount.toWei())]);
12749
- const call2 = this.contract.populate("deposit", [uint2563.bnToUint256(amountInfo.amount.toWei()), receiver.address]);
12795
+ assert(
12796
+ amountInfo.tokenInfo.address.eq(this.asset().address),
12797
+ "Deposit token mismatch"
12798
+ );
12799
+ const assetContract = new Contract5(
12800
+ vesu_rebalance_abi_default,
12801
+ this.asset().address.address,
12802
+ this.config.provider
12803
+ );
12804
+ const call1 = assetContract.populate("approve", [
12805
+ this.address.address,
12806
+ uint2563.bnToUint256(amountInfo.amount.toWei())
12807
+ ]);
12808
+ const call2 = this.contract.populate("deposit", [
12809
+ uint2563.bnToUint256(amountInfo.amount.toWei()),
12810
+ receiver.address
12811
+ ]);
12750
12812
  return [call1, call2];
12751
12813
  }
12752
12814
  /**
@@ -12757,7 +12819,13 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12757
12819
  * @returns Populated contract call for withdrawal
12758
12820
  */
12759
12821
  async withdrawCall(amountInfo, receiver, owner) {
12760
- return [this.contract.populate("withdraw", [uint2563.bnToUint256(amountInfo.amount.toWei()), receiver.address, owner.address])];
12822
+ return [
12823
+ this.contract.populate("withdraw", [
12824
+ uint2563.bnToUint256(amountInfo.amount.toWei()),
12825
+ receiver.address,
12826
+ owner.address
12827
+ ])
12828
+ ];
12761
12829
  }
12762
12830
  /**
12763
12831
  * Returns the underlying asset token of the strategy.
@@ -12780,9 +12848,16 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12780
12848
  */
12781
12849
  async getUserTVL(user) {
12782
12850
  const shares = await this.contract.balanceOf(user.address);
12783
- const assets = await this.contract.convert_to_assets(uint2563.bnToUint256(shares));
12784
- const amount = Web3Number.fromWei(assets.toString(), this.metadata.depositTokens[0].decimals);
12785
- let price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
12851
+ const assets = await this.contract.convert_to_assets(
12852
+ uint2563.bnToUint256(shares)
12853
+ );
12854
+ const amount = Web3Number.fromWei(
12855
+ assets.toString(),
12856
+ this.metadata.depositTokens[0].decimals
12857
+ );
12858
+ let price = await this.pricer.getPrice(
12859
+ this.metadata.depositTokens[0].symbol
12860
+ );
12786
12861
  const usdValue = Number(amount.toFixed(6)) * price.price;
12787
12862
  return {
12788
12863
  tokenInfo: this.asset(),
@@ -12796,8 +12871,13 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12796
12871
  */
12797
12872
  async getTVL() {
12798
12873
  const assets = await this.contract.total_assets();
12799
- const amount = Web3Number.fromWei(assets.toString(), this.metadata.depositTokens[0].decimals);
12800
- let price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
12874
+ const amount = Web3Number.fromWei(
12875
+ assets.toString(),
12876
+ this.metadata.depositTokens[0].decimals
12877
+ );
12878
+ let price = await this.pricer.getPrice(
12879
+ this.metadata.depositTokens[0].symbol
12880
+ );
12801
12881
  const usdValue = Number(amount.toFixed(6)) * price.price;
12802
12882
  return {
12803
12883
  tokenInfo: this.asset(),
@@ -12823,51 +12903,104 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12823
12903
  return pools;
12824
12904
  }
12825
12905
  async getPoolInfo(p, pools, vesuPositions, totalAssets, isErrorPositionsAPI, isErrorPoolsAPI) {
12826
- const vesuPosition = vesuPositions.find((d) => d.pool.id.toString() === num3.getDecimalString(p.pool_id.address.toString()));
12906
+ const vesuPosition = vesuPositions.find(
12907
+ (d) => d.pool.id.toString() === num3.getDecimalString(p.pool_id.address.toString())
12908
+ );
12827
12909
  const _pool = pools.find((d) => {
12828
- logger.verbose(`pool check: ${d.id == num3.getDecimalString(p.pool_id.address.toString())}, id: ${d.id}, pool_id: ${num3.getDecimalString(p.pool_id.address.toString())}`);
12910
+ logger.verbose(
12911
+ `pool check: ${d.id == num3.getDecimalString(p.pool_id.address.toString())}, id: ${d.id}, pool_id: ${num3.getDecimalString(
12912
+ p.pool_id.address.toString()
12913
+ )}`
12914
+ );
12829
12915
  return d.id == num3.getDecimalString(p.pool_id.address.toString());
12830
12916
  });
12831
12917
  logger.verbose(`pool: ${JSON.stringify(_pool)}`);
12832
12918
  logger.verbose(typeof _pool);
12833
12919
  logger.verbose(`name: ${_pool?.name}`);
12834
12920
  const name = _pool?.name;
12835
- logger.verbose(`name2: ${name}, ${!name ? true : false}, ${name?.length}, ${typeof name}`);
12836
- const assetInfo = _pool?.assets.find((d) => this.asset().address.eqString(d.address));
12921
+ logger.verbose(
12922
+ `name2: ${name}, ${!name ? true : false}, ${name?.length}, ${typeof name}`
12923
+ );
12924
+ const assetInfo = _pool?.assets.find(
12925
+ (d) => this.asset().address.eqString(d.address)
12926
+ );
12837
12927
  if (!name) {
12838
12928
  logger.verbose(`Pool not found`);
12839
12929
  throw new Error(`Pool name ${p.pool_id.address.toString()} not found`);
12840
12930
  }
12841
12931
  if (!assetInfo) {
12842
- throw new Error(`Asset ${this.asset().address.toString()} not found in pool ${p.pool_id.address.toString()}`);
12932
+ throw new Error(
12933
+ `Asset ${this.asset().address.toString()} not found in pool ${p.pool_id.address.toString()}`
12934
+ );
12843
12935
  }
12844
- let vTokenContract = new Contract5(vesu_rebalance_abi_default, p.v_token.address, this.config.provider);
12936
+ let vTokenContract = new Contract5(
12937
+ vesu_rebalance_abi_default,
12938
+ p.v_token.address,
12939
+ this.config.provider
12940
+ );
12845
12941
  const bal = await vTokenContract.balanceOf(this.address.address);
12846
- const assets = await vTokenContract.convert_to_assets(uint2563.bnToUint256(bal.toString()));
12942
+ const assets = await vTokenContract.convert_to_assets(
12943
+ uint2563.bnToUint256(bal.toString())
12944
+ );
12847
12945
  logger.verbose(`Collateral: ${JSON.stringify(vesuPosition?.collateral)}`);
12848
12946
  logger.verbose(`supplyApy: ${JSON.stringify(assetInfo?.stats.supplyApy)}`);
12849
- logger.verbose(`defiSpringSupplyApr: ${JSON.stringify(assetInfo?.stats.defiSpringSupplyApr)}`);
12850
- logger.verbose(`currentUtilization: ${JSON.stringify(assetInfo?.stats.currentUtilization)}`);
12851
- logger.verbose(`maxUtilization: ${JSON.stringify(assetInfo?.config.maxUtilization)}`);
12947
+ logger.verbose(
12948
+ `defiSpringSupplyApr: ${JSON.stringify(
12949
+ assetInfo?.stats.defiSpringSupplyApr
12950
+ )}`
12951
+ );
12952
+ logger.verbose(
12953
+ `currentUtilization: ${JSON.stringify(
12954
+ assetInfo?.stats.currentUtilization
12955
+ )}`
12956
+ );
12957
+ logger.verbose(
12958
+ `maxUtilization: ${JSON.stringify(assetInfo?.config.maxUtilization)}`
12959
+ );
12852
12960
  const item = {
12853
12961
  pool_id: p.pool_id,
12854
12962
  pool_name: _pool?.name,
12855
12963
  max_weight: p.max_weight,
12856
- current_weight: isErrorPositionsAPI || !vesuPosition ? 0 : Number(Web3Number.fromWei(vesuPosition.collateral.value, this.decimals()).dividedBy(totalAssets.toString()).toFixed(6)),
12964
+ current_weight: isErrorPositionsAPI || !vesuPosition ? 0 : Number(
12965
+ Web3Number.fromWei(vesuPosition.collateral.value, this.decimals()).dividedBy(totalAssets.toString()).toFixed(6)
12966
+ ),
12857
12967
  v_token: p.v_token,
12858
12968
  amount: Web3Number.fromWei(assets.toString(), this.decimals()),
12859
- usdValue: isErrorPositionsAPI || !vesuPosition ? Web3Number.fromWei("0", this.decimals()) : Web3Number.fromWei(vesuPosition.collateral.usdPrice.value, vesuPosition.collateral.usdPrice.decimals),
12969
+ usdValue: isErrorPositionsAPI || !vesuPosition ? Web3Number.fromWei("0", this.decimals()) : Web3Number.fromWei(
12970
+ vesuPosition.collateral.usdPrice.value,
12971
+ vesuPosition.collateral.usdPrice.decimals
12972
+ ),
12860
12973
  APY: isErrorPoolsAPI || !assetInfo ? {
12861
12974
  baseApy: 0,
12862
12975
  defiSpringApy: 0,
12863
12976
  netApy: 0
12864
12977
  } : {
12865
- baseApy: Number(Web3Number.fromWei(assetInfo.stats.supplyApy.value, assetInfo.stats.supplyApy.decimals).toFixed(6)),
12866
- defiSpringApy: assetInfo.stats.defiSpringSupplyApr ? Number(Web3Number.fromWei(assetInfo.stats.defiSpringSupplyApr.value, assetInfo.stats.defiSpringSupplyApr.decimals).toFixed(6)) : 0,
12978
+ baseApy: Number(
12979
+ Web3Number.fromWei(
12980
+ assetInfo.stats.supplyApy.value,
12981
+ assetInfo.stats.supplyApy.decimals
12982
+ ).toFixed(6)
12983
+ ),
12984
+ defiSpringApy: assetInfo.stats.defiSpringSupplyApr ? Number(
12985
+ Web3Number.fromWei(
12986
+ assetInfo.stats.defiSpringSupplyApr.value,
12987
+ assetInfo.stats.defiSpringSupplyApr.decimals
12988
+ ).toFixed(6)
12989
+ ) : 0,
12867
12990
  netApy: 0
12868
12991
  },
12869
- currentUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(Web3Number.fromWei(assetInfo.stats.currentUtilization.value, assetInfo.stats.currentUtilization.decimals).toFixed(6)),
12870
- maxUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(Web3Number.fromWei(assetInfo.config.maxUtilization.value, assetInfo.config.maxUtilization.decimals).toFixed(6))
12992
+ currentUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(
12993
+ Web3Number.fromWei(
12994
+ assetInfo.stats.currentUtilization.value,
12995
+ assetInfo.stats.currentUtilization.decimals
12996
+ ).toFixed(6)
12997
+ ),
12998
+ maxUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(
12999
+ Web3Number.fromWei(
13000
+ assetInfo.config.maxUtilization.value,
13001
+ assetInfo.config.maxUtilization.decimals
13002
+ ).toFixed(6)
13003
+ )
12871
13004
  };
12872
13005
  item.APY.netApy = item.APY.baseApy + item.APY.defiSpringApy;
12873
13006
  return item;
@@ -12877,7 +13010,7 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12877
13010
  * 1. Contract's allowed pools
12878
13011
  * 2. Vesu positions API for current positions
12879
13012
  * 3. Vesu pools API for APY and utilization data
12880
- *
13013
+ *
12881
13014
  * @returns {Promise<{
12882
13015
  * data: Array<PoolInfoFull>,
12883
13016
  * isErrorPositionsAPI: boolean
@@ -12894,15 +13027,29 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12894
13027
  let isErrorPositionsAPI = false;
12895
13028
  let vesuPositions = [];
12896
13029
  try {
12897
- const data2 = await getAPIUsingHeadlessBrowser(`https://api.vesu.xyz/positions?walletAddress=${this.address.address}`);
13030
+ const data2 = await getAPIUsingHeadlessBrowser(
13031
+ `https://api.vesu.xyz/positions?walletAddress=${this.address.address}`
13032
+ );
12898
13033
  vesuPositions = data2.data;
12899
13034
  } catch (e) {
12900
- console.error(`${_VesuRebalance.name}: Error fetching positions for ${this.address.address}`, e);
13035
+ console.error(
13036
+ `${_VesuRebalance.name}: Error fetching positions for ${this.address.address}`,
13037
+ e
13038
+ );
12901
13039
  isErrorPositionsAPI = true;
12902
13040
  }
12903
13041
  let { pools, isErrorPoolsAPI } = await this.getVesuPools();
12904
13042
  const totalAssets = (await this.getTVL()).amount;
12905
- const info = allowedPools.map((p) => this.getPoolInfo(p, pools, vesuPositions, totalAssets, isErrorPositionsAPI, isErrorPoolsAPI));
13043
+ const info = allowedPools.map(
13044
+ (p) => this.getPoolInfo(
13045
+ p,
13046
+ pools,
13047
+ vesuPositions,
13048
+ totalAssets,
13049
+ isErrorPositionsAPI,
13050
+ isErrorPoolsAPI
13051
+ )
13052
+ );
12906
13053
  const data = await Promise.all(info);
12907
13054
  return {
12908
13055
  data,
@@ -12915,18 +13062,25 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12915
13062
  let isErrorPoolsAPI = false;
12916
13063
  let pools = [];
12917
13064
  try {
12918
- const data = await getAPIUsingHeadlessBrowser("https://api.vesu.xyz/pools");
13065
+ const data = await getAPIUsingHeadlessBrowser(
13066
+ "https://api.vesu.xyz/pools"
13067
+ );
12919
13068
  pools = data.data;
12920
13069
  for (const pool of vesu_pools_default.data) {
12921
13070
  const found = pools.find((d) => d.id === pool.id);
12922
13071
  if (!found) {
12923
13072
  logger.verbose(`VesuRebalance: pools: ${JSON.stringify(pools)}`);
12924
- logger.verbose(`VesuRebalance: Pool ${pool.id} not found in Vesu API, using hardcoded data`);
13073
+ logger.verbose(
13074
+ `VesuRebalance: Pool ${pool.id} not found in Vesu API, using hardcoded data`
13075
+ );
12925
13076
  throw new Error("pool not found [sanity check]");
12926
13077
  }
12927
13078
  }
12928
13079
  } catch (e) {
12929
- logger.error(`${_VesuRebalance.name}: Error fetching pools for ${this.address.address}, retry ${retry}`, e);
13080
+ logger.error(
13081
+ `${_VesuRebalance.name}: Error fetching pools for ${this.address.address}, retry ${retry}`,
13082
+ e
13083
+ );
12930
13084
  isErrorPoolsAPI = true;
12931
13085
  if (retry < 10) {
12932
13086
  await new Promise((resolve) => setTimeout(resolve, 5e3 * (retry + 1)));
@@ -12964,8 +13118,8 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12964
13118
  * 3. For each pool that needs more funds:
12965
13119
  * - Takes funds from lowest APY pools that are over their target
12966
13120
  * 4. Validates that total assets remain constant
12967
- *
12968
- * @returns {Promise<{
13121
+ *
13122
+ * @returns {Promise<{
12969
13123
  * changes: Change[],
12970
13124
  * finalPools: PoolInfoFull[],
12971
13125
  * isAnyPoolOverMaxWeight: boolean
@@ -12981,27 +13135,38 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12981
13135
  _pools = _pools2;
12982
13136
  }
12983
13137
  const feeDeductions = await this.getFee(_pools);
12984
- logger.verbose(`VesuRebalance: feeDeductions: ${JSON.stringify(feeDeductions)}`);
13138
+ logger.verbose(
13139
+ `VesuRebalance: feeDeductions: ${JSON.stringify(feeDeductions)}`
13140
+ );
12985
13141
  const pools = _pools.map((p) => {
12986
13142
  const fee = feeDeductions.find((f) => p.v_token.eq(f.vToken))?.fee || Web3Number.fromWei("0", this.decimals());
12987
- logger.verbose(`FeeAdjustment: ${p.pool_id} => ${fee.toString()}, amt: ${p.amount.toString()}`);
13143
+ logger.verbose(
13144
+ `FeeAdjustment: ${p.pool_id} => ${fee.toString()}, amt: ${p.amount.toString()}`
13145
+ );
12988
13146
  return {
12989
13147
  ...p,
12990
13148
  amount: p.amount.minus(fee)
12991
13149
  };
12992
13150
  });
12993
13151
  let totalAssets = (await this.getTVL()).amount;
12994
- if (totalAssets.eq(0)) return {
12995
- changes: [],
12996
- finalPools: []
12997
- };
13152
+ if (totalAssets.eq(0))
13153
+ return {
13154
+ changes: [],
13155
+ finalPools: []
13156
+ };
12998
13157
  feeDeductions.forEach((f) => {
12999
13158
  totalAssets = totalAssets.minus(f.fee);
13000
13159
  });
13001
- const sumPools = pools.reduce((acc, curr) => acc.plus(curr.amount.toString()), Web3Number.fromWei("0", this.decimals()));
13160
+ const sumPools = pools.reduce(
13161
+ (acc, curr) => acc.plus(curr.amount.toString()),
13162
+ Web3Number.fromWei("0", this.decimals())
13163
+ );
13002
13164
  logger.verbose(`Sum of pools: ${sumPools.toString()}`);
13003
13165
  logger.verbose(`Total assets: ${totalAssets.toString()}`);
13004
- assert(sumPools.lte(totalAssets.multipliedBy(1.00001).toString()), "Sum of pools.amount must be less than or equal to totalAssets");
13166
+ assert(
13167
+ sumPools.lte(totalAssets.multipliedBy(1.00001).toString()),
13168
+ "Sum of pools.amount must be less than or equal to totalAssets"
13169
+ );
13005
13170
  const sortedPools = [...pools].sort((a, b) => b.APY.netApy - a.APY.netApy);
13006
13171
  const targetAmounts = {};
13007
13172
  let remainingAssets = totalAssets;
@@ -13023,7 +13188,10 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13023
13188
  assert(remainingAssets.lt(1e-5), "Remaining assets must be 0");
13024
13189
  const changes = sortedPools.map((pool) => {
13025
13190
  const target = targetAmounts[pool.pool_id.address.toString()] || Web3Number.fromWei("0", this.decimals());
13026
- const change = Web3Number.fromWei(target.minus(pool.amount.toString()).toWei(), this.decimals());
13191
+ const change = Web3Number.fromWei(
13192
+ target.minus(pool.amount.toString()).toWei(),
13193
+ this.decimals()
13194
+ );
13027
13195
  return {
13028
13196
  pool_id: pool.pool_id,
13029
13197
  changeAmt: change,
@@ -13032,14 +13200,21 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13032
13200
  };
13033
13201
  });
13034
13202
  logger.verbose(`Changes: ${JSON.stringify(changes)}`);
13035
- const sumChanges = changes.reduce((sum, c) => sum.plus(c.changeAmt.toString()), Web3Number.fromWei("0", this.decimals()));
13036
- const sumFinal = changes.reduce((sum, c) => sum.plus(c.finalAmt.toString()), Web3Number.fromWei("0", this.decimals()));
13203
+ const sumChanges = changes.reduce(
13204
+ (sum, c) => sum.plus(c.changeAmt.toString()),
13205
+ Web3Number.fromWei("0", this.decimals())
13206
+ );
13207
+ const sumFinal = changes.reduce(
13208
+ (sum, c) => sum.plus(c.finalAmt.toString()),
13209
+ Web3Number.fromWei("0", this.decimals())
13210
+ );
13037
13211
  const hasChanges = changes.some((c) => !c.changeAmt.eq(0));
13038
13212
  logger.verbose(`Sum of changes: ${sumChanges.toString()}`);
13039
13213
  if (!sumChanges.eq(0)) throw new Error("Sum of changes must be zero");
13040
13214
  logger.verbose(`Sum of final: ${sumFinal.toString()}`);
13041
13215
  logger.verbose(`Total assets: ${totalAssets.toString()}`);
13042
- if (!sumFinal.eq(totalAssets.toString())) throw new Error("Sum of final amounts must equal total assets");
13216
+ if (!sumFinal.eq(totalAssets.toString()))
13217
+ throw new Error("Sum of final amounts must equal total assets");
13043
13218
  if (!hasChanges) throw new Error("No changes required");
13044
13219
  const finalPools = pools.map((p) => {
13045
13220
  const target = targetAmounts[p.pool_id.address.toString()] || Web3Number.fromWei("0", this.decimals());
@@ -13067,9 +13242,13 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13067
13242
  if (p.changeAmt.eq(0)) return null;
13068
13243
  actions.push({
13069
13244
  pool_id: p.pool_id.address,
13070
- feature: new CairoCustomEnum(p.isDeposit ? { DEPOSIT: {} } : { WITHDRAW: {} }),
13245
+ feature: new CairoCustomEnum(
13246
+ p.isDeposit ? { DEPOSIT: {} } : { WITHDRAW: {} }
13247
+ ),
13071
13248
  token: this.asset().address.address,
13072
- amount: uint2563.bnToUint256(p.changeAmt.multipliedBy(p.isDeposit ? 1 : -1).toWei())
13249
+ amount: uint2563.bnToUint256(
13250
+ p.changeAmt.multipliedBy(p.isDeposit ? 1 : -1).toWei()
13251
+ )
13073
13252
  });
13074
13253
  });
13075
13254
  if (actions.length === 0) return null;
@@ -13082,18 +13261,29 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13082
13261
  const netYield = await this.netAPYGivenPools(pools);
13083
13262
  const baseFlow = {
13084
13263
  title: "Your Deposit",
13085
- subItems: [{ key: `Net yield`, value: `${(netYield * 100).toFixed(2)}%` }, { key: `Performance Fee`, value: `${(this.metadata.additionalInfo.feeBps / 100).toFixed(2)}%` }],
13264
+ subItems: [
13265
+ { key: `Net yield`, value: `${(netYield * 100).toFixed(2)}%` },
13266
+ {
13267
+ key: `Performance Fee`,
13268
+ value: `${(this.metadata.additionalInfo.feeBps / 100).toFixed(2)}%`
13269
+ }
13270
+ ],
13086
13271
  linkedFlows: [],
13087
13272
  style: { backgroundColor: "#6e53dc" /* Purple */.valueOf() }
13088
13273
  };
13089
13274
  let _pools = [...pools];
13090
- _pools = _pools.sort((a, b) => Number(b.amount.toString()) - Number(a.amount.toString()));
13275
+ _pools = _pools.sort(
13276
+ (a, b) => Number(b.amount.toString()) - Number(a.amount.toString())
13277
+ );
13091
13278
  _pools.forEach((p) => {
13092
13279
  const flow = {
13093
13280
  title: `Pool name: ${p.pool_name}`,
13094
13281
  subItems: [
13095
13282
  { key: `APY`, value: `${(p.APY.netApy * 100).toFixed(2)}%` },
13096
- { key: "Weight", value: `${(p.current_weight * 100).toFixed(2)} / ${(p.max_weight * 100).toFixed(2)}%` }
13283
+ {
13284
+ key: "Weight",
13285
+ value: `${(p.current_weight * 100).toFixed(2)} / ${(p.max_weight * 100).toFixed(2)}%`
13286
+ }
13097
13287
  ],
13098
13288
  linkedFlows: [],
13099
13289
  style: p.amount.greaterThan(0) ? { backgroundColor: "#35484f" /* Blue */.valueOf() } : { color: "gray" }
@@ -13125,7 +13315,12 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13125
13315
  harvest.actualReward.toWei(),
13126
13316
  this.address.address
13127
13317
  );
13128
- swapInfo = await avnu.getSwapInfo(quote, this.address.address, 0, this.address.address);
13318
+ swapInfo = await avnu.getSwapInfo(
13319
+ quote,
13320
+ this.address.address,
13321
+ 0,
13322
+ this.address.address
13323
+ );
13129
13324
  }
13130
13325
  return [
13131
13326
  this.contract.populate("harvest", [
@@ -13146,16 +13341,27 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13146
13341
  * @returns {Promise<Array<{ vToken: ContractAddr, fee: Web3Number }>>} Array of fees deducted in different vTokens
13147
13342
  */
13148
13343
  async getFee(allowedPools) {
13149
- const assets = Web3Number.fromWei((await this.contract.total_assets()).toString(), this.asset().decimals);
13150
- const totalSupply = Web3Number.fromWei((await this.contract.total_supply()).toString(), this.asset().decimals);
13151
- const prevIndex = Web3Number.fromWei((await this.contract.get_previous_index()).toString(), 18);
13344
+ const assets = Web3Number.fromWei(
13345
+ (await this.contract.total_assets()).toString(),
13346
+ this.asset().decimals
13347
+ );
13348
+ const totalSupply = Web3Number.fromWei(
13349
+ (await this.contract.total_supply()).toString(),
13350
+ this.asset().decimals
13351
+ );
13352
+ const prevIndex = Web3Number.fromWei(
13353
+ (await this.contract.get_previous_index()).toString(),
13354
+ 18
13355
+ );
13152
13356
  const currIndex = new Web3Number(1, 18).multipliedBy(assets).dividedBy(totalSupply);
13153
13357
  logger.verbose(`Previous index: ${prevIndex.toString()}`);
13154
13358
  logger.verbose(`Assets: ${assets.toString()}`);
13155
13359
  logger.verbose(`Total supply: ${totalSupply.toString()}`);
13156
13360
  logger.verbose(`Current index: ${currIndex.toNumber()}`);
13157
13361
  if (currIndex.lt(prevIndex)) {
13158
- logger.verbose(`getFee::Current index is less than previous index, no fees to be deducted`);
13362
+ logger.verbose(
13363
+ `getFee::Current index is less than previous index, no fees to be deducted`
13364
+ );
13159
13365
  return [];
13160
13366
  }
13161
13367
  const indexDiff = currIndex.minus(prevIndex);
@@ -13168,7 +13374,9 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13168
13374
  return [];
13169
13375
  }
13170
13376
  const fees = [];
13171
- let remainingFee = fee.plus(Web3Number.fromWei("100", this.asset().decimals));
13377
+ let remainingFee = fee.plus(
13378
+ Web3Number.fromWei("100", this.asset().decimals)
13379
+ );
13172
13380
  for (const pool of allowedPools) {
13173
13381
  const vToken = pool.v_token;
13174
13382
  const balance = pool.amount;
@@ -13177,7 +13385,9 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13177
13385
  break;
13178
13386
  } else {
13179
13387
  fees.push({ vToken, fee: Web3Number.fromWei(balance.toString(), 18) });
13180
- remainingFee = remainingFee.minus(Web3Number.fromWei(balance.toString(), 18));
13388
+ remainingFee = remainingFee.minus(
13389
+ Web3Number.fromWei(balance.toString(), 18)
13390
+ );
13181
13391
  }
13182
13392
  }
13183
13393
  logger.verbose(`Fees: ${JSON.stringify(fees)}`);
@@ -13185,101 +13395,179 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13185
13395
  }
13186
13396
  };
13187
13397
  var _description = "Automatically diversify {{TOKEN}} holdings into different Vesu pools while reducing risk and maximizing yield. Defi spring STRK Rewards are auto-compounded as well.";
13188
- var _protocol = { name: "Vesu", logo: "https://static-assets-8zct.onrender.com/integrations/vesu/logo.png" };
13398
+ var _protocol = {
13399
+ name: "Vesu",
13400
+ logo: "https://static-assets-8zct.onrender.com/integrations/vesu/logo.png"
13401
+ };
13189
13402
  var _riskFactor = [
13190
13403
  { type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 0.5, weight: 25 },
13191
13404
  { type: "Counterparty Risk" /* COUNTERPARTY_RISK */, value: 1, weight: 50 },
13192
13405
  { type: "Oracle Risk" /* ORACLE_RISK */, value: 0.5, weight: 25 }
13193
13406
  ];
13194
13407
  var AUDIT_URL = "https://assets.strkfarm.com/strkfarm/audit_report_vesu_and_ekubo_strats.pdf";
13195
- var VesuRebalanceStrategies = [{
13196
- name: "Vesu Fusion STRK",
13197
- description: _description.replace("{{TOKEN}}", "STRK"),
13198
- address: ContractAddr.from("0x7fb5bcb8525954a60fde4e8fb8220477696ce7117ef264775a1770e23571929"),
13199
- type: "ERC4626",
13200
- depositTokens: [Global.getDefaultTokens().find((t) => t.symbol === "STRK")],
13201
- protocols: [_protocol],
13202
- auditUrl: AUDIT_URL,
13203
- maxTVL: Web3Number.fromWei("0", 18),
13204
- risk: {
13205
- riskFactor: _riskFactor,
13206
- netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13207
- notARisks: getNoRiskTags(_riskFactor)
13408
+ var faqs = [
13409
+ {
13410
+ question: "What is the Vesu Rebalancing Strategy?",
13411
+ answer: "The Vesu Rebalancing Strategy is an automated investment strategy that diversifies your holdings across multiple Vesu pools. It optimizes yield by rebalancing assets based on pool performance while adhering to risk constraints."
13208
13412
  },
13209
- additionalInfo: {
13210
- feeBps: 1e3
13211
- }
13212
- }, {
13213
- name: "Vesu Fusion ETH",
13214
- description: _description.replace("{{TOKEN}}", "ETH"),
13215
- address: ContractAddr.from("0x5eaf5ee75231cecf79921ff8ded4b5ffe96be718bcb3daf206690ad1a9ad0ca"),
13216
- type: "ERC4626",
13217
- auditUrl: AUDIT_URL,
13218
- depositTokens: [Global.getDefaultTokens().find((t) => t.symbol === "ETH")],
13219
- protocols: [_protocol],
13220
- maxTVL: Web3Number.fromWei("0", 18),
13221
- risk: {
13222
- riskFactor: _riskFactor,
13223
- netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13224
- notARisks: getNoRiskTags(_riskFactor)
13413
+ {
13414
+ question: "Will I earn Vesu points?",
13415
+ answer: "Yes, of course! You will earn Vesu points for your deposits."
13225
13416
  },
13226
- additionalInfo: {
13227
- feeBps: 1e3
13228
- }
13229
- }, {
13230
- name: "Vesu Fusion USDC",
13231
- description: _description.replace("{{TOKEN}}", "USDC"),
13232
- address: ContractAddr.from("0xa858c97e9454f407d1bd7c57472fc8d8d8449a777c822b41d18e387816f29c"),
13233
- type: "ERC4626",
13234
- auditUrl: AUDIT_URL,
13235
- depositTokens: [Global.getDefaultTokens().find((t) => t.symbol === "USDC")],
13236
- protocols: [_protocol],
13237
- maxTVL: Web3Number.fromWei("0", 6),
13238
- risk: {
13239
- riskFactor: _riskFactor,
13240
- netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13241
- notARisks: getNoRiskTags(_riskFactor)
13417
+ {
13418
+ question: "How does the strategy optimize yield?",
13419
+ answer: "The strategy calculates the weighted average APY across all pools and reallocates assets to maximize returns. It prioritizes high-performing pools while ensuring compliance with maximum weight constraints."
13420
+ },
13421
+ {
13422
+ question: "What are the risks associated with this strategy?",
13423
+ answer: "The strategy involves usual DeFi risks such as smart contract vulnerabilities, counterparty risks, and oracle inaccuracies. However, we try our best to reduce these risks through audits and careful pool selection."
13242
13424
  },
13243
- additionalInfo: {
13244
- feeBps: 1e3
13425
+ {
13426
+ question: "How are fees calculated and deducted?",
13427
+ answer: "Fees are calculated based on the performance of the strategy and deducted proportionally from the total assets. We charge a 10% performance fee and is already accounted in the APY shown."
13428
+ },
13429
+ {
13430
+ question: "What happens if a pool exceeds its maximum weight?",
13431
+ answer: "If a pool exceeds its maximum weight, the strategy rebalances by withdrawing excess funds and reallocating them to other pools with available capacity."
13432
+ },
13433
+ {
13434
+ question: "Can I withdraw my assets at any time?",
13435
+ answer: "Yes, you can withdraw your assets at any time. In rare circumstances, if debt utilisation is high for certain pools on Vesu, it may not be possible to withdraw until markets restore balance."
13436
+ },
13437
+ {
13438
+ question: "What happens to my Defi Spring STRK rewards?",
13439
+ answer: "STRK rewards are automatically harvested and reinvested into the strategy every week to maximize compounding returns."
13440
+ },
13441
+ {
13442
+ question: "Is the strategy audited?",
13443
+ answer: /* @__PURE__ */ jsxs("div", { children: [
13444
+ "Yes, the strategy has been audited. You can review the audit report in our docs ",
13445
+ /* @__PURE__ */ jsx("a", { href: "https://docs.strkfarm.com/p/strategies/vesu-fusion-rebalancing-vaults#technical-details", style: { textDecoration: "underline", marginLeft: "5px" }, children: "Here" }),
13446
+ "."
13447
+ ] })
13245
13448
  }
13246
- }, {
13247
- name: "Vesu Fusion USDT",
13248
- description: _description.replace("{{TOKEN}}", "USDT"),
13249
- address: ContractAddr.from("0x115e94e722cfc4c77a2f15c4aefb0928c1c0029e5a57570df24c650cb7cec2c"),
13250
- type: "ERC4626",
13251
- depositTokens: [Global.getDefaultTokens().find((t) => t.symbol === "USDT")],
13252
- auditUrl: AUDIT_URL,
13253
- protocols: [_protocol],
13254
- maxTVL: Web3Number.fromWei("0", 6),
13255
- risk: {
13256
- riskFactor: _riskFactor,
13257
- netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13258
- notARisks: getNoRiskTags(_riskFactor)
13449
+ ];
13450
+ var VesuRebalanceStrategies = [
13451
+ {
13452
+ name: "Vesu Fusion STRK",
13453
+ description: _description.replace("{{TOKEN}}", "STRK"),
13454
+ address: ContractAddr.from(
13455
+ "0x7fb5bcb8525954a60fde4e8fb8220477696ce7117ef264775a1770e23571929"
13456
+ ),
13457
+ launchBlock: 0,
13458
+ type: "ERC4626",
13459
+ depositTokens: [
13460
+ Global.getDefaultTokens().find((t) => t.symbol === "STRK")
13461
+ ],
13462
+ protocols: [_protocol],
13463
+ auditUrl: AUDIT_URL,
13464
+ maxTVL: Web3Number.fromWei("0", 18),
13465
+ risk: {
13466
+ riskFactor: _riskFactor,
13467
+ netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13468
+ notARisks: getNoRiskTags(_riskFactor)
13469
+ },
13470
+ additionalInfo: {
13471
+ feeBps: 1e3
13472
+ },
13473
+ faqs
13474
+ },
13475
+ {
13476
+ name: "Vesu Fusion ETH",
13477
+ description: _description.replace("{{TOKEN}}", "ETH"),
13478
+ address: ContractAddr.from(
13479
+ "0x5eaf5ee75231cecf79921ff8ded4b5ffe96be718bcb3daf206690ad1a9ad0ca"
13480
+ ),
13481
+ launchBlock: 0,
13482
+ type: "ERC4626",
13483
+ auditUrl: AUDIT_URL,
13484
+ depositTokens: [
13485
+ Global.getDefaultTokens().find((t) => t.symbol === "ETH")
13486
+ ],
13487
+ protocols: [_protocol],
13488
+ maxTVL: Web3Number.fromWei("0", 18),
13489
+ risk: {
13490
+ riskFactor: _riskFactor,
13491
+ netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13492
+ notARisks: getNoRiskTags(_riskFactor)
13493
+ },
13494
+ additionalInfo: {
13495
+ feeBps: 1e3
13496
+ },
13497
+ faqs
13259
13498
  },
13260
- additionalInfo: {
13261
- feeBps: 1e3
13499
+ {
13500
+ name: "Vesu Fusion USDC",
13501
+ description: _description.replace("{{TOKEN}}", "USDC"),
13502
+ address: ContractAddr.from(
13503
+ "0xa858c97e9454f407d1bd7c57472fc8d8d8449a777c822b41d18e387816f29c"
13504
+ ),
13505
+ launchBlock: 0,
13506
+ type: "ERC4626",
13507
+ auditUrl: AUDIT_URL,
13508
+ depositTokens: [
13509
+ Global.getDefaultTokens().find((t) => t.symbol === "USDC")
13510
+ ],
13511
+ protocols: [_protocol],
13512
+ maxTVL: Web3Number.fromWei("0", 6),
13513
+ risk: {
13514
+ riskFactor: _riskFactor,
13515
+ netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13516
+ notARisks: getNoRiskTags(_riskFactor)
13517
+ },
13518
+ additionalInfo: {
13519
+ feeBps: 1e3
13520
+ },
13521
+ faqs
13522
+ },
13523
+ {
13524
+ name: "Vesu Fusion USDT",
13525
+ description: _description.replace("{{TOKEN}}", "USDT"),
13526
+ address: ContractAddr.from(
13527
+ "0x115e94e722cfc4c77a2f15c4aefb0928c1c0029e5a57570df24c650cb7cec2c"
13528
+ ),
13529
+ launchBlock: 0,
13530
+ type: "ERC4626",
13531
+ depositTokens: [
13532
+ Global.getDefaultTokens().find((t) => t.symbol === "USDT")
13533
+ ],
13534
+ auditUrl: AUDIT_URL,
13535
+ protocols: [_protocol],
13536
+ maxTVL: Web3Number.fromWei("0", 6),
13537
+ risk: {
13538
+ riskFactor: _riskFactor,
13539
+ netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13540
+ notARisks: getNoRiskTags(_riskFactor)
13541
+ },
13542
+ additionalInfo: {
13543
+ feeBps: 1e3
13544
+ },
13545
+ faqs
13546
+ // }, {
13547
+ // name: 'Vesu Fusion WBTC',
13548
+ // description: _description.replace('{{TOKEN}}', 'WBTC'),
13549
+ // address: ContractAddr.from('0x778007f8136a5b827325d21613803e796bda4d676fbe1e34aeab0b2a2ec027f'),
13550
+ // type: 'ERC4626',
13551
+ // depositTokens: [Global.getDefaultTokens().find(t => t.symbol === 'WBTC')!],
13552
+ // auditUrl: AUDIT_URL,
13553
+ // protocols: [_protocol],
13554
+ // maxTVL: Web3Number.fromWei('0', 8),
13555
+ // risk: {
13556
+ // riskFactor: _riskFactor,
13557
+ // netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13558
+ // },
13559
+ // additionalInfo: {
13560
+ // feeBps: 1000,
13561
+ // },
13262
13562
  }
13263
- // }, {
13264
- // name: 'Vesu Fusion WBTC',
13265
- // description: _description.replace('{{TOKEN}}', 'WBTC'),
13266
- // address: ContractAddr.from('0x778007f8136a5b827325d21613803e796bda4d676fbe1e34aeab0b2a2ec027f'),
13267
- // type: 'ERC4626',
13268
- // depositTokens: [Global.getDefaultTokens().find(t => t.symbol === 'WBTC')!],
13269
- // auditUrl: AUDIT_URL,
13270
- // protocols: [_protocol],
13271
- // maxTVL: Web3Number.fromWei('0', 8),
13272
- // risk: {
13273
- // riskFactor: _riskFactor,
13274
- // netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13275
- // },
13276
- // additionalInfo: {
13277
- // feeBps: 1000,
13278
- // },
13279
- }];
13563
+ ];
13280
13564
 
13281
13565
  // src/strategies/ekubo-cl-vault.tsx
13282
- import { Contract as Contract6, num as num4, uint256 as uint2564 } from "starknet";
13566
+ import {
13567
+ Contract as Contract6,
13568
+ num as num4,
13569
+ uint256 as uint2564
13570
+ } from "starknet";
13283
13571
 
13284
13572
  // src/data/cl-vault.abi.json
13285
13573
  var cl_vault_abi_default = [
@@ -18181,7 +18469,7 @@ var erc4626_abi_default = [
18181
18469
  ];
18182
18470
 
18183
18471
  // src/strategies/ekubo-cl-vault.tsx
18184
- import { jsx, jsxs } from "react/jsx-runtime";
18472
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
18185
18473
  var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18186
18474
  /**
18187
18475
  * Creates a new VesuRebalance strategy instance.
@@ -18194,15 +18482,38 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18194
18482
  super(config);
18195
18483
  this.BASE_WEIGHT = 1e4;
18196
18484
  this.pricer = pricer;
18197
- assert(metadata.depositTokens.length === 2, "EkuboCL only supports 2 deposit token");
18485
+ assert(
18486
+ metadata.depositTokens.length === 2,
18487
+ "EkuboCL only supports 2 deposit token"
18488
+ );
18198
18489
  this.metadata = metadata;
18199
18490
  this.address = metadata.address;
18200
- this.contract = new Contract6(cl_vault_abi_default, this.address.address, this.config.provider);
18201
- this.lstContract = new Contract6(erc4626_abi_default, this.metadata.additionalInfo.lstContract.address, this.config.provider);
18491
+ this.contract = new Contract6(
18492
+ cl_vault_abi_default,
18493
+ this.address.address,
18494
+ this.config.provider
18495
+ );
18496
+ if (this.metadata.additionalInfo.lstContract) {
18497
+ this.lstContract = new Contract6(
18498
+ erc4626_abi_default,
18499
+ this.metadata.additionalInfo.lstContract.address,
18500
+ this.config.provider
18501
+ );
18502
+ } else {
18503
+ this.lstContract = null;
18504
+ }
18202
18505
  const EKUBO_POSITION = "0x02e0af29598b407c8716b17f6d2795eca1b471413fa03fb145a5e33722184067";
18203
- this.ekuboPositionsContract = new Contract6(ekubo_positions_abi_default, EKUBO_POSITION, this.config.provider);
18506
+ this.ekuboPositionsContract = new Contract6(
18507
+ ekubo_positions_abi_default,
18508
+ EKUBO_POSITION,
18509
+ this.config.provider
18510
+ );
18204
18511
  const EKUBO_MATH = "0x04a72e9e166f6c0e9d800af4dc40f6b6fb4404b735d3f528d9250808b2481995";
18205
- this.ekuboMathContract = new Contract6(ekubo_math_abi_default, EKUBO_MATH, this.config.provider);
18512
+ this.ekuboMathContract = new Contract6(
18513
+ ekubo_math_abi_default,
18514
+ EKUBO_MATH,
18515
+ this.config.provider
18516
+ );
18206
18517
  this.avnu = new AvnuWrapper();
18207
18518
  }
18208
18519
  async matchInputAmounts(amountInfo) {
@@ -18227,25 +18538,52 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18227
18538
  /** Returns minimum amounts give given two amounts based on what can be added for liq */
18228
18539
  async getMinDepositAmounts(amountInfo) {
18229
18540
  const shares = await this.tokensToShares(amountInfo);
18230
- const { amount0, amount1 } = await this.contract.call("convert_to_assets", [uint2564.bnToUint256(shares.toWei())]);
18541
+ const { amount0, amount1 } = await this.contract.call(
18542
+ "convert_to_assets",
18543
+ [uint2564.bnToUint256(shares.toWei())]
18544
+ );
18231
18545
  return {
18232
18546
  token0: {
18233
18547
  tokenInfo: amountInfo.token0.tokenInfo,
18234
- amount: Web3Number.fromWei(amount0.toString(), amountInfo.token0.tokenInfo.decimals)
18548
+ amount: Web3Number.fromWei(
18549
+ amount0.toString(),
18550
+ amountInfo.token0.tokenInfo.decimals
18551
+ )
18235
18552
  },
18236
18553
  token1: {
18237
18554
  tokenInfo: amountInfo.token1.tokenInfo,
18238
- amount: Web3Number.fromWei(amount1.toString(), amountInfo.token1.tokenInfo.decimals)
18555
+ amount: Web3Number.fromWei(
18556
+ amount1.toString(),
18557
+ amountInfo.token1.tokenInfo.decimals
18558
+ )
18239
18559
  }
18240
18560
  };
18241
18561
  }
18242
18562
  async depositCall(amountInfo, receiver) {
18243
18563
  const updateAmountInfo = await this.getMinDepositAmounts(amountInfo);
18244
- const token0Contract = new Contract6(erc4626_abi_default, amountInfo.token0.tokenInfo.address.address, this.config.provider);
18245
- const token1Contract = new Contract6(erc4626_abi_default, amountInfo.token1.tokenInfo.address.address, this.config.provider);
18246
- const call1 = token0Contract.populate("approve", [this.address.address, uint2564.bnToUint256(updateAmountInfo.token0.amount.toWei())]);
18247
- const call2 = token1Contract.populate("approve", [this.address.address, uint2564.bnToUint256(updateAmountInfo.token1.amount.toWei())]);
18248
- const call3 = this.contract.populate("deposit", [uint2564.bnToUint256(updateAmountInfo.token0.amount.toWei()), uint2564.bnToUint256(updateAmountInfo.token1.amount.toWei()), receiver.address]);
18564
+ const token0Contract = new Contract6(
18565
+ erc4626_abi_default,
18566
+ amountInfo.token0.tokenInfo.address.address,
18567
+ this.config.provider
18568
+ );
18569
+ const token1Contract = new Contract6(
18570
+ erc4626_abi_default,
18571
+ amountInfo.token1.tokenInfo.address.address,
18572
+ this.config.provider
18573
+ );
18574
+ const call1 = token0Contract.populate("approve", [
18575
+ this.address.address,
18576
+ uint2564.bnToUint256(updateAmountInfo.token0.amount.toWei())
18577
+ ]);
18578
+ const call2 = token1Contract.populate("approve", [
18579
+ this.address.address,
18580
+ uint2564.bnToUint256(updateAmountInfo.token1.amount.toWei())
18581
+ ]);
18582
+ const call3 = this.contract.populate("deposit", [
18583
+ uint2564.bnToUint256(updateAmountInfo.token0.amount.toWei()),
18584
+ uint2564.bnToUint256(updateAmountInfo.token1.amount.toWei()),
18585
+ receiver.address
18586
+ ]);
18249
18587
  const calls = [];
18250
18588
  if (updateAmountInfo.token0.amount.greaterThan(0)) calls.push(call1);
18251
18589
  if (updateAmountInfo.token1.amount.greaterThan(0)) calls.push(call2);
@@ -18260,25 +18598,29 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18260
18598
  }
18261
18599
  async withdrawCall(amountInfo, receiver, owner) {
18262
18600
  const shares = await this.tokensToShares(amountInfo);
18263
- logger.verbose(`${_EkuboCLVault.name}: withdrawCall: shares=${shares.toString()}`);
18264
- return [this.contract.populate("withdraw", [
18265
- uint2564.bnToUint256(shares.toWei()),
18266
- receiver.address
18267
- ])];
18601
+ logger.verbose(
18602
+ `${_EkuboCLVault.name}: withdrawCall: shares=${shares.toString()}`
18603
+ );
18604
+ return [
18605
+ this.contract.populate("withdraw", [
18606
+ uint2564.bnToUint256(shares.toWei()),
18607
+ receiver.address
18608
+ ])
18609
+ ];
18268
18610
  }
18269
18611
  rebalanceCall(newBounds, swapParams) {
18270
- return [this.contract.populate("rebalance", [
18271
- {
18272
- lower: _EkuboCLVault.tickToi129(Number(newBounds.lowerTick)),
18273
- upper: _EkuboCLVault.tickToi129(Number(newBounds.upperTick))
18274
- },
18275
- swapParams
18276
- ])];
18612
+ return [
18613
+ this.contract.populate("rebalance", [
18614
+ {
18615
+ lower: _EkuboCLVault.tickToi129(Number(newBounds.lowerTick)),
18616
+ upper: _EkuboCLVault.tickToi129(Number(newBounds.upperTick))
18617
+ },
18618
+ swapParams
18619
+ ])
18620
+ ];
18277
18621
  }
18278
18622
  handleUnusedCall(swapParams) {
18279
- return [this.contract.populate("handle_unused", [
18280
- swapParams
18281
- ])];
18623
+ return [this.contract.populate("handle_unused", [swapParams])];
18282
18624
  }
18283
18625
  handleFeesCall() {
18284
18626
  return [this.contract.populate("handle_fees", [])];
@@ -18293,16 +18635,20 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18293
18635
  const priceNow = await this.getCurrentPrice(blockIdentifier);
18294
18636
  let blockNow = typeof blockIdentifier == "number" ? blockIdentifier : (await this.config.provider.getBlockLatestAccepted()).block_number;
18295
18637
  const blockNowTime = typeof blockIdentifier == "number" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
18296
- const blockBefore = blockNow - sinceBlocks;
18297
- const adjustedSupplyNow = supplyNow.minus(await this.getHarvestRewardShares(blockBefore, blockNow));
18298
- let blockBeforeInfo = await this.config.provider.getBlockWithTxs(blockBefore);
18638
+ const blockBefore = Math.max(blockNow - sinceBlocks, this.metadata.launchBlock);
18639
+ const adjustedSupplyNow = supplyNow.minus(
18640
+ await this.getHarvestRewardShares(blockBefore, blockNow)
18641
+ );
18642
+ let blockBeforeInfo = await this.config.provider.getBlockWithTxs(
18643
+ blockBefore
18644
+ );
18299
18645
  const tvlBefore = await this._getTVL(blockBefore);
18300
18646
  const supplyBefore = await this.totalSupply(blockBefore);
18301
18647
  const priceBefore = await this.getCurrentPrice(blockBefore);
18302
18648
  const tvlInToken0Now = tvlNow.amount0.multipliedBy(priceNow.price).plus(tvlNow.amount1);
18303
- const tvlPerShareNow = tvlInToken0Now.multipliedBy(1e18).dividedBy(adjustedSupplyNow);
18649
+ const tvlPerShareNow = tvlInToken0Now.multipliedBy(1e18).dividedBy(adjustedSupplyNow.toString());
18304
18650
  const tvlInToken0Bf = tvlBefore.amount0.multipliedBy(priceBefore.price).plus(tvlBefore.amount1);
18305
- const tvlPerShareBf = tvlInToken0Bf.multipliedBy(1e18).dividedBy(supplyBefore);
18651
+ const tvlPerShareBf = tvlInToken0Bf.multipliedBy(1e18).dividedBy(supplyBefore.toString());
18306
18652
  const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
18307
18653
  logger.verbose(`tvlInToken0Now: ${tvlInToken0Now.toString()}`);
18308
18654
  logger.verbose(`tvlInToken0Bf: ${tvlInToken0Bf.toString()}`);
@@ -18313,7 +18659,9 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18313
18659
  logger.verbose(`Supply before: ${supplyBefore.toString()}`);
18314
18660
  logger.verbose(`Supply now: ${adjustedSupplyNow.toString()}`);
18315
18661
  logger.verbose(`Time diff in seconds: ${timeDiffSeconds}`);
18316
- const apyForGivenBlocks = Number(tvlPerShareNow.minus(tvlPerShareBf).multipliedBy(1e4).dividedBy(tvlPerShareBf)) / 1e4;
18662
+ const apyForGivenBlocks = Number(
18663
+ tvlPerShareNow.minus(tvlPerShareBf).multipliedBy(1e4).dividedBy(tvlPerShareBf)
18664
+ ) / 1e4;
18317
18665
  return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
18318
18666
  }
18319
18667
  async getHarvestRewardShares(fromBlock, toBlock) {
@@ -18331,25 +18679,39 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18331
18679
  } else {
18332
18680
  shares = shares.plus(Web3Number.fromWei(record.shares.toString(), 18));
18333
18681
  }
18334
- logger.verbose(`${_EkuboCLVault.name}: getHarvestRewardShares: ${i} => ${shares.toWei()}`);
18682
+ logger.verbose(
18683
+ `${_EkuboCLVault.name}: getHarvestRewardShares: ${i} => ${shares.toWei()}`
18684
+ );
18335
18685
  }
18336
18686
  return shares;
18337
18687
  }
18338
18688
  async balanceOf(user, blockIdentifier = "pending") {
18339
- let bal = await this.contract.call("balance_of", [user.address]);
18689
+ let bal = await this.contract.call("balance_of", [user.address], {
18690
+ blockIdentifier
18691
+ });
18340
18692
  return Web3Number.fromWei(bal.toString(), 18);
18341
18693
  }
18342
18694
  async getUserTVL(user, blockIdentifier = "pending") {
18343
18695
  let bal = await this.balanceOf(user, blockIdentifier);
18344
- const assets = await this.contract.call("convert_to_assets", [uint2564.bnToUint256(bal.toWei())], {
18345
- blockIdentifier
18346
- });
18696
+ const assets = await this.contract.call(
18697
+ "convert_to_assets",
18698
+ [uint2564.bnToUint256(bal.toWei())],
18699
+ {
18700
+ blockIdentifier
18701
+ }
18702
+ );
18347
18703
  const poolKey = await this.getPoolKey(blockIdentifier);
18348
18704
  this.assertValidDepositTokens(poolKey);
18349
18705
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
18350
18706
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
18351
- const amount0 = Web3Number.fromWei(assets.amount0.toString(), token0Info.decimals);
18352
- const amount1 = Web3Number.fromWei(assets.amount1.toString(), token1Info.decimals);
18707
+ const amount0 = Web3Number.fromWei(
18708
+ assets.amount0.toString(),
18709
+ token0Info.decimals
18710
+ );
18711
+ const amount1 = Web3Number.fromWei(
18712
+ assets.amount1.toString(),
18713
+ token1Info.decimals
18714
+ );
18353
18715
  const P0 = await this.pricer.getPrice(token0Info.symbol);
18354
18716
  const P1 = await this.pricer.getPrice(token1Info.symbol);
18355
18717
  const token0Usd = Number(amount0.toFixed(13)) * P0.price;
@@ -18373,7 +18735,11 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18373
18735
  blockIdentifier
18374
18736
  });
18375
18737
  const bounds = await this.getCurrentBounds(blockIdentifier);
18376
- const { amount0, amount1 } = await this.getLiquidityToAmounts(Web3Number.fromWei(result.toString(), 18), bounds, blockIdentifier);
18738
+ const { amount0, amount1 } = await this.getLiquidityToAmounts(
18739
+ Web3Number.fromWei(result.toString(), 18),
18740
+ bounds,
18741
+ blockIdentifier
18742
+ );
18377
18743
  return { amount0, amount1 };
18378
18744
  }
18379
18745
  async totalSupply(blockIdentifier = "pending") {
@@ -18383,8 +18749,14 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18383
18749
  return Web3Number.fromWei(res.toString(), 18);
18384
18750
  }
18385
18751
  assertValidDepositTokens(poolKey) {
18386
- assert(poolKey.token0.eq(this.metadata.depositTokens[0].address), "Expected token0 in depositTokens[0]");
18387
- assert(poolKey.token1.eq(this.metadata.depositTokens[1].address), "Expected token1 in depositTokens[1]");
18752
+ assert(
18753
+ poolKey.token0.eq(this.metadata.depositTokens[0].address),
18754
+ "Expected token0 in depositTokens[0]"
18755
+ );
18756
+ assert(
18757
+ poolKey.token1.eq(this.metadata.depositTokens[1].address),
18758
+ "Expected token1 in depositTokens[1]"
18759
+ );
18388
18760
  }
18389
18761
  async getTVL(blockIdentifier = "pending") {
18390
18762
  const { amount0, amount1 } = await this._getTVL(blockIdentifier);
@@ -18414,26 +18786,35 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18414
18786
  const nftID = await this.getCurrentNFTID();
18415
18787
  const poolKey = await this.getPoolKey();
18416
18788
  const currentBounds = await this.getCurrentBounds();
18417
- const result = await this.ekuboPositionsContract.call("get_token_info", [
18418
- nftID,
18419
- {
18420
- token0: poolKey.token0.address,
18421
- token1: poolKey.token1.address,
18422
- fee: poolKey.fee,
18423
- tick_spacing: poolKey.tick_spacing,
18424
- extension: poolKey.extension
18425
- },
18426
- {
18427
- lower: _EkuboCLVault.tickToi129(Number(currentBounds.lowerTick)),
18428
- upper: _EkuboCLVault.tickToi129(Number(currentBounds.upperTick))
18429
- }
18430
- ]);
18789
+ const result = await this.ekuboPositionsContract.call(
18790
+ "get_token_info",
18791
+ [
18792
+ nftID,
18793
+ {
18794
+ token0: poolKey.token0.address,
18795
+ token1: poolKey.token1.address,
18796
+ fee: poolKey.fee,
18797
+ tick_spacing: poolKey.tick_spacing,
18798
+ extension: poolKey.extension
18799
+ },
18800
+ {
18801
+ lower: _EkuboCLVault.tickToi129(Number(currentBounds.lowerTick)),
18802
+ upper: _EkuboCLVault.tickToi129(Number(currentBounds.upperTick))
18803
+ }
18804
+ ]
18805
+ );
18431
18806
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
18432
18807
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
18433
18808
  const P0 = await this.pricer.getPrice(token0Info.symbol);
18434
18809
  const P1 = await this.pricer.getPrice(token1Info.symbol);
18435
- const token0Web3 = Web3Number.fromWei(result.fees0.toString(), token0Info.decimals);
18436
- const token1Web3 = Web3Number.fromWei(result.fees1.toString(), token1Info.decimals);
18810
+ const token0Web3 = Web3Number.fromWei(
18811
+ result.fees0.toString(),
18812
+ token0Info.decimals
18813
+ );
18814
+ const token1Web3 = Web3Number.fromWei(
18815
+ result.fees1.toString(),
18816
+ token1Info.decimals
18817
+ );
18437
18818
  const token0Usd = Number(token0Web3.toFixed(13)) * P0.price;
18438
18819
  const token1Usd = Number(token1Web3.toFixed(13)) * P1.price;
18439
18820
  return {
@@ -18455,31 +18836,52 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18455
18836
  return Number(result.salt.toString());
18456
18837
  }
18457
18838
  async truePrice() {
18458
- const result = await this.lstContract.call("convert_to_assets", [uint2564.bnToUint256(BigInt(1e18).toString())]);
18459
- const truePrice = Number(BigInt(result.toString()) * BigInt(1e9) / BigInt(1e18)) / 1e9;
18460
- return truePrice;
18839
+ if (this.metadata.additionalInfo.truePrice) {
18840
+ return this.metadata.additionalInfo.truePrice;
18841
+ } else if (this.lstContract) {
18842
+ const result = await this.lstContract.call("convert_to_assets", [
18843
+ uint2564.bnToUint256(BigInt(1e18).toString())
18844
+ ]);
18845
+ const truePrice = Number(BigInt(result.toString()) * BigInt(1e9) / BigInt(1e18)) / 1e9;
18846
+ return truePrice;
18847
+ }
18848
+ throw new Error("No true price available");
18461
18849
  }
18462
18850
  async getCurrentPrice(blockIdentifier = "pending") {
18463
18851
  const poolKey = await this.getPoolKey(blockIdentifier);
18464
18852
  return this._getCurrentPrice(poolKey, blockIdentifier);
18465
18853
  }
18466
18854
  async _getCurrentPrice(poolKey, blockIdentifier = "pending") {
18467
- const priceInfo = await this.ekuboPositionsContract.call("get_pool_price", [
18855
+ const priceInfo = await this.ekuboPositionsContract.call(
18856
+ "get_pool_price",
18857
+ [
18858
+ {
18859
+ token0: poolKey.token0.address,
18860
+ token1: poolKey.token1.address,
18861
+ fee: poolKey.fee,
18862
+ tick_spacing: poolKey.tick_spacing,
18863
+ extension: poolKey.extension
18864
+ }
18865
+ ],
18468
18866
  {
18469
- token0: poolKey.token0.address,
18470
- token1: poolKey.token1.address,
18471
- fee: poolKey.fee,
18472
- tick_spacing: poolKey.tick_spacing,
18473
- extension: poolKey.extension
18867
+ blockIdentifier
18474
18868
  }
18475
- ], {
18476
- blockIdentifier
18477
- });
18478
- const sqrtRatio = _EkuboCLVault.div2Power128(BigInt(priceInfo.sqrt_ratio.toString()));
18479
- console.log(`EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, sqrtRatio: ${sqrtRatio}, ${priceInfo.sqrt_ratio.toString()}`);
18869
+ );
18870
+ const sqrtRatio = _EkuboCLVault.div2Power128(
18871
+ BigInt(priceInfo.sqrt_ratio.toString())
18872
+ );
18873
+ console.log(
18874
+ `EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, sqrtRatio: ${sqrtRatio}, ${priceInfo.sqrt_ratio.toString()}`
18875
+ );
18480
18876
  const price = sqrtRatio * sqrtRatio;
18481
- const tick = _EkuboCLVault.priceToTick(price, true, Number(poolKey.tick_spacing));
18482
- console.log(`EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, price: ${price}, tick: ${tick.mag}, ${tick.sign}`);
18877
+ const tick = _EkuboCLVault.priceToTick(
18878
+ price,
18879
+ true,
18880
+ Number(poolKey.tick_spacing)
18881
+ );
18882
+ console.log(
18883
+ `EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, price: ${price}, tick: ${tick.mag}, ${tick.sign}`
18884
+ );
18483
18885
  return {
18484
18886
  price,
18485
18887
  tick: tick.mag * (tick.sign == 0 ? 1 : -1),
@@ -18519,7 +18921,10 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18519
18921
  };
18520
18922
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
18521
18923
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
18522
- assert(token0Info.decimals == token1Info.decimals, "Tested only for equal decimals");
18924
+ assert(
18925
+ token0Info.decimals == token1Info.decimals,
18926
+ "Tested only for equal decimals"
18927
+ );
18523
18928
  this.poolKey = poolKey;
18524
18929
  return poolKey;
18525
18930
  }
@@ -18543,11 +18948,18 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18543
18948
  async _getExpectedAmountsForLiquidity(amount0, amount1, bounds, justUseInputAmount = true) {
18544
18949
  assert(amount0.greaterThan(0) || amount1.greaterThan(0), "Amount is 0");
18545
18950
  const sampleLiq = 1e20;
18546
- const { amount0: sampleAmount0, amount1: sampleAmount1 } = await this.getLiquidityToAmounts(Web3Number.fromWei(sampleLiq.toString(), 18), bounds);
18547
- logger.verbose(`${_EkuboCLVault.name}: _getExpectedAmountsForLiquidity => sampleAmount0: ${sampleAmount0.toString()}, sampleAmount1: ${sampleAmount1.toString()}`);
18951
+ const { amount0: sampleAmount0, amount1: sampleAmount1 } = await this.getLiquidityToAmounts(
18952
+ Web3Number.fromWei(sampleLiq.toString(), 18),
18953
+ bounds
18954
+ );
18955
+ logger.verbose(
18956
+ `${_EkuboCLVault.name}: _getExpectedAmountsForLiquidity => sampleAmount0: ${sampleAmount0.toString()}, sampleAmount1: ${sampleAmount1.toString()}`
18957
+ );
18548
18958
  assert(!sampleAmount0.eq(0) || !sampleAmount1.eq(0), "Sample amount is 0");
18549
18959
  const price = await (await this.getCurrentPrice()).price;
18550
- logger.verbose(`${_EkuboCLVault.name}: _getExpectedAmountsForLiquidity => price: ${price}`);
18960
+ logger.verbose(
18961
+ `${_EkuboCLVault.name}: _getExpectedAmountsForLiquidity => price: ${price}`
18962
+ );
18551
18963
  if (amount1.eq(0) && amount0.greaterThan(0)) {
18552
18964
  if (sampleAmount1.eq(0)) {
18553
18965
  return {
@@ -18577,12 +18989,22 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18577
18989
  };
18578
18990
  }
18579
18991
  }
18580
- assert(sampleAmount0.decimals == sampleAmount1.decimals, "Sample amounts have different decimals");
18992
+ assert(
18993
+ sampleAmount0.decimals == sampleAmount1.decimals,
18994
+ "Sample amounts have different decimals"
18995
+ );
18581
18996
  const ratioWeb3Number = sampleAmount0.multipliedBy(1e18).dividedBy(sampleAmount1.toString()).dividedBy(1e18);
18582
18997
  const ratio = Number(ratioWeb3Number.toFixed(18));
18583
- logger.verbose(`${_EkuboCLVault.name}: ${this.metadata.name} => ratio: ${ratio.toString()}`);
18998
+ logger.verbose(
18999
+ `${_EkuboCLVault.name}: ${this.metadata.name} => ratio: ${ratio.toString()}`
19000
+ );
18584
19001
  if (justUseInputAmount)
18585
- return this._solveExpectedAmountsEq(amount0, amount1, ratioWeb3Number, price);
19002
+ return this._solveExpectedAmountsEq(
19003
+ amount0,
19004
+ amount1,
19005
+ ratioWeb3Number,
19006
+ price
19007
+ );
18586
19008
  if (amount1.eq(0) && amount0.greaterThan(0)) {
18587
19009
  const _amount1 = amount0.dividedBy(ratioWeb3Number);
18588
19010
  return {
@@ -18598,7 +19020,9 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18598
19020
  ratio
18599
19021
  };
18600
19022
  } else {
18601
- throw new Error("Both amounts are non-zero, cannot compute expected amounts");
19023
+ throw new Error(
19024
+ "Both amounts are non-zero, cannot compute expected amounts"
19025
+ );
18602
19026
  }
18603
19027
  }
18604
19028
  _solveExpectedAmountsEq(availableAmount0, availableAmount1, ratio, price) {
@@ -18615,34 +19039,65 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18615
19039
  const erc20Mod = new ERC20(this.config);
18616
19040
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
18617
19041
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
18618
- const token0Bal1 = await erc20Mod.balanceOf(poolKey.token0, this.address.address, token0Info.decimals);
18619
- const token1Bal1 = await erc20Mod.balanceOf(poolKey.token1, this.address.address, token1Info.decimals);
18620
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal1: ${token0Bal1.toString()}, token1Bal1: ${token1Bal1.toString()}`);
19042
+ const token0Bal1 = await erc20Mod.balanceOf(
19043
+ poolKey.token0,
19044
+ this.address.address,
19045
+ token0Info.decimals
19046
+ );
19047
+ const token1Bal1 = await erc20Mod.balanceOf(
19048
+ poolKey.token1,
19049
+ this.address.address,
19050
+ token1Info.decimals
19051
+ );
19052
+ logger.verbose(
19053
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal1: ${token0Bal1.toString()}, token1Bal1: ${token1Bal1.toString()}`
19054
+ );
18621
19055
  const token0Price = await this.pricer.getPrice(token0Info.symbol);
18622
19056
  const token1Price = await this.pricer.getPrice(token1Info.symbol);
18623
19057
  const token0PriceUsd = token0Price.price * Number(token0Bal1.toFixed(13));
18624
19058
  const token1PriceUsd = token1Price.price * Number(token1Bal1.toFixed(13));
18625
19059
  if (token0PriceUsd > 1 && token1PriceUsd > 1) {
18626
- throw new Error("Both tokens are non-zero and above $1, call handle_fees first");
19060
+ throw new Error(
19061
+ "Both tokens are non-zero and above $1, call handle_fees first"
19062
+ );
18627
19063
  }
18628
19064
  let token0Bal = token0Bal1;
18629
19065
  let token1Bal = token1Bal1;
18630
19066
  if (considerRebalance) {
18631
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => considerRebalance: true`);
19067
+ logger.verbose(
19068
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => considerRebalance: true`
19069
+ );
18632
19070
  const tvl = await this.getTVL();
18633
19071
  token0Bal = token0Bal.plus(tvl.token0.amount.toString());
18634
19072
  token1Bal = token1Bal.plus(tvl.token1.amount.toString());
18635
19073
  } else {
18636
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => considerRebalance: false`);
19074
+ logger.verbose(
19075
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => considerRebalance: false`
19076
+ );
18637
19077
  }
18638
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`);
19078
+ logger.verbose(
19079
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`
19080
+ );
18639
19081
  const newBounds = await this.getNewBounds();
18640
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newBounds: ${newBounds.lowerTick}, ${newBounds.upperTick}`);
18641
- return await this.getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, newBounds);
19082
+ logger.verbose(
19083
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newBounds: ${newBounds.lowerTick}, ${newBounds.upperTick}`
19084
+ );
19085
+ return await this.getSwapInfoGivenAmounts(
19086
+ poolKey,
19087
+ token0Bal,
19088
+ token1Bal,
19089
+ newBounds
19090
+ );
18642
19091
  }
18643
19092
  async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds) {
18644
- let expectedAmounts = await this._getExpectedAmountsForLiquidity(token0Bal, token1Bal, bounds);
18645
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`);
19093
+ let expectedAmounts = await this._getExpectedAmountsForLiquidity(
19094
+ token0Bal,
19095
+ token1Bal,
19096
+ bounds
19097
+ );
19098
+ logger.verbose(
19099
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`
19100
+ );
18646
19101
  let retry = 0;
18647
19102
  const maxRetry = 10;
18648
19103
  while (retry < maxRetry) {
@@ -18659,9 +19114,15 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18659
19114
  const remainingSellAmount = tokenToSell == poolKey.token0 ? expectedAmounts.amount0 : expectedAmounts.amount1;
18660
19115
  const tokenToBuyInfo = await Global.getTokenInfoFromAddr(tokenToBuy);
18661
19116
  const expectedRatio = expectedAmounts.ratio;
18662
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => tokenToSell: ${tokenToSell.address}, tokenToBuy: ${tokenToBuy.address}, amountToSell: ${amountToSell.toWei()}`);
18663
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => remainingSellAmount: ${remainingSellAmount.toString()}`);
18664
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedRatio: ${expectedRatio}`);
19117
+ logger.verbose(
19118
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => tokenToSell: ${tokenToSell.address}, tokenToBuy: ${tokenToBuy.address}, amountToSell: ${amountToSell.toWei()}`
19119
+ );
19120
+ logger.verbose(
19121
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => remainingSellAmount: ${remainingSellAmount.toString()}`
19122
+ );
19123
+ logger.verbose(
19124
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedRatio: ${expectedRatio}`
19125
+ );
18665
19126
  if (amountToSell.eq(0)) {
18666
19127
  return {
18667
19128
  token_from_address: tokenToSell.address,
@@ -18675,23 +19136,62 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18675
19136
  routes: []
18676
19137
  };
18677
19138
  }
18678
- const quote = await this.avnu.getQuotes(tokenToSell.address, tokenToBuy.address, amountToSell.toWei(), this.address.address);
19139
+ const quote = await this.avnu.getQuotes(
19140
+ tokenToSell.address,
19141
+ tokenToBuy.address,
19142
+ amountToSell.toWei(),
19143
+ this.address.address
19144
+ );
18679
19145
  if (remainingSellAmount.eq(0)) {
18680
- const minAmountOut = Web3Number.fromWei(quote.buyAmount.toString(), tokenToBuyInfo.decimals).multipliedBy(0.9999);
18681
- return await this.avnu.getSwapInfo(quote, this.address.address, 0, this.address.address, minAmountOut.toWei());
19146
+ const minAmountOut = Web3Number.fromWei(
19147
+ quote.buyAmount.toString(),
19148
+ tokenToBuyInfo.decimals
19149
+ ).multipliedBy(0.9999);
19150
+ return await this.avnu.getSwapInfo(
19151
+ quote,
19152
+ this.address.address,
19153
+ 0,
19154
+ this.address.address,
19155
+ minAmountOut.toWei()
19156
+ );
18682
19157
  }
18683
- const amountOut = Web3Number.fromWei(quote.buyAmount.toString(), tokenToBuyInfo.decimals);
19158
+ const amountOut = Web3Number.fromWei(
19159
+ quote.buyAmount.toString(),
19160
+ tokenToBuyInfo.decimals
19161
+ );
18684
19162
  const swapPrice = tokenToSell == poolKey.token0 ? amountOut.dividedBy(amountToSell) : amountToSell.dividedBy(amountOut);
18685
19163
  const newRatio = tokenToSell == poolKey.token0 ? remainingSellAmount.dividedBy(token1Bal.plus(amountOut)) : token0Bal.plus(amountOut).dividedBy(remainingSellAmount);
18686
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => amountOut: ${amountOut.toString()}`);
18687
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => swapPrice: ${swapPrice.toString()}`);
18688
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newRatio: ${newRatio.toString()}`);
19164
+ logger.verbose(
19165
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => amountOut: ${amountOut.toString()}`
19166
+ );
19167
+ logger.verbose(
19168
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => swapPrice: ${swapPrice.toString()}`
19169
+ );
19170
+ logger.verbose(
19171
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newRatio: ${newRatio.toString()}`
19172
+ );
18689
19173
  if (Number(newRatio.toString()) > expectedRatio * 1.0000001 || Number(newRatio.toString()) < expectedRatio * 0.9999999) {
18690
- expectedAmounts = await this._solveExpectedAmountsEq(token0Bal, token1Bal, new Web3Number(Number(expectedRatio).toFixed(13), 18), Number(swapPrice.toString()));
18691
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`);
19174
+ expectedAmounts = await this._solveExpectedAmountsEq(
19175
+ token0Bal,
19176
+ token1Bal,
19177
+ new Web3Number(Number(expectedRatio).toFixed(13), 18),
19178
+ Number(swapPrice.toString())
19179
+ );
19180
+ logger.verbose(
19181
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`
19182
+ );
18692
19183
  } else {
18693
- const minAmountOut = Web3Number.fromWei(quote.buyAmount.toString(), tokenToBuyInfo.decimals).multipliedBy(0.9999);
18694
- return await this.avnu.getSwapInfo(quote, this.address.address, 0, this.address.address, minAmountOut.toWei());
19184
+ const minAmountOut = Web3Number.fromWei(
19185
+ quote.buyAmount.toString(),
19186
+ tokenToBuyInfo.decimals
19187
+ ).multipliedBy(0.9999);
19188
+ return await this.avnu.getSwapInfo(
19189
+ quote,
19190
+ this.address.address,
19191
+ 0,
19192
+ this.address.address,
19193
+ minAmountOut.toWei()
19194
+ );
18695
19195
  }
18696
19196
  retry++;
18697
19197
  }
@@ -18700,8 +19200,8 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18700
19200
  /**
18701
19201
  * Attempts to rebalance the vault by iteratively adjusting swap amounts if initial attempt fails.
18702
19202
  * Uses binary search approach to find optimal swap amount.
18703
- *
18704
- * @param newBounds - The new tick bounds to rebalance to
19203
+ *
19204
+ * @param newBounds - The new tick bounds to rebalance to
18705
19205
  * @param swapInfo - Initial swap parameters for rebalancing
18706
19206
  * @param acc - Account to estimate gas fees with
18707
19207
  * @param retry - Current retry attempt number (default 0)
@@ -18728,7 +19228,9 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18728
19228
  logger.error(`Rebalance failed after ${MAX_RETRIES} retries`);
18729
19229
  throw err;
18730
19230
  }
18731
- logger.error(`Rebalance attempt ${retry + 1} failed, adjusting swap amount...`);
19231
+ logger.error(
19232
+ `Rebalance attempt ${retry + 1} failed, adjusting swap amount...`
19233
+ );
18732
19234
  const newSwapInfo = { ...swapInfo };
18733
19235
  const currentAmount = Web3Number.fromWei(fromAmount.toString(), 18);
18734
19236
  logger.verbose(`Current amount: ${currentAmount.toString()}`);
@@ -18820,23 +19322,39 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18820
19322
  const currentPrice = _currentPrice || await this.getCurrentPrice(blockIdentifier);
18821
19323
  const lowerPrice = _EkuboCLVault.tickToPrice(bounds.lowerTick);
18822
19324
  const upperPrice = _EkuboCLVault.tickToPrice(bounds.upperTick);
18823
- logger.verbose(`${_EkuboCLVault.name}: getLiquidityToAmounts => currentPrice: ${currentPrice.price}, lowerPrice: ${lowerPrice}, upperPrice: ${upperPrice}`);
18824
- const result = await this.ekuboMathContract.call("liquidity_delta_to_amount_delta", [
18825
- uint2564.bnToUint256(currentPrice.sqrtRatio),
19325
+ logger.verbose(
19326
+ `${_EkuboCLVault.name}: getLiquidityToAmounts => currentPrice: ${currentPrice.price}, lowerPrice: ${lowerPrice}, upperPrice: ${upperPrice}`
19327
+ );
19328
+ const result = await this.ekuboMathContract.call(
19329
+ "liquidity_delta_to_amount_delta",
19330
+ [
19331
+ uint2564.bnToUint256(currentPrice.sqrtRatio),
19332
+ {
19333
+ mag: liquidity.toWei(),
19334
+ sign: 0
19335
+ },
19336
+ uint2564.bnToUint256(
19337
+ _EkuboCLVault.priceToSqrtRatio(lowerPrice).toString()
19338
+ ),
19339
+ uint2564.bnToUint256(
19340
+ _EkuboCLVault.priceToSqrtRatio(upperPrice).toString()
19341
+ )
19342
+ ],
18826
19343
  {
18827
- mag: liquidity.toWei(),
18828
- sign: 0
18829
- },
18830
- uint2564.bnToUint256(_EkuboCLVault.priceToSqrtRatio(lowerPrice).toString()),
18831
- uint2564.bnToUint256(_EkuboCLVault.priceToSqrtRatio(upperPrice).toString())
18832
- ], {
18833
- blockIdentifier
18834
- });
19344
+ blockIdentifier
19345
+ }
19346
+ );
18835
19347
  const poolKey = _poolKey || await this.getPoolKey(blockIdentifier);
18836
19348
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
18837
19349
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
18838
- const amount0 = Web3Number.fromWei(_EkuboCLVault.i129ToNumber(result.amount0).toString(), token0Info.decimals);
18839
- const amount1 = Web3Number.fromWei(_EkuboCLVault.i129ToNumber(result.amount1).toString(), token1Info.decimals);
19350
+ const amount0 = Web3Number.fromWei(
19351
+ _EkuboCLVault.i129ToNumber(result.amount0).toString(),
19352
+ token0Info.decimals
19353
+ );
19354
+ const amount1 = Web3Number.fromWei(
19355
+ _EkuboCLVault.i129ToNumber(result.amount1).toString(),
19356
+ token1Info.decimals
19357
+ );
18840
19358
  return {
18841
19359
  amount0,
18842
19360
  amount1
@@ -18844,7 +19362,9 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18844
19362
  }
18845
19363
  async harvest(acc) {
18846
19364
  const ekuboHarvests = new EkuboHarvests(this.config);
18847
- const unClaimedRewards = await ekuboHarvests.getUnHarvestedRewards(this.address);
19365
+ const unClaimedRewards = await ekuboHarvests.getUnHarvestedRewards(
19366
+ this.address
19367
+ );
18848
19368
  const poolKey = await this.getPoolKey();
18849
19369
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
18850
19370
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
@@ -18854,18 +19374,38 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18854
19374
  const fee = claim.claim.amount.multipliedBy(this.metadata.additionalInfo.feeBps).dividedBy(1e4);
18855
19375
  const postFeeAmount = claim.claim.amount.minus(fee);
18856
19376
  const isToken1 = claim.token.eq(poolKey.token1);
18857
- logger.verbose(`${_EkuboCLVault.name}: harvest => Processing claim, isToken1: ${isToken1} amount: ${postFeeAmount.toWei()}`);
19377
+ logger.verbose(
19378
+ `${_EkuboCLVault.name}: harvest => Processing claim, isToken1: ${isToken1} amount: ${postFeeAmount.toWei()}`
19379
+ );
18858
19380
  const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
18859
19381
  const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
18860
- logger.verbose(`${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`);
18861
- const swapInfo = await this.getSwapInfoGivenAmounts(poolKey, token0Amt, token1Amt, bounds);
19382
+ logger.verbose(
19383
+ `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
19384
+ );
19385
+ const swapInfo = await this.getSwapInfoGivenAmounts(
19386
+ poolKey,
19387
+ token0Amt,
19388
+ token1Amt,
19389
+ bounds
19390
+ );
18862
19391
  swapInfo.token_to_address = token0Info.address.address;
18863
- logger.verbose(`${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`);
18864
- logger.verbose(`${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`);
19392
+ logger.verbose(
19393
+ `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
19394
+ );
19395
+ logger.verbose(
19396
+ `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
19397
+ );
18865
19398
  const harvestEstimateCall = async (swapInfo1) => {
18866
- const swap1Amount = Web3Number.fromWei(uint2564.uint256ToBN(swapInfo1.token_from_amount).toString(), 18);
19399
+ const swap1Amount = Web3Number.fromWei(
19400
+ uint2564.uint256ToBN(swapInfo1.token_from_amount).toString(),
19401
+ 18
19402
+ // cause its always STRK?
19403
+ );
18867
19404
  const remainingAmount = postFeeAmount.minus(swap1Amount);
18868
- const swapInfo2 = { ...swapInfo, token_from_amount: uint2564.bnToUint256(remainingAmount.toWei()) };
19405
+ const swapInfo2 = {
19406
+ ...swapInfo,
19407
+ token_from_amount: uint2564.bnToUint256(remainingAmount.toWei())
19408
+ };
18869
19409
  swapInfo2.token_to_address = token1Info.address.address;
18870
19410
  const calldata = [
18871
19411
  claim.rewardsContract.address,
@@ -18878,11 +19418,23 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18878
19418
  swapInfo,
18879
19419
  swapInfo2
18880
19420
  ];
18881
- logger.verbose(`${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(calldata)}`);
19421
+ logger.verbose(
19422
+ `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
19423
+ calldata
19424
+ )}`
19425
+ );
18882
19426
  return [this.contract.populate("harvest", calldata)];
18883
19427
  };
18884
- const _callsFinal = await this.rebalanceIter(swapInfo, acc, harvestEstimateCall);
18885
- logger.verbose(`${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(_callsFinal)}`);
19428
+ const _callsFinal = await this.rebalanceIter(
19429
+ swapInfo,
19430
+ acc,
19431
+ harvestEstimateCall
19432
+ );
19433
+ logger.verbose(
19434
+ `${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
19435
+ _callsFinal
19436
+ )}`
19437
+ );
18886
19438
  calls.push(..._callsFinal);
18887
19439
  }
18888
19440
  return calls;
@@ -18892,24 +19444,37 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18892
19444
  const poolKey = await this.getPoolKey();
18893
19445
  const linkedFlow = {
18894
19446
  title: this.metadata.name,
18895
- subItems: [{ key: "Pool", value: `${(_EkuboCLVault.div2Power128(BigInt(poolKey.fee)) * 100).toFixed(2)}%, ${poolKey.tick_spacing} tick spacing` }],
19447
+ subItems: [
19448
+ {
19449
+ key: "Pool",
19450
+ value: `${(_EkuboCLVault.div2Power128(BigInt(poolKey.fee)) * 100).toFixed(2)}%, ${poolKey.tick_spacing} tick spacing`
19451
+ }
19452
+ ],
18896
19453
  linkedFlows: [],
18897
19454
  style: { backgroundColor: "#35484f" /* Blue */.valueOf() }
18898
19455
  };
18899
19456
  const baseFlow = {
18900
19457
  id: "base",
18901
19458
  title: "Your Deposit",
18902
- subItems: [{ key: `Net yield`, value: `${(netYield * 100).toFixed(2)}%` }, { key: `Performance Fee`, value: `${(this.metadata.additionalInfo.feeBps / 100).toFixed(2)}%` }],
19459
+ subItems: [
19460
+ { key: `Net yield`, value: `${(netYield * 100).toFixed(2)}%` },
19461
+ {
19462
+ key: `Performance Fee`,
19463
+ value: `${(this.metadata.additionalInfo.feeBps / 100).toFixed(2)}%`
19464
+ }
19465
+ ],
18903
19466
  linkedFlows: [linkedFlow],
18904
19467
  style: { backgroundColor: "#6e53dc" /* Purple */.valueOf() }
18905
19468
  };
18906
19469
  const rebalanceFlow = {
18907
19470
  id: "rebalance",
18908
19471
  title: "Automated Rebalance",
18909
- subItems: [{
18910
- key: "Range selection",
18911
- value: `${this.metadata.additionalInfo.newBounds.lower * Number(poolKey.tick_spacing)} to ${this.metadata.additionalInfo.newBounds.upper * Number(poolKey.tick_spacing)} ticks`
18912
- }],
19472
+ subItems: [
19473
+ {
19474
+ key: "Range selection",
19475
+ value: `${this.metadata.additionalInfo.newBounds.lower * Number(poolKey.tick_spacing)} to ${this.metadata.additionalInfo.newBounds.upper * Number(poolKey.tick_spacing)} ticks`
19476
+ }
19477
+ ],
18913
19478
  linkedFlows: [linkedFlow],
18914
19479
  style: { backgroundColor: "purple" /* Green */.valueOf() }
18915
19480
  };
@@ -18917,43 +19482,145 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18917
19482
  }
18918
19483
  };
18919
19484
  var _description2 = "Deploys your {{POOL_NAME}} into an Ekubo liquidity pool, automatically rebalancing positions around the current price to optimize yield and reduce the need for manual adjustments. Trading fees and DeFi Spring rewards are automatically compounded back into the strategy. In return, you receive an ERC-20 token representing your share of the strategy. The APY is calculated based on 7-day historical performance.";
18920
- var _protocol2 = { name: "Ekubo", logo: "https://app.ekubo.org/favicon.ico" };
19485
+ var _protocol2 = {
19486
+ name: "Ekubo",
19487
+ logo: "https://app.ekubo.org/favicon.ico"
19488
+ };
18921
19489
  var _riskFactor2 = [
18922
19490
  { type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 0.5, weight: 25 },
18923
19491
  { type: "Impermanent Loss Risk" /* IMPERMANENT_LOSS */, value: 1, weight: 75 }
18924
19492
  ];
19493
+ var _riskFactorStable = [
19494
+ { type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 0.5, weight: 25 }
19495
+ ];
18925
19496
  var AUDIT_URL2 = "https://assets.strkfarm.com/strkfarm/audit_report_vesu_and_ekubo_strats.pdf";
18926
- var EkuboCLVaultStrategies = [{
18927
- name: "Ekubo xSTRK/STRK",
18928
- description: /* @__PURE__ */ jsxs("div", { children: [
18929
- /* @__PURE__ */ jsx("p", { children: _description2.replace("{{POOL_NAME}}", "xSTRK/STRK") }),
18930
- /* @__PURE__ */ jsxs("ul", { style: { marginLeft: "20px", listStyle: "circle", fontSize: "12px" }, children: [
18931
- /* @__PURE__ */ jsx("li", { style: { marginTop: "10px" }, children: "During withdrawal, you may receive either or both tokens depending on market conditions and prevailing prices." }),
18932
- /* @__PURE__ */ jsx("li", { style: { marginTop: "10px" }, children: "Sometimes you might see a negative APY \u2014 this is usually not a big deal. It happens when xSTRK's price drops on DEXes, but things typically bounce back within a few days or a week." })
19497
+ var faqs2 = [
19498
+ {
19499
+ question: "What is the Ekubo CL Vault strategy?",
19500
+ answer: "The Ekubo CL Vault strategy deploys your assets into an Ekubo liquidity pool, automatically rebalancing positions around the current price to optimize yield and reduce manual adjustments."
19501
+ },
19502
+ {
19503
+ question: "How are trading fees and rewards handled?",
19504
+ answer: "Trading fees and DeFi Spring rewards are automatically compounded back into the strategy, increasing your overall returns."
19505
+ },
19506
+ {
19507
+ question: "What happens during withdrawal?",
19508
+ answer: "During withdrawal, you may receive either or both tokens depending on market conditions and prevailing prices."
19509
+ },
19510
+ {
19511
+ question: "Is the strategy audited?",
19512
+ answer: /* @__PURE__ */ jsxs2("div", { children: [
19513
+ "Yes, the strategy has been audited. You can review the audit report in our docs ",
19514
+ /* @__PURE__ */ jsx2("a", { href: "https://docs.strkfarm.com/p/ekubo-cl-vaults#technical-details", style: { textDecoration: "underline", marginLeft: "5px" }, children: "Here" }),
19515
+ "."
18933
19516
  ] })
18934
- ] }),
18935
- address: ContractAddr.from("0x01f083b98674bc21effee29ef443a00c7b9a500fd92cf30341a3da12c73f2324"),
18936
- type: "Other",
18937
- // must be same order as poolKey token0 and token1
18938
- depositTokens: [Global.getDefaultTokens().find((t) => t.symbol === "xSTRK"), Global.getDefaultTokens().find((t) => t.symbol === "STRK")],
18939
- protocols: [_protocol2],
18940
- auditUrl: AUDIT_URL2,
18941
- maxTVL: Web3Number.fromWei("0", 18),
18942
- risk: {
18943
- riskFactor: _riskFactor2,
18944
- netRisk: _riskFactor2.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor2.reduce((acc, curr) => acc + curr.weight, 0),
18945
- notARisks: getNoRiskTags(_riskFactor2)
19517
+ }
19518
+ ];
19519
+ var EkuboCLVaultStrategies = [
19520
+ {
19521
+ name: "Ekubo xSTRK/STRK",
19522
+ description: /* @__PURE__ */ jsxs2("div", { children: [
19523
+ /* @__PURE__ */ jsx2("p", { children: _description2.replace("{{POOL_NAME}}", "xSTRK/STRK") }),
19524
+ /* @__PURE__ */ jsxs2(
19525
+ "ul",
19526
+ {
19527
+ style: {
19528
+ marginLeft: "20px",
19529
+ listStyle: "circle",
19530
+ fontSize: "12px"
19531
+ },
19532
+ children: [
19533
+ /* @__PURE__ */ jsx2("li", { style: { marginTop: "10px" }, children: "During withdrawal, you may receive either or both tokens depending on market conditions and prevailing prices." }),
19534
+ /* @__PURE__ */ jsx2("li", { style: { marginTop: "10px" }, children: "Sometimes you might see a negative APY \u2014 this is usually not a big deal. It happens when xSTRK's price drops on DEXes, but things typically bounce back within a few days or a week." })
19535
+ ]
19536
+ }
19537
+ )
19538
+ ] }),
19539
+ address: ContractAddr.from(
19540
+ "0x01f083b98674bc21effee29ef443a00c7b9a500fd92cf30341a3da12c73f2324"
19541
+ ),
19542
+ launchBlock: 1209881,
19543
+ type: "Other",
19544
+ // must be same order as poolKey token0 and token1
19545
+ depositTokens: [
19546
+ Global.getDefaultTokens().find((t) => t.symbol === "xSTRK"),
19547
+ Global.getDefaultTokens().find((t) => t.symbol === "STRK")
19548
+ ],
19549
+ protocols: [_protocol2],
19550
+ auditUrl: AUDIT_URL2,
19551
+ maxTVL: Web3Number.fromWei("0", 18),
19552
+ risk: {
19553
+ riskFactor: _riskFactor2,
19554
+ netRisk: _riskFactor2.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor2.reduce((acc, curr) => acc + curr.weight, 0),
19555
+ notARisks: getNoRiskTags(_riskFactor2)
19556
+ },
19557
+ apyMethodology: "APY based on 7-day historical performance, including fees and rewards.",
19558
+ additionalInfo: {
19559
+ newBounds: {
19560
+ lower: -1,
19561
+ upper: 1
19562
+ },
19563
+ lstContract: ContractAddr.from(
19564
+ "0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a"
19565
+ ),
19566
+ feeBps: 1e3
19567
+ },
19568
+ faqs: [
19569
+ ...faqs2,
19570
+ {
19571
+ question: "Why might I see a negative APY?",
19572
+ answer: "A negative APY can occur when xSTRK's price drops on DEXes. This is usually temporary and tends to recover within a few days or a week."
19573
+ }
19574
+ ]
18946
19575
  },
18947
- apyMethodology: "APY based on 7-day historical performance, including fees and rewards.",
18948
- additionalInfo: {
18949
- newBounds: {
18950
- lower: -1,
18951
- upper: 1
19576
+ {
19577
+ name: "Ekubo USDC/USDT",
19578
+ description: /* @__PURE__ */ jsxs2("div", { children: [
19579
+ /* @__PURE__ */ jsx2("p", { children: _description2.replace("{{POOL_NAME}}", "USDC/USDT") }),
19580
+ /* @__PURE__ */ jsx2(
19581
+ "ul",
19582
+ {
19583
+ style: {
19584
+ marginLeft: "20px",
19585
+ listStyle: "circle",
19586
+ fontSize: "12px"
19587
+ },
19588
+ children: /* @__PURE__ */ jsx2("li", { style: { marginTop: "10px" }, children: "During withdrawal, you may receive either or both tokens depending on market conditions and prevailing prices." })
19589
+ }
19590
+ )
19591
+ ] }),
19592
+ address: ContractAddr.from(
19593
+ "0xd647ed735f0db52f2a5502b6e06ed21dc4284a43a36af4b60d3c80fbc56c91"
19594
+ ),
19595
+ launchBlock: 1385576,
19596
+ type: "Other",
19597
+ // must be same order as poolKey token0 and token1
19598
+ depositTokens: [
19599
+ Global.getDefaultTokens().find((t) => t.symbol === "USDC"),
19600
+ Global.getDefaultTokens().find((t) => t.symbol === "USDT")
19601
+ ],
19602
+ protocols: [_protocol2],
19603
+ auditUrl: AUDIT_URL2,
19604
+ maxTVL: Web3Number.fromWei("0", 6),
19605
+ risk: {
19606
+ riskFactor: _riskFactorStable,
19607
+ netRisk: _riskFactorStable.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactorStable.reduce((acc, curr) => acc + curr.weight, 0),
19608
+ notARisks: getNoRiskTags(_riskFactorStable)
18952
19609
  },
18953
- lstContract: ContractAddr.from("0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a"),
18954
- feeBps: 1e3
19610
+ apyMethodology: "APY based on 7-day historical performance, including fees and rewards.",
19611
+ additionalInfo: {
19612
+ newBounds: {
19613
+ lower: -1,
19614
+ upper: 1
19615
+ },
19616
+ truePrice: 1,
19617
+ feeBps: 1e3
19618
+ },
19619
+ faqs: [
19620
+ ...faqs2
19621
+ ]
18955
19622
  }
18956
- }];
19623
+ ];
18957
19624
 
18958
19625
  // src/notifs/telegram.ts
18959
19626
  import TelegramBot from "node-telegram-bot-api";