@strkfarm/sdk 1.1.10 → 1.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20191,7 +20191,7 @@ ${r2}}` : "}", l2;
20191
20191
  toHexString: () => toHexString2,
20192
20192
  toStorageKey: () => toStorageKey2
20193
20193
  });
20194
- var import_utils58 = require_utils2();
20194
+ var import_utils59 = require_utils2();
20195
20195
  function isHex3(hex) {
20196
20196
  return /^0x[0-9a-f]*$/i.test(hex);
20197
20197
  }
@@ -20264,7 +20264,7 @@ ${r2}}` : "}", l2;
20264
20264
  if (adaptedValue.length % 2 !== 0) {
20265
20265
  adaptedValue = `0${adaptedValue}`;
20266
20266
  }
20267
- return (0, import_utils58.hexToBytes)(adaptedValue);
20267
+ return (0, import_utils59.hexToBytes)(adaptedValue);
20268
20268
  }
20269
20269
  function addPercent2(number2, percent) {
20270
20270
  const bigIntNum = BigInt(number2);
@@ -28662,6 +28662,7 @@ ${r2}}` : "}", l2;
28662
28662
  Pragma: () => Pragma,
28663
28663
  Pricer: () => Pricer,
28664
28664
  PricerFromApi: () => PricerFromApi,
28665
+ PricerLST: () => PricerLST,
28665
28666
  Protocols: () => Protocols,
28666
28667
  RiskType: () => RiskType,
28667
28668
  SenseiStrategies: () => SenseiStrategies,
@@ -49159,6 +49160,17 @@ ${JSON.stringify(data, null, 2)}`;
49159
49160
  symbol: "xtBTC",
49160
49161
  logo: "https://assets.strkfarm.com/integrations/tokens/xtbtc.svg",
49161
49162
  address: ContractAddr.from("0x43a35c1425a0125ef8c171f1a75c6f31ef8648edcc8324b55ce1917db3f9b91"),
49163
+ decimals: 18,
49164
+ coingeckId: void 0,
49165
+ displayDecimals: 6,
49166
+ priceProxySymbol: "WBTC",
49167
+ priceCheckAmount: 1e-4
49168
+ // 112000 * 0.0001 = $11.2
49169
+ }, {
49170
+ name: "xLBTC",
49171
+ symbol: "xLBTC",
49172
+ logo: "https://assets.strkfarm.com/integrations/tokens/xlbtc.svg",
49173
+ address: ContractAddr.from("0x036834a40984312f7f7de8d31e3f6305b325389eaeea5b1c0664b2fb936461a4"),
49162
49174
  decimals: 8,
49163
49175
  coingeckId: void 0,
49164
49176
  displayDecimals: 6,
@@ -49747,7 +49759,7 @@ ${JSON.stringify(data, null, 2)}`;
49747
49759
  }
49748
49760
  async getPriceFromMyAPI(tokenSymbol) {
49749
49761
  logger2.verbose(`getPrice from redis: ${tokenSymbol}`);
49750
- const endpoint = "https://app.troves.fi";
49762
+ const endpoint = "https://cache-server-t2me.onrender.com";
49751
49763
  const url = `${endpoint}/api/price/${tokenSymbol}`;
49752
49764
  const priceInfoRes = await fetch(url);
49753
49765
  const priceInfo = await priceInfoRes.json();
@@ -51373,7 +51385,7 @@ ${JSON.stringify(data, null, 2)}`;
51373
51385
  oid: Uint8Array.from([6, 9, 96, 134, 72, 1, 101, 3, 4, 2, suffix])
51374
51386
  });
51375
51387
 
51376
- // node_modules/.pnpm/@noble+curves@2.0.0/node_modules/@noble/curves/utils.js
51388
+ // node_modules/@scure/starknet/node_modules/@noble/curves/utils.js
51377
51389
  var _0n7 = /* @__PURE__ */ BigInt(0);
51378
51390
  var _1n7 = /* @__PURE__ */ BigInt(1);
51379
51391
  function abool2(value, title = "") {
@@ -51519,7 +51531,7 @@ ${JSON.stringify(data, null, 2)}`;
51519
51531
  };
51520
51532
  }
51521
51533
 
51522
- // node_modules/.pnpm/@noble+curves@2.0.0/node_modules/@noble/curves/abstract/modular.js
51534
+ // node_modules/@scure/starknet/node_modules/@noble/curves/abstract/modular.js
51523
51535
  var _0n8 = /* @__PURE__ */ BigInt(0);
51524
51536
  var _1n8 = /* @__PURE__ */ BigInt(1);
51525
51537
  var _2n6 = /* @__PURE__ */ BigInt(2);
@@ -51897,7 +51909,7 @@ ${JSON.stringify(data, null, 2)}`;
51897
51909
  return isLE2 ? numberToBytesLE2(reduced, fieldLen) : numberToBytesBE2(reduced, fieldLen);
51898
51910
  }
51899
51911
 
51900
- // node_modules/.pnpm/@noble+curves@2.0.0/node_modules/@noble/curves/abstract/poseidon.js
51912
+ // node_modules/@scure/starknet/node_modules/@noble/curves/abstract/poseidon.js
51901
51913
  function assertValidPosOpts(opts) {
51902
51914
  const { Fp, roundsFull } = opts;
51903
51915
  validateField2(Fp);
@@ -52065,7 +52077,7 @@ ${JSON.stringify(data, null, 2)}`;
52065
52077
  var hmac2 = (hash2, key, message) => new _HMAC(hash2, key).update(message).digest();
52066
52078
  hmac2.create = (hash2, key) => new _HMAC(hash2, key);
52067
52079
 
52068
- // node_modules/.pnpm/@noble+curves@2.0.0/node_modules/@noble/curves/abstract/curve.js
52080
+ // node_modules/@scure/starknet/node_modules/@noble/curves/abstract/curve.js
52069
52081
  var _0n9 = /* @__PURE__ */ BigInt(0);
52070
52082
  var _1n9 = /* @__PURE__ */ BigInt(1);
52071
52083
  function negateCt(condition, item) {
@@ -52298,7 +52310,7 @@ ${JSON.stringify(data, null, 2)}`;
52298
52310
  };
