@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.js CHANGED
@@ -78,6 +78,7 @@ __export(index_exports, {
78
78
  PositionTypeAvnuExtended: () => PositionTypeAvnuExtended,
79
79
  Pragma: () => Pragma,
80
80
  Pricer: () => Pricer,
81
+ PricerAvnuApi: () => PricerAvnuApi,
81
82
  PricerBase: () => PricerBase,
82
83
  PricerFromApi: () => PricerFromApi,
83
84
  PricerLST: () => PricerLST2,
@@ -832,20 +833,20 @@ var defaultTokens = [
832
833
  decimals: 18,
833
834
  coingeckId: void 0,
834
835
  displayDecimals: 6,
835
- priceCheckAmount: 1e-4
836
+ priceCheckAmount: 1e-4,
836
837
  // 112000 * 0.0001 = $11.2
838
+ dontPrice: true
837
839
  },
838
840
  {
839
841
  name: "mRe7YIELD",
840
842
  symbol: "mRe7YIELD",
841
843
  logo: "https://midas.app/assets/mre7-BcOOHm7i.svg",
842
- address: ContractAddr.from(
843
- "0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"
844
- ),
844
+ address: ContractAddr.from("0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"),
845
845
  decimals: 18,
846
846
  coingeckId: void 0,
847
847
  displayDecimals: 2,
848
- priceCheckAmount: 100
848
+ priceCheckAmount: 100,
849
+ dontPrice: true
849
850
  },
850
851
  {
851
852
  name: "fyWBTC",
@@ -855,8 +856,9 @@ var defaultTokens = [
855
856
  decimals: 8,
856
857
  coingeckId: void 0,
857
858
  displayDecimals: 6,
858
- priceCheckAmount: 1e-3
859
+ priceCheckAmount: 1e-3,
859
860
  // 112000 * 0.0001 = $110.2
861
+ dontPrice: true
860
862
  },
861
863
  {
862
864
  name: "fyETH",
@@ -866,7 +868,8 @@ var defaultTokens = [
866
868
  decimals: 18,
867
869
  coingeckId: void 0,
868
870
  displayDecimals: 4,
869
- priceCheckAmount: 0.1
871
+ priceCheckAmount: 0.1,
872
+ dontPrice: true
870
873
  },
871
874
  {
872
875
  name: "fyUSDC",
@@ -876,7 +879,8 @@ var defaultTokens = [
876
879
  decimals: 6,
877
880
  coingeckId: void 0,
878
881
  displayDecimals: 2,
879
- priceCheckAmount: 100
882
+ priceCheckAmount: 100,
883
+ dontPrice: true
880
884
  },
881
885
  {
882
886
  name: "strkBTC",
@@ -3894,7 +3898,7 @@ var TokenMarketData = class {
3894
3898
  };
3895
3899
 
3896
3900
  // src/modules/pricer.ts
3897
- var import_axios3 = __toESM(require("axios"));
3901
+ var import_axios4 = __toESM(require("axios"));
3898
3902
 
3899
3903
  // src/modules/pricerBase.ts
3900
3904
  var PricerBase = class {
@@ -3998,7 +4002,96 @@ var AvnuWrapper = class _AvnuWrapper {
3998
4002
  }
3999
4003
  };
4000
4004
 
4005
+ // src/modules/pricer-avnu-api.ts
4006
+ var import_axios3 = __toESM(require("axios"));
4007
+ var AVNU_TOKENS_API = "https://starknet.impulse.avnu.fi/v3/tokens";
4008
+ var PricerAvnuApi = class extends PricerBase {
4009
+ constructor(config, tokens2) {
4010
+ super(config, tokens2);
4011
+ this.prices = {};
4012
+ this.refreshInterval = 15e3;
4013
+ this.staleTime = 5 * 60 * 1e3;
4014
+ this.pollTimer = null;
4015
+ this.loading = false;
4016
+ }
4017
+ start() {
4018
+ this._loadPrices();
4019
+ this.pollTimer = setInterval(() => {
4020
+ this._loadPrices();
4021
+ }, this.refreshInterval);
4022
+ }
4023
+ stop() {
4024
+ if (this.pollTimer) {
4025
+ clearInterval(this.pollTimer);
4026
+ this.pollTimer = null;
4027
+ }
4028
+ }
4029
+ isStale(timestamp) {
4030
+ return Date.now() - timestamp.getTime() > this.staleTime;
4031
+ }
4032
+ hasPrice(tokenSymbol) {
4033
+ const info = this.prices[tokenSymbol];
4034
+ return !!info && !this.isStale(info.timestamp);
4035
+ }
4036
+ async getPrice(tokenSymbol) {
4037
+ const info = this.prices[tokenSymbol];
4038
+ if (!info) {
4039
+ throw new Error(`AvnuApi: price of ${tokenSymbol} not found`);
4040
+ }
4041
+ if (this.isStale(info.timestamp)) {
4042
+ throw new Error(`AvnuApi: price of ${tokenSymbol} is stale`);
4043
+ }
4044
+ return info;
4045
+ }
4046
+ async _loadPrices() {
4047
+ if (this.loading) {
4048
+ return;
4049
+ }
4050
+ this.loading = true;
4051
+ const timestamp = /* @__PURE__ */ new Date();
4052
+ try {
4053
+ const result = await import_axios3.default.get(AVNU_TOKENS_API);
4054
+ const priceByAddress = /* @__PURE__ */ new Map();
4055
+ for (const entry of result.data) {
4056
+ const usd = entry.starknet?.usd;
4057
+ if (usd != null && usd > 0) {
4058
+ priceByAddress.set(ContractAddr.standardise(entry.address), usd);
4059
+ }
4060
+ }
4061
+ for (const token of this.tokens) {
4062
+ if (token.symbol === "USDT" || token.symbol === "USDC") {
4063
+ this.prices[token.symbol] = { price: 1, timestamp };
4064
+ continue;
4065
+ }
4066
+ const targetToken = token.priceProxySymbol ? this.tokens.find((t) => t.symbol === token.priceProxySymbol) : token;
4067
+ if (!targetToken) {
4068
+ continue;
4069
+ }
4070
+ const addr = targetToken.address.address;
4071
+ const price = priceByAddress.get(addr);
4072
+ if (price != null) {
4073
+ this.prices[token.symbol] = { price, timestamp };
4074
+ logger.verbose(
4075
+ `AvnuApi: ${token.symbol} -> $${price}`
4076
+ );
4077
+ }
4078
+ }
4079
+ } catch (error) {
4080
+ logger.warn(`AvnuApi: failed to fetch tokens: ${error?.message ?? error}`);
4081
+ } finally {
4082
+ this.loading = false;
4083
+ }
4084
+ }
4085
+ };
4086
+
4001
4087
  // src/modules/pricer.ts
4088
+ var PRICE_METHOD_PRIORITY = [
4089
+ "AvnuApi",
4090
+ "Coinbase",
4091
+ "Coinmarketcap",
4092
+ "Ekubo",
4093
+ "Avnu"
4094
+ ];
4002
4095
  var Pricer = class extends PricerBase {
4003
4096
  // e.g. ETH/USDC
4004
4097
  constructor(config, tokens2, refreshInterval = 3e4, staleTime = 6e4) {
@@ -4017,6 +4110,7 @@ var Pricer = class extends PricerBase {
4017
4110
  this.EKUBO_API = "https://prod-api-quoter.ekubo.org/23448594291968334/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
4018
4111
  this.refreshInterval = refreshInterval;
4019
4112
  this.staleTime = staleTime;
4113
+ this.avnuApiPricer = new PricerAvnuApi(config, tokens2);
4020
4114
  }
4021
4115
  isReady() {
4022
4116
  const allPricesExist = Object.keys(this.prices).length === this.tokens.length;
@@ -4046,6 +4140,7 @@ var Pricer = class extends PricerBase {
4046
4140
  });
4047
4141
  }
4048
4142
  start() {
4143
+ this.avnuApiPricer.start();
4049
4144
  this._loadPrices();
4050
4145
  setInterval(() => {
4051
4146
  this._loadPrices();
@@ -4070,6 +4165,9 @@ var Pricer = class extends PricerBase {
4070
4165
  let retry = 0;
4071
4166
  while (retry < MAX_RETRIES) {
4072
4167
  try {
4168
+ if (token.dontPrice) {
4169
+ return;
4170
+ }
4073
4171
  if (token.symbol === "USDT" || token.symbol === "USDC") {
4074
4172
  this.prices[token.symbol] = {
4075
4173
  price: 1,
@@ -4112,60 +4210,61 @@ var Pricer = class extends PricerBase {
4112
4210
  });
4113
4211
  if (this.isReady() && this.config.heartbeatUrl) {
4114
4212
  console.log(`sending beat`);
4115
- import_axios3.default.get(this.config.heartbeatUrl).catch((err) => {
4213
+ import_axios4.default.get(this.config.heartbeatUrl).catch((err) => {
4116
4214
  console.error("Pricer: Heartbeat err", err);
4117
4215
  });
4118
4216
  }
4119
4217
  }
4120
- async _getPrice(token, defaultMethod = "all") {
4121
- const methodToUse = this.methodToUse[token.symbol] || defaultMethod;
4122
- logger.verbose(`Fetching price of ${token.symbol} using ${methodToUse}`);
4123
- switch (methodToUse) {
4218
+ async _getPrice(token) {
4219
+ const pinned = this.methodToUse[token.symbol];
4220
+ if (pinned) {
4221
+ logger.verbose(`Fetching price of ${token.symbol} using pinned ${pinned}`);
4222
+ try {
4223
+ return await this._tryPriceMethod(token, pinned);
4224
+ } catch (error) {
4225
+ console.warn(`${pinned}: pinned price failed [${token.symbol}]: `, error.message);
4226
+ delete this.methodToUse[token.symbol];
4227
+ }
4228
+ }
4229
+ for (const method of PRICE_METHOD_PRIORITY) {
4230
+ logger.verbose(`Fetching price of ${token.symbol} using ${method}`);
4231
+ try {
4232
+ const result = await this._tryPriceMethod(token, method);
4233
+ this.methodToUse[token.symbol] = method;
4234
+ return result;
4235
+ } catch (error) {
4236
+ console.warn(`${method}: price err [${token.symbol}]: `, error.message);
4237
+ }
4238
+ }
4239
+ throw new FatalError(`Price not found for ${token.symbol}`);
4240
+ }
4241
+ async _tryPriceMethod(token, method) {
4242
+ switch (method) {
4243
+ case "AvnuApi":
4244
+ return await this._getPriceAvnuApi(token);
4124
4245
  case "Coinbase":
4125
- // try {
4126
- // const result = await this._getPriceCoinbase(token);
4127
- // this.methodToUse[token.symbol] = 'Coinbase';
4128
- // return result;
4129
- // } catch (error: any) {
4130
- // console.warn(`Coinbase: price err: message [${token.symbol}]: `, error.message);
4131
- // // do nothing, try next
4132
- // }
4246
+ return await this._getPriceCoinbase(token);
4133
4247
  case "Coinmarketcap":
4134
- try {
4135
- const result = await this._getPriceCoinMarketCap(token);
4136
- this.methodToUse[token.symbol] = "Coinmarketcap";
4137
- return result;
4138
- } catch (error) {
4139
- console.warn(`CoinMarketCap: price err [${token.symbol}]: `, Object.keys(error));
4140
- console.warn(`CoinMarketCap: price err [${token.symbol}]: `, error.message);
4141
- }
4248
+ return await this._getPriceCoinMarketCap(token);
4142
4249
  case "Ekubo":
4143
- try {
4144
- const result = await this._getPriceEkubo(token, new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals));
4145
- this.methodToUse[token.symbol] = "Ekubo";
4146
- return result;
4147
- } catch (error) {
4148
- console.warn(`Ekubo: price err [${token.symbol}]: `, error.message);
4149
- console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error));
4150
- }
4250
+ return await this._getPriceEkubo(
4251
+ token,
4252
+ new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals)
4253
+ );
4151
4254
  case "Avnu":
4152
- try {
4153
- const result = await this._getAvnuPrice(token, new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals));
4154
- this.methodToUse[token.symbol] = "Avnu";
4155
- return result;
4156
- } catch (error) {
4157
- console.warn(`Avnu: price err [${token.symbol}]: `, error.message);
4158
- console.warn(`Avnu: price err [${token.symbol}]: `, Object.keys(error));
4159
- }
4160
- }
4161
- if (defaultMethod == "all") {
4162
- return await this._getPrice(token, "Coinbase");
4255
+ return await this._getAvnuPrice(
4256
+ token,
4257
+ new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals)
4258
+ );
4163
4259
  }
4164
- throw new FatalError(`Price not found for ${token.symbol}`);
4260
+ }
4261
+ async _getPriceAvnuApi(token) {
4262
+ const priceInfo = await this.avnuApiPricer.getPrice(token.symbol);
4263
+ return priceInfo.price;
4165
4264
  }
4166
4265
  async _getPriceCoinbase(token) {
4167
4266
  const url = this.PRICE_API.replace("{{PRICER_KEY}}", `${token.symbol}-USD`);
4168
- const result = await import_axios3.default.get(url);
4267
+ const result = await import_axios4.default.get(url);
4169
4268
  const data = result.data;
4170
4269
  return Number(data.data.amount);
4171
4270
  }
@@ -4191,7 +4290,7 @@ var Pricer = class extends PricerBase {
4191
4290
  async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
4192
4291
  logger.verbose(`Getting price of ${token.symbol} using Ekubo, amountIn: ${amountIn.toWei()}`);
4193
4292
  const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei());
4194
- const result = await import_axios3.default.get(url);
4293
+ const result = await import_axios4.default.get(url);
4195
4294
  const data = result.data;
4196
4295
  const multiplier = 1 / amountIn.toNumber();
4197
4296
  const outputUSDC = Number(Web3Number.fromWei(data.total_calculated, 6).toFixed(6)) * multiplier;
@@ -4337,7 +4436,7 @@ var Pragma = class extends PricerBase {
4337
4436
  };
4338
4437
 
4339
4438
  // src/modules/zkLend.ts
4340
- var import_axios4 = __toESM(require("axios"));
4439
+ var import_axios5 = __toESM(require("axios"));
4341
4440
 
4342
4441
  // src/dataTypes/bignumber.browser.ts
4343
4442
  var import_starknet11 = require("starknet");
@@ -4396,7 +4495,7 @@ var _ZkLend = class _ZkLend extends ILending {
4396
4495
  async init() {
4397
4496
  try {
4398
4497
  logger.verbose(`Initialising ${this.metadata.name}`);
4399
- const result = await import_axios4.default.get(_ZkLend.POOLS_URL);
4498
+ const result = await import_axios5.default.get(_ZkLend.POOLS_URL);
4400
4499
  const data = result.data;
4401
4500
  const savedTokens = await Global.getTokens();
4402
4501
  data.forEach((pool) => {
@@ -4488,7 +4587,7 @@ var _ZkLend = class _ZkLend extends ILending {
4488
4587
  */
4489
4588
  async getPositions(user) {
4490
4589
  const url = this.POSITION_URL.replace("{{USER_ADDR}}", user.address);
4491
- const result = await import_axios4.default.get(url);
4590
+ const result = await import_axios5.default.get(url);
4492
4591
  const data = result.data;
4493
4592
  const lendingPosition = [];
4494
4593
  logger.verbose(`${this.metadata.name}:: Positions: ${JSON.stringify(data)}`);
@@ -4521,7 +4620,7 @@ _ZkLend.POOLS_URL = "https://app.zklend.com/api/pools";
4521
4620
  var ZkLend = _ZkLend;
4522
4621
 
4523
4622
  // src/modules/pricer-from-api.ts
4524
- var import_axios5 = __toESM(require("axios"));
4623
+ var import_axios6 = __toESM(require("axios"));
4525
4624
 
4526
4625
  // src/modules/apollo-client-config.ts
4527
4626
  var import_client = require("@apollo/client");
@@ -4908,7 +5007,7 @@ var PricerFromApi = class extends PricerBase {
4908
5007
  const MAX_RETRIES = 5;
4909
5008
  for (retry = 1; retry < MAX_RETRIES + 1; retry++) {
4910
5009
  try {
4911
- const priceInfo = await import_axios5.default.get(
5010
+ const priceInfo = await import_axios6.default.get(
4912
5011
  `https://api.coinbase.com/v2/prices/${tokenSymbol}-USDT/spot`
4913
5012
  );
4914
5013
  if (!priceInfo) {
@@ -6219,7 +6318,7 @@ var ERC20 = class {
6219
6318
  };
6220
6319
 
6221
6320
  // src/modules/ekubo-quoter.ts
6222
- var import_axios6 = __toESM(require("axios"));
6321
+ var import_axios7 = __toESM(require("axios"));
6223
6322
  var import_starknet14 = require("starknet");
6224
6323
  var import_starknet15 = require("starknet");
6225
6324
  var EkuboQuoter = class _EkuboQuoter {
@@ -6232,7 +6331,7 @@ var EkuboQuoter = class _EkuboQuoter {
6232
6331
  try {
6233
6332
  const url = this.ENDPOINT.replace("{{AMOUNT}}", amount.toWei()).replace("{{TOKEN_FROM_ADDRESS}}", fromToken).replace("{{TOKEN_TO_ADDRESS}}", toToken);
6234
6333
  logger.verbose(`EkuboQuoter::_callQuoterApi url: ${url}`);
6235
- const quote = await import_axios6.default.get(url);
6334
+ const quote = await import_axios7.default.get(url);
6236
6335
  return quote.data;
6237
6336
  } catch (error) {
6238
6337
  logger.error(`EkuboQuoter::_callQuoterApi error: ${error.message}`);
@@ -8243,9 +8342,9 @@ var BaseStrategy = class extends CacheClass {
8243
8342
  };
8244
8343
 
8245
8344
  // src/node/headless.browser.ts
8246
- var import_axios7 = __toESM(require("axios"));
8345
+ var import_axios8 = __toESM(require("axios"));
8247
8346
  async function getAPIUsingHeadlessBrowser(url) {
8248
- const res = await import_axios7.default.get(url);
8347
+ const res = await import_axios8.default.get(url);
8249
8348
  return res.data;
8250
8349
  }
8251
8350
 
@@ -19750,6 +19849,9 @@ var xSTRKSTRK = {
19750
19849
  },
19751
19850
  apyMethodology: "APY based on 30-day historical performance, including fees and rewards.",
19752
19851
  realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
19852
+ feeBps: {
19853
+ performanceFeeBps: 1e3
19854
+ },
19753
19855
  additionalInfo: {
19754
19856
  newBounds: {
19755
19857
  lower: -1,
@@ -30476,6 +30578,9 @@ var YoloVaultStrategies = yoloVaultsConfig.map((yoloConfig) => {
30476
30578
  notARisks: getNoRiskTags(yoloRiskFactors)
30477
30579
  },
30478
30580
  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.",
30581
+ feeBps: {
30582
+ performanceFeeBps: 1e3
30583
+ },
30479
30584
  additionalInfo: {
30480
30585
  mainToken: yoloConfig.mainToken,
30481
30586
  secondaryToken: yoloConfig.secondaryToken,
@@ -33256,7 +33361,7 @@ var TokenTransferAdapter = class _TokenTransferAdapter extends BaseAdapter {
33256
33361
 
33257
33362
  // src/strategies/universal-adapters/avnu-adapter.ts
33258
33363
  var import_starknet32 = require("starknet");
33259
- var import_axios8 = __toESM(require("axios"));
33364
+ var import_axios9 = __toESM(require("axios"));
33260
33365
  var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
33261
33366
  constructor(config) {
33262
33367
  super(config, _AvnuAdapter.name, Protocols.AVNU);
@@ -33463,7 +33568,7 @@ var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
33463
33568
  async fetchQuoteWithRetry(params, retries = 5) {
33464
33569
  for (let attempt = 0; attempt < retries; attempt++) {
33465
33570
  try {
33466
- const response = await import_axios8.default.get(this.config.baseUrl, { params });
33571
+ const response = await import_axios9.default.get(this.config.baseUrl, { params });
33467
33572
  if (response.data && response.data.length > 0) {
33468
33573
  return response;
33469
33574
  }
@@ -36997,6 +37102,29 @@ var SVKStrategy = class extends BaseStrategy {
36997
37102
  ]);
36998
37103
  return [call];
36999
37104
  }
37105
+ async getUserTVL(user, blockIdentifier = "latest") {
37106
+ const shares = await this.contract.call("balanceOf", [user.address], { blockIdentifier });
37107
+ const assets = await this.contract.call(
37108
+ "convert_to_assets",
37109
+ [import_starknet34.uint256.bnToUint256(shares)],
37110
+ { blockIdentifier }
37111
+ );
37112
+ const amount = Web3Number.fromWei(
37113
+ assets.toString(),
37114
+ this.metadata.depositTokens[0].decimals
37115
+ );
37116
+ const blockNumber = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : void 0;
37117
+ const price = await this.pricer.getPrice(
37118
+ this.metadata.depositTokens[0].symbol,
37119
+ blockNumber
37120
+ );
37121
+ const usdValue = Number(amount.toFixed(6)) * price.price;
37122
+ return {
37123
+ tokenInfo: this.asset(),
37124
+ amount,
37125
+ usdValue
37126
+ };
37127
+ }
37000
37128
  /**
37001
37129
  * Returns the unused balance in the vault allocator.
37002
37130
  * Note: This function is common for any SVK strategy.
@@ -37188,6 +37316,100 @@ var SVKStrategy = class extends BaseStrategy {
37188
37316
  usdValue
37189
37317
  };
37190
37318
  }
37319
+ async getUserRealizedAPY(blockIdentifier = "latest", sinceBlocks = 6e5) {
37320
+ logger.verbose(
37321
+ `${this.getTag()}: getUserRealizedAPY => starting with blockIdentifier=${blockIdentifier}, sinceBlocks=${sinceBlocks}`
37322
+ );
37323
+ const blockNow = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : (await this.config.provider.getBlockLatestAccepted()).block_number;
37324
+ const blockNowTime = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
37325
+ const blockBefore = Math.max(
37326
+ blockNow - sinceBlocks,
37327
+ this.metadata.launchBlock
37328
+ );
37329
+ const assetsNowRaw = await this.contract.call("total_assets", [], {
37330
+ blockIdentifier
37331
+ });
37332
+ const amountNow = Web3Number.fromWei(
37333
+ assetsNowRaw.toString(),
37334
+ this.metadata.depositTokens[0].decimals
37335
+ );
37336
+ const supplyNowRaw = await this.contract.call("total_supply", [], {
37337
+ blockIdentifier
37338
+ });
37339
+ const supplyNow = Web3Number.fromWei(supplyNowRaw.toString(), 18);
37340
+ const assetsBeforeRaw = await this.contract.call(
37341
+ "total_assets",
37342
+ [],
37343
+ { blockIdentifier: blockBefore }
37344
+ );
37345
+ const amountBefore = Web3Number.fromWei(
37346
+ assetsBeforeRaw.toString(),
37347
+ this.metadata.depositTokens[0].decimals
37348
+ );
37349
+ const supplyBeforeRaw = await this.contract.call(
37350
+ "total_supply",
37351
+ [],
37352
+ { blockIdentifier: blockBefore }
37353
+ );
37354
+ const supplyBefore = Web3Number.fromWei(supplyBeforeRaw.toString(), 18);
37355
+ const blockBeforeInfo = await this.config.provider.getBlockWithTxs(
37356
+ blockBefore
37357
+ );
37358
+ const assetsPerShareNow = amountNow.multipliedBy(1e18).dividedBy(supplyNow.toString());
37359
+ const assetsPerShareBf = amountBefore.multipliedBy(1e18).dividedBy(supplyBefore.toString());
37360
+ const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
37361
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsNow: ${amountNow.toString()}`);
37362
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsBefore: ${amountBefore.toString()}`);
37363
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareNow: ${assetsPerShareNow.toString()}`);
37364
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareBf: ${assetsPerShareBf.toString()}`);
37365
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply before: ${supplyBefore.toString()}`);
37366
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply now: ${supplyNow.toString()}`);
37367
+ logger.verbose(`${this.getTag()} [getUserRealizedAPY] Time diff in seconds: ${timeDiffSeconds}`);
37368
+ const apyForGivenBlocks = Number(
37369
+ assetsPerShareNow.minus(assetsPerShareBf).multipliedBy(1e4).dividedBy(assetsPerShareBf)
37370
+ ) / 1e4;
37371
+ return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
37372
+ }
37373
+ async getUserPositionCards(input) {
37374
+ const { user, investmentFlows = [] } = input;
37375
+ const [userTVL] = await Promise.all([
37376
+ this.getUserTVL(user)
37377
+ ]);
37378
+ const cards = [
37379
+ {
37380
+ title: "Your Holdings",
37381
+ tooltip: "Your Holdings",
37382
+ value: this.formatTokenAmountForCard(userTVL.amount, userTVL.tokenInfo),
37383
+ subValue: `\u2248 ${this.formatUSDForCard(userTVL.usdValue)}`,
37384
+ subValueColor: "positive"
37385
+ }
37386
+ ];
37387
+ let lifetimeAmount = userTVL.amount.multipliedBy(0);
37388
+ let lifetimeTokenInfo = userTVL.tokenInfo;
37389
+ let lifetimeUsdValue = 0;
37390
+ if (investmentFlows.length > 0) {
37391
+ try {
37392
+ const earningsResult = this.getLifetimeEarnings(userTVL, investmentFlows);
37393
+ lifetimeAmount = earningsResult.lifetimeEarnings;
37394
+ lifetimeTokenInfo = earningsResult.tokenInfo.tokenInfo;
37395
+ const userAmount = userTVL.amount.toNumber();
37396
+ if (Number.isFinite(userAmount) && userAmount > 0) {
37397
+ const pricePerToken = userTVL.usdValue / userAmount;
37398
+ lifetimeUsdValue = lifetimeAmount.toNumber() * pricePerToken;
37399
+ }
37400
+ } catch (error) {
37401
+ logger.warn(`${this.getTag()}::getUserPositionCards lifetime earnings fallback`, error);
37402
+ }
37403
+ }
37404
+ cards.push({
37405
+ title: "Lifetime Earnings",
37406
+ tooltip: "Lifetime Earnings",
37407
+ value: this.formatTokenAmountForCard(lifetimeAmount, lifetimeTokenInfo),
37408
+ subValue: `\u2248 ${this.formatUSDForCard(lifetimeUsdValue)}`,
37409
+ subValueColor: this.getSubValueColorFromSignedNumber(lifetimeUsdValue)
37410
+ });
37411
+ return cards;
37412
+ }
37191
37413
  async getPrevAUM() {
37192
37414
  const currentAUM = await this.contract.call("aum", []);
37193
37415
  const prevAum = Web3Number.fromWei(currentAUM.toString(), this.asset().decimals);
@@ -37301,29 +37523,6 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
37301
37523
  ]);
37302
37524
  return [call];
37303
37525
  }
37304
- async getUserTVL(user, blockIdentifier = "latest") {
37305
- const shares = await this.contract.call("balanceOf", [user.address], { blockIdentifier });
37306
- const assets = await this.contract.call(
37307
- "convert_to_assets",
37308
- [import_starknet35.uint256.bnToUint256(shares)],
37309
- { blockIdentifier }
37310
- );
37311
- const amount = Web3Number.fromWei(
37312
- assets.toString(),
37313
- this.metadata.depositTokens[0].decimals
37314
- );
37315
- const blockNumber = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : void 0;
37316
- let price = await this.pricer.getPrice(
37317
- this.metadata.depositTokens[0].symbol,
37318
- blockNumber
37319
- );
37320
- const usdValue = Number(amount.toFixed(6)) * price.price;
37321
- return {
37322
- tokenInfo: this.asset(),
37323
- amount,
37324
- usdValue
37325
- };
37326
- }
37327
37526
  async getVesuAPYs() {
37328
37527
  const vesuAdapters = this.getVesuAdapters();
37329
37528
  const allVesuPools = await VesuAdapter.getVesuPools();
@@ -37364,13 +37563,16 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
37364
37563
  */
37365
37564
  async netAPY() {
37366
37565
  if (this.metadata.isPreview) {
37367
- return { net: 0, splits: [{
37368
- apy: 0,
37369
- id: "base"
37370
- }, {
37371
- apy: 0,
37372
- id: "defispring"
37373
- }] };
37566
+ return {
37567
+ net: 0,
37568
+ splits: [{
37569
+ apy: 0,
37570
+ id: "base"
37571
+ }, {
37572
+ apy: 0,
37573
+ id: "defispring"
37574
+ }]
37575
+ };
37374
37576
  }
37375
37577
  const { positions, baseAPYs, rewardAPYs } = await this.getVesuAPYs();
37376
37578
  const unusedBalanceAPY = await this.getUnusedBalanceAPY();
@@ -37385,25 +37587,31 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
37385
37587
  }
37386
37588
  async returnNetAPY(baseAPYs, rewardAPYs, weights, prevAUMUSD) {
37387
37589
  if (weights.every((p) => p == 0)) {
37388
- return { net: 0, splits: [{
37389
- apy: 0,
37390
- id: "base"
37391
- }, {
37392
- apy: 0,
37393
- id: "defispring"
37394
- }] };
37590
+ return {
37591
+ net: 0,
37592
+ splits: [{
37593
+ apy: 0,
37594
+ id: "base"
37595
+ }, {
37596
+ apy: 0,
37597
+ id: "defispring"
37598
+ }]
37599
+ };
37395
37600
  }
37396
37601
  const baseAPY = this.computeAPY(baseAPYs, weights, prevAUMUSD);
37397
37602
  const rewardAPY = this.computeAPY(rewardAPYs, weights, prevAUMUSD);
37398
37603
  const netAPY = baseAPY + rewardAPY;
37399
37604
  logger.verbose(`${this.metadata.name}::netAPY: net: ${netAPY}, baseAPY: ${baseAPY}, rewardAPY: ${rewardAPY}`);
37400
- return { net: netAPY, splits: [{
37401
- apy: baseAPY,
37402
- id: "base"
37403
- }, {
37404
- apy: rewardAPY,
37405
- id: "defispring"
37406
- }] };
37605
+ return {
37606
+ net: netAPY,
37607
+ splits: [{
37608
+ apy: baseAPY,
37609
+ id: "base"
37610
+ }, {
37611
+ apy: rewardAPY,
37612
+ id: "defispring"
37613
+ }]
37614
+ };
37407
37615
  }
37408
37616
  async getUnusedBalanceAPY() {
37409
37617
  return {
@@ -37417,104 +37625,6 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
37417
37625
  logger.verbose(`${this.getTag()} computeAPY: apys: ${JSON.stringify(apys)}, weights: ${JSON.stringify(weights)}, weightedSum: ${weightedSum}, currentAUM: ${currentAUM}`);
37418
37626
  return weightedSum / currentAUM.toNumber();
37419
37627
  }
37420
- /**
37421
- * Calculates user realized APY based on trueSharesBasedAPY method.
37422
- * Returns the APY as a number.
37423
- */
37424
- async getUserRealizedAPY(blockIdentifier = "latest", sinceBlocks = 6e5) {
37425
- logger.verbose(
37426
- `${this.getTag()}: getUserRealizedAPY => starting with blockIdentifier=${blockIdentifier}, sinceBlocks=${sinceBlocks}`
37427
- );
37428
- let blockNow = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : (await this.config.provider.getBlockLatestAccepted()).block_number;
37429
- const blockNowTime = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
37430
- const blockBefore = Math.max(
37431
- blockNow - sinceBlocks,
37432
- this.metadata.launchBlock
37433
- );
37434
- const assetsNowRaw = await this.contract.call("total_assets", [], {
37435
- blockIdentifier
37436
- });
37437
- const amountNow = Web3Number.fromWei(
37438
- assetsNowRaw.toString(),
37439
- this.metadata.depositTokens[0].decimals
37440
- );
37441
- const supplyNowRaw = await this.contract.call("total_supply", [], {
37442
- blockIdentifier
37443
- });
37444
- const supplyNow = Web3Number.fromWei(supplyNowRaw.toString(), 18);
37445
- const assetsBeforeRaw = await this.contract.call(
37446
- "total_assets",
37447
- [],
37448
- { blockIdentifier: blockBefore }
37449
- );
37450
- const amountBefore = Web3Number.fromWei(
37451
- assetsBeforeRaw.toString(),
37452
- this.metadata.depositTokens[0].decimals
37453
- );
37454
- const supplyBeforeRaw = await this.contract.call(
37455
- "total_supply",
37456
- [],
37457
- { blockIdentifier: blockBefore }
37458
- );
37459
- const supplyBefore = Web3Number.fromWei(supplyBeforeRaw.toString(), 18);
37460
- const blockBeforeInfo = await this.config.provider.getBlockWithTxs(
37461
- blockBefore
37462
- );
37463
- const assetsPerShareNow = amountNow.multipliedBy(1e18).dividedBy(supplyNow.toString());
37464
- const assetsPerShareBf = amountBefore.multipliedBy(1e18).dividedBy(supplyBefore.toString());
37465
- const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
37466
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsNow: ${amountNow.toString()}`);
37467
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsBefore: ${amountBefore.toString()}`);
37468
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareNow: ${assetsPerShareNow.toString()}`);
37469
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareBf: ${assetsPerShareBf.toString()}`);
37470
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply before: ${supplyBefore.toString()}`);
37471
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply now: ${supplyNow.toString()}`);
37472
- logger.verbose(`${this.getTag()} [getUserRealizedAPY] Time diff in seconds: ${timeDiffSeconds}`);
37473
- const apyForGivenBlocks = Number(
37474
- assetsPerShareNow.minus(assetsPerShareBf).multipliedBy(1e4).dividedBy(assetsPerShareBf)
37475
- ) / 1e4;
37476
- return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
37477
- }
37478
- async getUserPositionCards(input) {
37479
- const { user, investmentFlows = [] } = input;
37480
- const [userTVL] = await Promise.all([
37481
- this.getUserTVL(user)
37482
- ]);
37483
- const cards = [
37484
- {
37485
- title: "Your Holdings",
37486
- tooltip: "Your Holdings",
37487
- value: this.formatTokenAmountForCard(userTVL.amount, userTVL.tokenInfo),
37488
- subValue: `\u2248 ${this.formatUSDForCard(userTVL.usdValue)}`,
37489
- subValueColor: "positive"
37490
- }
37491
- ];
37492
- let lifetimeAmount = userTVL.amount.multipliedBy(0);
37493
- let lifetimeTokenInfo = userTVL.tokenInfo;
37494
- let lifetimeUsdValue = 0;
37495
- if (investmentFlows.length > 0) {
37496
- try {
37497
- const earningsResult = this.getLifetimeEarnings(userTVL, investmentFlows);
37498
- lifetimeAmount = earningsResult.lifetimeEarnings;
37499
- lifetimeTokenInfo = earningsResult.tokenInfo.tokenInfo;
37500
- const userAmount = userTVL.amount.toNumber();
37501
- if (Number.isFinite(userAmount) && userAmount > 0) {
37502
- const pricePerToken = userTVL.usdValue / userAmount;
37503
- lifetimeUsdValue = lifetimeAmount.toNumber() * pricePerToken;
37504
- }
37505
- } catch (error) {
37506
- logger.warn(`${this.getTag()}::getUserPositionCards lifetime earnings fallback`, error);
37507
- }
37508
- }
37509
- cards.push({
37510
- title: "Lifetime Earnings",
37511
- tooltip: "Lifetime Earnings",
37512
- value: this.formatTokenAmountForCard(lifetimeAmount, lifetimeTokenInfo),
37513
- subValue: `\u2248 ${this.formatUSDForCard(lifetimeUsdValue)}`,
37514
- subValueColor: this.getSubValueColorFromSignedNumber(lifetimeUsdValue)
37515
- });
37516
- return cards;
37517
- }
37518
37628
  /**
37519
37629
  * Calculates the total TVL of the strategy.
37520
37630
  * @returns Object containing the total amount in token units and USD value
@@ -37591,13 +37701,17 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
37591
37701
  };
37592
37702
  const aumToken = vesuAum.plus(balance.amount);
37593
37703
  if (aumToken.isZero()) {
37594
- return { net, splits: [{
37595
- aum: zeroAmt,
37596
- id: "finalised" /* FINALISED */
37597
- }, {
37598
- aum: zeroAmt,
37599
- id: "defispring" /* DEFISPRING */
37600
- }], prevAum };
37704
+ return {
37705
+ net,
37706
+ splits: [{
37707
+ aum: zeroAmt,
37708
+ id: "finalised" /* FINALISED */
37709
+ }, {
37710
+ aum: zeroAmt,
37711
+ id: "defispring" /* DEFISPRING */
37712
+ }],
37713
+ prevAum
37714
+ };
37601
37715
  }
37602
37716
  logger.verbose(`${this.getTag()} Actual AUM: ${aumToken}`);
37603
37717
  const rewardAssets = await this.getRewardsAUM(prevAum);
@@ -38250,6 +38364,9 @@ var createUniversalStrategy = (params) => {
38250
38364
  auditUrl: AUDIT_URL3,
38251
38365
  protocols: [Protocols.VESU],
38252
38366
  realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
38367
+ feeBps: {
38368
+ performanceFeeBps: 1e3
38369
+ },
38253
38370
  curator: UnwrapLabsCurator,
38254
38371
  settings: createUniversalSettings(params.tokenSymbol, params.maxTVLDecimals),
38255
38372
  contractDetails: getContractDetails(params.vaultSettings),
@@ -38891,11 +39008,15 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
38891
39008
  remarks: "defispring" /* DEFISPRING */,
38892
39009
  protocol: Protocols.NONE
38893
39010
  };
38894
- return { net: {
38895
- tokenInfo: underlying,
38896
- amount: netAUM,
38897
- usdValue: netAUM.toNumber() * assetPrice.price
38898
- }, prevAum, splits: [realAUM, estimatedAUMDelta] };
39011
+ return {
39012
+ net: {
39013
+ tokenInfo: underlying,
39014
+ amount: netAUM,
39015
+ usdValue: netAUM.toNumber() * assetPrice.price
39016
+ },
39017
+ prevAum,
39018
+ splits: [realAUM, estimatedAUMDelta]
39019
+ };
38899
39020
  }
38900
39021
  async getTVLUnrealized() {
38901
39022
  return await this.getAUM(true);
@@ -38913,6 +39034,62 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
38913
39034
  tokenInfo: this.asset()
38914
39035
  };
38915
39036
  }
39037
+ async getUserPositionCards(input) {
39038
+ const cards = await super.getUserPositionCards(input);
39039
+ try {
39040
+ const [unrealizedResult, userTVL, realizedApyRaw] = await Promise.all([
39041
+ this.getUserUnrealizedGains(input.user),
39042
+ this.getUserTVL(input.user),
39043
+ this.getUserRealizedAPY().catch(() => null)
39044
+ ]);
39045
+ const amount = unrealizedResult.unrealizedGains;
39046
+ let usdValue = 0;
39047
+ const userAmount = userTVL.amount.toNumber();
39048
+ if (Number.isFinite(userAmount) && userAmount > 0) {
39049
+ usdValue = userTVL.usdValue / userAmount * amount.toNumber();
39050
+ }
39051
+ cards.push({
39052
+ title: "Unrealized Gains",
39053
+ tooltip: "Unrealized gains based on current market prices vs Endur prices. If you withdraw now, you will forgo these gains.",
39054
+ value: this.formatTokenAmountForCard(amount, unrealizedResult.tokenInfo),
39055
+ subValue: `\u2248 ${this.formatUSDForCard(usdValue)}`,
39056
+ subValueColor: this.getSubValueColorFromSignedNumber(usdValue)
39057
+ });
39058
+ const realizedApy = typeof realizedApyRaw === "number" ? this.formatPercentForCard(realizedApyRaw) : "N/A";
39059
+ cards.push({
39060
+ title: "Realized APY",
39061
+ tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
39062
+ value: realizedApy
39063
+ });
39064
+ } catch (error) {
39065
+ logger.warn(`${this.getTag()}::getUserPositionCards unrealized gains fallback`, error);
39066
+ cards.push({
39067
+ title: "Unrealized Gains",
39068
+ tooltip: "Unrealized gains based on current market prices vs Endur prices. If you withdraw now, you will forgo these gains.",
39069
+ value: this.formatTokenAmountForCard(
39070
+ Web3Number.fromWei("0", this.asset().decimals),
39071
+ this.asset()
39072
+ ),
39073
+ subValue: `\u2248 ${this.formatUSDForCard(0)}`,
39074
+ subValueColor: "default"
39075
+ });
39076
+ cards.push({
39077
+ title: "Realized APY",
39078
+ tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
39079
+ value: "N/A"
39080
+ });
39081
+ }
39082
+ if (this.asset().symbol === "xSTRK") {
39083
+ const index = cards.findIndex((card) => card.title === "Lifetime Earnings");
39084
+ if (index >= 0) {
39085
+ cards[index] = {
39086
+ ...cards[index],
39087
+ 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."
39088
+ };
39089
+ }
39090
+ }
39091
+ return cards;
39092
+ }
38916
39093
  };
38917
39094
  function VaultDescription(lstSymbol, underlyingSymbol) {
38918
39095
  const containerStyle = {
@@ -39320,6 +39497,9 @@ function getStrategySettings(lstSymbol, underlyingSymbol, settings, isPreview =
39320
39497
  isPreview,
39321
39498
  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.",
39322
39499
  realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
39500
+ feeBps: {
39501
+ performanceFeeBps: 1e3
39502
+ },
39323
39503
  tags: lstSymbol.includes("BTC") ? ["BTC" /* BTC */, "Maxx" /* LEVERED */] : ["Maxx" /* LEVERED */],
39324
39504
  security: HYPER_LST_SECURITY,
39325
39505
  redemptionInfo: HYPER_LST_REDEMPTION_INFO,
@@ -39533,6 +39713,23 @@ var BoostedxSTRKCarryStrategy = class _BoostedxSTRKCarryStrategy extends SVKStra
39533
39713
  usdValue
39534
39714
  };
39535
39715
  }
39716
+ async getUserPositionCards(input) {
39717
+ const cards = await super.getUserPositionCards(input);
39718
+ const realizedApyRaw = await this.getUserRealizedAPY().catch((error) => {
39719
+ logger.warn(
39720
+ `${this.getTag()}::getUserPositionCards realized APY fallback`,
39721
+ error
39722
+ );
39723
+ return null;
39724
+ });
39725
+ const realizedApy = typeof realizedApyRaw === "number" ? this.formatPercentForCard(realizedApyRaw) : "N/A";
39726
+ cards.push({
39727
+ title: "Realized APY",
39728
+ tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
39729
+ value: realizedApy
39730
+ });
39731
+ return cards;
39732
+ }
39536
39733
  async getAUM() {
39537
39734
  const underlying = this.asset();
39538
39735
  const depositTokenPrice = await this.pricer.getPrice(underlying.symbol);
@@ -40042,38 +40239,38 @@ var wbtcBoostedSettings = {
40042
40239
  var boostedCarryRiskFactors = [
40043
40240
  {
40044
40241
  type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */,
40045
- value: 2 /* WELL_AUDITED */,
40242
+ value: 1 /* BATTLE_TESTED */,
40046
40243
  // 20% — core trust assumption; SVK is audited but still multi-contract (vault, manager, adapters).
40047
40244
  weight: 20,
40048
40245
  reason: "Built on the Starknet Vault Kit (SVK), with audits under the Sherlock-audited branch."
40049
40246
  },
40050
40247
  {
40051
40248
  type: "Liquidation Risk" /* LIQUIDATION_RISK */,
40052
- value: 3 /* MODERATE_PROBABILITY */,
40249
+ value: 2 /* LOW_PROBABILITY */,
40053
40250
  // 20% — tied with smart contract; uncorrelated collateral/debt is the main principal risk here.
40054
40251
  weight: 20,
40055
40252
  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."
40056
40253
  },
40057
40254
  {
40058
40255
  type: "Low Liquidity Risk" /* LOW_LIQUIDITY_RISK */,
40059
- value: 3 /* MODERATE_CONCERNS */,
40256
+ value: 1 /* GOOD_LIQUIDITY */,
40060
40257
  // 15% — below liquidation but above ops risks; every unwind/withdraw depends on xSTRK→STRK depth.
40061
40258
  weight: 15,
40062
- 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."
40259
+ 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."
40063
40260
  },
40064
40261
  {
40065
40262
  type: "Technical Risk" /* TECHNICAL_RISK */,
40066
40263
  value: 3 /* SOME_COMPLEXITY */,
40067
40264
  // 13% — monitoring/rebalancing stack matters, but usually recoverable without instant loss.
40068
- weight: 13,
40265
+ weight: 10,
40069
40266
  reason: "Yield routes across Vesu, Avnu, and Hyper xSTRK with automated monitoring. Technical failures can delay rebalancing."
40070
40267
  },
40071
40268
  {
40072
40269
  type: "Depeg Risk" /* DEPEG_RISK */,
40073
- value: 3 /* OCCASIONAL_DEPEG */,
40270
+ value: 2 /* GENERALLY_STABLE */,
40074
40271
  // 12% — affects yield and swap notionals; USDC/WBTC depeg is rarer than xSTRK/STRK drift.
40075
40272
  weight: 12,
40076
- reason: "xSTRK yield depends on its exchange rate vs STRK; USDC and WBTC carry standard stablecoin and BTC market risks."
40273
+ reason: "Historically, xSTRK's DEX price has been generally stable compared to its true price."
40077
40274
  },
40078
40275
  {
40079
40276
  type: "Oracle Risk" /* ORACLE_RISK */,
@@ -40093,7 +40290,7 @@ var boostedCarryRiskFactors = [
40093
40290
  type: "Market Risk" /* MARKET_RISK */,
40094
40291
  value: 3 /* MODERATE_VOLATILITY */,
40095
40292
  // 5% — largely captured by liquidation + depeg factors; kept small to avoid double-counting vol.
40096
- weight: 5,
40293
+ weight: 8,
40097
40294
  reason: "STRK, BTC, and stablecoin volatility can move loan-to-value and swap costs."
40098
40295
  }
40099
40296
  ];
@@ -40122,15 +40319,15 @@ function getBoostedCarryFAQs(depositSymbol, debtSymbol, lstSymbol) {
40122
40319
  question: "Which protocols are used?",
40123
40320
  answer: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
40124
40321
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Vesu" }),
40125
- " for collateral and borrowing, ",
40126
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Avnu" }),
40322
+ " for collateral and borrowing,",
40127
40323
  " ",
40128
- "for swaps, ",
40324
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Avnu" }),
40325
+ " for swaps, ",
40129
40326
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Endur" }),
40130
- " for ",
40131
- lstSymbol,
40132
- ", and the Troves",
40327
+ " for",
40133
40328
  " ",
40329
+ lstSymbol,
40330
+ ", and the Troves ",
40134
40331
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("strong", { children: [
40135
40332
  "Hyper-",
40136
40333
  lstSymbol
@@ -40218,6 +40415,9 @@ function getStrategySettings2(settings, meta) {
40218
40415
  ]
40219
40416
  },
40220
40417
  contractDetails: getContractDetails(settings),
40418
+ feeBps: {
40419
+ performanceFeeBps: 1500
40420
+ },
40221
40421
  faqs: getBoostedCarryFAQs(
40222
40422
  depositToken.symbol,
40223
40423
  debtToken.symbol,
@@ -40538,7 +40738,7 @@ function createStrategy(type, config, pricer, metadata) {
40538
40738
  }
40539
40739
 
40540
40740
  // src/modules/pricer-lst.ts
40541
- var import_axios9 = __toESM(require("axios"));
40741
+ var import_axios10 = __toESM(require("axios"));
40542
40742
  var PricerLST2 = class extends Pricer {
40543
40743
  // e.g. xSTRK/STRK
40544
40744
  constructor(config, tokenMaps) {
@@ -40574,7 +40774,7 @@ var PricerLST2 = class extends Pricer {
40574
40774
  async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
40575
40775
  const underlying = this.getUnderlying(token);
40576
40776
  const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei()).replace("{{UNDERLYING_ADDRESS}}", underlying.address.toString());
40577
- const result = await import_axios9.default.get(url);
40777
+ const result = await import_axios10.default.get(url);
40578
40778
  const data = result.data;
40579
40779
  const multiplier = 1 / amountIn.toNumber();
40580
40780
  const outputUnderlying = Number(Web3Number.fromWei(data.total_calculated, underlying.decimals).toFixed(6)) * multiplier;
@@ -40726,6 +40926,7 @@ var PricerRedis = class extends Pricer {
40726
40926
  async startWithRedis(redisUrl) {
40727
40927
  await this.initRedis(redisUrl);
40728
40928
  logger.info(`Starting Pricer with Redis`);
40929
+ this.avnuApiPricer.start();
40729
40930
  this._loadPrices(this._setRedisPrices.bind(this));
40730
40931
  setInterval(() => {
40731
40932
  this._loadPrices(this._setRedisPrices.bind(this));
@@ -41173,6 +41374,7 @@ var deployer_default = Deployer;
41173
41374
  PositionTypeAvnuExtended,
41174
41375
  Pragma,
41175
41376
  Pricer,
41377
+ PricerAvnuApi,
41176
41378
  PricerBase,
41177
41379
  PricerFromApi,
41178
41380
  PricerLST,