@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.js CHANGED
@@ -76,6 +76,43 @@ var import_axios = __toESM(require("axios"));
76
76
  // src/dataTypes/bignumber.node.ts
77
77
  var import_util = __toESM(require("util"));
78
78
 
79
+ // src/utils/logger.node.ts
80
+ var import_winston = __toESM(require("winston"));
81
+ var colors = {
82
+ error: "red",
83
+ warn: "yellow",
84
+ info: "blue",
85
+ verbose: "white",
86
+ debug: "white"
87
+ };
88
+ import_winston.default.addColors(colors);
89
+ var logger = import_winston.default.createLogger({
90
+ level: "verbose",
91
+ // Set the minimum logging level
92
+ format: import_winston.format.combine(
93
+ import_winston.format.colorize({ all: true }),
94
+ // Apply custom colors
95
+ import_winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
96
+ // Add timestamp to log messages
97
+ import_winston.format.printf(({ timestamp, level, message, ...meta }) => {
98
+ let msg = `${timestamp} ${level}: ${message}`;
99
+ if (meta && meta[Symbol.for("splat")]) {
100
+ for (const arg of meta[Symbol.for("splat")]) {
101
+ if (arg instanceof Error) {
102
+ msg += `
103
+ ${arg.stack}`;
104
+ }
105
+ }
106
+ }
107
+ return msg;
108
+ })
109
+ ),
110
+ transports: [
111
+ new import_winston.default.transports.Console()
112
+ // Output logs to the console
113
+ ]
114
+ });
115
+
79
116
  // src/dataTypes/_bignumber.ts
80
117
  var import_bignumber = __toESM(require("bignumber.js"));