52299
52311
  }
52300
52312
 
52301
- // node_modules/.pnpm/@noble+curves@2.0.0/node_modules/@noble/curves/abstract/weierstrass.js
52313
+ // node_modules/@scure/starknet/node_modules/@noble/curves/abstract/weierstrass.js
52302
52314
  var divNearest2 = (num2, den) => (num2 + (num2 >= 0 ? den : -den) / _2n7) / den;
52303
52315
  function _splitEndoScalar(k, basis, n) {
52304
52316
  const [[a1, b1], [a2, b2]] = basis;
@@ -53434,7 +53446,7 @@ ${JSON.stringify(data, null, 2)}`;
53434
53446
  /* @__PURE__ */ oidNist(1)
53435
53447
  );
53436
53448
 
53437
- // node_modules/.pnpm/@scure+starknet@2.0.0/node_modules/@scure/starknet/index.js
53449
+ // node_modules/@scure/starknet/index.js
53438
53450
  var CURVE_ORDER2 = BigInt("3618502788666131213697322783095070105526743751716087489154079457884512865583");
53439
53451
  var MAX_VALUE2 = BigInt("0x800000000000000000000000000000000000000000000000000000000000000");
53440
53452
  var nBitLength2 = 252;
@@ -53807,6 +53819,55 @@ ${JSON.stringify(data, null, 2)}`;
53807
53819
  }
53808
53820
  };
53809
53821
 
53822
+ // src/modules/pricer-lst.ts
53823
+ var PricerLST = class extends Pricer {
53824
+ // e.g. xSTRK/STRK
53825
+ constructor(config3, tokenMaps) {
53826
+ const refreshInterval = 5e3;
53827
+ const staleTime = 6e4;
53828
+ const allTokens = tokenMaps.map((map2) => [map2.lst, map2.underlying]).flat();
53829
+ super(config3, allTokens, refreshInterval, staleTime);
53830
+ this.EKUBO_API = "https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_ADDRESS}}/{{UNDERLYING_ADDRESS}}";
53831
+ this.tokenMaps = tokenMaps;
53832
+ }
53833
+ isUnderlying(token) {
53834
+ return this.tokenMaps.some((map2) => map2.underlying.address.eq(token.address));
53835
+ }
53836
+ getUnderlying(token) {
53837
+ return this.tokenMaps.find((map2) => map2.lst.address.eq(token.address)).underlying;
53838
+ }
53839
+ async _getPrice(token, defaultMethod = "all") {
53840
+ if (this.isUnderlying(token)) {
53841
+ return 1;
53842
+ }
53843
+ const methodToUse = this.methodToUse[token.symbol] || defaultMethod;
53844
+ logger2.verbose(`Fetching price of ${token.symbol} using ${methodToUse}`);
53845
+ try {
53846
+ const result = await this._getPriceEkubo(token, new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals));
53847
+ this.methodToUse[token.symbol] = "Ekubo";
53848
+ return result;
53849
+ } catch (error2) {
53850
+ console.warn(`Ekubo: price err [${token.symbol}]: `, error2.message);
53851
+ console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error2));
53852
+ }
53853
+ throw new FatalError(`Price not found for ${token.symbol}`);
53854
+ }
53855
+ async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
53856
+ const underlying = this.getUnderlying(token);
53857
+ const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei()).replace("{{UNDERLYING_ADDRESS}}", underlying.address.toString());
53858
+ const result = await axios_default.get(url);
53859
+ const data = result.data;
53860
+ const multiplier = 1 / amountIn.toNumber();
53861
+ const outputUnderlying = Number(Web3Number.fromWei(data.total_calculated, underlying.decimals).toFixed(6)) * multiplier;
53862
+ logger2.verbose(`Ekubo: ${token.symbol} -> ${underlying.symbol}: ${outputUnderlying}, retry: ${retry}`);
53863
+ if (outputUnderlying === 0 && retry < 3) {
53864
+ const amountIn2 = new Web3Number(100, token.decimals);
53865
+ return await this._getPriceEkubo(token, amountIn2, retry + 1);
53866
+ }
53867
+ return outputUnderlying;
53868
+ }
53869
+ };
53870
+
53810
53871
  // src/interfaces/common.tsx
53811
53872
  var import_jsx_runtime = __toESM(require_jsx_runtime());
