@strkfarm/sdk 2.0.0-dev.40 → 2.0.0-dev.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -664,20 +664,20 @@ var defaultTokens = [
664
664
  decimals: 18,
665
665
  coingeckId: void 0,
666
666
  displayDecimals: 6,
667
- priceCheckAmount: 1e-4
667
+ priceCheckAmount: 1e-4,
668
668
  // 112000 * 0.0001 = $11.2
669
+ dontPrice: true
669
670
  },
670
671
  {
671
672
  name: "mRe7YIELD",
672
673
  symbol: "mRe7YIELD",
673
674
  logo: "https://midas.app/assets/mre7-BcOOHm7i.svg",
674
- address: ContractAddr.from(
675
- "0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"
676
- ),
675
+ address: ContractAddr.from("0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"),
677
676
  decimals: 18,
678
677
  coingeckId: void 0,
679
678
  displayDecimals: 2,
680
- priceCheckAmount: 100
679
+ priceCheckAmount: 100,
680
+ dontPrice: true
681
681
  },
682
682
  {
683
683
  name: "fyWBTC",
@@ -687,8 +687,9 @@ var defaultTokens = [
687
687
  decimals: 8,
688
688
  coingeckId: void 0,
689
689
  displayDecimals: 6,
690
- priceCheckAmount: 1e-3
690
+ priceCheckAmount: 1e-3,
691
691
  // 112000 * 0.0001 = $110.2
692
+ dontPrice: true
692
693
  },
693
694
  {
694
695
  name: "fyETH",
@@ -698,7 +699,8 @@ var defaultTokens = [
698
699
  decimals: 18,
699
700
  coingeckId: void 0,
700
701
  displayDecimals: 4,
701
- priceCheckAmount: 0.1
702
+ priceCheckAmount: 0.1,
703
+ dontPrice: true
702
704
  },
703
705
  {
704
706
  name: "fyUSDC",
@@ -708,7 +710,8 @@ var defaultTokens = [
708
710
  decimals: 6,
709
711
  coingeckId: void 0,
710
712
  displayDecimals: 2,
711
- priceCheckAmount: 100
713
+ priceCheckAmount: 100,
714
+ dontPrice: true
712
715
  },
713
716
  {
714
717
  name: "strkBTC",
@@ -3726,7 +3729,7 @@ var TokenMarketData = class {
3726
3729
  };
3727
3730
 
3728
3731
  // src/modules/pricer.ts
3729
- import axios3 from "axios";
3732
+ import axios4 from "axios";
3730
3733
 
3731
3734
  // src/modules/pricerBase.ts
3732
3735
  var PricerBase = class {
@@ -3830,7 +3833,96 @@ var AvnuWrapper = class _AvnuWrapper {
3830
3833
  }
3831
3834
  };
3832
3835
 
3836
+ // src/modules/pricer-avnu-api.ts
3837
+ import axios3 from "axios";
3838
+ var AVNU_TOKENS_API = "https://starknet.impulse.avnu.fi/v3/tokens";
3839
+ var PricerAvnuApi = class extends PricerBase {
3840
+ constructor(config, tokens2) {
3841
+ super(config, tokens2);
3842
+ this.prices = {};
3843
+ this.refreshInterval = 15e3;
3844
+ this.staleTime = 5 * 60 * 1e3;
3845
+ this.pollTimer = null;
3846
+ this.loading = false;
3847
+ }
3848
+ start() {
3849
+ this._loadPrices();
3850
+ this.pollTimer = setInterval(() => {
3851
+ this._loadPrices();
3852
+ }, this.refreshInterval);
3853
+ }
3854
+ stop() {
3855
+ if (this.pollTimer) {
3856
+ clearInterval(this.pollTimer);
3857
+ this.pollTimer = null;
3858
+ }
3859
+ }
3860
+ isStale(timestamp) {
3861
+ return Date.now() - timestamp.getTime() > this.staleTime;
3862
+ }
3863
+ hasPrice(tokenSymbol) {
3864
+ const info = this.prices[tokenSymbol];
3865
+ return !!info && !this.isStale(info.timestamp);
3866
+ }
3867
+ async getPrice(tokenSymbol) {
3868
+ const info = this.prices[tokenSymbol];
3869
+ if (!info) {
3870
+ throw new Error(`AvnuApi: price of ${tokenSymbol} not found`);
3871
+ }
3872
+ if (this.isStale(info.timestamp)) {
3873
+ throw new Error(`AvnuApi: price of ${tokenSymbol} is stale`);
3874
+ }
3875
+ return info;
3876
+ }
3877
+ async _loadPrices() {
3878
+ if (this.loading) {
3879
+ return;
3880
+ }
3881
+ this.loading = true;
3882
+ const timestamp = /* @__PURE__ */ new Date();
3883
+ try {
3884
+ const result = await axios3.get(AVNU_TOKENS_API);
3885
+ const priceByAddress = /* @__PURE__ */ new Map();
3886
+ for (const entry of result.data) {
3887
+ const usd = entry.starknet?.usd;
3888
+ if (usd != null && usd > 0) {
3889
+ priceByAddress.set(ContractAddr.standardise(entry.address), usd);
3890
+ }
3891
+ }
3892
+ for (const token of this.tokens) {
3893
+ if (token.symbol === "USDT" || token.symbol === "USDC") {
3894
+ this.prices[token.symbol] = { price: 1, timestamp };
3895
+ continue;
3896
+ }
3897
+ const targetToken = token.priceProxySymbol ? this.tokens.find((t) => t.symbol === token.priceProxySymbol) : token;
3898
+ if (!targetToken) {
3899
+ continue;
3900
+ }
3901
+ const addr = targetToken.address.address;
3902
+ const price = priceByAddress.get(addr);
3903
+ if (price != null) {
3904
+ this.prices[token.symbol] = { price, timestamp };
3905
+ logger.verbose(
3906
+ `AvnuApi: ${token.symbol} -> $${price}`
3907
+ );
3908
+ }
3909
+ }
3910
+ } catch (error) {
3911
+ logger.warn(`AvnuApi: failed to fetch tokens: ${error?.message ?? error}`);
3912
+ } finally {
3913
+ this.loading = false;
3914
+ }
3915
+ }
3916
+ };
3917
+
3833
3918
  // src/modules/pricer.ts
3919
+ var PRICE_METHOD_PRIORITY = [
3920
+ "AvnuApi",
3921
+ "Coinbase",
3922
+ "Coinmarketcap",
3923
+ "Ekubo",
3924
+ "Avnu"
3925
+ ];
3834
3926
  var Pricer = class extends PricerBase {
3835
3927
  // e.g. ETH/USDC
3836
3928
  constructor(config, tokens2, refreshInterval = 3e4, staleTime = 6e4) {
@@ -3849,6 +3941,7 @@ var Pricer = class extends PricerBase {
3849
3941
  this.EKUBO_API = "https://prod-api-quoter.ekubo.org/23448594291968334/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
3850
3942
  this.refreshInterval = refreshInterval;
3851
3943
  this.staleTime = staleTime;
3944
+ this.avnuApiPricer = new PricerAvnuApi(config, tokens2);
3852
3945
  }
3853
3946
  isReady() {
3854
3947
  const allPricesExist = Object.keys(this.prices).length === this.tokens.length;
@@ -3878,6 +3971,7 @@ var Pricer = class extends PricerBase {
3878
3971
  });
3879
3972
  }
3880
3973
  start() {
3974
+ this.avnuApiPricer.start();
3881
3975
  this._loadPrices();
3882
3976
  setInterval(() => {
3883
3977
  this._loadPrices();
@@ -3902,6 +3996,9 @@ var Pricer = class extends PricerBase {
3902
3996
  let retry = 0;
3903
3997
  while (retry < MAX_RETRIES) {
3904
3998
  try {
3999
+ if (token.dontPrice) {
4000
+ return;
4001
+ }
3905
4002
  if (token.symbol === "USDT" || token.symbol === "USDC") {
3906
4003
  this.prices[token.symbol] = {
3907
4004
  price: 1,
@@ -3944,60 +4041,61 @@ var Pricer = class extends PricerBase {
3944
4041
  });
3945
4042
  if (this.isReady() && this.config.heartbeatUrl) {
3946
4043
  console.log(`sending beat`);
3947
- axios3.get(this.config.heartbeatUrl).catch((err) => {
4044
+ axios4.get(this.config.heartbeatUrl).catch((err) => {
3948
4045
  console.error("Pricer: Heartbeat err", err);
3949
4046
  });
3950
4047
  }
3951
4048
  }
3952
- async _getPrice(token, defaultMethod = "all") {
3953
- const methodToUse = this.methodToUse[token.symbol] || defaultMethod;
3954
- logger.verbose(`Fetching price of ${token.symbol} using ${methodToUse}`);
3955
- switch (methodToUse) {
4049
+ async _getPrice(token) {
4050
+ const pinned = this.methodToUse[token.symbol];
4051
+ if (pinned) {
4052
+ logger.verbose(`Fetching price of ${token.symbol} using pinned ${pinned}`);
4053
+ try {
4054
+ return await this._tryPriceMethod(token, pinned);
4055
+ } catch (error) {
4056
+ console.warn(`${pinned}: pinned price failed [${token.symbol}]: `, error.message);
4057
+ delete this.methodToUse[token.symbol];
4058
+ }
4059
+ }
4060
+ for (const method of PRICE_METHOD_PRIORITY) {
4061
+ logger.verbose(`Fetching price of ${token.symbol} using ${method}`);
4062
+ try {
4063
+ const result = await this._tryPriceMethod(token, method);
4064
+ this.methodToUse[token.symbol] = method;
4065
+ return result;
4066
+ } catch (error) {
4067
+ console.warn(`${method}: price err [${token.symbol}]: `, error.message);
4068
+ }
4069
+ }
4070
+ throw new FatalError(`Price not found for ${token.symbol}`);
4071
+ }
4072
+ async _tryPriceMethod(token, method) {
4073
+ switch (method) {
4074
+ case "AvnuApi":
4075
+ return await this._getPriceAvnuApi(token);
3956
4076
  case "Coinbase":
3957
- // try {
3958
- // const result = await this._getPriceCoinbase(token);
3959
- // this.methodToUse[token.symbol] = 'Coinbase';
3960
- // return result;
3961
- // } catch (error: any) {
3962
- // console.warn(`Coinbase: price err: message [${token.symbol}]: `, error.message);
3963
- // // do nothing, try next
3964
- // }
4077
+ return await this._getPriceCoinbase(token);
3965
4078
  case "Coinmarketcap":
3966
- try {
3967
- const result = await this._getPriceCoinMarketCap(token);
3968
- this.methodToUse[token.symbol] = "Coinmarketcap";
3969
- return result;
3970
- } catch (error) {
3971
- console.warn(`CoinMarketCap: price err [${token.symbol}]: `, Object.keys(error));
3972
- console.warn(`CoinMarketCap: price err [${token.symbol}]: `, error.message);
3973
- }
4079
+ return await this._getPriceCoinMarketCap(token);
3974
4080
  case "Ekubo":
3975
- try {
3976
- const result = await this._getPriceEkubo(token, new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals));
3977
- this.methodToUse[token.symbol] = "Ekubo";
3978
- return result;
3979
- } catch (error) {
3980
- console.warn(`Ekubo: price err [${token.symbol}]: `, error.message);
3981
- console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error));
3982
- }
4081
+ return await this._getPriceEkubo(
4082
+ token,
4083
+ new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals)
4084
+ );
3983
4085
  case "Avnu":
3984
- try {
3985
- const result = await this._getAvnuPrice(token, new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals));
3986
- this.methodToUse[token.symbol] = "Avnu";
3987
- return result;
3988
- } catch (error) {
3989
- console.warn(`Avnu: price err [${token.symbol}]: `, error.message);
3990
- console.warn(`Avnu: price err [${token.symbol}]: `, Object.keys(error));
3991
- }
3992
- }
3993
- if (defaultMethod == "all") {
3994
- return await this._getPrice(token, "Coinbase");
4086
+ return await this._getAvnuPrice(
4087
+ token,
4088
+ new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals)
4089
+ );
3995
4090
  }
3996
- throw new FatalError(`Price not found for ${token.symbol}`);
4091
+ }
4092
+ async _getPriceAvnuApi(token) {
4093
+ const priceInfo = await this.avnuApiPricer.getPrice(token.symbol);
4094
+ return priceInfo.price;
3997
4095
  }
3998
4096
  async _getPriceCoinbase(token) {
3999
4097
  const url = this.PRICE_API.replace("{{PRICER_KEY}}", `${token.symbol}-USD`);
4000
- const result = await axios3.get(url);
4098
+ const result = await axios4.get(url);
4001
4099
  const data = result.data;
4002
4100
  return Number(data.data.amount);
4003
4101
  }
@@ -4023,7 +4121,7 @@ var Pricer = class extends PricerBase {
4023
4121
  async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
4024
4122
  logger.verbose(`Getting price of ${token.symbol} using Ekubo, amountIn: ${amountIn.toWei()}`);
4025
4123
  const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei());
4026
- const result = await axios3.get(url);
4124
+ const result = await axios4.get(url);
4027
4125
  const data = result.data;
4028
4126
  const multiplier = 1 / amountIn.toNumber();
4029
4127
  const outputUSDC = Number(Web3Number.fromWei(data.total_calculated, 6).toFixed(6)) * multiplier;
@@ -4169,7 +4267,7 @@ var Pragma = class extends PricerBase {
4169
4267
  };
4170
4268
 
4171
4269
  // src/modules/zkLend.ts
4172
- import axios4 from "axios";
4270
+ import axios5 from "axios";
4173
4271
 
4174
4272
  // src/dataTypes/bignumber.browser.ts
4175
4273
  import { uint256 as uint2566 } from "starknet";
@@ -4228,7 +4326,7 @@ var _ZkLend = class _ZkLend extends ILending {
4228
4326
  async init() {
4229
4327
  try {
4230
4328
  logger.verbose(`Initialising ${this.metadata.name}`);
4231
- const result = await axios4.get(_ZkLend.POOLS_URL);
4329
+ const result = await axios5.get(_ZkLend.POOLS_URL);
4232
4330
  const data = result.data;
4233
4331
  const savedTokens = await Global.getTokens();
4234
4332
  data.forEach((pool) => {
@@ -4320,7 +4418,7 @@ var _ZkLend = class _ZkLend extends ILending {
4320
4418
  */
4321
4419
  async getPositions(user) {
4322
4420
  const url = this.POSITION_URL.replace("{{USER_ADDR}}", user.address);
4323
- const result = await axios4.get(url);
4421
+ const result = await axios5.get(url);
4324
4422
  const data = result.data;
4325
4423
  const lendingPosition = [];
4326
4424
  logger.verbose(`${this.metadata.name}:: Positions: ${JSON.stringify(data)}`);
@@ -4353,7 +4451,7 @@ _ZkLend.POOLS_URL = "https://app.zklend.com/api/pools";
4353
4451
  var ZkLend = _ZkLend;
4354
4452
 
4355
4453
  // src/modules/pricer-from-api.ts
4356
- import axios5 from "axios";
4454
+ import axios6 from "axios";
4357
4455
 
4358
4456
  // src/modules/apollo-client-config.ts
4359
4457
  import { ApolloClient, InMemoryCache } from "@apollo/client";
@@ -4740,7 +4838,7 @@ var PricerFromApi = class extends PricerBase {
4740
4838
  const MAX_RETRIES = 5;
4741
4839
  for (retry = 1; retry < MAX_RETRIES + 1; retry++) {
4742
4840
  try {
4743
- const priceInfo = await axios5.get(
4841
+ const priceInfo = await axios6.get(
4744
4842
  `https://api.coinbase.com/v2/prices/${tokenSymbol}-USDT/spot`
4745
4843
  );
4746
4844
  if (!priceInfo) {
@@ -6051,7 +6149,7 @@ var ERC20 = class {
6051
6149
  };
6052
6150
 
6053
6151
  // src/modules/ekubo-quoter.ts
6054
- import axios6 from "axios";
6152
+ import axios7 from "axios";
6055
6153
  import { uint256 as uint2568 } from "starknet";
6056
6154
  import { Contract as Contract5 } from "starknet";
6057
6155
  var EkuboQuoter = class _EkuboQuoter {
@@ -6064,7 +6162,7 @@ var EkuboQuoter = class _EkuboQuoter {
6064
6162
  try {
6065
6163
  const url = this.ENDPOINT.replace("{{AMOUNT}}", amount.toWei()).replace("{{TOKEN_FROM_ADDRESS}}", fromToken).replace("{{TOKEN_TO_ADDRESS}}", toToken);
6066
6164
  logger.verbose(`EkuboQuoter::_callQuoterApi url: ${url}`);
6067
- const quote = await axios6.get(url);
6165
+ const quote = await axios7.get(url);
6068
6166
  return quote.data;
6069
6167
  } catch (error) {
6070
6168
  logger.error(`EkuboQuoter::_callQuoterApi error: ${error.message}`);
@@ -8075,9 +8173,9 @@ var BaseStrategy = class extends CacheClass {
8075
8173
  };
8076
8174
 
8077
8175
  // src/node/headless.browser.ts
8078
- import axios7 from "axios";
8176
+ import axios8 from "axios";
8079
8177
  async function getAPIUsingHeadlessBrowser(url) {
8080
- const res = await axios7.get(url);
8178
+ const res = await axios8.get(url);
8081
8179
  return res.data;
8082
8180
  }
8083
8181
 
@@ -19586,6 +19684,9 @@ var xSTRKSTRK = {
19586
19684
  },
19587
19685
  apyMethodology: "APY based on 30-day historical performance, including fees and rewards.",
19588
19686
  realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
19687
+ feeBps: {
19688
+ performanceFeeBps: 1e3
19689
+ },
19589
19690
  additionalInfo: {
19590
19691
  newBounds: {
19591
19692
  lower: -1,
@@ -30312,6 +30413,9 @@ var YoloVaultStrategies = yoloVaultsConfig.map((yoloConfig) => {
30312
30413
  notARisks: getNoRiskTags(yoloRiskFactors)
30313
30414
  },
30314
30415
  apyMethodology: "Not a primary yield strategy. Funds earn yield when idle, but the main return comes from BTC price appreciation and your conviction to hold. This vault simply helps you accumulate more BTC.",
30416
+ feeBps: {
30417
+ performanceFeeBps: 1e3
30418
+ },
30315
30419
  additionalInfo: {
30316
30420
  mainToken: yoloConfig.mainToken,
30317
30421
  secondaryToken: yoloConfig.secondaryToken,
@@ -33092,7 +33196,7 @@ var TokenTransferAdapter = class _TokenTransferAdapter extends BaseAdapter {
33092
33196
 
33093
33197
  // src/strategies/universal-adapters/avnu-adapter.ts
33094
33198
  import { hash as hash9, uint256 as uint25620 } from "starknet";
33095
- import axios8 from "axios";
33199
+ import axios9 from "axios";
33096
33200
  var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
33097
33201
  constructor(config) {
33098
33202
  super(config, _AvnuAdapter.name, Protocols.AVNU);
@@ -33299,7 +33403,7 @@ var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
33299
33403
  async fetchQuoteWithRetry(params, retries = 5) {
33300
33404
  for (let attempt = 0; attempt < retries; attempt++) {
33301
33405
  try {
33302
- const response = await axios8.get(this.config.baseUrl, { params });
33406
+ const response = await axios9.get(this.config.baseUrl, { params });
33303
33407
  if (response.data && response.data.length > 0) {
33304
33408
  return response;
33305
33409
  }
@@ -36833,6 +36937,29 @@ var SVKStrategy = class extends BaseStrategy {
36833
36937
  ]);
36834
36938
  return [call];
36835
36939
  }
36940
+ async getUserTVL(user, blockIdentifier = "latest") {
36941
+ const shares = await this.contract.call("balanceOf", [user.address], { blockIdentifier });
36942
+ const assets = await this.contract.call(
36943
+ "convert_to_assets",
36944
+ [uint25622.bnToUint256(shares)],
36945
+ { blockIdentifier }
36946
+ );
36947
+ const amount = Web3Number.fromWei(
36948
+ assets.toString(),
36949
+ this.metadata.depositTokens[0].decimals
36950
+ );
36951
+ const blockNumber = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : void 0;
36952
+ const price = await this.pricer.getPrice(
36953
+ this.metadata.depositTokens[0].symbol,
36954
+ blockNumber
36955
+ );
36956
+ const usdValue = Number(amount.toFixed(6)) * price.price;
36957
+ return {
36958
+ tokenInfo: this.asset(),
36959
+ amount,
36960
+ usdValue
36961
+ };
36962
+ }
36836
36963
  /**
36837
36964
  * Returns the unused balance in the vault allocator.
36838
36965
  * Note: This function is common for any SVK strategy.
@@ -37024,6 +37151,100 @@ var SVKStrategy = class extends BaseStrategy {
37024
37151
  usdValue
37025
37152
  };
37026
37153
  }
37154
+ async getUserRealizedAPY(blockIdentifier = "latest", sinceBlocks = 6e5) {
37155
+ logger.verbose(
37156
+ `${this.getTag()}: getUserRealizedAPY => starting with blockIdentifier=${blockIdentifier}, sinceBlocks=${sinceBlocks}`
37157
+ );
37158
+ const blockNow = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : (await this.config.provider.getBlockLatestAccepted()).block_number;
37159
+ const blockNowTime = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
37160
+ const blockBefore = Math.max(
37161
+ blockNow - sinceBlocks,
37162
+ this.metadata.launchBlock
37163
+ );
37164
+ const assetsNowRaw = await this.contract.call("total_assets", [], {
37165
+ blockIdentifier
37166
+ });
37167
+ const amountNow = Web3Number.fromWei(
37168
+ assetsNowRaw.toString(),
37169
+ this.metadata.depositTokens[0].decimals
37170
+ );
37171
+ const supplyNowRaw = await this.contract.call("total_supply", [], {
37172
+ blockIdentifier
37173
+ });
37174
+ const supplyNow = Web3Number.fromWei(supplyNowRaw.toString(), 18);
37175
+ const assetsBeforeRaw = await this.contract.call(
37176
+ "total_assets",
37177
+ [],
37178
+ { blockIdentifier: blockBefore }
37179
+ );
37180
+ const amountBefore = Web3Number.fromWei(
37181
+ assetsBeforeRaw.toString(),
37182
+ this.metadata.depositTokens[0].decimals
37183
+ );
37184
+ const supplyBeforeRaw = await this.contract.call(
37185
+ "total_supply",
37186
+ [],
37187
+ { blockIdentifier: blockBefore }
37188
+ );
37189
+ const supplyBefore = Web3Number.fromWei(supplyBeforeRaw.toString(), 18);
37190
+ const blockBeforeInfo = await this.config.provider.getBlockWithTxs(
37191
+ blockBefore
37192
+ );
37193
+ const assetsPerShareNow = amountNow.multipliedBy(1e18).dividedBy(supplyNow.toString());
37194
+ const assetsPerShareBf = amountBefore.multipliedBy(1e18).dividedBy(supplyBefore.toString());
37195
+ const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
37196
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsNow: ${amountNow.toString()}`);
37197
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsBefore: ${amountBefore.toString()}`);
37198
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareNow: ${assetsPerShareNow.toString()}`);
37199
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareBf: ${assetsPerShareBf.toString()}`);
37200
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply before: ${supplyBefore.toString()}`);
37201
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply now: ${supplyNow.toString()}`);
37202
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] Time diff in seconds: ${timeDiffSeconds}`);
37203
+ const apyForGivenBlocks = Number(
37204
+ assetsPerShareNow.minus(assetsPerShareBf).multipliedBy(1e4).dividedBy(assetsPerShareBf)
37205
+ ) / 1e4;
37206
+ return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
37207
+ }
37208
+ async getUserPositionCards(input) {
37209
+ const { user, investmentFlows = [] } = input;
37210
+ const [userTVL] = await Promise.all([
37211
+ this.getUserTVL(user)
37212
+ ]);
37213
+ const cards = [
37214
+ {
37215
+ title: "Your Holdings",
37216
+ tooltip: "Your Holdings",
37217
+ value: this.formatTokenAmountForCard(userTVL.amount, userTVL.tokenInfo),
37218
+ subValue: `\u2248 ${this.formatUSDForCard(userTVL.usdValue)}`,
37219
+ subValueColor: "positive"
37220
+ }
37221
+ ];
37222
+ let lifetimeAmount = userTVL.amount.multipliedBy(0);
37223
+ let lifetimeTokenInfo = userTVL.tokenInfo;
37224
+ let lifetimeUsdValue = 0;
37225
+ if (investmentFlows.length > 0) {
37226
+ try {
37227
+ const earningsResult = this.getLifetimeEarnings(userTVL, investmentFlows);
37228
+ lifetimeAmount = earningsResult.lifetimeEarnings;
37229
+ lifetimeTokenInfo = earningsResult.tokenInfo.tokenInfo;
37230
+ const userAmount = userTVL.amount.toNumber();
37231
+ if (Number.isFinite(userAmount) && userAmount > 0) {
37232
+ const pricePerToken = userTVL.usdValue / userAmount;
37233
+ lifetimeUsdValue = lifetimeAmount.toNumber() * pricePerToken;
37234
+ }
37235
+ } catch (error) {
37236
+ logger.warn(`${this.getTag()}::getUserPositionCards lifetime earnings fallback`, error);
37237
+ }
37238
+ }
37239
+ cards.push({
37240
+ title: "Lifetime Earnings",
37241
+ tooltip: "Lifetime Earnings",
37242
+ value: this.formatTokenAmountForCard(lifetimeAmount, lifetimeTokenInfo),
37243
+ subValue: `\u2248 ${this.formatUSDForCard(lifetimeUsdValue)}`,
37244
+ subValueColor: this.getSubValueColorFromSignedNumber(lifetimeUsdValue)
37245
+ });
37246
+ return cards;
37247
+ }
37027
37248
  async getPrevAUM() {
37028
37249
  const currentAUM = await this.contract.call("aum", []);
37029
37250
  const prevAum = Web3Number.fromWei(currentAUM.toString(), this.asset().decimals);
@@ -37137,29 +37358,6 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
37137
37358
  ]);
37138
37359
  return [call];
37139
37360
  }
37140
- async getUserTVL(user, blockIdentifier = "latest") {
37141
- const shares = await this.contract.call("balanceOf", [user.address], { blockIdentifier });
37142
- const assets = await this.contract.call(
37143
- "convert_to_assets",
37144
- [uint25623.bnToUint256(shares)],
37145
- { blockIdentifier }
37146
- );
37147
- const amount = Web3Number.fromWei(
37148
- assets.toString(),
37149
- this.metadata.depositTokens[0].decimals
37150
- );
37151
- const blockNumber = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : void 0;
37152
- let price = await this.pricer.getPrice(
37153
- this.metadata.depositTokens[0].symbol,
37154
- blockNumber
37155
- );
37156
- const usdValue = Number(amount.toFixed(6)) * price.price;
37157
- return {
37158
- tokenInfo: this.asset(),
37159
- amount,
37160
- usdValue
37161
- };
37162
- }
37163
37361
  async getVesuAPYs() {
37164
37362
  const vesuAdapters = this.getVesuAdapters();
37165
37363
  const allVesuPools = await VesuAdapter.getVesuPools();
@@ -37200,13 +37398,16 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
37200
37398
  */
37201
37399
  async netAPY() {
37202
37400
  if (this.metadata.isPreview) {
37203
- return { net: 0, splits: [{
37204
- apy: 0,
37205
- id: "base"
37206
- }, {
37207
- apy: 0,
37208
- id: "defispring"
37209
- }] };
37401
+ return {
37402
+ net: 0,
37403
+ splits: [{
37404
+ apy: 0,
37405
+ id: "base"
37406
+ }, {
37407
+ apy: 0,
37408
+ id: "defispring"
37409
+ }]
37410
+ };
37210
37411
  }
37211
37412
  const { positions, baseAPYs, rewardAPYs } = await this.getVesuAPYs();
37212
37413
  const unusedBalanceAPY = await this.getUnusedBalanceAPY();
@@ -37221,25 +37422,31 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
37221
37422
  }
37222
37423
  async returnNetAPY(baseAPYs, rewardAPYs, weights, prevAUMUSD) {
37223
37424
  if (weights.every((p) => p == 0)) {
37224
- return { net: 0, splits: [{
37225
- apy: 0,
37226
- id: "base"
37227
- }, {
37228
- apy: 0,
37229
- id: "defispring"
37230
- }] };
37425
+ return {
37426
+ net: 0,
37427
+ splits: [{
37428
+ apy: 0,
37429
+ id: "base"
37430
+ }, {
37431
+ apy: 0,
37432
+ id: "defispring"
37433
+ }]
37434
+ };
37231
37435
  }
37232
37436
  const baseAPY = this.computeAPY(baseAPYs, weights, prevAUMUSD);
37233
37437
  const rewardAPY = this.computeAPY(rewardAPYs, weights, prevAUMUSD);
37234
37438
  const netAPY = baseAPY + rewardAPY;
37235
37439
  logger.verbose(`${this.metadata.name}::netAPY: net: ${netAPY}, baseAPY: ${baseAPY}, rewardAPY: ${rewardAPY}`);
37236
- return { net: netAPY, splits: [{
37237
- apy: baseAPY,
37238
- id: "base"
37239
- }, {
37240
- apy: rewardAPY,
37241
- id: "defispring"
37242
- }] };
37440
+ return {
37441
+ net: netAPY,
37442
+ splits: [{
37443
+ apy: baseAPY,
37444
+ id: "base"
37445
+ }, {
37446
+ apy: rewardAPY,
37447
+ id: "defispring"
37448
+ }]
37449
+ };
37243
37450
  }
37244
37451
  async getUnusedBalanceAPY() {
37245
37452
  return {
@@ -37253,104 +37460,6 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
37253
37460
  logger.verbose(`${this.getTag()} computeAPY: apys: ${JSON.stringify(apys)}, weights: ${JSON.stringify(weights)}, weightedSum: ${weightedSum}, currentAUM: ${currentAUM}`);
37254
37461
  return weightedSum / currentAUM.toNumber();
37255
37462
  }
37256
- /**
37257
- * Calculates user realized APY based on trueSharesBasedAPY method.
37258
- * Returns the APY as a number.
37259
- */
37260
- async getUserRealizedAPY(blockIdentifier = "latest", sinceBlocks = 6e5) {
37261
- logger.verbose(
37262
- `${this.getTag()}: getUserRealizedAPY => starting with blockIdentifier=${blockIdentifier}, sinceBlocks=${sinceBlocks}`
37263
- );
37264
- let blockNow = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : (await this.config.provider.getBlockLatestAccepted()).block_number;
37265
- const blockNowTime = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
37266
- const blockBefore = Math.max(
37267
- blockNow - sinceBlocks,
37268
- this.metadata.launchBlock
37269
- );
37270
- const assetsNowRaw = await this.contract.call("total_assets", [], {
37271
- blockIdentifier
37272
- });
37273
- const amountNow = Web3Number.fromWei(
37274
- assetsNowRaw.toString(),
37275
- this.metadata.depositTokens[0].decimals
37276
- );
37277
- const supplyNowRaw = await this.contract.call("total_supply", [], {
37278
- blockIdentifier
37279
- });
37280
- const supplyNow = Web3Number.fromWei(supplyNowRaw.toString(), 18);
37281
- const assetsBeforeRaw = await this.contract.call(
37282
- "total_assets",
37283
- [],
37284
- { blockIdentifier: blockBefore }
37285
- );
37286
- const amountBefore = Web3Number.fromWei(
37287
- assetsBeforeRaw.toString(),
37288
- this.metadata.depositTokens[0].decimals
37289
- );
37290
- const supplyBeforeRaw = await this.contract.call(
37291
- "total_supply",
37292
- [],
37293
- { blockIdentifier: blockBefore }
37294
- );
37295
- const supplyBefore = Web3Number.fromWei(supplyBeforeRaw.toString(), 18);
37296
- const blockBeforeInfo = await this.config.provider.getBlockWithTxs(
37297
- blockBefore
37298
- );
37299
- const assetsPerShareNow = amountNow.multipliedBy(1e18).dividedBy(supplyNow.toString());
37300
- const assetsPerShareBf = amountBefore.multipliedBy(1e18).dividedBy(supplyBefore.toString());
37301
- const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
37302
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsNow: ${amountNow.toString()}`);
37303
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsBefore: ${amountBefore.toString()}`);
37304
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareNow: ${assetsPerShareNow.toString()}`);
37305
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareBf: ${assetsPerShareBf.toString()}`);
37306
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply before: ${supplyBefore.toString()}`);
37307
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply now: ${supplyNow.toString()}`);
37308
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] Time diff in seconds: ${timeDiffSeconds}`);
37309
- const apyForGivenBlocks = Number(
37310
- assetsPerShareNow.minus(assetsPerShareBf).multipliedBy(1e4).dividedBy(assetsPerShareBf)
37311
- ) / 1e4;
37312
- return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
37313
- }
37314
- async getUserPositionCards(input) {
37315
- const { user, investmentFlows = [] } = input;
37316
- const [userTVL] = await Promise.all([
37317
- this.getUserTVL(user)
37318
- ]);
37319
- const cards = [
37320
- {
37321
- title: "Your Holdings",
37322
- tooltip: "Your Holdings",
37323
- value: this.formatTokenAmountForCard(userTVL.amount, userTVL.tokenInfo),
37324
- subValue: `\u2248 ${this.formatUSDForCard(userTVL.usdValue)}`,
37325
- subValueColor: "positive"
37326
- }
37327
- ];
37328
- let lifetimeAmount = userTVL.amount.multipliedBy(0);
37329
- let lifetimeTokenInfo = userTVL.tokenInfo;
37330
- let lifetimeUsdValue = 0;
37331
- if (investmentFlows.length > 0) {
37332
- try {
37333
- const earningsResult = this.getLifetimeEarnings(userTVL, investmentFlows);
37334
- lifetimeAmount = earningsResult.lifetimeEarnings;
37335
- lifetimeTokenInfo = earningsResult.tokenInfo.tokenInfo;
37336
- const userAmount = userTVL.amount.toNumber();
37337
- if (Number.isFinite(userAmount) && userAmount > 0) {
37338
- const pricePerToken = userTVL.usdValue / userAmount;
37339
- lifetimeUsdValue = lifetimeAmount.toNumber() * pricePerToken;
37340
- }
37341
- } catch (error) {
37342
- logger.warn(`${this.getTag()}::getUserPositionCards lifetime earnings fallback`, error);
37343
- }
37344
- }
37345
- cards.push({
37346
- title: "Lifetime Earnings",
37347
- tooltip: "Lifetime Earnings",
37348
- value: this.formatTokenAmountForCard(lifetimeAmount, lifetimeTokenInfo),
37349
- subValue: `\u2248 ${this.formatUSDForCard(lifetimeUsdValue)}`,
37350
- subValueColor: this.getSubValueColorFromSignedNumber(lifetimeUsdValue)
37351
- });
37352
- return cards;
37353
- }
37354
37463
  /**
37355
37464
  * Calculates the total TVL of the strategy.
37356
37465
  * @returns Object containing the total amount in token units and USD value
@@ -37427,13 +37536,17 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
37427
37536
  };
37428
37537
  const aumToken = vesuAum.plus(balance.amount);
37429
37538
  if (aumToken.isZero()) {
37430
- return { net, splits: [{
37431
- aum: zeroAmt,
37432
- id: "finalised" /* FINALISED */
37433
- }, {
37434
- aum: zeroAmt,
37435
- id: "defispring" /* DEFISPRING */
37436
- }], prevAum };
37539
+ return {
37540
+ net,
37541
+ splits: [{
37542
+ aum: zeroAmt,
37543
+ id: "finalised" /* FINALISED */
37544
+ }, {
37545
+ aum: zeroAmt,
37546
+ id: "defispring" /* DEFISPRING */
37547
+ }],
37548
+ prevAum
37549
+ };
37437
37550
  }
37438
37551
  logger.verbose(`${this.getTag()} Actual AUM: ${aumToken}`);
37439
37552
  const rewardAssets = await this.getRewardsAUM(prevAum);
@@ -38086,6 +38199,9 @@ var createUniversalStrategy = (params) => {
38086
38199
  auditUrl: AUDIT_URL3,
38087
38200
  protocols: [Protocols.VESU],
38088
38201
  realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
38202
+ feeBps: {
38203
+ performanceFeeBps: 1e3
38204
+ },
38089
38205
  curator: UnwrapLabsCurator,
38090
38206
  settings: createUniversalSettings(params.tokenSymbol, params.maxTVLDecimals),
38091
38207
  contractDetails: getContractDetails(params.vaultSettings),
@@ -38727,11 +38843,15 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
38727
38843
  remarks: "defispring" /* DEFISPRING */,
38728
38844
  protocol: Protocols.NONE
38729
38845
  };
38730
- return { net: {
38731
- tokenInfo: underlying,
38732
- amount: netAUM,
38733
- usdValue: netAUM.toNumber() * assetPrice.price
38734
- }, prevAum, splits: [realAUM, estimatedAUMDelta] };
38846
+ return {
38847
+ net: {
38848
+ tokenInfo: underlying,
38849
+ amount: netAUM,
38850
+ usdValue: netAUM.toNumber() * assetPrice.price
38851
+ },
38852
+ prevAum,
38853
+ splits: [realAUM, estimatedAUMDelta]
38854
+ };
38735
38855
  }
38736
38856
  async getTVLUnrealized() {
38737
38857
  return await this.getAUM(true);
@@ -38749,6 +38869,62 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
38749
38869
  tokenInfo: this.asset()
38750
38870
  };
38751
38871
  }
38872
+ async getUserPositionCards(input) {
38873
+ const cards = await super.getUserPositionCards(input);
38874
+ try {
38875
+ const [unrealizedResult, userTVL, realizedApyRaw] = await Promise.all([
38876
+ this.getUserUnrealizedGains(input.user),
38877
+ this.getUserTVL(input.user),
38878
+ this.getUserRealizedAPY().catch(() => null)
38879
+ ]);
38880
+ const amount = unrealizedResult.unrealizedGains;
38881
+ let usdValue = 0;
38882
+ const userAmount = userTVL.amount.toNumber();
38883
+ if (Number.isFinite(userAmount) && userAmount > 0) {
38884
+ usdValue = userTVL.usdValue / userAmount * amount.toNumber();
38885
+ }
38886
+ cards.push({
38887
+ title: "Unrealized Gains",
38888
+ tooltip: "Unrealized gains based on current market prices vs Endur prices. If you withdraw now, you will forgo these gains.",
38889
+ value: this.formatTokenAmountForCard(amount, unrealizedResult.tokenInfo),
38890
+ subValue: `\u2248 ${this.formatUSDForCard(usdValue)}`,
38891
+ subValueColor: this.getSubValueColorFromSignedNumber(usdValue)
38892
+ });
38893
+ const realizedApy = typeof realizedApyRaw === "number" ? this.formatPercentForCard(realizedApyRaw) : "N/A";
38894
+ cards.push({
38895
+ title: "Realized APY",
38896
+ tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
38897
+ value: realizedApy
38898
+ });
38899
+ } catch (error) {
38900
+ logger.warn(`${this.getTag()}::getUserPositionCards unrealized gains fallback`, error);
38901
+ cards.push({
38902
+ title: "Unrealized Gains",
38903
+ tooltip: "Unrealized gains based on current market prices vs Endur prices. If you withdraw now, you will forgo these gains.",
38904
+ value: this.formatTokenAmountForCard(
38905
+ Web3Number.fromWei("0", this.asset().decimals),
38906
+ this.asset()
38907
+ ),
38908
+ subValue: `\u2248 ${this.formatUSDForCard(0)}`,
38909
+ subValueColor: "default"
38910
+ });
38911
+ cards.push({
38912
+ title: "Realized APY",
38913
+ tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
38914
+ value: "N/A"
38915
+ });
38916
+ }
38917
+ if (this.asset().symbol === "xSTRK") {
38918
+ const index = cards.findIndex((card) => card.title === "Lifetime Earnings");
38919
+ if (index >= 0) {
38920
+ cards[index] = {
38921
+ ...cards[index],
38922
+ tooltip: "Lifetime earnings of the vault. Due to migration of xSTRK Sensei to this vault, any migrated funds are also seen as lifetime earnings. Team is working to fix this soon."
38923
+ };
38924
+ }
38925
+ }
38926
+ return cards;
38927
+ }
38752
38928
  };
38753
38929
  function VaultDescription(lstSymbol, underlyingSymbol) {
38754
38930
  const containerStyle = {
@@ -39156,6 +39332,9 @@ function getStrategySettings(lstSymbol, underlyingSymbol, settings, isPreview =
39156
39332
  isPreview,
39157
39333
  apyMethodology: "Current annualized APY in terms of base asset of the LST. There is no additional fee taken by Troves on LST APY. We charge a 10% performance fee on the additional gain which is already accounted in the APY shown.",
39158
39334
  realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
39335
+ feeBps: {
39336
+ performanceFeeBps: 1e3
39337
+ },
39159
39338
  tags: lstSymbol.includes("BTC") ? ["BTC" /* BTC */, "Maxx" /* LEVERED */] : ["Maxx" /* LEVERED */],
39160
39339
  security: HYPER_LST_SECURITY,
39161
39340
  redemptionInfo: HYPER_LST_REDEMPTION_INFO,
@@ -39369,6 +39548,23 @@ var BoostedxSTRKCarryStrategy = class _BoostedxSTRKCarryStrategy extends SVKStra
39369
39548
  usdValue
39370
39549
  };
39371
39550
  }
39551
+ async getUserPositionCards(input) {
39552
+ const cards = await super.getUserPositionCards(input);
39553
+ const realizedApyRaw = await this.getUserRealizedAPY().catch((error) => {
39554
+ logger.warn(
39555
+ `${this.getTag()}::getUserPositionCards realized APY fallback`,
39556
+ error
39557
+ );
39558
+ return null;
39559
+ });
39560
+ const realizedApy = typeof realizedApyRaw === "number" ? this.formatPercentForCard(realizedApyRaw) : "N/A";
39561
+ cards.push({
39562
+ title: "Realized APY",
39563
+ tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
39564
+ value: realizedApy
39565
+ });
39566
+ return cards;
39567
+ }
39372
39568
  async getAUM() {
39373
39569
  const underlying = this.asset();
39374
39570
  const depositTokenPrice = await this.pricer.getPrice(underlying.symbol);
@@ -39878,38 +40074,38 @@ var wbtcBoostedSettings = {
39878
40074
  var boostedCarryRiskFactors = [
39879
40075
  {
39880
40076
  type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */,
39881
- value: 2 /* WELL_AUDITED */,
40077
+ value: 1 /* BATTLE_TESTED */,
39882
40078
  // 20% — core trust assumption; SVK is audited but still multi-contract (vault, manager, adapters).
39883
40079
  weight: 20,
39884
40080
  reason: "Built on the Starknet Vault Kit (SVK), with audits under the Sherlock-audited branch."
39885
40081
  },
39886
40082
  {
39887
40083
  type: "Liquidation Risk" /* LIQUIDATION_RISK */,
39888
- value: 3 /* MODERATE_PROBABILITY */,
40084
+ value: 2 /* LOW_PROBABILITY */,
39889
40085
  // 20% — tied with smart contract; uncorrelated collateral/debt is the main principal risk here.
39890
40086
  weight: 20,
39891
40087
  reason: "Collateral (USDC or WBTC) and STRK debt are not price-correlated. We target ~50% LTV and rebalance above ~55%, with a health-factor buffer, but extreme moves or prolonged monitoring gaps can still trigger liquidation."
39892
40088
  },
39893
40089
  {
39894
40090
  type: "Low Liquidity Risk" /* LOW_LIQUIDITY_RISK */,
39895
- value: 3 /* MODERATE_CONCERNS */,
40091
+ value: 1 /* GOOD_LIQUIDITY */,
39896
40092
  // 15% — below liquidation but above ops risks; every unwind/withdraw depends on xSTRK→STRK depth.
39897
40093
  weight: 15,
39898
- reason: "Closing the loop requires selling xSTRK to STRK on DEXes to repay Vesu debt. xSTRK liquidity can be thin at fair prices; larger withdrawals or rebalances may take longer or complete in smaller chunks."
40094
+ reason: "Closing the loop requires selling xSTRK to STRK on DEXes to repay Vesu debt. larger withdrawals or rebalances may take longer or complete in smaller chunks."
39899
40095
  },
39900
40096
  {
39901
40097
  type: "Technical Risk" /* TECHNICAL_RISK */,
39902
40098
  value: 3 /* SOME_COMPLEXITY */,
39903
40099
  // 13% — monitoring/rebalancing stack matters, but usually recoverable without instant loss.
39904
- weight: 13,
40100
+ weight: 10,
39905
40101
  reason: "Yield routes across Vesu, Avnu, and Hyper xSTRK with automated monitoring. Technical failures can delay rebalancing."
39906
40102
  },
39907
40103
  {
39908
40104
  type: "Depeg Risk" /* DEPEG_RISK */,
39909
- value: 3 /* OCCASIONAL_DEPEG */,
40105
+ value: 2 /* GENERALLY_STABLE */,
39910
40106
  // 12% — affects yield and swap notionals; USDC/WBTC depeg is rarer than xSTRK/STRK drift.
39911
40107
  weight: 12,
39912
- reason: "xSTRK yield depends on its exchange rate vs STRK; USDC and WBTC carry standard stablecoin and BTC market risks."
40108
+ reason: "Historically, xSTRK's DEX price has been generally stable compared to its true price."
39913
40109
  },
39914
40110
  {
39915
40111
  type: "Oracle Risk" /* ORACLE_RISK */,
@@ -39929,7 +40125,7 @@ var boostedCarryRiskFactors = [
39929
40125
  type: "Market Risk" /* MARKET_RISK */,
39930
40126
  value: 3 /* MODERATE_VOLATILITY */,
39931
40127
  // 5% — largely captured by liquidation + depeg factors; kept small to avoid double-counting vol.
39932
- weight: 5,
40128
+ weight: 8,
39933
40129
  reason: "STRK, BTC, and stablecoin volatility can move loan-to-value and swap costs."
39934
40130
  }
39935
40131
  ];
@@ -39958,15 +40154,15 @@ function getBoostedCarryFAQs(depositSymbol, debtSymbol, lstSymbol) {
39958
40154
  question: "Which protocols are used?",
39959
40155
  answer: /* @__PURE__ */ jsxs5("span", { children: [
39960
40156
  /* @__PURE__ */ jsx6("strong", { children: "Vesu" }),
39961
- " for collateral and borrowing, ",
39962
- /* @__PURE__ */ jsx6("strong", { children: "Avnu" }),
40157
+ " for collateral and borrowing,",
39963
40158
  " ",
39964
- "for swaps, ",
40159
+ /* @__PURE__ */ jsx6("strong", { children: "Avnu" }),
40160
+ " for swaps, ",
39965
40161
  /* @__PURE__ */ jsx6("strong", { children: "Endur" }),
39966
- " for ",
39967
- lstSymbol,
39968
- ", and the Troves",
40162
+ " for",
39969
40163
  " ",
40164
+ lstSymbol,
40165
+ ", and the Troves ",
39970
40166
  /* @__PURE__ */ jsxs5("strong", { children: [
39971
40167
  "Hyper-",
39972
40168
  lstSymbol
@@ -40054,6 +40250,9 @@ function getStrategySettings2(settings, meta) {
40054
40250
  ]
40055
40251
  },
40056
40252
  contractDetails: getContractDetails(settings),
40253
+ feeBps: {
40254
+ performanceFeeBps: 1500
40255
+ },
40057
40256
  faqs: getBoostedCarryFAQs(
40058
40257
  depositToken.symbol,
40059
40258
  debtToken.symbol,
@@ -40374,7 +40573,7 @@ function createStrategy(type, config, pricer, metadata) {
40374
40573
  }
40375
40574
 
40376
40575
  // src/modules/pricer-lst.ts
40377
- import axios9 from "axios";
40576
+ import axios10 from "axios";
40378
40577
  var PricerLST2 = class extends Pricer {
40379
40578
  // e.g. xSTRK/STRK
40380
40579
  constructor(config, tokenMaps) {
@@ -40410,7 +40609,7 @@ var PricerLST2 = class extends Pricer {
40410
40609
  async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
40411
40610
  const underlying = this.getUnderlying(token);
40412
40611
  const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei()).replace("{{UNDERLYING_ADDRESS}}", underlying.address.toString());
40413
- const result = await axios9.get(url);
40612
+ const result = await axios10.get(url);
40414
40613
  const data = result.data;
40415
40614
  const multiplier = 1 / amountIn.toNumber();
40416
40615
  const outputUnderlying = Number(Web3Number.fromWei(data.total_calculated, underlying.decimals).toFixed(6)) * multiplier;
@@ -40562,6 +40761,7 @@ var PricerRedis = class extends Pricer {
40562
40761
  async startWithRedis(redisUrl) {
40563
40762
  await this.initRedis(redisUrl);
40564
40763
  logger.info(`Starting Pricer with Redis`);
40764
+ this.avnuApiPricer.start();
40565
40765
  this._loadPrices(this._setRedisPrices.bind(this));
40566
40766
  setInterval(() => {
40567
40767
  this._loadPrices(this._setRedisPrices.bind(this));
@@ -41008,6 +41208,7 @@ export {
41008
41208
  PositionTypeAvnuExtended,
41009
41209
  Pragma,
41010
41210
  Pricer,
41211
+ PricerAvnuApi,
41011
41212
  PricerBase,
41012
41213
  PricerFromApi,
41013
41214
  PricerLST2 as PricerLST,