81
118
  var _Web3Number = class extends import_bignumber.default {
@@ -92,6 +129,7 @@ var _Web3Number = class extends import_bignumber.default {
92
129
  }
93
130
  dividedBy(value) {
94
131
  const _value = this.getStandardString(value);
132
+ console.log("dividedBy", _value);
95
133
  return this.construct(this.div(_value).toString(), this.decimals);
96
134
  }
97
135
  plus(value) {
@@ -105,13 +143,15 @@ var _Web3Number = class extends import_bignumber.default {
105
143
  construct(value, decimals) {
106
144
  return new this.constructor(value, decimals);
107
145
  }
108
- toString(decimals = this.maxToFixedDecimals()) {
109
- return super.toFixed(decimals);
146
+ toString() {
147
+ return super.toString();
110
148
  }
111
149
  toJSON() {
150
+ logger.verbose(`converting to json with decimals`);
112
151
  return this.toString();
113
152
  }
114
153
  valueOf() {
154
+ logger.verbose(`converting to valueOf with decimals`);
115
155
  return this.toString();
116
156
  }
117
157
  maxToFixedDecimals() {
@@ -176,12 +216,6 @@ var ContractAddr = class _ContractAddr {
176
216
  };
177
217
 
178
218
  // src/global.ts
179
- var logger = {
180
- ...console,
181
- verbose(message) {
182
- console.log(`[VERBOSE] ${message}`);
183
- }
184
- };
185
219
  var FatalError = class extends Error {
186
220
  constructor(message, err) {
187
221
  super(message);
@@ -775,7 +809,7 @@ var PricerFromApi = class extends PricerBase {
775
809
  } catch (e) {
776
810
  logger.warn("getPriceFromMyAPI error", JSON.stringify(e.message || e));
777
811
  }
778
- logger.log("getPrice coinbase", tokenSymbol);
812
+ logger.info("getPrice coinbase", tokenSymbol);
779
813
  let retry = 0;
780
814
  const MAX_RETRIES = 5;
781
815
  for (retry = 1; retry < MAX_RETRIES + 1; retry++) {
@@ -1956,6 +1990,11 @@ var ERC20 = class {
1956
1990
  const balance = await contract.call("balanceOf", [address.toString()]);
1957
1991
  return Web3Number.fromWei(balance.toString(), tokenDecimals);
1958
1992
  }
1993
+ async allowance(token, owner, spender, tokenDecimals) {
1994
+ const contract = this.contract(token);
1995
+ const allowance = await contract.call("allowance", [owner.toString(), spender.toString()]);
1996
+ return Web3Number.fromWei(allowance.toString(), tokenDecimals);
1997
+ }
1959
1998
  };
1960
1999
 
1961
2000
  // src/modules/avnu.ts
@@ -2095,7 +2134,9 @@ var getRiskColor = (risk) => {
2095
2134
  };
2096
2135
  var getNoRiskTags = (risks) => {
2097
2136
  const noRisks1 = risks.filter((risk) => risk.value === 0).map((risk) => risk.type);
2098
- const noRisks2 = Object.values(RiskType).filter((risk) => !risks.map((risk2) => risk2.type).includes(risk));
2137
+ const noRisks2 = Object.values(RiskType).filter(
2138
+ (risk) => !risks.map((risk2) => risk2.type).includes(risk)
2139
+ );
2099
2140
  const mergedUnique = [.../* @__PURE__ */ new Set([...noRisks1, ...noRisks2])];
2100
2141
  return mergedUnique.map((risk) => `No ${risk}`);
2101
2142
  };
@@ -12787,6 +12828,7 @@ var vesu_pools_default = {
12787
12828
  };
12788
12829
 
12789
12830
  // src/strategies/vesu-rebalance.tsx
12831
+ var import_jsx_runtime = require("react/jsx-runtime");
12790
12832
  var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12791
12833
  // 10000 bps = 100%
12792
12834
  /**
@@ -12800,10 +12842,17 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12800
12842
  super(config);
12801
12843
  this.BASE_WEIGHT = 1e4;
12802
12844
  this.pricer = pricer;
12803
- assert(metadata.depositTokens.length === 1, "VesuRebalance only supports 1 deposit token");
12845
+ assert(
12846
+ metadata.depositTokens.length === 1,
12847
+ "VesuRebalance only supports 1 deposit token"
12848
+ );
12804
12849
  this.metadata = metadata;
12805
12850
  this.address = metadata.address;
12806
- this.contract = new import_starknet8.Contract(vesu_rebalance_abi_default, this.address.address, this.config.provider);
12851
+ this.contract = new import_starknet8.Contract(
12852
+ vesu_rebalance_abi_default,
12853
+ this.address.address,
12854
+ this.config.provider
12855
+ );
12807
12856
  }
12808
12857
  /**
12809
12858
  * Creates a deposit call to the strategy contract.
@@ -12812,10 +12861,23 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12812
12861
  * @returns Populated contract call for deposit
12813
12862
  */
12814
12863
  async depositCall(amountInfo, receiver) {
12815
- assert(amountInfo.tokenInfo.address.eq(this.asset().address), "Deposit token mismatch");
12816
- const assetContract = new import_starknet8.Contract(vesu_rebalance_abi_default, this.asset().address.address, this.config.provider);
12817
- const call1 = assetContract.populate("approve", [this.address.address, import_starknet8.uint256.bnToUint256(amountInfo.amount.toWei())]);
12818
- const call2 = this.contract.populate("deposit", [import_starknet8.uint256.bnToUint256(amountInfo.amount.toWei()), receiver.address]);
12864
+ assert(
12865
+ amountInfo.tokenInfo.address.eq(this.asset().address),
12866
+ "Deposit token mismatch"
12867
+ );
12868
+ const assetContract = new import_starknet8.Contract(
12869
+ vesu_rebalance_abi_default,
12870
+ this.asset().address.address,
12871
+ this.config.provider
12872
+ );
12873
+ const call1 = assetContract.populate("approve", [
12874
+ this.address.address,
12875
+ import_starknet8.uint256.bnToUint256(amountInfo.amount.toWei())
12876
+ ]);
12877
+ const call2 = this.contract.populate("deposit", [
12878
+ import_starknet8.uint256.bnToUint256(amountInfo.amount.toWei()),
12879
+ receiver.address
12880
+ ]);
12819
12881
  return [call1, call2];
12820
12882
  }
12821
12883
  /**
@@ -12826,7 +12888,13 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12826
12888
  * @returns Populated contract call for withdrawal
12827
12889
  */
12828
12890
  async withdrawCall(amountInfo, receiver, owner) {
12829
- return [this.contract.populate("withdraw", [import_starknet8.uint256.bnToUint256(amountInfo.amount.toWei()), receiver.address, owner.address])];
12891
+ return [
12892
+ this.contract.populate("withdraw", [
12893
+ import_starknet8.uint256.bnToUint256(amountInfo.amount.toWei()),
12894
+ receiver.address,
12895
+ owner.address
12896
+ ])
12897
+ ];
12830
12898
  }
12831
12899
  /**
12832
12900
  * Returns the underlying asset token of the strategy.
@@ -12849,9 +12917,16 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12849
12917
  */
12850
12918
  async getUserTVL(user) {
12851
12919
  const shares = await this.contract.balanceOf(user.address);
12852
- const assets = await this.contract.convert_to_assets(import_starknet8.uint256.bnToUint256(shares));
12853
- const amount = Web3Number.fromWei(assets.toString(), this.metadata.depositTokens[0].decimals);
12854
- let price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
12920
+ const assets = await this.contract.convert_to_assets(
12921
+ import_starknet8.uint256.bnToUint256(shares)
12922
+ );
12923
+ const amount = Web3Number.fromWei(
12924
+ assets.toString(),
12925
+ this.metadata.depositTokens[0].decimals
12926
+ );
12927
+ let price = await this.pricer.getPrice(
12928
+ this.metadata.depositTokens[0].symbol
12929
+ );
12855
12930
  const usdValue = Number(amount.toFixed(6)) * price.price;
12856
12931
  return {
12857
12932
  tokenInfo: this.asset(),
@@ -12865,8 +12940,13 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12865
12940
  */
12866
12941
  async getTVL() {
12867
12942
  const assets = await this.contract.total_assets();
12868
- const amount = Web3Number.fromWei(assets.toString(), this.metadata.depositTokens[0].decimals);
12869
- let price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
12943
+ const amount = Web3Number.fromWei(
12944
+ assets.toString(),
12945
+ this.metadata.depositTokens[0].decimals
12946
+ );
12947
+ let price = await this.pricer.getPrice(
12948
+ this.metadata.depositTokens[0].symbol
12949
+ );
12870
12950
  const usdValue = Number(amount.toFixed(6)) * price.price;
12871
12951
  return {
12872
12952
  tokenInfo: this.asset(),
@@ -12892,51 +12972,104 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12892
12972
  return pools;
12893
12973
  }
12894
12974
  async getPoolInfo(p, pools, vesuPositions, totalAssets, isErrorPositionsAPI, isErrorPoolsAPI) {
12895
- const vesuPosition = vesuPositions.find((d) => d.pool.id.toString() === import_starknet8.num.getDecimalString(p.pool_id.address.toString()));
12975
+ const vesuPosition = vesuPositions.find(
12976
+ (d) => d.pool.id.toString() === import_starknet8.num.getDecimalString(p.pool_id.address.toString())
12977
+ );
12896
12978
  const _pool = pools.find((d) => {
12897
- logger.verbose(`pool check: ${d.id == import_starknet8.num.getDecimalString(p.pool_id.address.toString())}, id: ${d.id}, pool_id: ${import_starknet8.num.getDecimalString(p.pool_id.address.toString())}`);
12979
+ logger.verbose(
12980
+ `pool check: ${d.id == import_starknet8.num.getDecimalString(p.pool_id.address.toString())}, id: ${d.id}, pool_id: ${import_starknet8.num.getDecimalString(
12981
+ p.pool_id.address.toString()
12982
+ )}`
12983
+ );
12898
12984
  return d.id == import_starknet8.num.getDecimalString(p.pool_id.address.toString());
12899
12985
  });
12900
12986
  logger.verbose(`pool: ${JSON.stringify(_pool)}`);
12901
12987
  logger.verbose(typeof _pool);
12902
12988
  logger.verbose(`name: ${_pool?.name}`);
12903
12989
  const name = _pool?.name;
12904
- logger.verbose(`name2: ${name}, ${!name ? true : false}, ${name?.length}, ${typeof name}`);
12905
- const assetInfo = _pool?.assets.find((d) => this.asset().address.eqString(d.address));
12990
+ logger.verbose(
12991
+ `name2: ${name}, ${!name ? true : false}, ${name?.length}, ${typeof name}`
12992
+ );
12993
+ const assetInfo = _pool?.assets.find(
12994
+ (d) => this.asset().address.eqString(d.address)
12995
+ );
12906
12996
  if (!name) {
12907
12997
  logger.verbose(`Pool not found`);
12908
12998
  throw new Error(`Pool name ${p.pool_id.address.toString()} not found`);
12909
12999
  }
12910
13000
  if (!assetInfo) {
12911
- throw new Error(`Asset ${this.asset().address.toString()} not found in pool ${p.pool_id.address.toString()}`);
13001
+ throw new Error(
13002
+ `Asset ${this.asset().address.toString()} not found in pool ${p.pool_id.address.toString()}`
13003
+ );
12912
13004
  }
12913
- let vTokenContract = new import_starknet8.Contract(vesu_rebalance_abi_default, p.v_token.address, this.config.provider);
13005
+ let vTokenContract = new import_starknet8.Contract(
13006
+ vesu_rebalance_abi_default,
13007
+ p.v_token.address,
13008
+ this.config.provider
13009
+ );
12914
13010
  const bal = await vTokenContract.balanceOf(this.address.address);
12915
- const assets = await vTokenContract.convert_to_assets(import_starknet8.uint256.bnToUint256(bal.toString()));
13011
+ const assets = await vTokenContract.convert_to_assets(
13012
+ import_starknet8.uint256.bnToUint256(bal.toString())
13013
+ );
12916
13014
  logger.verbose(`Collateral: ${JSON.stringify(vesuPosition?.collateral)}`);
12917
13015
  logger.verbose(`supplyApy: ${JSON.stringify(assetInfo?.stats.supplyApy)}`);
12918
- logger.verbose(`defiSpringSupplyApr: ${JSON.stringify(assetInfo?.stats.defiSpringSupplyApr)}`);
12919
- logger.verbose(`currentUtilization: ${JSON.stringify(assetInfo?.stats.currentUtilization)}`);
12920
- logger.verbose(`maxUtilization: ${JSON.stringify(assetInfo?.config.maxUtilization)}`);
13016
+ logger.verbose(
13017
+ `defiSpringSupplyApr: ${JSON.stringify(
13018
+ assetInfo?.stats.defiSpringSupplyApr
13019
+ )}`
13020
+ );
13021
+ logger.verbose(
13022
+ `currentUtilization: ${JSON.stringify(
13023
+ assetInfo?.stats.currentUtilization
13024
+ )}`
13025
+ );
13026
+ logger.verbose(
13027
+ `maxUtilization: ${JSON.stringify(assetInfo?.config.maxUtilization)}`
13028
+ );
12921
13029
  const item = {
12922
13030
  pool_id: p.pool_id,
12923
13031
  pool_name: _pool?.name,
12924
13032
  max_weight: p.max_weight,
12925
- current_weight: isErrorPositionsAPI || !vesuPosition ? 0 : Number(Web3Number.fromWei(vesuPosition.collateral.value, this.decimals()).dividedBy(totalAssets.toString()).toFixed(6)),
13033
+ current_weight: isErrorPositionsAPI || !vesuPosition ? 0 : Number(
13034
+ Web3Number.fromWei(vesuPosition.collateral.value, this.decimals()).dividedBy(totalAssets.toString()).toFixed(6)
13035
+ ),
12926
13036
  v_token: p.v_token,
12927
13037
  amount: Web3Number.fromWei(assets.toString(), this.decimals()),
12928
- usdValue: isErrorPositionsAPI || !vesuPosition ? Web3Number.fromWei("0", this.decimals()) : Web3Number.fromWei(vesuPosition.collateral.usdPrice.value, vesuPosition.collateral.usdPrice.decimals),
13038
+ usdValue: isErrorPositionsAPI || !vesuPosition ? Web3Number.fromWei("0", this.decimals()) : Web3Number.fromWei(
13039
+ vesuPosition.collateral.usdPrice.value,
13040
+ vesuPosition.collateral.usdPrice.decimals
13041
+ ),
12929
13042
  APY: isErrorPoolsAPI || !assetInfo ? {
12930
13043
  baseApy: 0,
12931
13044
  defiSpringApy: 0,
12932
13045
  netApy: 0
12933
13046
  } : {
12934
- baseApy: Number(Web3Number.fromWei(assetInfo.stats.supplyApy.value, assetInfo.stats.supplyApy.decimals).toFixed(6)),
12935
- defiSpringApy: assetInfo.stats.defiSpringSupplyApr ? Number(Web3Number.fromWei(assetInfo.stats.defiSpringSupplyApr.value, assetInfo.stats.defiSpringSupplyApr.decimals).toFixed(6)) : 0,
13047
+ baseApy: Number(
13048
+ Web3Number.fromWei(
13049
+ assetInfo.stats.supplyApy.value,
13050
+ assetInfo.stats.supplyApy.decimals
13051
+ ).toFixed(6)
13052
+ ),
13053
+ defiSpringApy: assetInfo.stats.defiSpringSupplyApr ? Number(
13054
+ Web3Number.fromWei(
13055
+ assetInfo.stats.defiSpringSupplyApr.value,
13056
+ assetInfo.stats.defiSpringSupplyApr.decimals
13057
+ ).toFixed(6)
13058
+ ) : 0,
12936
13059
  netApy: 0
12937
13060
  },
12938
- currentUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(Web3Number.fromWei(assetInfo.stats.currentUtilization.value, assetInfo.stats.currentUtilization.decimals).toFixed(6)),
12939
- maxUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(Web3Number.fromWei(assetInfo.config.maxUtilization.value, assetInfo.config.maxUtilization.decimals).toFixed(6))
13061
+ currentUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(
13062
+ Web3Number.fromWei(
13063
+ assetInfo.stats.currentUtilization.value,
13064
+ assetInfo.stats.currentUtilization.decimals
13065
+ ).toFixed(6)
13066
+ ),
13067
+ maxUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(
13068
+ Web3Number.fromWei(
13069
+ assetInfo.config.maxUtilization.value,
13070
+ assetInfo.config.maxUtilization.decimals
13071
+ ).toFixed(6)
13072
+ )
12940
13073
  };
12941
13074
  item.APY.netApy = item.APY.baseApy + item.APY.defiSpringApy;
12942
13075
  return item;
@@ -12946,7 +13079,7 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12946
13079
  * 1. Contract's allowed pools
12947
13080
  * 2. Vesu positions API for current positions
12948
13081
  * 3. Vesu pools API for APY and utilization data
12949
- *
13082
+ *
12950
13083
  * @returns {Promise<{
12951
13084
  * data: Array<PoolInfoFull>,
12952
13085
  * isErrorPositionsAPI: boolean
@@ -12963,15 +13096,29 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12963
13096
  let isErrorPositionsAPI = false;
12964
13097
  let vesuPositions = [];
12965
13098
  try {
12966
- const data2 = await getAPIUsingHeadlessBrowser(`https://api.vesu.xyz/positions?walletAddress=${this.address.address}`);
13099
+ const data2 = await getAPIUsingHeadlessBrowser(
13100
+ `https://api.vesu.xyz/positions?walletAddress=${this.address.address}`
13101
+ );
12967
13102
  vesuPositions = data2.data;
12968
13103
  } catch (e) {
12969
- console.error(`${_VesuRebalance.name}: Error fetching positions for ${this.address.address}`, e);
13104
+ console.error(
13105
+ `${_VesuRebalance.name}: Error fetching positions for ${this.address.address}`,
13106
+ e
13107
+ );
12970
13108
  isErrorPositionsAPI = true;
12971
13109
  }
12972
13110
  let { pools, isErrorPoolsAPI } = await this.getVesuPools();
12973
13111
  const totalAssets = (await this.getTVL()).amount;
12974
- const info = allowedPools.map((p) => this.getPoolInfo(p, pools, vesuPositions, totalAssets, isErrorPositionsAPI, isErrorPoolsAPI));
13112
+ const info = allowedPools.map(
13113
+ (p) => this.getPoolInfo(
13114
+ p,
13115
+ pools,
13116
+ vesuPositions,
13117
+ totalAssets,
13118
+ isErrorPositionsAPI,
13119
+ isErrorPoolsAPI
13120
+ )
13121
+ );
12975
13122
  const data = await Promise.all(info);
12976
13123
  return {
12977
13124
  data,
@@ -12984,18 +13131,25 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
12984
13131
  let isErrorPoolsAPI = false;
12985
13132
  let pools = [];
12986
13133
  try {
12987
- const data = await getAPIUsingHeadlessBrowser("https://api.vesu.xyz/pools");
13134
+ const data = await getAPIUsingHeadlessBrowser(
13135
+ "https://api.vesu.xyz/pools"
13136
+ );
12988
13137
  pools = data.data;
12989
13138
  for (const pool of vesu_pools_default.data) {
12990
13139
  const found = pools.find((d) => d.id === pool.id);
12991
13140
  if (!found) {
12992
13141
  logger.verbose(`VesuRebalance: pools: ${JSON.stringify(pools)}`);
12993
- logger.verbose(`VesuRebalance: Pool ${pool.id} not found in Vesu API, using hardcoded data`);
13142
+ logger.verbose(
13143
+ `VesuRebalance: Pool ${pool.id} not found in Vesu API, using hardcoded data`
13144
+ );
12994
13145
  throw new Error("pool not found [sanity check]");
12995
13146
  }
12996
13147
  }
12997
13148
  } catch (e) {
12998
- logger.error(`${_VesuRebalance.name}: Error fetching pools for ${this.address.address}, retry ${retry}`, e);
13149
+ logger.error(
13150
+ `${_VesuRebalance.name}: Error fetching pools for ${this.address.address}, retry ${retry}`,
13151
+ e
13152
+ );
12999
13153
  isErrorPoolsAPI = true;
13000
13154
  if (retry < 10) {
13001
13155
  await new Promise((resolve) => setTimeout(resolve, 5e3 * (retry + 1)));
@@ -13033,8 +13187,8 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13033
13187
  * 3. For each pool that needs more funds:
13034
13188
  * - Takes funds from lowest APY pools that are over their target
13035
13189
  * 4. Validates that total assets remain constant
13036
- *
13037
- * @returns {Promise<{
13190
+ *
13191
+ * @returns {Promise<{
13038
13192
  * changes: Change[],
13039
13193
  * finalPools: PoolInfoFull[],
13040
13194
  * isAnyPoolOverMaxWeight: boolean
@@ -13050,27 +13204,38 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13050
13204
  _pools = _pools2;
13051
13205
  }
13052
13206
  const feeDeductions = await this.getFee(_pools);
13053
- logger.verbose(`VesuRebalance: feeDeductions: ${JSON.stringify(feeDeductions)}`);
13207
+ logger.verbose(
13208
+ `VesuRebalance: feeDeductions: ${JSON.stringify(feeDeductions)}`
13209
+ );
13054
13210
  const pools = _pools.map((p) => {
13055
13211
  const fee = feeDeductions.find((f) => p.v_token.eq(f.vToken))?.fee || Web3Number.fromWei("0", this.decimals());
13056
- logger.verbose(`FeeAdjustment: ${p.pool_id} => ${fee.toString()}, amt: ${p.amount.toString()}`);
13212
+ logger.verbose(
13213
+ `FeeAdjustment: ${p.pool_id} => ${fee.toString()}, amt: ${p.amount.toString()}`
13214
+ );
13057
13215
  return {
13058
13216
  ...p,
13059
13217
  amount: p.amount.minus(fee)
13060
13218
  };
13061
13219
  });
13062
13220
  let totalAssets = (await this.getTVL()).amount;
13063
- if (totalAssets.eq(0)) return {
13064
- changes: [],
13065
- finalPools: []
13066
- };
13221
+ if (totalAssets.eq(0))
13222
+ return {
13223
+ changes: [],
13224
+ finalPools: []
13225
+ };
13067
13226
  feeDeductions.forEach((f) => {
13068
13227
  totalAssets = totalAssets.minus(f.fee);
13069
13228
  });
13070
- const sumPools = pools.reduce((acc, curr) => acc.plus(curr.amount.toString()), Web3Number.fromWei("0", this.decimals()));
13229
+ const sumPools = pools.reduce(
13230
+ (acc, curr) => acc.plus(curr.amount.toString()),
13231
+ Web3Number.fromWei("0", this.decimals())
13232
+ );
13071
13233
  logger.verbose(`Sum of pools: ${sumPools.toString()}`);
13072
13234
  logger.verbose(`Total assets: ${totalAssets.toString()}`);
13073
- assert(sumPools.lte(totalAssets.multipliedBy(1.00001).toString()), "Sum of pools.amount must be less than or equal to totalAssets");
13235
+ assert(
13236
+ sumPools.lte(totalAssets.multipliedBy(1.00001).toString()),
13237
+ "Sum of pools.amount must be less than or equal to totalAssets"
13238
+ );
13074
13239
  const sortedPools = [...pools].sort((a, b) => b.APY.netApy - a.APY.netApy);
13075
13240
  const targetAmounts = {};
13076
13241
  let remainingAssets = totalAssets;
@@ -13092,7 +13257,10 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13092
13257
  assert(remainingAssets.lt(1e-5), "Remaining assets must be 0");
13093
13258
  const changes = sortedPools.map((pool) => {
13094
13259
  const target = targetAmounts[pool.pool_id.address.toString()] || Web3Number.fromWei("0", this.decimals());
13095
- const change = Web3Number.fromWei(target.minus(pool.amount.toString()).toWei(), this.decimals());
13260
+ const change = Web3Number.fromWei(
13261
+ target.minus(pool.amount.toString()).toWei(),
13262
+ this.decimals()
13263
+ );
13096
13264
  return {
13097
13265
  pool_id: pool.pool_id,
13098
13266
  changeAmt: change,
@@ -13101,14 +13269,21 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13101
13269
  };
13102
13270
  });
13103
13271
  logger.verbose(`Changes: ${JSON.stringify(changes)}`);
13104
- const sumChanges = changes.reduce((sum, c) => sum.plus(c.changeAmt.toString()), Web3Number.fromWei("0", this.decimals()));
13105
- const sumFinal = changes.reduce((sum, c) => sum.plus(c.finalAmt.toString()), Web3Number.fromWei("0", this.decimals()));
13272
+ const sumChanges = changes.reduce(
13273
+ (sum, c) => sum.plus(c.changeAmt.toString()),
13274
+ Web3Number.fromWei("0", this.decimals())
13275
+ );
13276
+ const sumFinal = changes.reduce(
13277
+ (sum, c) => sum.plus(c.finalAmt.toString()),
13278
+ Web3Number.fromWei("0", this.decimals())
13279
+ );
13106
13280
  const hasChanges = changes.some((c) => !c.changeAmt.eq(0));
13107
13281
  logger.verbose(`Sum of changes: ${sumChanges.toString()}`);
13108
13282
  if (!sumChanges.eq(0)) throw new Error("Sum of changes must be zero");
13109
13283
  logger.verbose(`Sum of final: ${sumFinal.toString()}`);
13110
13284
  logger.verbose(`Total assets: ${totalAssets.toString()}`);
13111
- if (!sumFinal.eq(totalAssets.toString())) throw new Error("Sum of final amounts must equal total assets");
13285
+ if (!sumFinal.eq(totalAssets.toString()))
13286
+ throw new Error("Sum of final amounts must equal total assets");
13112
13287
  if (!hasChanges) throw new Error("No changes required");
13113
13288
  const finalPools = pools.map((p) => {
13114
13289
  const target = targetAmounts[p.pool_id.address.toString()] || Web3Number.fromWei("0", this.decimals());
@@ -13136,9 +13311,13 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13136
13311
  if (p.changeAmt.eq(0)) return null;
13137
13312
  actions.push({
13138
13313
  pool_id: p.pool_id.address,
13139
- feature: new import_starknet8.CairoCustomEnum(p.isDeposit ? { DEPOSIT: {} } : { WITHDRAW: {} }),
13314
+ feature: new import_starknet8.CairoCustomEnum(
13315
+ p.isDeposit ? { DEPOSIT: {} } : { WITHDRAW: {} }
13316
+ ),
13140
13317
  token: this.asset().address.address,
13141
- amount: import_starknet8.uint256.bnToUint256(p.changeAmt.multipliedBy(p.isDeposit ? 1 : -1).toWei())
13318
+ amount: import_starknet8.uint256.bnToUint256(
13319
+ p.changeAmt.multipliedBy(p.isDeposit ? 1 : -1).toWei()
13320
+ )
13142
13321
  });
13143
13322
  });
13144
13323
  if (actions.length === 0) return null;
@@ -13151,18 +13330,29 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13151
13330
  const netYield = await this.netAPYGivenPools(pools);
13152
13331
  const baseFlow = {
13153
13332
  title: "Your Deposit",
13154
- subItems: [{ key: `Net yield`, value: `${(netYield * 100).toFixed(2)}%` }, { key: `Performance Fee`, value: `${(this.metadata.additionalInfo.feeBps / 100).toFixed(2)}%` }],
13333
+ subItems: [
13334
+ { key: `Net yield`, value: `${(netYield * 100).toFixed(2)}%` },
13335
+ {
13336
+ key: `Performance Fee`,
13337
+ value: `${(this.metadata.additionalInfo.feeBps / 100).toFixed(2)}%`
13338
+ }
13339
+ ],
13155
13340
  linkedFlows: [],
13156
13341
  style: { backgroundColor: "#6e53dc" /* Purple */.valueOf() }
13157
13342
  };
13158
13343
  let _pools = [...pools];
13159
- _pools = _pools.sort((a, b) => Number(b.amount.toString()) - Number(a.amount.toString()));
13344
+ _pools = _pools.sort(
13345
+ (a, b) => Number(b.amount.toString()) - Number(a.amount.toString())
13346
+ );
13160
13347
  _pools.forEach((p) => {
13161
13348
  const flow = {
13162
13349
  title: `Pool name: ${p.pool_name}`,
13163
13350
  subItems: [
13164
13351
  { key: `APY`, value: `${(p.APY.netApy * 100).toFixed(2)}%` },
13165
- { key: "Weight", value: `${(p.current_weight * 100).toFixed(2)} / ${(p.max_weight * 100).toFixed(2)}%` }
13352
+ {
13353
+ key: "Weight",
13354
+ value: `${(p.current_weight * 100).toFixed(2)} / ${(p.max_weight * 100).toFixed(2)}%`
13355
+ }
13166
13356
  ],
13167
13357
  linkedFlows: [],
13168
13358
  style: p.amount.greaterThan(0) ? { backgroundColor: "#35484f" /* Blue */.valueOf() } : { color: "gray" }
@@ -13194,7 +13384,12 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13194
13384
  harvest.actualReward.toWei(),
13195
13385
  this.address.address
13196
13386
  );
13197
- swapInfo = await avnu.getSwapInfo(quote, this.address.address, 0, this.address.address);
13387
+ swapInfo = await avnu.getSwapInfo(
13388
+ quote,
13389
+ this.address.address,
13390
+ 0,
13391
+ this.address.address
13392
+ );
13198
13393
  }
13199
13394
  return [
13200
13395
  this.contract.populate("harvest", [
@@ -13215,16 +13410,27 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13215
13410
  * @returns {Promise<Array<{ vToken: ContractAddr, fee: Web3Number }>>} Array of fees deducted in different vTokens
13216
13411
  */
13217
13412
  async getFee(allowedPools) {
13218
- const assets = Web3Number.fromWei((await this.contract.total_assets()).toString(), this.asset().decimals);
13219
- const totalSupply = Web3Number.fromWei((await this.contract.total_supply()).toString(), this.asset().decimals);
13220
- const prevIndex = Web3Number.fromWei((await this.contract.get_previous_index()).toString(), 18);
13413
+ const assets = Web3Number.fromWei(
13414
+ (await this.contract.total_assets()).toString(),
13415
+ this.asset().decimals
13416
+ );
13417
+ const totalSupply = Web3Number.fromWei(
13418
+ (await this.contract.total_supply()).toString(),
13419
+ this.asset().decimals
13420
+ );
13421
+ const prevIndex = Web3Number.fromWei(
13422
+ (await this.contract.get_previous_index()).toString(),
13423
+ 18
13424
+ );
13221
13425
  const currIndex = new Web3Number(1, 18).multipliedBy(assets).dividedBy(totalSupply);
13222
13426
  logger.verbose(`Previous index: ${prevIndex.toString()}`);
13223
13427
  logger.verbose(`Assets: ${assets.toString()}`);
13224
13428
  logger.verbose(`Total supply: ${totalSupply.toString()}`);
13225
13429
  logger.verbose(`Current index: ${currIndex.toNumber()}`);
13226
13430
  if (currIndex.lt(prevIndex)) {
13227
- logger.verbose(`getFee::Current index is less than previous index, no fees to be deducted`);
13431
+ logger.verbose(
13432
+ `getFee::Current index is less than previous index, no fees to be deducted`
13433
+ );
13228
13434
  return [];
13229
13435
  }
13230
13436
  const indexDiff = currIndex.minus(prevIndex);
@@ -13237,7 +13443,9 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13237
13443
  return [];
13238
13444
  }
13239
13445
  const fees = [];
13240
- let remainingFee = fee.plus(Web3Number.fromWei("100", this.asset().decimals));
13446
+ let remainingFee = fee.plus(
13447
+ Web3Number.fromWei("100", this.asset().decimals)
13448
+ );
13241
13449
  for (const pool of allowedPools) {
13242
13450
  const vToken = pool.v_token;
13243
13451
  const balance = pool.amount;
@@ -13246,7 +13454,9 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13246
13454
  break;
13247
13455
  } else {
13248
13456
  fees.push({ vToken, fee: Web3Number.fromWei(balance.toString(), 18) });
13249
- remainingFee = remainingFee.minus(Web3Number.fromWei(balance.toString(), 18));
13457
+ remainingFee = remainingFee.minus(
13458
+ Web3Number.fromWei(balance.toString(), 18)
13459
+ );
13250
13460
  }
13251
13461
  }
13252
13462
  logger.verbose(`Fees: ${JSON.stringify(fees)}`);
@@ -13254,98 +13464,172 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
13254
13464
  }
13255
13465
  };
13256
13466
  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.";
13257
- var _protocol = { name: "Vesu", logo: "https://static-assets-8zct.onrender.com/integrations/vesu/logo.png" };
13467
+ var _protocol = {
13468
+ name: "Vesu",
13469
+ logo: "https://static-assets-8zct.onrender.com/integrations/vesu/logo.png"
13470
+ };
13258
13471
  var _riskFactor = [
13259
13472
  { type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 0.5, weight: 25 },
13260
13473
  { type: "Counterparty Risk" /* COUNTERPARTY_RISK */, value: 1, weight: 50 },
13261
13474
  { type: "Oracle Risk" /* ORACLE_RISK */, value: 0.5, weight: 25 }
13262
13475
  ];
13263
13476
  var AUDIT_URL = "https://assets.strkfarm.com/strkfarm/audit_report_vesu_and_ekubo_strats.pdf";
13264
- var VesuRebalanceStrategies = [{
13265
- name: "Vesu Fusion STRK",
13266
- description: _description.replace("{{TOKEN}}", "STRK"),
13267
- address: ContractAddr.from("0x7fb5bcb8525954a60fde4e8fb8220477696ce7117ef264775a1770e23571929"),
13268
- type: "ERC4626",
13269
- depositTokens: [Global.getDefaultTokens().find((t) => t.symbol === "STRK")],
13270
- protocols: [_protocol],
13271
- auditUrl: AUDIT_URL,
13272
- maxTVL: Web3Number.fromWei("0", 18),
13273
- risk: {
13274
- riskFactor: _riskFactor,
13275
- netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13276
- notARisks: getNoRiskTags(_riskFactor)
13477
+ var faqs = [
13478
+ {
13479
+ question: "What is the Vesu Rebalancing Strategy?",
13480
+ 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."
13277
13481
  },
13278
- additionalInfo: {
13279
- feeBps: 1e3
13280
- }
13281
- }, {
13282
- name: "Vesu Fusion ETH",
13283
- description: _description.replace("{{TOKEN}}", "ETH"),
13284
- address: ContractAddr.from("0x5eaf5ee75231cecf79921ff8ded4b5ffe96be718bcb3daf206690ad1a9ad0ca"),
13285
- type: "ERC4626",
13286
- auditUrl: AUDIT_URL,
13287
- depositTokens: [Global.getDefaultTokens().find((t) => t.symbol === "ETH")],
13288
- protocols: [_protocol],
13289
- maxTVL: Web3Number.fromWei("0", 18),
13290
- risk: {
13291
- riskFactor: _riskFactor,
13292
- netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13293
- notARisks: getNoRiskTags(_riskFactor)
13482
+ {
13483
+ question: "Will I earn Vesu points?",
13484
+ answer: "Yes, of course! You will earn Vesu points for your deposits."
13294
13485
  },
13295
- additionalInfo: {
13296
- feeBps: 1e3
13297
- }
13298
- }, {
13299
- name: "Vesu Fusion USDC",
13300
- description: _description.replace("{{TOKEN}}", "USDC"),
13301
- address: ContractAddr.from("0xa858c97e9454f407d1bd7c57472fc8d8d8449a777c822b41d18e387816f29c"),
13302
- type: "ERC4626",
13303
- auditUrl: AUDIT_URL,
13304
- depositTokens: [Global.getDefaultTokens().find((t) => t.symbol === "USDC")],
13305
- protocols: [_protocol],
13306
- maxTVL: Web3Number.fromWei("0", 6),
13307
- risk: {
13308
- riskFactor: _riskFactor,
13309
- netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13310
- notARisks: getNoRiskTags(_riskFactor)
13486
+ {
13487
+ question: "How does the strategy optimize yield?",
13488
+ 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."
13489
+ },
13490
+ {
13491
+ question: "What are the risks associated with this strategy?",
13492
+ 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."
13493
+ },
13494
+ {
13495
+ question: "How are fees calculated and deducted?",
13496
+ 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."
13497
+ },
13498
+ {
13499
+ question: "What happens if a pool exceeds its maximum weight?",
13500
+ answer: "If a pool exceeds its maximum weight, the strategy rebalances by withdrawing excess funds and reallocating them to other pools with available capacity."
13501
+ },
13502
+ {
13503
+ question: "Can I withdraw my assets at any time?",
13504
+ 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."
13505
+ },
13506
+ {
13507
+ question: "What happens to my Defi Spring STRK rewards?",
13508
+ answer: "STRK rewards are automatically harvested and reinvested into the strategy every week to maximize compounding returns."
13311
13509
  },
13312
- additionalInfo: {
13313
- feeBps: 1e3
13510
+ {
13511
+ question: "Is the strategy audited?",
13512
+ answer: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
13513
+ "Yes, the strategy has been audited. You can review the audit report in our docs ",
13514
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: "https://docs.strkfarm.com/p/strategies/vesu-fusion-rebalancing-vaults#technical-details", style: { textDecoration: "underline", marginLeft: "5px" }, children: "Here" }),
13515
+ "."
13516
+ ] })
13314
13517
  }
13315
- }, {
13316
- name: "Vesu Fusion USDT",
13317
- description: _description.replace("{{TOKEN}}", "USDT"),
13318
- address: ContractAddr.from("0x115e94e722cfc4c77a2f15c4aefb0928c1c0029e5a57570df24c650cb7cec2c"),
13319
- type: "ERC4626",
13320
- depositTokens: [Global.getDefaultTokens().find((t) => t.symbol === "USDT")],
13321
- auditUrl: AUDIT_URL,
13322
- protocols: [_protocol],
13323
- maxTVL: Web3Number.fromWei("0", 6),
13324
- risk: {
13325
- riskFactor: _riskFactor,
13326
- netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13327
- notARisks: getNoRiskTags(_riskFactor)
13518
+ ];
13519
+ var VesuRebalanceStrategies = [
13520
+ {
13521
+ name: "Vesu Fusion STRK",
13522
+ description: _description.replace("{{TOKEN}}", "STRK"),
13523
+ address: ContractAddr.from(
13524
+ "0x7fb5bcb8525954a60fde4e8fb8220477696ce7117ef264775a1770e23571929"
13525
+ ),
13526
+ launchBlock: 0,
13527
+ type: "ERC4626",
13528
+ depositTokens: [
13529
+ Global.getDefaultTokens().find((t) => t.symbol === "STRK")
13530
+ ],
13531
+ protocols: [_protocol],
13532
+ auditUrl: AUDIT_URL,
13533
+ maxTVL: Web3Number.fromWei("0", 18),
13534
+ risk: {
13535
+ riskFactor: _riskFactor,
13536
+ netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13537
+ notARisks: getNoRiskTags(_riskFactor)
13538
+ },
13539
+ additionalInfo: {
13540
+ feeBps: 1e3
13541
+ },
13542
+ faqs
13543
+ },
13544
+ {
13545
+ name: "Vesu Fusion ETH",
13546
+ description: _description.replace("{{TOKEN}}", "ETH"),
13547
+ address: ContractAddr.from(
13548
+ "0x5eaf5ee75231cecf79921ff8ded4b5ffe96be718bcb3daf206690ad1a9ad0ca"
13549
+ ),
13550
+ launchBlock: 0,
13551
+ type: "ERC4626",
13552
+ auditUrl: AUDIT_URL,
13553
+ depositTokens: [
13554
+ Global.getDefaultTokens().find((t) => t.symbol === "ETH")
13555
+ ],
13556
+ protocols: [_protocol],
13557
+ maxTVL: Web3Number.fromWei("0", 18),
13558
+ risk: {
13559
+ riskFactor: _riskFactor,
13560
+ netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13561
+ notARisks: getNoRiskTags(_riskFactor)
13562
+ },
13563
+ additionalInfo: {
13564
+ feeBps: 1e3
13565
+ },
13566
+ faqs
13567
+ },
13568
+ {
13569
+ name: "Vesu Fusion USDC",
13570
+ description: _description.replace("{{TOKEN}}", "USDC"),
13571
+ address: ContractAddr.from(
13572
+ "0xa858c97e9454f407d1bd7c57472fc8d8d8449a777c822b41d18e387816f29c"
13573
+ ),
13574
+ launchBlock: 0,
13575
+ type: "ERC4626",
13576
+ auditUrl: AUDIT_URL,
13577
+ depositTokens: [
13578
+ Global.getDefaultTokens().find((t) => t.symbol === "USDC")
13579
+ ],
13580
+ protocols: [_protocol],
13581
+ maxTVL: Web3Number.fromWei("0", 6),
13582
+ risk: {
13583
+ riskFactor: _riskFactor,
13584
+ netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13585
+ notARisks: getNoRiskTags(_riskFactor)
13586
+ },
13587
+ additionalInfo: {
13588
+ feeBps: 1e3
13589
+ },
13590
+ faqs
13328
13591
  },
13329
- additionalInfo: {
13330
- feeBps: 1e3
13592
+ {
13593
+ name: "Vesu Fusion USDT",
13594
+ description: _description.replace("{{TOKEN}}", "USDT"),
13595
+ address: ContractAddr.from(
13596
+ "0x115e94e722cfc4c77a2f15c4aefb0928c1c0029e5a57570df24c650cb7cec2c"
13597
+ ),
13598
+ launchBlock: 0,
13599
+ type: "ERC4626",
13600
+ depositTokens: [
13601
+ Global.getDefaultTokens().find((t) => t.symbol === "USDT")
13602
+ ],
13603
+ auditUrl: AUDIT_URL,
13604
+ protocols: [_protocol],
13605
+ maxTVL: Web3Number.fromWei("0", 6),
13606
+ risk: {
13607
+ riskFactor: _riskFactor,
13608
+ netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13609
+ notARisks: getNoRiskTags(_riskFactor)
13610
+ },
13611
+ additionalInfo: {
13612
+ feeBps: 1e3
13613
+ },
13614
+ faqs
13615
+ // }, {
13616
+ // name: 'Vesu Fusion WBTC',
13617
+ // description: _description.replace('{{TOKEN}}', 'WBTC'),
13618
+ // address: ContractAddr.from('0x778007f8136a5b827325d21613803e796bda4d676fbe1e34aeab0b2a2ec027f'),
13619
+ // type: 'ERC4626',
13620
+ // depositTokens: [Global.getDefaultTokens().find(t => t.symbol === 'WBTC')!],
13621
+ // auditUrl: AUDIT_URL,
13622
+ // protocols: [_protocol],
13623
+ // maxTVL: Web3Number.fromWei('0', 8),
13624
+ // risk: {
13625
+ // riskFactor: _riskFactor,
13626
+ // netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13627
+ // },
13628
+ // additionalInfo: {
13629
+ // feeBps: 1000,
13630
+ // },
13331
13631
  }
13332
- // }, {
13333
- // name: 'Vesu Fusion WBTC',
13334
- // description: _description.replace('{{TOKEN}}', 'WBTC'),
13335
- // address: ContractAddr.from('0x778007f8136a5b827325d21613803e796bda4d676fbe1e34aeab0b2a2ec027f'),
13336
- // type: 'ERC4626',
13337
- // depositTokens: [Global.getDefaultTokens().find(t => t.symbol === 'WBTC')!],
13338
- // auditUrl: AUDIT_URL,
13339
- // protocols: [_protocol],
13340
- // maxTVL: Web3Number.fromWei('0', 8),
13341
- // risk: {
13342
- // riskFactor: _riskFactor,
13343
- // netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
13344
- // },
13345
- // additionalInfo: {
13346
- // feeBps: 1000,
13347
- // },
13348
- }];
13632
+ ];
13349
13633
 
13350
13634
  // src/strategies/ekubo-cl-vault.tsx
13351
13635
  var import_starknet9 = require("starknet");
@@ -18250,7 +18534,7 @@ var erc4626_abi_default = [
18250
18534
  ];
18251
18535
 
18252
18536
  // src/strategies/ekubo-cl-vault.tsx
18253
- var import_jsx_runtime = require("react/jsx-runtime");
18537
+ var import_jsx_runtime2 = require("react/jsx-runtime");
18254
18538
  var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18255
18539
  /**
18256
18540
  * Creates a new VesuRebalance strategy instance.
@@ -18263,15 +18547,38 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18263
18547
  super(config);
18264
18548
  this.BASE_WEIGHT = 1e4;
18265
18549
  this.pricer = pricer;
18266
- assert(metadata.depositTokens.length === 2, "EkuboCL only supports 2 deposit token");
18550
+ assert(
18551
+ metadata.depositTokens.length === 2,
18552
+ "EkuboCL only supports 2 deposit token"
18553
+ );
18267
18554
  this.metadata = metadata;
18268
18555
  this.address = metadata.address;
18269
- this.contract = new import_starknet9.Contract(cl_vault_abi_default, this.address.address, this.config.provider);
18270
- this.lstContract = new import_starknet9.Contract(erc4626_abi_default, this.metadata.additionalInfo.lstContract.address, this.config.provider);
18556
+ this.contract = new import_starknet9.Contract(
18557
+ cl_vault_abi_default,
18558
+ this.address.address,
18559
+ this.config.provider
18560
+ );
18561
+ if (this.metadata.additionalInfo.lstContract) {
18562
+ this.lstContract = new import_starknet9.Contract(
18563
+ erc4626_abi_default,
18564
+ this.metadata.additionalInfo.lstContract.address,
18565
+ this.config.provider
18566
+ );
18567
+ } else {
18568
+ this.lstContract = null;
18569
+ }
18271
18570
  const EKUBO_POSITION = "0x02e0af29598b407c8716b17f6d2795eca1b471413fa03fb145a5e33722184067";
18272
- this.ekuboPositionsContract = new import_starknet9.Contract(ekubo_positions_abi_default, EKUBO_POSITION, this.config.provider);
18571
+ this.ekuboPositionsContract = new import_starknet9.Contract(
18572
+ ekubo_positions_abi_default,
18573
+ EKUBO_POSITION,
18574
+ this.config.provider
18575
+ );
18273
18576
  const EKUBO_MATH = "0x04a72e9e166f6c0e9d800af4dc40f6b6fb4404b735d3f528d9250808b2481995";
18274
- this.ekuboMathContract = new import_starknet9.Contract(ekubo_math_abi_default, EKUBO_MATH, this.config.provider);
18577
+ this.ekuboMathContract = new import_starknet9.Contract(
18578
+ ekubo_math_abi_default,
18579
+ EKUBO_MATH,
18580
+ this.config.provider
18581
+ );
18275
18582
  this.avnu = new AvnuWrapper();
18276
18583
  }
18277
18584
  async matchInputAmounts(amountInfo) {
@@ -18296,25 +18603,52 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18296
18603
  /** Returns minimum amounts give given two amounts based on what can be added for liq */
18297
18604
  async getMinDepositAmounts(amountInfo) {
18298
18605
  const shares = await this.tokensToShares(amountInfo);
18299
- const { amount0, amount1 } = await this.contract.call("convert_to_assets", [import_starknet9.uint256.bnToUint256(shares.toWei())]);
18606
+ const { amount0, amount1 } = await this.contract.call(
18607
+ "convert_to_assets",
18608
+ [import_starknet9.uint256.bnToUint256(shares.toWei())]
18609
+ );
18300
18610
  return {
18301
18611
  token0: {
18302
18612
  tokenInfo: amountInfo.token0.tokenInfo,
18303
- amount: Web3Number.fromWei(amount0.toString(), amountInfo.token0.tokenInfo.decimals)
18613
+ amount: Web3Number.fromWei(
18614
+ amount0.toString(),
18615
+ amountInfo.token0.tokenInfo.decimals
18616
+ )
18304
18617
  },
18305
18618
  token1: {
18306
18619
  tokenInfo: amountInfo.token1.tokenInfo,
18307
- amount: Web3Number.fromWei(amount1.toString(), amountInfo.token1.tokenInfo.decimals)
18620
+ amount: Web3Number.fromWei(
18621
+ amount1.toString(),
18622
+ amountInfo.token1.tokenInfo.decimals
18623
+ )
18308
18624
  }
18309
18625
  };
18310
18626
  }
18311
18627
  async depositCall(amountInfo, receiver) {
18312
18628
  const updateAmountInfo = await this.getMinDepositAmounts(amountInfo);
18313
- const token0Contract = new import_starknet9.Contract(erc4626_abi_default, amountInfo.token0.tokenInfo.address.address, this.config.provider);
18314
- const token1Contract = new import_starknet9.Contract(erc4626_abi_default, amountInfo.token1.tokenInfo.address.address, this.config.provider);
18315
- const call1 = token0Contract.populate("approve", [this.address.address, import_starknet9.uint256.bnToUint256(updateAmountInfo.token0.amount.toWei())]);
18316
- const call2 = token1Contract.populate("approve", [this.address.address, import_starknet9.uint256.bnToUint256(updateAmountInfo.token1.amount.toWei())]);
18317
- const call3 = this.contract.populate("deposit", [import_starknet9.uint256.bnToUint256(updateAmountInfo.token0.amount.toWei()), import_starknet9.uint256.bnToUint256(updateAmountInfo.token1.amount.toWei()), receiver.address]);
18629
+ const token0Contract = new import_starknet9.Contract(
18630
+ erc4626_abi_default,
18631
+ amountInfo.token0.tokenInfo.address.address,
18632
+ this.config.provider
18633
+ );
18634
+ const token1Contract = new import_starknet9.Contract(
18635
+ erc4626_abi_default,
18636
+ amountInfo.token1.tokenInfo.address.address,
18637
+ this.config.provider
18638
+ );
18639
+ const call1 = token0Contract.populate("approve", [
18640
+ this.address.address,
18641
+ import_starknet9.uint256.bnToUint256(updateAmountInfo.token0.amount.toWei())
18642
+ ]);
18643
+ const call2 = token1Contract.populate("approve", [
18644
+ this.address.address,
18645
+ import_starknet9.uint256.bnToUint256(updateAmountInfo.token1.amount.toWei())
18646
+ ]);
18647
+ const call3 = this.contract.populate("deposit", [
18648
+ import_starknet9.uint256.bnToUint256(updateAmountInfo.token0.amount.toWei()),
18649
+ import_starknet9.uint256.bnToUint256(updateAmountInfo.token1.amount.toWei()),
18650
+ receiver.address
18651
+ ]);
18318
18652
  const calls = [];
18319
18653
  if (updateAmountInfo.token0.amount.greaterThan(0)) calls.push(call1);
18320
18654
  if (updateAmountInfo.token1.amount.greaterThan(0)) calls.push(call2);
@@ -18329,25 +18663,29 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18329
18663
  }
18330
18664
  async withdrawCall(amountInfo, receiver, owner) {
18331
18665
  const shares = await this.tokensToShares(amountInfo);
18332
- logger.verbose(`${_EkuboCLVault.name}: withdrawCall: shares=${shares.toString()}`);
18333
- return [this.contract.populate("withdraw", [
18334
- import_starknet9.uint256.bnToUint256(shares.toWei()),
18335
- receiver.address
18336
- ])];
18666
+ logger.verbose(
18667
+ `${_EkuboCLVault.name}: withdrawCall: shares=${shares.toString()}`
18668
+ );
18669
+ return [
18670
+ this.contract.populate("withdraw", [
18671
+ import_starknet9.uint256.bnToUint256(shares.toWei()),
18672
+ receiver.address
18673
+ ])
18674
+ ];
18337
18675
  }
18338
18676
  rebalanceCall(newBounds, swapParams) {
18339
- return [this.contract.populate("rebalance", [
18340
- {
18341
- lower: _EkuboCLVault.tickToi129(Number(newBounds.lowerTick)),
18342
- upper: _EkuboCLVault.tickToi129(Number(newBounds.upperTick))
18343
- },
18344
- swapParams
18345
- ])];
18677
+ return [
18678
+ this.contract.populate("rebalance", [
18679
+ {
18680
+ lower: _EkuboCLVault.tickToi129(Number(newBounds.lowerTick)),
18681
+ upper: _EkuboCLVault.tickToi129(Number(newBounds.upperTick))
18682
+ },
18683
+ swapParams
18684
+ ])
18685
+ ];
18346
18686
  }
18347
18687
  handleUnusedCall(swapParams) {
18348
- return [this.contract.populate("handle_unused", [
18349
- swapParams
18350
- ])];
18688
+ return [this.contract.populate("handle_unused", [swapParams])];
18351
18689
  }
18352
18690
  handleFeesCall() {
18353
18691
  return [this.contract.populate("handle_fees", [])];
@@ -18362,16 +18700,20 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18362
18700
  const priceNow = await this.getCurrentPrice(blockIdentifier);
18363
18701
  let blockNow = typeof blockIdentifier == "number" ? blockIdentifier : (await this.config.provider.getBlockLatestAccepted()).block_number;
18364
18702
  const blockNowTime = typeof blockIdentifier == "number" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
18365
- const blockBefore = blockNow - sinceBlocks;
18366
- const adjustedSupplyNow = supplyNow.minus(await this.getHarvestRewardShares(blockBefore, blockNow));
18367
- let blockBeforeInfo = await this.config.provider.getBlockWithTxs(blockBefore);
18703
+ const blockBefore = Math.max(blockNow - sinceBlocks, this.metadata.launchBlock);
18704
+ const adjustedSupplyNow = supplyNow.minus(
18705
+ await this.getHarvestRewardShares(blockBefore, blockNow)
18706
+ );
18707
+ let blockBeforeInfo = await this.config.provider.getBlockWithTxs(
18708
+ blockBefore
18709
+ );
18368
18710
  const tvlBefore = await this._getTVL(blockBefore);
18369
18711
  const supplyBefore = await this.totalSupply(blockBefore);
18370
18712
  const priceBefore = await this.getCurrentPrice(blockBefore);
18371
18713
  const tvlInToken0Now = tvlNow.amount0.multipliedBy(priceNow.price).plus(tvlNow.amount1);
18372
- const tvlPerShareNow = tvlInToken0Now.multipliedBy(1e18).dividedBy(adjustedSupplyNow);
18714
+ const tvlPerShareNow = tvlInToken0Now.multipliedBy(1e18).dividedBy(adjustedSupplyNow.toString());
18373
18715
  const tvlInToken0Bf = tvlBefore.amount0.multipliedBy(priceBefore.price).plus(tvlBefore.amount1);
18374
- const tvlPerShareBf = tvlInToken0Bf.multipliedBy(1e18).dividedBy(supplyBefore);
18716
+ const tvlPerShareBf = tvlInToken0Bf.multipliedBy(1e18).dividedBy(supplyBefore.toString());
18375
18717
  const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
18376
18718
  logger.verbose(`tvlInToken0Now: ${tvlInToken0Now.toString()}`);
18377
18719
  logger.verbose(`tvlInToken0Bf: ${tvlInToken0Bf.toString()}`);
@@ -18382,7 +18724,9 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18382
18724
  logger.verbose(`Supply before: ${supplyBefore.toString()}`);
18383
18725
  logger.verbose(`Supply now: ${adjustedSupplyNow.toString()}`);
18384
18726
  logger.verbose(`Time diff in seconds: ${timeDiffSeconds}`);
18385
- const apyForGivenBlocks = Number(tvlPerShareNow.minus(tvlPerShareBf).multipliedBy(1e4).dividedBy(tvlPerShareBf)) / 1e4;
18727
+ const apyForGivenBlocks = Number(
18728
+ tvlPerShareNow.minus(tvlPerShareBf).multipliedBy(1e4).dividedBy(tvlPerShareBf)
18729
+ ) / 1e4;
18386
18730
  return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
18387
18731
  }
18388
18732
  async getHarvestRewardShares(fromBlock, toBlock) {
@@ -18400,25 +18744,39 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18400
18744
  } else {
18401
18745
  shares = shares.plus(Web3Number.fromWei(record.shares.toString(), 18));
18402
18746
  }
18403
- logger.verbose(`${_EkuboCLVault.name}: getHarvestRewardShares: ${i} => ${shares.toWei()}`);
18747
+ logger.verbose(
18748
+ `${_EkuboCLVault.name}: getHarvestRewardShares: ${i} => ${shares.toWei()}`
18749
+ );
18404
18750
  }
18405
18751
  return shares;
18406
18752
  }
18407
18753
  async balanceOf(user, blockIdentifier = "pending") {
18408
- let bal = await this.contract.call("balance_of", [user.address]);
18754
+ let bal = await this.contract.call("balance_of", [user.address], {
18755
+ blockIdentifier
18756
+ });
18409
18757
  return Web3Number.fromWei(bal.toString(), 18);
18410
18758
  }
18411
18759
  async getUserTVL(user, blockIdentifier = "pending") {
18412
18760
  let bal = await this.balanceOf(user, blockIdentifier);
18413
- const assets = await this.contract.call("convert_to_assets", [import_starknet9.uint256.bnToUint256(bal.toWei())], {
18414
- blockIdentifier
18415
- });
18761
+ const assets = await this.contract.call(
18762
+ "convert_to_assets",
18763
+ [import_starknet9.uint256.bnToUint256(bal.toWei())],
18764
+ {
18765
+ blockIdentifier
18766
+ }
18767
+ );
18416
18768
  const poolKey = await this.getPoolKey(blockIdentifier);
18417
18769
  this.assertValidDepositTokens(poolKey);
18418
18770
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
18419
18771
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
18420
- const amount0 = Web3Number.fromWei(assets.amount0.toString(), token0Info.decimals);
18421
- const amount1 = Web3Number.fromWei(assets.amount1.toString(), token1Info.decimals);
18772
+ const amount0 = Web3Number.fromWei(
18773
+ assets.amount0.toString(),
18774
+ token0Info.decimals
18775
+ );
18776
+ const amount1 = Web3Number.fromWei(
18777
+ assets.amount1.toString(),
18778
+ token1Info.decimals
18779
+ );
18422
18780
  const P0 = await this.pricer.getPrice(token0Info.symbol);
18423
18781
  const P1 = await this.pricer.getPrice(token1Info.symbol);
18424
18782
  const token0Usd = Number(amount0.toFixed(13)) * P0.price;
@@ -18442,7 +18800,11 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18442
18800
  blockIdentifier
18443
18801
  });
18444
18802
  const bounds = await this.getCurrentBounds(blockIdentifier);
18445
- const { amount0, amount1 } = await this.getLiquidityToAmounts(Web3Number.fromWei(result.toString(), 18), bounds, blockIdentifier);
18803
+ const { amount0, amount1 } = await this.getLiquidityToAmounts(
18804
+ Web3Number.fromWei(result.toString(), 18),
18805
+ bounds,
18806
+ blockIdentifier
18807
+ );
18446
18808
  return { amount0, amount1 };
18447
18809
  }
18448
18810
  async totalSupply(blockIdentifier = "pending") {
@@ -18452,8 +18814,14 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18452
18814
  return Web3Number.fromWei(res.toString(), 18);
18453
18815
  }
18454
18816
  assertValidDepositTokens(poolKey) {
18455
- assert(poolKey.token0.eq(this.metadata.depositTokens[0].address), "Expected token0 in depositTokens[0]");
18456
- assert(poolKey.token1.eq(this.metadata.depositTokens[1].address), "Expected token1 in depositTokens[1]");
18817
+ assert(
18818
+ poolKey.token0.eq(this.metadata.depositTokens[0].address),
18819
+ "Expected token0 in depositTokens[0]"
18820
+ );
18821
+ assert(
18822
+ poolKey.token1.eq(this.metadata.depositTokens[1].address),
18823
+ "Expected token1 in depositTokens[1]"
18824
+ );
18457
18825
  }
18458
18826
  async getTVL(blockIdentifier = "pending") {
18459
18827
  const { amount0, amount1 } = await this._getTVL(blockIdentifier);
@@ -18483,26 +18851,35 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18483
18851
  const nftID = await this.getCurrentNFTID();
18484
18852
  const poolKey = await this.getPoolKey();
18485
18853
  const currentBounds = await this.getCurrentBounds();
18486
- const result = await this.ekuboPositionsContract.call("get_token_info", [
18487
- nftID,
18488
- {
18489
- token0: poolKey.token0.address,
18490
- token1: poolKey.token1.address,
18491
- fee: poolKey.fee,
18492
- tick_spacing: poolKey.tick_spacing,
18493
- extension: poolKey.extension
18494
- },
18495
- {
18496
- lower: _EkuboCLVault.tickToi129(Number(currentBounds.lowerTick)),
18497
- upper: _EkuboCLVault.tickToi129(Number(currentBounds.upperTick))
18498
- }
18499
- ]);
18854
+ const result = await this.ekuboPositionsContract.call(
18855
+ "get_token_info",
18856
+ [
18857
+ nftID,
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
+ {
18866
+ lower: _EkuboCLVault.tickToi129(Number(currentBounds.lowerTick)),
18867
+ upper: _EkuboCLVault.tickToi129(Number(currentBounds.upperTick))
18868
+ }
18869
+ ]
18870
+ );
18500
18871
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
18501
18872
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
18502
18873
  const P0 = await this.pricer.getPrice(token0Info.symbol);
18503
18874
  const P1 = await this.pricer.getPrice(token1Info.symbol);
18504
- const token0Web3 = Web3Number.fromWei(result.fees0.toString(), token0Info.decimals);
18505
- const token1Web3 = Web3Number.fromWei(result.fees1.toString(), token1Info.decimals);
18875
+ const token0Web3 = Web3Number.fromWei(
18876
+ result.fees0.toString(),
18877
+ token0Info.decimals
18878
+ );
18879
+ const token1Web3 = Web3Number.fromWei(
18880
+ result.fees1.toString(),
18881
+ token1Info.decimals
18882
+ );
18506
18883
  const token0Usd = Number(token0Web3.toFixed(13)) * P0.price;
18507
18884
  const token1Usd = Number(token1Web3.toFixed(13)) * P1.price;
18508
18885
  return {
@@ -18524,31 +18901,52 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18524
18901
  return Number(result.salt.toString());
18525
18902
  }
18526
18903
  async truePrice() {
18527
- const result = await this.lstContract.call("convert_to_assets", [import_starknet9.uint256.bnToUint256(BigInt(1e18).toString())]);
18528
- const truePrice = Number(BigInt(result.toString()) * BigInt(1e9) / BigInt(1e18)) / 1e9;
18529
- return truePrice;
18904
+ if (this.metadata.additionalInfo.truePrice) {
18905
+ return this.metadata.additionalInfo.truePrice;
18906
+ } else if (this.lstContract) {
18907
+ const result = await this.lstContract.call("convert_to_assets", [
18908
+ import_starknet9.uint256.bnToUint256(BigInt(1e18).toString())
18909
+ ]);
18910
+ const truePrice = Number(BigInt(result.toString()) * BigInt(1e9) / BigInt(1e18)) / 1e9;
18911
+ return truePrice;
18912
+ }
18913
+ throw new Error("No true price available");
18530
18914
  }
18531
18915
  async getCurrentPrice(blockIdentifier = "pending") {
18532
18916
  const poolKey = await this.getPoolKey(blockIdentifier);
18533
18917
  return this._getCurrentPrice(poolKey, blockIdentifier);
18534
18918
  }
18535
18919
  async _getCurrentPrice(poolKey, blockIdentifier = "pending") {
18536
- const priceInfo = await this.ekuboPositionsContract.call("get_pool_price", [
18920
+ const priceInfo = await this.ekuboPositionsContract.call(
18921
+ "get_pool_price",
18922
+ [
18923
+ {
18924
+ token0: poolKey.token0.address,
18925
+ token1: poolKey.token1.address,
18926
+ fee: poolKey.fee,
18927
+ tick_spacing: poolKey.tick_spacing,
18928
+ extension: poolKey.extension
18929
+ }
18930
+ ],
18537
18931
  {
18538
- token0: poolKey.token0.address,
18539
- token1: poolKey.token1.address,
18540
- fee: poolKey.fee,
18541
- tick_spacing: poolKey.tick_spacing,
18542
- extension: poolKey.extension
18932
+ blockIdentifier
18543
18933
  }
18544
- ], {
18545
- blockIdentifier
18546
- });
18547
- const sqrtRatio = _EkuboCLVault.div2Power128(BigInt(priceInfo.sqrt_ratio.toString()));
18548
- console.log(`EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, sqrtRatio: ${sqrtRatio}, ${priceInfo.sqrt_ratio.toString()}`);
18934
+ );
18935
+ const sqrtRatio = _EkuboCLVault.div2Power128(
18936
+ BigInt(priceInfo.sqrt_ratio.toString())
18937
+ );
18938
+ console.log(
18939
+ `EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, sqrtRatio: ${sqrtRatio}, ${priceInfo.sqrt_ratio.toString()}`
18940
+ );
18549
18941
  const price = sqrtRatio * sqrtRatio;
18550
- const tick = _EkuboCLVault.priceToTick(price, true, Number(poolKey.tick_spacing));
18551
- console.log(`EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, price: ${price}, tick: ${tick.mag}, ${tick.sign}`);
18942
+ const tick = _EkuboCLVault.priceToTick(
18943
+ price,
18944
+ true,
18945
+ Number(poolKey.tick_spacing)
18946
+ );
18947
+ console.log(
18948
+ `EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, price: ${price}, tick: ${tick.mag}, ${tick.sign}`
18949
+ );
18552
18950
  return {
18553
18951
  price,
18554
18952
  tick: tick.mag * (tick.sign == 0 ? 1 : -1),
@@ -18588,7 +18986,10 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18588
18986
  };
18589
18987
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
18590
18988
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
18591
- assert(token0Info.decimals == token1Info.decimals, "Tested only for equal decimals");
18989
+ assert(
18990
+ token0Info.decimals == token1Info.decimals,
18991
+ "Tested only for equal decimals"
18992
+ );
18592
18993
  this.poolKey = poolKey;
18593
18994
  return poolKey;
18594
18995
  }
@@ -18612,11 +19013,18 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18612
19013
  async _getExpectedAmountsForLiquidity(amount0, amount1, bounds, justUseInputAmount = true) {
18613
19014
  assert(amount0.greaterThan(0) || amount1.greaterThan(0), "Amount is 0");
18614
19015
  const sampleLiq = 1e20;
18615
- const { amount0: sampleAmount0, amount1: sampleAmount1 } = await this.getLiquidityToAmounts(Web3Number.fromWei(sampleLiq.toString(), 18), bounds);
18616
- logger.verbose(`${_EkuboCLVault.name}: _getExpectedAmountsForLiquidity => sampleAmount0: ${sampleAmount0.toString()}, sampleAmount1: ${sampleAmount1.toString()}`);
19016
+ const { amount0: sampleAmount0, amount1: sampleAmount1 } = await this.getLiquidityToAmounts(
19017
+ Web3Number.fromWei(sampleLiq.toString(), 18),
19018
+ bounds
19019
+ );
19020
+ logger.verbose(
19021
+ `${_EkuboCLVault.name}: _getExpectedAmountsForLiquidity => sampleAmount0: ${sampleAmount0.toString()}, sampleAmount1: ${sampleAmount1.toString()}`
19022
+ );
18617
19023
  assert(!sampleAmount0.eq(0) || !sampleAmount1.eq(0), "Sample amount is 0");
18618
19024
  const price = await (await this.getCurrentPrice()).price;
18619
- logger.verbose(`${_EkuboCLVault.name}: _getExpectedAmountsForLiquidity => price: ${price}`);
19025
+ logger.verbose(
19026
+ `${_EkuboCLVault.name}: _getExpectedAmountsForLiquidity => price: ${price}`
19027
+ );
18620
19028
  if (amount1.eq(0) && amount0.greaterThan(0)) {
18621
19029
  if (sampleAmount1.eq(0)) {
18622
19030
  return {
@@ -18646,12 +19054,22 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18646
19054
  };
18647
19055
  }
18648
19056
  }
18649
- assert(sampleAmount0.decimals == sampleAmount1.decimals, "Sample amounts have different decimals");
19057
+ assert(
19058
+ sampleAmount0.decimals == sampleAmount1.decimals,
19059
+ "Sample amounts have different decimals"
19060
+ );
18650
19061
  const ratioWeb3Number = sampleAmount0.multipliedBy(1e18).dividedBy(sampleAmount1.toString()).dividedBy(1e18);
18651
19062
  const ratio = Number(ratioWeb3Number.toFixed(18));
18652
- logger.verbose(`${_EkuboCLVault.name}: ${this.metadata.name} => ratio: ${ratio.toString()}`);
19063
+ logger.verbose(
19064
+ `${_EkuboCLVault.name}: ${this.metadata.name} => ratio: ${ratio.toString()}`
19065
+ );
18653
19066
  if (justUseInputAmount)
18654
- return this._solveExpectedAmountsEq(amount0, amount1, ratioWeb3Number, price);
19067
+ return this._solveExpectedAmountsEq(
19068
+ amount0,
19069
+ amount1,
19070
+ ratioWeb3Number,
19071
+ price
19072
+ );
18655
19073
  if (amount1.eq(0) && amount0.greaterThan(0)) {
18656
19074
  const _amount1 = amount0.dividedBy(ratioWeb3Number);
18657
19075
  return {
@@ -18667,7 +19085,9 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18667
19085
  ratio
18668
19086
  };
18669
19087
  } else {
18670
- throw new Error("Both amounts are non-zero, cannot compute expected amounts");
19088
+ throw new Error(
19089
+ "Both amounts are non-zero, cannot compute expected amounts"
19090
+ );
18671
19091
  }
18672
19092
  }
18673
19093
  _solveExpectedAmountsEq(availableAmount0, availableAmount1, ratio, price) {
@@ -18684,34 +19104,65 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18684
19104
  const erc20Mod = new ERC20(this.config);
18685
19105
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
18686
19106
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
18687
- const token0Bal1 = await erc20Mod.balanceOf(poolKey.token0, this.address.address, token0Info.decimals);
18688
- const token1Bal1 = await erc20Mod.balanceOf(poolKey.token1, this.address.address, token1Info.decimals);
18689
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal1: ${token0Bal1.toString()}, token1Bal1: ${token1Bal1.toString()}`);
19107
+ const token0Bal1 = await erc20Mod.balanceOf(
19108
+ poolKey.token0,
19109
+ this.address.address,
19110
+ token0Info.decimals
19111
+ );
19112
+ const token1Bal1 = await erc20Mod.balanceOf(
19113
+ poolKey.token1,
19114
+ this.address.address,
19115
+ token1Info.decimals
19116
+ );
19117
+ logger.verbose(
19118
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal1: ${token0Bal1.toString()}, token1Bal1: ${token1Bal1.toString()}`
19119
+ );
18690
19120
  const token0Price = await this.pricer.getPrice(token0Info.symbol);
18691
19121
  const token1Price = await this.pricer.getPrice(token1Info.symbol);
18692
19122
  const token0PriceUsd = token0Price.price * Number(token0Bal1.toFixed(13));
18693
19123
  const token1PriceUsd = token1Price.price * Number(token1Bal1.toFixed(13));
18694
19124
  if (token0PriceUsd > 1 && token1PriceUsd > 1) {
18695
- throw new Error("Both tokens are non-zero and above $1, call handle_fees first");
19125
+ throw new Error(
19126
+ "Both tokens are non-zero and above $1, call handle_fees first"
19127
+ );
18696
19128
  }
18697
19129
  let token0Bal = token0Bal1;
18698
19130
  let token1Bal = token1Bal1;
18699
19131
  if (considerRebalance) {
18700
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => considerRebalance: true`);
19132
+ logger.verbose(
19133
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => considerRebalance: true`
19134
+ );
18701
19135
  const tvl = await this.getTVL();
18702
19136
  token0Bal = token0Bal.plus(tvl.token0.amount.toString());
18703
19137
  token1Bal = token1Bal.plus(tvl.token1.amount.toString());
18704
19138
  } else {
18705
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => considerRebalance: false`);
19139
+ logger.verbose(
19140
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => considerRebalance: false`
19141
+ );
18706
19142
  }
18707
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`);
19143
+ logger.verbose(
19144
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`
19145
+ );
18708
19146
  const newBounds = await this.getNewBounds();
18709
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newBounds: ${newBounds.lowerTick}, ${newBounds.upperTick}`);
18710
- return await this.getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, newBounds);
19147
+ logger.verbose(
19148
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newBounds: ${newBounds.lowerTick}, ${newBounds.upperTick}`
19149
+ );
19150
+ return await this.getSwapInfoGivenAmounts(
19151
+ poolKey,
19152
+ token0Bal,
19153
+ token1Bal,
19154
+ newBounds
19155
+ );
18711
19156
  }
18712
19157
  async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds) {
18713
- let expectedAmounts = await this._getExpectedAmountsForLiquidity(token0Bal, token1Bal, bounds);
18714
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`);
19158
+ let expectedAmounts = await this._getExpectedAmountsForLiquidity(
19159
+ token0Bal,
19160
+ token1Bal,
19161
+ bounds
19162
+ );
19163
+ logger.verbose(
19164
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`
19165
+ );
18715
19166
  let retry = 0;
18716
19167
  const maxRetry = 10;
18717
19168
  while (retry < maxRetry) {
@@ -18728,9 +19179,15 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18728
19179
  const remainingSellAmount = tokenToSell == poolKey.token0 ? expectedAmounts.amount0 : expectedAmounts.amount1;
18729
19180
  const tokenToBuyInfo = await Global.getTokenInfoFromAddr(tokenToBuy);
18730
19181
  const expectedRatio = expectedAmounts.ratio;
18731
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => tokenToSell: ${tokenToSell.address}, tokenToBuy: ${tokenToBuy.address}, amountToSell: ${amountToSell.toWei()}`);
18732
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => remainingSellAmount: ${remainingSellAmount.toString()}`);
18733
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedRatio: ${expectedRatio}`);
19182
+ logger.verbose(
19183
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => tokenToSell: ${tokenToSell.address}, tokenToBuy: ${tokenToBuy.address}, amountToSell: ${amountToSell.toWei()}`
19184
+ );
19185
+ logger.verbose(
19186
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => remainingSellAmount: ${remainingSellAmount.toString()}`
19187
+ );
19188
+ logger.verbose(
19189
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedRatio: ${expectedRatio}`
19190
+ );
18734
19191
  if (amountToSell.eq(0)) {
18735
19192
  return {
18736
19193
  token_from_address: tokenToSell.address,
@@ -18744,23 +19201,62 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18744
19201
  routes: []
18745
19202
  };
18746
19203
  }
18747
- const quote = await this.avnu.getQuotes(tokenToSell.address, tokenToBuy.address, amountToSell.toWei(), this.address.address);
19204
+ const quote = await this.avnu.getQuotes(
19205
+ tokenToSell.address,
19206
+ tokenToBuy.address,
19207
+ amountToSell.toWei(),
19208
+ this.address.address
19209
+ );
18748
19210
  if (remainingSellAmount.eq(0)) {
18749
- const minAmountOut = Web3Number.fromWei(quote.buyAmount.toString(), tokenToBuyInfo.decimals).multipliedBy(0.9999);
18750
- return await this.avnu.getSwapInfo(quote, this.address.address, 0, this.address.address, minAmountOut.toWei());
19211
+ const minAmountOut = Web3Number.fromWei(
19212
+ quote.buyAmount.toString(),
19213
+ tokenToBuyInfo.decimals
19214
+ ).multipliedBy(0.9999);
19215
+ return await this.avnu.getSwapInfo(
19216
+ quote,
19217
+ this.address.address,
19218
+ 0,
19219
+ this.address.address,
19220
+ minAmountOut.toWei()
19221
+ );
18751
19222
  }
18752
- const amountOut = Web3Number.fromWei(quote.buyAmount.toString(), tokenToBuyInfo.decimals);
19223
+ const amountOut = Web3Number.fromWei(
19224
+ quote.buyAmount.toString(),
19225
+ tokenToBuyInfo.decimals
19226
+ );
18753
19227
  const swapPrice = tokenToSell == poolKey.token0 ? amountOut.dividedBy(amountToSell) : amountToSell.dividedBy(amountOut);
18754
19228
  const newRatio = tokenToSell == poolKey.token0 ? remainingSellAmount.dividedBy(token1Bal.plus(amountOut)) : token0Bal.plus(amountOut).dividedBy(remainingSellAmount);
18755
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => amountOut: ${amountOut.toString()}`);
18756
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => swapPrice: ${swapPrice.toString()}`);
18757
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newRatio: ${newRatio.toString()}`);
19229
+ logger.verbose(
19230
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => amountOut: ${amountOut.toString()}`
19231
+ );
19232
+ logger.verbose(
19233
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => swapPrice: ${swapPrice.toString()}`
19234
+ );
19235
+ logger.verbose(
19236
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newRatio: ${newRatio.toString()}`
19237
+ );
18758
19238
  if (Number(newRatio.toString()) > expectedRatio * 1.0000001 || Number(newRatio.toString()) < expectedRatio * 0.9999999) {
18759
- expectedAmounts = await this._solveExpectedAmountsEq(token0Bal, token1Bal, new Web3Number(Number(expectedRatio).toFixed(13), 18), Number(swapPrice.toString()));
18760
- logger.verbose(`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`);
19239
+ expectedAmounts = await this._solveExpectedAmountsEq(
19240
+ token0Bal,
19241
+ token1Bal,
19242
+ new Web3Number(Number(expectedRatio).toFixed(13), 18),
19243
+ Number(swapPrice.toString())
19244
+ );
19245
+ logger.verbose(
19246
+ `${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`
19247
+ );
18761
19248
  } else {
18762
- const minAmountOut = Web3Number.fromWei(quote.buyAmount.toString(), tokenToBuyInfo.decimals).multipliedBy(0.9999);
18763
- return await this.avnu.getSwapInfo(quote, this.address.address, 0, this.address.address, minAmountOut.toWei());
19249
+ const minAmountOut = Web3Number.fromWei(
19250
+ quote.buyAmount.toString(),
19251
+ tokenToBuyInfo.decimals
19252
+ ).multipliedBy(0.9999);
19253
+ return await this.avnu.getSwapInfo(
19254
+ quote,
19255
+ this.address.address,
19256
+ 0,
19257
+ this.address.address,
19258
+ minAmountOut.toWei()
19259
+ );
18764
19260
  }
18765
19261
  retry++;
18766
19262
  }
@@ -18769,8 +19265,8 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18769
19265
  /**
18770
19266
  * Attempts to rebalance the vault by iteratively adjusting swap amounts if initial attempt fails.
18771
19267
  * Uses binary search approach to find optimal swap amount.
18772
- *
18773
- * @param newBounds - The new tick bounds to rebalance to
19268
+ *
19269
+ * @param newBounds - The new tick bounds to rebalance to
18774
19270
  * @param swapInfo - Initial swap parameters for rebalancing
18775
19271
  * @param acc - Account to estimate gas fees with
18776
19272
  * @param retry - Current retry attempt number (default 0)
@@ -18797,7 +19293,9 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18797
19293
  logger.error(`Rebalance failed after ${MAX_RETRIES} retries`);
18798
19294
  throw err;
18799
19295
  }
18800
- logger.error(`Rebalance attempt ${retry + 1} failed, adjusting swap amount...`);
19296
+ logger.error(
19297
+ `Rebalance attempt ${retry + 1} failed, adjusting swap amount...`
19298
+ );
18801
19299
  const newSwapInfo = { ...swapInfo };
18802
19300
  const currentAmount = Web3Number.fromWei(fromAmount.toString(), 18);
18803
19301
  logger.verbose(`Current amount: ${currentAmount.toString()}`);
@@ -18889,23 +19387,39 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18889
19387
  const currentPrice = _currentPrice || await this.getCurrentPrice(blockIdentifier);
18890
19388
  const lowerPrice = _EkuboCLVault.tickToPrice(bounds.lowerTick);
18891
19389
  const upperPrice = _EkuboCLVault.tickToPrice(bounds.upperTick);
18892
- logger.verbose(`${_EkuboCLVault.name}: getLiquidityToAmounts => currentPrice: ${currentPrice.price}, lowerPrice: ${lowerPrice}, upperPrice: ${upperPrice}`);
18893
- const result = await this.ekuboMathContract.call("liquidity_delta_to_amount_delta", [
18894
- import_starknet9.uint256.bnToUint256(currentPrice.sqrtRatio),
19390
+ logger.verbose(
19391
+ `${_EkuboCLVault.name}: getLiquidityToAmounts => currentPrice: ${currentPrice.price}, lowerPrice: ${lowerPrice}, upperPrice: ${upperPrice}`
19392
+ );
19393
+ const result = await this.ekuboMathContract.call(
19394
+ "liquidity_delta_to_amount_delta",
19395
+ [
19396
+ import_starknet9.uint256.bnToUint256(currentPrice.sqrtRatio),
19397
+ {
19398
+ mag: liquidity.toWei(),
19399
+ sign: 0
19400
+ },
19401
+ import_starknet9.uint256.bnToUint256(
19402
+ _EkuboCLVault.priceToSqrtRatio(lowerPrice).toString()
19403
+ ),
19404
+ import_starknet9.uint256.bnToUint256(
19405
+ _EkuboCLVault.priceToSqrtRatio(upperPrice).toString()
19406
+ )
19407
+ ],
18895
19408
  {
18896
- mag: liquidity.toWei(),
18897
- sign: 0
18898
- },
18899
- import_starknet9.uint256.bnToUint256(_EkuboCLVault.priceToSqrtRatio(lowerPrice).toString()),
18900
- import_starknet9.uint256.bnToUint256(_EkuboCLVault.priceToSqrtRatio(upperPrice).toString())
18901
- ], {
18902
- blockIdentifier
18903
- });
19409
+ blockIdentifier
19410
+ }
19411
+ );
18904
19412
  const poolKey = _poolKey || await this.getPoolKey(blockIdentifier);
18905
19413
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
18906
19414
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
18907
- const amount0 = Web3Number.fromWei(_EkuboCLVault.i129ToNumber(result.amount0).toString(), token0Info.decimals);
18908
- const amount1 = Web3Number.fromWei(_EkuboCLVault.i129ToNumber(result.amount1).toString(), token1Info.decimals);
19415
+ const amount0 = Web3Number.fromWei(
19416
+ _EkuboCLVault.i129ToNumber(result.amount0).toString(),
19417
+ token0Info.decimals
19418
+ );
19419
+ const amount1 = Web3Number.fromWei(
19420
+ _EkuboCLVault.i129ToNumber(result.amount1).toString(),
19421
+ token1Info.decimals
19422
+ );
18909
19423
  return {
18910
19424
  amount0,
18911
19425
  amount1
@@ -18913,7 +19427,9 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18913
19427
  }
18914
19428
  async harvest(acc) {
18915
19429
  const ekuboHarvests = new EkuboHarvests(this.config);
18916
- const unClaimedRewards = await ekuboHarvests.getUnHarvestedRewards(this.address);
19430
+ const unClaimedRewards = await ekuboHarvests.getUnHarvestedRewards(
19431
+ this.address
19432
+ );
18917
19433
  const poolKey = await this.getPoolKey();
18918
19434
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
18919
19435
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
@@ -18923,18 +19439,38 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18923
19439
  const fee = claim.claim.amount.multipliedBy(this.metadata.additionalInfo.feeBps).dividedBy(1e4);
18924
19440
  const postFeeAmount = claim.claim.amount.minus(fee);
18925
19441
  const isToken1 = claim.token.eq(poolKey.token1);
18926
- logger.verbose(`${_EkuboCLVault.name}: harvest => Processing claim, isToken1: ${isToken1} amount: ${postFeeAmount.toWei()}`);
19442
+ logger.verbose(
19443
+ `${_EkuboCLVault.name}: harvest => Processing claim, isToken1: ${isToken1} amount: ${postFeeAmount.toWei()}`
19444
+ );
18927
19445
  const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
18928
19446
  const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
18929
- logger.verbose(`${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`);
18930
- const swapInfo = await this.getSwapInfoGivenAmounts(poolKey, token0Amt, token1Amt, bounds);
19447
+ logger.verbose(
19448
+ `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
19449
+ );
19450
+ const swapInfo = await this.getSwapInfoGivenAmounts(
19451
+ poolKey,
19452
+ token0Amt,
19453
+ token1Amt,
19454
+ bounds
19455
+ );
18931
19456
  swapInfo.token_to_address = token0Info.address.address;
18932
- logger.verbose(`${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`);
18933
- logger.verbose(`${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`);
19457
+ logger.verbose(
19458
+ `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
19459
+ );
19460
+ logger.verbose(
19461
+ `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
19462
+ );
18934
19463
  const harvestEstimateCall = async (swapInfo1) => {
18935
- const swap1Amount = Web3Number.fromWei(import_starknet9.uint256.uint256ToBN(swapInfo1.token_from_amount).toString(), 18);
19464
+ const swap1Amount = Web3Number.fromWei(
19465
+ import_starknet9.uint256.uint256ToBN(swapInfo1.token_from_amount).toString(),
19466
+ 18
19467
+ // cause its always STRK?
19468
+ );
18936
19469
  const remainingAmount = postFeeAmount.minus(swap1Amount);
18937
- const swapInfo2 = { ...swapInfo, token_from_amount: import_starknet9.uint256.bnToUint256(remainingAmount.toWei()) };
19470
+ const swapInfo2 = {
19471
+ ...swapInfo,
19472
+ token_from_amount: import_starknet9.uint256.bnToUint256(remainingAmount.toWei())
19473
+ };
18938
19474
  swapInfo2.token_to_address = token1Info.address.address;
18939
19475
  const calldata = [
18940
19476
  claim.rewardsContract.address,
@@ -18947,11 +19483,23 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18947
19483
  swapInfo,
18948
19484
  swapInfo2
18949
19485
  ];
18950
- logger.verbose(`${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(calldata)}`);
19486
+ logger.verbose(
19487
+ `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
19488
+ calldata
19489
+ )}`
19490
+ );
18951
19491
  return [this.contract.populate("harvest", calldata)];
18952
19492
  };
18953
- const _callsFinal = await this.rebalanceIter(swapInfo, acc, harvestEstimateCall);
18954
- logger.verbose(`${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(_callsFinal)}`);
19493
+ const _callsFinal = await this.rebalanceIter(
19494
+ swapInfo,
19495
+ acc,
19496
+ harvestEstimateCall
19497
+ );
19498
+ logger.verbose(
19499
+ `${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
19500
+ _callsFinal
19501
+ )}`
19502
+ );
18955
19503
  calls.push(..._callsFinal);
18956
19504
  }
18957
19505
  return calls;
@@ -18961,24 +19509,37 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18961
19509
  const poolKey = await this.getPoolKey();
18962
19510
  const linkedFlow = {
18963
19511
  title: this.metadata.name,
18964
- subItems: [{ key: "Pool", value: `${(_EkuboCLVault.div2Power128(BigInt(poolKey.fee)) * 100).toFixed(2)}%, ${poolKey.tick_spacing} tick spacing` }],
19512
+ subItems: [
19513
+ {
19514
+ key: "Pool",
19515
+ value: `${(_EkuboCLVault.div2Power128(BigInt(poolKey.fee)) * 100).toFixed(2)}%, ${poolKey.tick_spacing} tick spacing`
19516
+ }
19517
+ ],
18965
19518
  linkedFlows: [],
18966
19519
  style: { backgroundColor: "#35484f" /* Blue */.valueOf() }
18967
19520
  };
18968
19521
  const baseFlow = {
18969
19522
  id: "base",
18970
19523
  title: "Your Deposit",
18971
- subItems: [{ key: `Net yield`, value: `${(netYield * 100).toFixed(2)}%` }, { key: `Performance Fee`, value: `${(this.metadata.additionalInfo.feeBps / 100).toFixed(2)}%` }],
19524
+ subItems: [
19525
+ { key: `Net yield`, value: `${(netYield * 100).toFixed(2)}%` },
19526
+ {
19527
+ key: `Performance Fee`,
19528
+ value: `${(this.metadata.additionalInfo.feeBps / 100).toFixed(2)}%`
19529
+ }
19530
+ ],
18972
19531
  linkedFlows: [linkedFlow],
18973
19532
  style: { backgroundColor: "#6e53dc" /* Purple */.valueOf() }
18974
19533
  };
18975
19534
  const rebalanceFlow = {
18976
19535
  id: "rebalance",
18977
19536
  title: "Automated Rebalance",
18978
- subItems: [{
18979
- key: "Range selection",
18980
- value: `${this.metadata.additionalInfo.newBounds.lower * Number(poolKey.tick_spacing)} to ${this.metadata.additionalInfo.newBounds.upper * Number(poolKey.tick_spacing)} ticks`
18981
- }],
19537
+ subItems: [
19538
+ {
19539
+ key: "Range selection",
19540
+ value: `${this.metadata.additionalInfo.newBounds.lower * Number(poolKey.tick_spacing)} to ${this.metadata.additionalInfo.newBounds.upper * Number(poolKey.tick_spacing)} ticks`
19541
+ }
19542
+ ],
18982
19543
  linkedFlows: [linkedFlow],
18983
19544
  style: { backgroundColor: "purple" /* Green */.valueOf() }
18984
19545
  };
@@ -18986,43 +19547,145 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
18986
19547
  }
18987
19548
  };
18988
19549
  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.";
18989
- var _protocol2 = { name: "Ekubo", logo: "https://app.ekubo.org/favicon.ico" };
19550
+ var _protocol2 = {
19551
+ name: "Ekubo",
19552
+ logo: "https://app.ekubo.org/favicon.ico"
19553
+ };
18990
19554
  var _riskFactor2 = [
18991
19555
  { type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 0.5, weight: 25 },
18992
19556
  { type: "Impermanent Loss Risk" /* IMPERMANENT_LOSS */, value: 1, weight: 75 }
18993
19557
  ];
19558
+ var _riskFactorStable = [
19559
+ { type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 0.5, weight: 25 }
19560
+ ];
18994
19561
  var AUDIT_URL2 = "https://assets.strkfarm.com/strkfarm/audit_report_vesu_and_ekubo_strats.pdf";
18995
- var EkuboCLVaultStrategies = [{
18996
- name: "Ekubo xSTRK/STRK",
18997
- description: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
18998
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: _description2.replace("{{POOL_NAME}}", "xSTRK/STRK") }),
18999
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("ul", { style: { marginLeft: "20px", listStyle: "circle", fontSize: "12px" }, children: [
19000
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { style: { marginTop: "10px" }, children: "During withdrawal, you may receive either or both tokens depending on market conditions and prevailing prices." }),
19001
- /* @__PURE__ */ (0, import_jsx_runtime.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." })
19562
+ var faqs2 = [
19563
+ {
19564
+ question: "What is the Ekubo CL Vault strategy?",
19565
+ 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."
19566
+ },
19567
+ {
19568
+ question: "How are trading fees and rewards handled?",
19569
+ answer: "Trading fees and DeFi Spring rewards are automatically compounded back into the strategy, increasing your overall returns."
19570
+ },
19571
+ {
19572
+ question: "What happens during withdrawal?",
19573
+ answer: "During withdrawal, you may receive either or both tokens depending on market conditions and prevailing prices."
19574
+ },
19575
+ {
19576
+ question: "Is the strategy audited?",
19577
+ answer: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
19578
+ "Yes, the strategy has been audited. You can review the audit report in our docs ",
19579
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { href: "https://docs.strkfarm.com/p/ekubo-cl-vaults#technical-details", style: { textDecoration: "underline", marginLeft: "5px" }, children: "Here" }),
19580
+ "."
19002
19581
  ] })
19003
- ] }),
19004
- address: ContractAddr.from("0x01f083b98674bc21effee29ef443a00c7b9a500fd92cf30341a3da12c73f2324"),
19005
- type: "Other",
19006
- // must be same order as poolKey token0 and token1
19007
- depositTokens: [Global.getDefaultTokens().find((t) => t.symbol === "xSTRK"), Global.getDefaultTokens().find((t) => t.symbol === "STRK")],
19008
- protocols: [_protocol2],
19009
- auditUrl: AUDIT_URL2,
19010
- maxTVL: Web3Number.fromWei("0", 18),
19011
- risk: {
19012
- riskFactor: _riskFactor2,
19013
- netRisk: _riskFactor2.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor2.reduce((acc, curr) => acc + curr.weight, 0),
19014
- notARisks: getNoRiskTags(_riskFactor2)
19582
+ }
19583
+ ];
19584
+ var EkuboCLVaultStrategies = [
19585
+ {
19586
+ name: "Ekubo xSTRK/STRK",
19587
+ description: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
19588
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: _description2.replace("{{POOL_NAME}}", "xSTRK/STRK") }),
19589
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
19590
+ "ul",
19591
+ {
19592
+ style: {
19593
+ marginLeft: "20px",
19594
+ listStyle: "circle",
19595
+ fontSize: "12px"
19596
+ },
19597
+ children: [
19598
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { style: { marginTop: "10px" }, children: "During withdrawal, you may receive either or both tokens depending on market conditions and prevailing prices." }),
19599
+ /* @__PURE__ */ (0, import_jsx_runtime2.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." })
19600
+ ]
19601
+ }
19602
+ )
19603
+ ] }),
19604
+ address: ContractAddr.from(
19605
+ "0x01f083b98674bc21effee29ef443a00c7b9a500fd92cf30341a3da12c73f2324"
19606
+ ),
19607
+ launchBlock: 1209881,
19608
+ type: "Other",
19609
+ // must be same order as poolKey token0 and token1
19610
+ depositTokens: [
19611
+ Global.getDefaultTokens().find((t) => t.symbol === "xSTRK"),
19612
+ Global.getDefaultTokens().find((t) => t.symbol === "STRK")
19613
+ ],
19614
+ protocols: [_protocol2],
19615
+ auditUrl: AUDIT_URL2,
19616
+ maxTVL: Web3Number.fromWei("0", 18),
19617
+ risk: {
19618
+ riskFactor: _riskFactor2,
19619
+ netRisk: _riskFactor2.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor2.reduce((acc, curr) => acc + curr.weight, 0),
19620
+ notARisks: getNoRiskTags(_riskFactor2)
19621
+ },
19622
+ apyMethodology: "APY based on 7-day historical performance, including fees and rewards.",
19623
+ additionalInfo: {
19624
+ newBounds: {
19625
+ lower: -1,
19626
+ upper: 1
19627
+ },
19628
+ lstContract: ContractAddr.from(
19629
+ "0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a"
19630
+ ),
19631
+ feeBps: 1e3
19632
+ },
19633
+ faqs: [
19634
+ ...faqs2,
19635
+ {
19636
+ question: "Why might I see a negative APY?",
19637
+ 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."
19638
+ }
19639
+ ]
19015
19640
  },