53812
53873
  var RiskType = /* @__PURE__ */ ((RiskType2) => {
@@ -68129,6 +68190,29 @@ ${JSON.stringify(data, null, 2)}`;
68129
68190
  points: [],
68130
68191
  contractDetails: [],
68131
68192
  investmentSteps: []
68193
+ },
68194
+ {
68195
+ ...xSTRKSTRK,
68196
+ name: "Ekubo xLBTC/LBTC",
68197
+ description: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, {}),
68198
+ address: ContractAddr.from(
68199
+ "0x315a614603b1f702e466aedcbcb1ad97a77eb1192b8bd077e5154d4f2ee4fab"
68200
+ ),
68201
+ launchBlock: 2344809,
68202
+ // must be same order as poolKey token0 and token1
68203
+ depositTokens: [
68204
+ Global.getDefaultTokens().find((t) => t.symbol === "LBTC"),
68205
+ Global.getDefaultTokens().find((t) => t.symbol === "xLBTC")
68206
+ ],
68207
+ additionalInfo: {
68208
+ ...xSTRKSTRK.additionalInfo,
68209
+ quoteAsset: Global.getDefaultTokens().find((t) => t.symbol === "LBTC"),
68210
+ lstContract: Global.getDefaultTokens().find((t) => t.symbol === "xLBTC").address
68211
+ },
68212
+ faqs: getLSTFAQs("xLBTC"),
68213
+ points: [],
68214
+ contractDetails: [],
68215
+ investmentSteps: []
68132
68216
  }
68133
68217
  ];
68134
68218
  var ETHUSDCRe7Strategy = {
@@ -76218,17 +76302,16 @@ ${JSON.stringify(data, null, 2)}`;
76218
76302
  const legAUM = await adapter.getPositions(this.config);
76219
76303
  const underlying = this.asset();
76220
76304
  let vesuAum = Web3Number.fromWei("0", underlying.decimals);
76305
+ let tokenUnderlyingPrice = await this.pricer.getPrice(this.asset().symbol);
76221
76306
  if (legAUM[0].token.address.eq(underlying.address)) {
76222
76307
  vesuAum = vesuAum.plus(legAUM[0].amount);
76223
76308
  } else {
76224
- const tokenPrice = await this.pricer.getPrice(legAUM[1].token.symbol);
76225
- vesuAum = vesuAum.plus(legAUM[1].usdValue / tokenPrice.price);
76309
+ vesuAum = vesuAum.plus(legAUM[1].usdValue / tokenUnderlyingPrice.price);
76226
76310
  }
76227
76311
  if (legAUM[1].token.address.eq(underlying.address)) {
76228
76312
  vesuAum = vesuAum.minus(legAUM[1].amount);
76229
76313
  } else {
76230
- const tokenPrice = await this.pricer.getPrice(legAUM[1].token.symbol);
76231
- vesuAum = vesuAum.minus(legAUM[1].usdValue / tokenPrice.price);
76314
+ vesuAum = vesuAum.minus(legAUM[1].usdValue / tokenUnderlyingPrice.price);
76232
76315
  }
76233
76316
  ;
76234
76317
  logger2.verbose(`${this.getTag()} Vesu AUM: ${vesuAum}, legCollateral: ${legAUM[0].amount.toNumber()}, legDebt: ${legAUM[1].amount.toNumber()}`);
@@ -76984,9 +77067,9 @@ ${JSON.stringify(data, null, 2)}`;
76984
77067
  }
76985
77068
  // not applicable for this strategy
76986
77069
  // No rewards on collateral or borrowing of LST assets
76987
- async getRewardsAUM(prevAum) {
76988
- return Web3Number.fromWei("0", this.asset().decimals);
76989
- }
77070
+ // protected async getRewardsAUM(prevAum: Web3Number): Promise<Web3Number> {
77071
+ // return Web3Number.fromWei("0", this.asset().decimals);
77072
+ // }
76990
77073
  async getLSTDexPrice() {
76991
77074
  const ekuboQuoter = new EkuboQuoter(this.config);
76992
77075
  const lstTokenInfo = this.asset();
@@ -77018,12 +77101,12 @@ ${JSON.stringify(data, null, 2)}`;
77018
77101
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
77019
77102
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
77020
77103
  logger2.debug(`${this.getTag()}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
77104
+ const dexPrice = await this.getLSTDexPrice();
77021
77105
  const addedCollateral = params.leg1DepositAmount.multipliedBy(params.isDeposit ? 1 : -1);
77022
- const DEXPrice = await this.getLSTDexPrice();
77023
77106
  logger2.verbose(`${this.getTag()}::getVesuMultiplyCall addedCollateral: ${addedCollateral}`);
77024
77107
  const numeratorPart1 = existingCollateralInfo.amount.plus(addedCollateral).multipliedBy(collateralPrice).multipliedBy(legLTV);
77025
77108
  const numeratorPart2 = existingDebtInfo.amount.multipliedBy(debtPrice).multipliedBy(this.metadata.additionalInfo.targetHealthFactor);
77026
- const denominatorPart = this.metadata.additionalInfo.targetHealthFactor - legLTV / DEXPrice;
77109
+ const denominatorPart = this.metadata.additionalInfo.targetHealthFactor - legLTV / dexPrice;
77027
77110
  const x_debt_usd = numeratorPart1.minus(numeratorPart2).dividedBy(denominatorPart);
77028
77111
  logger2.verbose(`${this.getTag()}::getVesuMultiplyCall x_debt_usd: ${x_debt_usd}`);
77029
77112
  logger2.debug(`${this.getTag()}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}, numeratorPart2: ${numeratorPart2}, denominatorPart: ${denominatorPart}`);
@@ -77033,6 +77116,7 @@ ${JSON.stringify(data, null, 2)}`;
77033
77116
  return this.getModifyLeverCall({
77034
77117
  marginAmount,
77035
77118
  debtAmount,
77119
+ lstDexPriceInUnderlying: dexPrice,
77036
77120
  isIncrease: debtAmount.greaterThan(0)
77037
77121
  });
77038
77122
  }
@@ -77074,8 +77158,8 @@ ${JSON.stringify(data, null, 2)}`;
77074
77158
  proofsIDs.push(STEP1_ID);
77075
77159
  manageCalls.push(manageCall1);
77076
77160
  }
77161
+ const lstDexPriceInUnderlying = params.lstDexPriceInUnderlying;
77077
77162
  const ekuboQuoter = new EkuboQuoter(this.config);
77078
- const lstPrice = await this.getLSTExchangeRate();
77079
77163
  const marginSwap = [];
77080
77164
  const MAX_SLIPPAGE = 0.01;
77081
77165
  const fromToken = params.isIncrease ? lstUnderlyingTokenInfo : lstTokenInfo;
@@ -77088,8 +77172,8 @@ ${JSON.stringify(data, null, 2)}`;
77088
77172
  );
77089
77173
  assert3(leverSwapQuote.price_impact < MAX_SLIPPAGE, "getIncreaseLeverCall: Price impact is too high [Debt swap]");
77090
77174
  const leverSwap = ekuboQuoter.getVesuMultiplyQuote(leverSwapQuote, fromToken, toToken);
77091
- const minExpectedDebt = params.debtAmount.dividedBy(lstPrice).multipliedBy(1 - MAX_SLIPPAGE);
77092
- const maxUsedCollateral = params.debtAmount.abs().dividedBy(lstPrice).multipliedBy(1 + MAX_SLIPPAGE);
77175
+ const minExpectedDebt = params.debtAmount.dividedBy(lstDexPriceInUnderlying).multipliedBy(1 - MAX_SLIPPAGE);
77176
+ const maxUsedCollateral = params.debtAmount.abs().dividedBy(lstDexPriceInUnderlying).multipliedBy(1 + MAX_SLIPPAGE);
77093
77177
  const STEP2_ID = "switch_delegation_on" /* SWITCH_DELEGATION_ON */;
77094
77178
  const manage2Info = this.getProofs(STEP2_ID);
77095
77179
  const manageCall2 = manage2Info.callConstructor({
@@ -77287,6 +77371,17 @@ ${JSON.stringify(data, null, 2)}`;
77287
77371
  targetHealthFactor: 1.1,
77288
77372
  minHealthFactor: 1.05
77289
77373
  };
77374
+ var hyperxLBTC = {
77375
+ vaultAddress: ContractAddr.from("0x38e96a301428d204ab4553799aa386a0f14a5ef9b30a5830be1814e4fb8da1c"),
77376
+ manager: ContractAddr.from("0x18d376446d9df1f783e17aff1f21bac3d97aa3ba378e367742cdd744468ad35"),
77377
+ vaultAllocator: ContractAddr.from("0x3e98774ca0508505ba6d7f17d95ec391648f44f947b0d211241464a4f5b9b20"),
77378
+ redeemRequestNFT: ContractAddr.from("0x268017b4c8b2117ca0136d9a77e3666db44b143447566f0746ca0b1c9ab1e72"),
77379
+ aumOracle: ContractAddr.from("0x521a3f339c65e918e0d8a065b14baef1ea25676bb7fca1e0238ac47e20d7755"),
77380
+ leafAdapters: [],
77381
+ adapters: [],
77382
+ targetHealthFactor: 1.1,
77383
+ minHealthFactor: 1.05
77384
+ };
77290
77385
  function getInvestmentSteps(lstSymbol, underlyingSymbol) {
77291
77386
  return [
77292
77387
  `Deposit ${underlyingSymbol} into the vault`,
@@ -77323,7 +77418,8 @@ ${JSON.stringify(data, null, 2)}`;
77323
77418
  getStrategySettings("xSTRK", "STRK", hyperxSTRK, false),
77324
77419
  getStrategySettings("xWBTC", "WBTC", hyperxWBTC, true),
77325
77420
  getStrategySettings("xtBTC", "tBTC", hyperxtBTC, true),
77326
- getStrategySettings("xsBTC", "solvBTC", hyperxsBTC, true)
77421
+ getStrategySettings("xsBTC", "solvBTC", hyperxsBTC, true),
77422
+ getStrategySettings("xLBTC", "LBTC", hyperxLBTC, true)
77327
77423
  ];
77328
77424
  return __toCommonJS(index_browser_exports);
77329
77425
  })();