19016
- apyMethodology: "APY based on 7-day historical performance, including fees and rewards.",
19017
- additionalInfo: {
19018
- newBounds: {
19019
- lower: -1,
19020
- upper: 1
19641
+ {
19642
+ name: "Ekubo USDC/USDT",
19643
+ description: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
19644
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: _description2.replace("{{POOL_NAME}}", "USDC/USDT") }),
19645
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
19646
+ "ul",
19647
+ {
19648
+ style: {
19649
+ marginLeft: "20px",
19650
+ listStyle: "circle",
19651
+ fontSize: "12px"
19652
+ },
19653
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { style: { marginTop: "10px" }, children: "During withdrawal, you may receive either or both tokens depending on market conditions and prevailing prices." })
19654
+ }
19655
+ )
19656
+ ] }),
19657
+ address: ContractAddr.from(
19658
+ "0xd647ed735f0db52f2a5502b6e06ed21dc4284a43a36af4b60d3c80fbc56c91"
19659
+ ),
19660
+ launchBlock: 1385576,
19661
+ type: "Other",
19662
+ // must be same order as poolKey token0 and token1
19663
+ depositTokens: [
19664
+ Global.getDefaultTokens().find((t) => t.symbol === "USDC"),
19665
+ Global.getDefaultTokens().find((t) => t.symbol === "USDT")
19666
+ ],
19667
+ protocols: [_protocol2],
19668
+ auditUrl: AUDIT_URL2,
19669
+ maxTVL: Web3Number.fromWei("0", 6),
19670
+ risk: {
19671
+ riskFactor: _riskFactorStable,
19672
+ netRisk: _riskFactorStable.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactorStable.reduce((acc, curr) => acc + curr.weight, 0),
19673
+ notARisks: getNoRiskTags(_riskFactorStable)
19021
19674
  },
19022
- lstContract: ContractAddr.from("0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a"),
19023
- feeBps: 1e3
19675
+ apyMethodology: "APY based on 7-day historical performance, including fees and rewards.",
19676
+ additionalInfo: {
19677
+ newBounds: {
19678
+ lower: -1,
19679
+ upper: 1
19680
+ },
19681
+ truePrice: 1,
19682
+ feeBps: 1e3
19683
+ },
19684
+ faqs: [
19685
+ ...faqs2
19686
+ ]
19024
19687
  }
19025
- }];
19688
+ ];
19026
19689
 
19027
19690
  // src/notifs/telegram.ts
19028
19691
  var import_node_telegram_bot_api = __toESM(require("node-telegram-bot-api"));