@@ -253,6 +253,17 @@ var defaultTokens = [{
253
253
  symbol: "xtBTC",
254
254
  logo: "https://assets.strkfarm.com/integrations/tokens/xtbtc.svg",
255
255
  address: ContractAddr.from("0x43a35c1425a0125ef8c171f1a75c6f31ef8648edcc8324b55ce1917db3f9b91"),
256
+ decimals: 18,
257
+ coingeckId: void 0,
258
+ displayDecimals: 6,
259
+ priceProxySymbol: "WBTC",
260
+ priceCheckAmount: 1e-4
261
+ // 112000 * 0.0001 = $11.2
262
+ }, {
263
+ name: "xLBTC",
264
+ symbol: "xLBTC",
265
+ logo: "https://assets.strkfarm.com/integrations/tokens/xlbtc.svg",
266
+ address: ContractAddr.from("0x036834a40984312f7f7de8d31e3f6305b325389eaeea5b1c0664b2fb936461a4"),
256
267
  decimals: 8,
257
268
  coingeckId: void 0,
258
269
  displayDecimals: 6,
@@ -848,7 +859,7 @@ var PricerFromApi = class extends PricerBase {
848
859
  }
849
860
  async getPriceFromMyAPI(tokenSymbol) {
850
861
  logger.verbose(`getPrice from redis: ${tokenSymbol}`);
851
- const endpoint = "https://app.troves.fi";
862
+ const endpoint = "https://cache-server-t2me.onrender.com";
852
863
  const url = `${endpoint}/api/price/${tokenSymbol}`;
853
864
  const priceInfoRes = await fetch(url);
854
865
  const priceInfo = await priceInfoRes.json();
@@ -2213,6 +2224,56 @@ var EkuboQuoter = class {
2213
2224
  }
2214
2225
  };
2215
2226
 
2227
+ // src/modules/pricer-lst.ts
2228
+ import axios6 from "axios";
2229
+ var PricerLST = class extends Pricer {
2230
+ // e.g. xSTRK/STRK
2231
+ constructor(config, tokenMaps) {
2232
+ const refreshInterval = 5e3;
2233
+ const staleTime = 6e4;
2234
+ const allTokens = tokenMaps.map((map) => [map.lst, map.underlying]).flat();
2235
+ super(config, allTokens, refreshInterval, staleTime);
2236
+ this.EKUBO_API = "https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_ADDRESS}}/{{UNDERLYING_ADDRESS}}";
2237
+ this.tokenMaps = tokenMaps;
2238
+ }
2239
+ isUnderlying(token) {
2240
+ return this.tokenMaps.some((map) => map.underlying.address.eq(token.address));
2241
+ }
2242
+ getUnderlying(token) {
2243
+ return this.tokenMaps.find((map) => map.lst.address.eq(token.address)).underlying;
2244
+ }
2245
+ async _getPrice(token, defaultMethod = "all") {
2246
+ if (this.isUnderlying(token)) {
2247
+ return 1;
2248
+ }
2249
+ const methodToUse = this.methodToUse[token.symbol] || defaultMethod;
2250
+ logger.verbose(`Fetching price of ${token.symbol} using ${methodToUse}`);
2251
+ try {
2252
+ const result = await this._getPriceEkubo(token, new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals));
2253
+ this.methodToUse[token.symbol] = "Ekubo";
2254
+ return result;
2255
+ } catch (error) {
2256
+ console.warn(`Ekubo: price err [${token.symbol}]: `, error.message);
2257
+ console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error));
2258
+ }
2259
+ throw new FatalError(`Price not found for ${token.symbol}`);
2260
+ }
2261
+ async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
2262
+ const underlying = this.getUnderlying(token);
2263
+ const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei()).replace("{{UNDERLYING_ADDRESS}}", underlying.address.toString());
2264
+ const result = await axios6.get(url);
2265
+ const data = result.data;
2266
+ const multiplier = 1 / amountIn.toNumber();
2267
+ const outputUnderlying = Number(Web3Number.fromWei(data.total_calculated, underlying.decimals).toFixed(6)) * multiplier;
2268
+ logger.verbose(`Ekubo: ${token.symbol} -> ${underlying.symbol}: ${outputUnderlying}, retry: ${retry}`);
2269
+ if (outputUnderlying === 0 && retry < 3) {
2270
+ const amountIn2 = new Web3Number(100, token.decimals);
2271
+ return await this._getPriceEkubo(token, amountIn2, retry + 1);
2272
+ }
2273
+ return outputUnderlying;
2274
+ }
2275
+ };
2276
+
2216
2277
  // src/interfaces/common.tsx
2217
2278
  import { BlockTag, RpcProvider as RpcProvider2 } from "starknet";
2218
2279
  import { Fragment, jsx } from "react/jsx-runtime";
@@ -3919,9 +3980,9 @@ var BaseStrategy = class extends CacheClass {
3919
3980
  };
3920
3981
 
3921
3982
  // src/node/headless.browser.ts
3922
- import axios6 from "axios";
3983
+ import axios7 from "axios";
3923
3984
  async function getAPIUsingHeadlessBrowser(url) {
3924
- const res = await axios6.get(url);
3985
+ const res = await axios7.get(url);
3925
3986
  return res.data;
3926
3987
  }
3927
3988
 
@@ -16551,6 +16612,29 @@ var lstStrategies = [
16551
16612
  points: [],
16552
16613
  contractDetails: [],
16553
16614
  investmentSteps: []
16615
+ },
16616
+ {
16617
+ ...xSTRKSTRK,
16618
+ name: "Ekubo xLBTC/LBTC",
16619
+ description: /* @__PURE__ */ jsx3(Fragment2, {}),
16620
+ address: ContractAddr.from(
16621
+ "0x315a614603b1f702e466aedcbcb1ad97a77eb1192b8bd077e5154d4f2ee4fab"
16622
+ ),
16623
+ launchBlock: 2344809,
16624
+ // must be same order as poolKey token0 and token1
16625
+ depositTokens: [
16626
+ Global.getDefaultTokens().find((t) => t.symbol === "LBTC"),
16627
+ Global.getDefaultTokens().find((t) => t.symbol === "xLBTC")
16628
+ ],
16629
+ additionalInfo: {
16630
+ ...xSTRKSTRK.additionalInfo,
16631
+ quoteAsset: Global.getDefaultTokens().find((t) => t.symbol === "LBTC"),
16632
+ lstContract: Global.getDefaultTokens().find((t) => t.symbol === "xLBTC").address
16633
+ },
16634
+ faqs: getLSTFAQs("xLBTC"),
16635
+ points: [],
16636
+ contractDetails: [],
16637
+ investmentSteps: []
16554
16638
  }
16555
16639
  ];
16556
16640
  var ETHUSDCRe7Strategy = {
@@ -24653,17 +24737,16 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
24653
24737
  const legAUM = await adapter.getPositions(this.config);
24654
24738
  const underlying = this.asset();
24655
24739
  let vesuAum = Web3Number.fromWei("0", underlying.decimals);
24740
+ let tokenUnderlyingPrice = await this.pricer.getPrice(this.asset().symbol);
24656
24741
  if (legAUM[0].token.address.eq(underlying.address)) {
24657
24742
  vesuAum = vesuAum.plus(legAUM[0].amount);
24658
24743
  } else {
24659
- const tokenPrice = await this.pricer.getPrice(legAUM[1].token.symbol);
24660
- vesuAum = vesuAum.plus(legAUM[1].usdValue / tokenPrice.price);
24744
+ vesuAum = vesuAum.plus(legAUM[1].usdValue / tokenUnderlyingPrice.price);
24661
24745
  }
24662
24746
  if (legAUM[1].token.address.eq(underlying.address)) {
24663
24747
  vesuAum = vesuAum.minus(legAUM[1].amount);
24664
24748
  } else {
24665
- const tokenPrice = await this.pricer.getPrice(legAUM[1].token.symbol);
24666
- vesuAum = vesuAum.minus(legAUM[1].usdValue / tokenPrice.price);
24749
+ vesuAum = vesuAum.minus(legAUM[1].usdValue / tokenUnderlyingPrice.price);
24667
24750
  }
24668
24751
  ;
24669
24752
  logger.verbose(`${this.getTag()} Vesu AUM: ${vesuAum}, legCollateral: ${legAUM[0].amount.toNumber()}, legDebt: ${legAUM[1].amount.toNumber()}`);
@@ -25420,9 +25503,9 @@ var UniversalLstMultiplierStrategy = class extends UniversalStrategy {
25420
25503
  }
25421
25504
  // not applicable for this strategy
25422
25505
  // No rewards on collateral or borrowing of LST assets
25423
- async getRewardsAUM(prevAum) {
25424
- return Web3Number.fromWei("0", this.asset().decimals);
25425
- }
25506
+ // protected async getRewardsAUM(prevAum: Web3Number): Promise<Web3Number> {
25507
+ // return Web3Number.fromWei("0", this.asset().decimals);
25508
+ // }
25426
25509
  async getLSTDexPrice() {
25427
25510
  const ekuboQuoter = new EkuboQuoter(this.config);
25428
25511
  const lstTokenInfo = this.asset();
@@ -25454,12 +25537,12 @@ var UniversalLstMultiplierStrategy = class extends UniversalStrategy {
25454
25537
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
25455
25538
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
25456
25539
  logger.debug(`${this.getTag()}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
25540
+ const dexPrice = await this.getLSTDexPrice();
25457
25541
  const addedCollateral = params.leg1DepositAmount.multipliedBy(params.isDeposit ? 1 : -1);
25458
- const DEXPrice = await this.getLSTDexPrice();
25459
25542
  logger.verbose(`${this.getTag()}::getVesuMultiplyCall addedCollateral: ${addedCollateral}`);
25460
25543
  const numeratorPart1 = existingCollateralInfo.amount.plus(addedCollateral).multipliedBy(collateralPrice).multipliedBy(legLTV);
25461
25544
  const numeratorPart2 = existingDebtInfo.amount.multipliedBy(debtPrice).multipliedBy(this.metadata.additionalInfo.targetHealthFactor);
25462
- const denominatorPart = this.metadata.additionalInfo.targetHealthFactor - legLTV / DEXPrice;
25545
+ const denominatorPart = this.metadata.additionalInfo.targetHealthFactor - legLTV / dexPrice;
25463
25546
  const x_debt_usd = numeratorPart1.minus(numeratorPart2).dividedBy(denominatorPart);
25464
25547
  logger.verbose(`${this.getTag()}::getVesuMultiplyCall x_debt_usd: ${x_debt_usd}`);
25465
25548
  logger.debug(`${this.getTag()}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}, numeratorPart2: ${numeratorPart2}, denominatorPart: ${denominatorPart}`);
@@ -25469,6 +25552,7 @@ var UniversalLstMultiplierStrategy = class extends UniversalStrategy {
25469
25552
  return this.getModifyLeverCall({
25470
25553
  marginAmount,
25471
25554
  debtAmount,
25555
+ lstDexPriceInUnderlying: dexPrice,
25472
25556
  isIncrease: debtAmount.greaterThan(0)
25473
25557
  });
25474
25558
  }
@@ -25510,8 +25594,8 @@ var UniversalLstMultiplierStrategy = class extends UniversalStrategy {
25510
25594
  proofsIDs.push(STEP1_ID);
25511
25595
  manageCalls.push(manageCall1);
25512
25596
  }
25597
+ const lstDexPriceInUnderlying = params.lstDexPriceInUnderlying;
25513
25598
  const ekuboQuoter = new EkuboQuoter(this.config);
25514
- const lstPrice = await this.getLSTExchangeRate();
25515
25599
  const marginSwap = [];
25516
25600
  const MAX_SLIPPAGE = 0.01;
25517
25601
  const fromToken = params.isIncrease ? lstUnderlyingTokenInfo : lstTokenInfo;
@@ -25524,8 +25608,8 @@ var UniversalLstMultiplierStrategy = class extends UniversalStrategy {
25524
25608
  );
25525
25609
  assert(leverSwapQuote.price_impact < MAX_SLIPPAGE, "getIncreaseLeverCall: Price impact is too high [Debt swap]");
25526
25610
  const leverSwap = ekuboQuoter.getVesuMultiplyQuote(leverSwapQuote, fromToken, toToken);
25527
- const minExpectedDebt = params.debtAmount.dividedBy(lstPrice).multipliedBy(1 - MAX_SLIPPAGE);
25528
- const maxUsedCollateral = params.debtAmount.abs().dividedBy(lstPrice).multipliedBy(1 + MAX_SLIPPAGE);
25611
+ const minExpectedDebt = params.debtAmount.dividedBy(lstDexPriceInUnderlying).multipliedBy(1 - MAX_SLIPPAGE);
25612
+ const maxUsedCollateral = params.debtAmount.abs().dividedBy(lstDexPriceInUnderlying).multipliedBy(1 + MAX_SLIPPAGE);
25529
25613
  const STEP2_ID = "switch_delegation_on" /* SWITCH_DELEGATION_ON */;
25530
25614
  const manage2Info = this.getProofs(STEP2_ID);
25531
25615
  const manageCall2 = manage2Info.callConstructor({
@@ -25723,6 +25807,17 @@ var hyperxsBTC = {
25723
25807
  targetHealthFactor: 1.1,
25724
25808
  minHealthFactor: 1.05
25725
25809
  };
25810
+ var hyperxLBTC = {
25811
+ vaultAddress: ContractAddr.from("0x38e96a301428d204ab4553799aa386a0f14a5ef9b30a5830be1814e4fb8da1c"),
25812
+ manager: ContractAddr.from("0x18d376446d9df1f783e17aff1f21bac3d97aa3ba378e367742cdd744468ad35"),
25813
+ vaultAllocator: ContractAddr.from("0x3e98774ca0508505ba6d7f17d95ec391648f44f947b0d211241464a4f5b9b20"),
25814
+ redeemRequestNFT: ContractAddr.from("0x268017b4c8b2117ca0136d9a77e3666db44b143447566f0746ca0b1c9ab1e72"),
25815
+ aumOracle: ContractAddr.from("0x521a3f339c65e918e0d8a065b14baef1ea25676bb7fca1e0238ac47e20d7755"),
25816
+ leafAdapters: [],
25817
+ adapters: [],
25818
+ targetHealthFactor: 1.1,
25819
+ minHealthFactor: 1.05
25820
+ };
25726
25821
  function getInvestmentSteps(lstSymbol, underlyingSymbol) {
25727
25822
  return [
25728
25823
  `Deposit ${underlyingSymbol} into the vault`,
@@ -25759,7 +25854,8 @@ var HyperLSTStrategies = [
25759
25854
  getStrategySettings("xSTRK", "STRK", hyperxSTRK, false),
25760
25855
  getStrategySettings("xWBTC", "WBTC", hyperxWBTC, true),
25761
25856
  getStrategySettings("xtBTC", "tBTC", hyperxtBTC, true),
25762
- getStrategySettings("xsBTC", "solvBTC", hyperxsBTC, true)
25857
+ getStrategySettings("xsBTC", "solvBTC", hyperxsBTC, true),
25858
+ getStrategySettings("xLBTC", "LBTC", hyperxLBTC, true)
25763
25859
  ];
25764
25860
  export {
25765
25861
  AUMTypes,
@@ -25784,6 +25880,7 @@ export {
25784
25880
  Pragma,
25785
25881
  Pricer,
25786
25882
  PricerFromApi,
25883
+ PricerLST,
25787
25884
  Protocols,
25788
25885
  RiskType,
25789
25886
  SenseiStrategies,
package/dist/index.d.ts CHANGED
@@ -245,7 +245,9 @@ declare class Pricer extends PricerBase {
245
245
  };
246
246
  refreshInterval: number;
247
247
  staleTime: number;
248
- private methodToUse;
248
+ protected methodToUse: {
249
+ [tokenSymbol: string]: 'Ekubo' | 'Coinbase' | 'Coinmarketcap';
250
+ };
249
251
  /**
250
252
  * TOKENA and TOKENB are the two token names to get price of TokenA in terms of TokenB
251
253
  */
@@ -1247,9 +1249,8 @@ declare const UniversalStrategies: IStrategyMetadata<UniversalStrategySettings>[
1247
1249
 
1248
1250
  declare class UniversalLstMultiplierStrategy extends UniversalStrategy<UniversalStrategySettings> {
1249
1251
  private quoteAmountToFetchPrice;
1250
- constructor(config: IConfig, pricer: PricerBase, metadata: IStrategyMetadata<UniversalStrategySettings>);
1252
+ constructor(config: IConfig, pricer: PricerLST, metadata: IStrategyMetadata<UniversalStrategySettings>);
1251
1253
  getVesuAdapters(): VesuAdapter[];
1252
- protected getRewardsAUM(prevAum: Web3Number): Promise<Web3Number>;
1253
1254
  getLSTDexPrice(): Promise<number>;
1254
1255
  /**
1255
1256
  * Uses vesu's multiple call to create leverage on LST
@@ -1269,6 +1270,7 @@ declare class UniversalLstMultiplierStrategy extends UniversalStrategy<Universal
1269
1270
  getModifyLeverCall(params: {
1270
1271
  marginAmount: Web3Number;
1271
1272
  debtAmount: Web3Number;
1273
+ lstDexPriceInUnderlying: number;
1272
1274
  isIncrease: boolean;
1273
1275
  }): Promise<Call[]>;
1274
1276
  }
@@ -1338,6 +1340,19 @@ declare class Global {
1338
1340
  static getGlobalCache<T>(key: string): T | null;
1339
1341
  }
1340
1342
 
1343
+ declare class PricerLST extends Pricer {
1344
+ private tokenMaps;
1345
+ protected EKUBO_API: string;
1346
+ constructor(config: IConfig, tokenMaps: {
1347
+ lst: TokenInfo;
1348
+ underlying: TokenInfo;
1349
+ }[]);
1350
+ isUnderlying(token: TokenInfo): boolean;
1351
+ getUnderlying(token: TokenInfo): TokenInfo;
1352
+ _getPrice(token: TokenInfo, defaultMethod?: string): Promise<number>;
1353
+ _getPriceEkubo(token: TokenInfo, amountIn?: Web3Number, retry?: number): Promise<number>;
1354
+ }
1355
+
1341
1356
  declare class TelegramNotif {
1342
1357
  private subscribers;
1343
1358
  readonly bot: TelegramBot;
@@ -1470,4 +1485,4 @@ declare class PasswordJsonCryptoUtil {
1470
1485
  decrypt(encryptedData: string, password: string): any;
1471
1486
  }
1472
1487
 
1473
- export { AUMTypes, type AccountInfo, type AdapterLeafType, type AllAccountsStore, type ApproveCallParams, AutoCompounderSTRK, type AvnuSwapCallParams, AvnuWrapper, BaseAdapter, BaseStrategy, type CLVaultStrategySettings, CommonAdapter, type CommonAdapterConfig, ContractAddr, type DecreaseLeverParams, Deployer, type DualActionAmount, type DualTokenInfo, ERC20, type EkuboBounds, EkuboCLVault, EkuboCLVaultStrategies, type EkuboPoolKey, type EkuboQuote, EkuboQuoter, type EkuboRouteNode, type EkuboSplit, type FAQ, FatalError, type FlashloanCallParams, FlowChartColors, type GenerateCallFn, Global, HyperLSTStrategies, type IConfig, type IInvestmentFlow, ILending, type ILendingMetadata, type ILendingPosition, type IProtocol, type IStrategyMetadata, type IncreaseLeverParams, Initializable, type LeafAdapterFn, type LeafData, type LendingToken, type ManageCall, MarginType, Network, PasswordJsonCryptoUtil, Pragma, type PriceInfo, Pricer, PricerFromApi, PricerRedis, Protocols, type RequiredFields, type RequiredKeys, type RequiredStoreConfig, type RiskFactor, RiskType, type Route, type RouteNode, SenseiStrategies, SenseiVault, type SenseiVaultSettings, type SingleActionAmount, type SingleTokenInfo, StandardMerkleTree, type StandardMerkleTreeData, Store, type StoreConfig, type Swap, type SwapInfo, TelegramNotif, type TokenAmount, type TokenInfo, UNIVERSAL_ADAPTERS, UNIVERSAL_MANAGE_IDS, UniversalLstMultiplierStrategy, type UniversalManageCall, UniversalStrategies, UniversalStrategy, type UniversalStrategySettings, type VaultPosition, VesuAdapter, type VesuAdapterConfig, type VesuAmount, VesuAmountDenomination, VesuAmountType, type VesuDefiSpringRewardsCallParams, type VesuModifyDelegationCallParams, type VesuModifyPositionCallParams, type VesuMultiplyCallParams, VesuPools, VesuRebalance, type VesuRebalanceSettings, VesuRebalanceStrategies, Web3Number, ZkLend, assert, getAPIUsingHeadlessBrowser, getContractDetails, getDefaultStoreConfig, getMainnetConfig, getNoRiskTags, getRiskColor, getRiskExplaination, getTrovesEndpoint, highlightTextWithLinks, type i257, logger };
1488
+ export { AUMTypes, type AccountInfo, type AdapterLeafType, type AllAccountsStore, type ApproveCallParams, AutoCompounderSTRK, type AvnuSwapCallParams, AvnuWrapper, BaseAdapter, BaseStrategy, type CLVaultStrategySettings, CommonAdapter, type CommonAdapterConfig, ContractAddr, type DecreaseLeverParams, Deployer, type DualActionAmount, type DualTokenInfo, ERC20, type EkuboBounds, EkuboCLVault, EkuboCLVaultStrategies, type EkuboPoolKey, type EkuboQuote, EkuboQuoter, type EkuboRouteNode, type EkuboSplit, type FAQ, FatalError, type FlashloanCallParams, FlowChartColors, type GenerateCallFn, Global, HyperLSTStrategies, type IConfig, type IInvestmentFlow, ILending, type ILendingMetadata, type ILendingPosition, type IProtocol, type IStrategyMetadata, type IncreaseLeverParams, Initializable, type LeafAdapterFn, type LeafData, type LendingToken, type ManageCall, MarginType, Network, PasswordJsonCryptoUtil, Pragma, type PriceInfo, Pricer, PricerFromApi, PricerLST, PricerRedis, Protocols, type RequiredFields, type RequiredKeys, type RequiredStoreConfig, type RiskFactor, RiskType, type Route, type RouteNode, SenseiStrategies, SenseiVault, type SenseiVaultSettings, type SingleActionAmount, type SingleTokenInfo, StandardMerkleTree, type StandardMerkleTreeData, Store, type StoreConfig, type Swap, type SwapInfo, TelegramNotif, type TokenAmount, type TokenInfo, UNIVERSAL_ADAPTERS, UNIVERSAL_MANAGE_IDS, UniversalLstMultiplierStrategy, type UniversalManageCall, UniversalStrategies, UniversalStrategy, type UniversalStrategySettings, type VaultPosition, VesuAdapter, type VesuAdapterConfig, type VesuAmount, VesuAmountDenomination, VesuAmountType, type VesuDefiSpringRewardsCallParams, type VesuModifyDelegationCallParams, type VesuModifyPositionCallParams, type VesuMultiplyCallParams, VesuPools, VesuRebalance, type VesuRebalanceSettings, VesuRebalanceStrategies, Web3Number, ZkLend, assert, getAPIUsingHeadlessBrowser, getContractDetails, getDefaultStoreConfig, getMainnetConfig, getNoRiskTags, getRiskColor, getRiskExplaination, getTrovesEndpoint, highlightTextWithLinks, type i257, logger };