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

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.
@@ -27952,6 +27952,7 @@ ${JSON.stringify(data, null, 2)}`;
27952
27952
  PositionTypeAvnuExtended: () => PositionTypeAvnuExtended,
27953
27953
  Pragma: () => Pragma,
27954
27954
  Pricer: () => Pricer,
27955
+ PricerAvnuApi: () => PricerAvnuApi,
27955
27956
  PricerBase: () => PricerBase,
27956
27957
  PricerFromApi: () => PricerFromApi,
27957
27958
  PricerLST: () => PricerLST,
@@ -73153,20 +73154,20 @@ ${JSON.stringify(data, null, 2)}`;
73153
73154
  decimals: 18,
73154
73155
  coingeckId: void 0,
73155
73156
  displayDecimals: 6,
73156
- priceCheckAmount: 1e-4
73157
+ priceCheckAmount: 1e-4,
73157
73158
  // 112000 * 0.0001 = $11.2
73159
+ dontPrice: true
73158
73160
  },
73159
73161
  {
73160
73162
  name: "mRe7YIELD",
73161
73163
  symbol: "mRe7YIELD",
73162
73164
  logo: "https://midas.app/assets/mre7-BcOOHm7i.svg",
73163
- address: ContractAddr.from(
73164
- "0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"
73165
- ),
73165
+ address: ContractAddr.from("0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"),
73166
73166
  decimals: 18,
73167
73167
  coingeckId: void 0,
73168
73168
  displayDecimals: 2,
73169
- priceCheckAmount: 100
73169
+ priceCheckAmount: 100,
73170
+ dontPrice: true
73170
73171
  },
73171
73172
  {
73172
73173
  name: "fyWBTC",
@@ -73176,8 +73177,9 @@ ${JSON.stringify(data, null, 2)}`;
73176
73177
  decimals: 8,
73177
73178
  coingeckId: void 0,
73178
73179
  displayDecimals: 6,
73179
- priceCheckAmount: 1e-3
73180
+ priceCheckAmount: 1e-3,
73180
73181
  // 112000 * 0.0001 = $110.2
73182
+ dontPrice: true
73181
73183
  },
73182
73184
  {
73183
73185
  name: "fyETH",
@@ -73187,7 +73189,8 @@ ${JSON.stringify(data, null, 2)}`;
73187
73189
  decimals: 18,
73188
73190
  coingeckId: void 0,
73189
73191
  displayDecimals: 4,
73190
- priceCheckAmount: 0.1
73192
+ priceCheckAmount: 0.1,
73193
+ dontPrice: true
73191
73194
  },
73192
73195
  {
73193
73196
  name: "fyUSDC",
@@ -73197,7 +73200,8 @@ ${JSON.stringify(data, null, 2)}`;
73197
73200
  decimals: 6,
73198
73201
  coingeckId: void 0,
73199
73202
  displayDecimals: 2,
73200
- priceCheckAmount: 100
73203
+ priceCheckAmount: 100,
73204
+ dontPrice: true
73201
73205
  },
73202
73206
  {
73203
73207
  name: "strkBTC",
@@ -78771,7 +78775,95 @@ ${JSON.stringify(data, null, 2)}`;
78771
78775
  }
78772
78776
  };
78773
78777
 
78778
+ // src/modules/pricer-avnu-api.ts
78779
+ var AVNU_TOKENS_API = "https://starknet.impulse.avnu.fi/v3/tokens";
78780
+ var PricerAvnuApi = class extends PricerBase {
78781
+ constructor(config3, tokens2) {
78782
+ super(config3, tokens2);
78783
+ this.prices = {};
78784
+ this.refreshInterval = 15e3;
78785
+ this.staleTime = 5 * 60 * 1e3;
78786
+ this.pollTimer = null;
78787
+ this.loading = false;
78788
+ }
78789
+ start() {
78790
+ this._loadPrices();
78791
+ this.pollTimer = setInterval(() => {
78792
+ this._loadPrices();
78793
+ }, this.refreshInterval);
78794
+ }
78795
+ stop() {
78796
+ if (this.pollTimer) {
78797
+ clearInterval(this.pollTimer);
78798
+ this.pollTimer = null;
78799
+ }
78800
+ }
78801
+ isStale(timestamp) {
78802
+ return Date.now() - timestamp.getTime() > this.staleTime;
78803
+ }
78804
+ hasPrice(tokenSymbol) {
78805
+ const info = this.prices[tokenSymbol];
78806
+ return !!info && !this.isStale(info.timestamp);
78807
+ }
78808
+ async getPrice(tokenSymbol) {
78809
+ const info = this.prices[tokenSymbol];
78810
+ if (!info) {
78811
+ throw new Error(`AvnuApi: price of ${tokenSymbol} not found`);
78812
+ }
78813
+ if (this.isStale(info.timestamp)) {
78814
+ throw new Error(`AvnuApi: price of ${tokenSymbol} is stale`);
78815
+ }
78816
+ return info;
78817
+ }
78818
+ async _loadPrices() {
78819
+ if (this.loading) {
78820
+ return;
78821
+ }
78822
+ this.loading = true;
78823
+ const timestamp = /* @__PURE__ */ new Date();
78824
+ try {
78825
+ const result2 = await axios_default.get(AVNU_TOKENS_API);
78826
+ const priceByAddress = /* @__PURE__ */ new Map();
78827
+ for (const entry of result2.data) {
78828
+ const usd = entry.starknet?.usd;
78829
+ if (usd != null && usd > 0) {
78830
+ priceByAddress.set(ContractAddr.standardise(entry.address), usd);
78831
+ }
78832
+ }
78833
+ for (const token of this.tokens) {
78834
+ if (token.symbol === "USDT" || token.symbol === "USDC") {
78835
+ this.prices[token.symbol] = { price: 1, timestamp };
78836
+ continue;
78837
+ }
78838
+ const targetToken = token.priceProxySymbol ? this.tokens.find((t) => t.symbol === token.priceProxySymbol) : token;
78839
+ if (!targetToken) {
78840
+ continue;
78841
+ }
78842
+ const addr = targetToken.address.address;
78843
+ const price = priceByAddress.get(addr);
78844
+ if (price != null) {
78845
+ this.prices[token.symbol] = { price, timestamp };
78846
+ logger2.verbose(
78847
+ `AvnuApi: ${token.symbol} -> $${price}`
78848
+ );
78849
+ }
78850
+ }
78851
+ } catch (error2) {
78852
+ logger2.warn(`AvnuApi: failed to fetch tokens: ${error2?.message ?? error2}`);
78853
+ } finally {
78854
+ this.loading = false;
78855
+ }
78856
+ }
78857
+ };
78858
+
78774
78859
  // src/modules/pricer.ts
78860
+ var PRICE_METHOD_PRIORITY = [
78861
+ "AvnuApi",
78862
+ "Coinbase",
78863
+ "Coinmarketcap",
78864
+ "Ekubo",
78865
+ "Avnu"
78866
+ ];
78775
78867
  var Pricer = class extends PricerBase {
78776
78868
  // e.g. ETH/USDC
78777
78869
  constructor(config3, tokens2, refreshInterval = 3e4, staleTime = 6e4) {
@@ -78790,6 +78882,7 @@ ${JSON.stringify(data, null, 2)}`;
78790
78882
  this.EKUBO_API = "https://prod-api-quoter.ekubo.org/23448594291968334/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
78791
78883
  this.refreshInterval = refreshInterval;
78792
78884
  this.staleTime = staleTime;
78885
+ this.avnuApiPricer = new PricerAvnuApi(config3, tokens2);
78793
78886
  }
78794
78887
  isReady() {
78795
78888
  const allPricesExist = Object.keys(this.prices).length === this.tokens.length;
@@ -78819,6 +78912,7 @@ ${JSON.stringify(data, null, 2)}`;
78819
78912
  });
78820
78913
  }
78821
78914
  start() {
78915
+ this.avnuApiPricer.start();
78822
78916
  this._loadPrices();
78823
78917
  setInterval(() => {
78824
78918
  this._loadPrices();
@@ -78843,6 +78937,9 @@ ${JSON.stringify(data, null, 2)}`;
78843
78937
  let retry = 0;
78844
78938
  while (retry < MAX_RETRIES) {
78845
78939
  try {
78940
+ if (token.dontPrice) {
78941
+ return;
78942
+ }
78846
78943
  if (token.symbol === "USDT" || token.symbol === "USDC") {
78847
78944
  this.prices[token.symbol] = {
78848
78945
  price: 1,
@@ -78890,51 +78987,52 @@ ${JSON.stringify(data, null, 2)}`;
78890
78987
  });
78891
78988
  }
78892
78989
  }
78893
- async _getPrice(token, defaultMethod = "all") {
78894
- const methodToUse = this.methodToUse[token.symbol] || defaultMethod;
78895
- logger2.verbose(`Fetching price of ${token.symbol} using ${methodToUse}`);
78896
- switch (methodToUse) {
78990
+ async _getPrice(token) {
78991
+ const pinned = this.methodToUse[token.symbol];
78992
+ if (pinned) {
78993
+ logger2.verbose(`Fetching price of ${token.symbol} using pinned ${pinned}`);
78994
+ try {
78995
+ return await this._tryPriceMethod(token, pinned);
78996
+ } catch (error2) {
78997
+ console.warn(`${pinned}: pinned price failed [${token.symbol}]: `, error2.message);
78998
+ delete this.methodToUse[token.symbol];
78999
+ }
79000
+ }
79001
+ for (const method of PRICE_METHOD_PRIORITY) {
79002
+ logger2.verbose(`Fetching price of ${token.symbol} using ${method}`);
79003
+ try {
79004
+ const result2 = await this._tryPriceMethod(token, method);
79005
+ this.methodToUse[token.symbol] = method;
79006
+ return result2;
79007
+ } catch (error2) {
79008
+ console.warn(`${method}: price err [${token.symbol}]: `, error2.message);
79009
+ }
79010
+ }
79011
+ throw new FatalError(`Price not found for ${token.symbol}`);
79012
+ }
79013
+ async _tryPriceMethod(token, method) {
79014
+ switch (method) {
79015
+ case "AvnuApi":
79016
+ return await this._getPriceAvnuApi(token);
78897
79017
  case "Coinbase":
78898
- // try {
78899
- // const result = await this._getPriceCoinbase(token);
78900
- // this.methodToUse[token.symbol] = 'Coinbase';
78901
- // return result;
78902
- // } catch (error: any) {
78903
- // console.warn(`Coinbase: price err: message [${token.symbol}]: `, error.message);
78904
- // // do nothing, try next
78905
- // }
79018
+ return await this._getPriceCoinbase(token);
78906
79019
  case "Coinmarketcap":
78907
- try {
78908
- const result2 = await this._getPriceCoinMarketCap(token);
78909
- this.methodToUse[token.symbol] = "Coinmarketcap";
78910
- return result2;
78911
- } catch (error2) {
78912
- console.warn(`CoinMarketCap: price err [${token.symbol}]: `, Object.keys(error2));
78913
- console.warn(`CoinMarketCap: price err [${token.symbol}]: `, error2.message);
78914
- }
79020
+ return await this._getPriceCoinMarketCap(token);
78915
79021
  case "Ekubo":
78916
- try {
78917
- const result2 = await this._getPriceEkubo(token, new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals));
78918
- this.methodToUse[token.symbol] = "Ekubo";
78919
- return result2;
78920
- } catch (error2) {
78921
- console.warn(`Ekubo: price err [${token.symbol}]: `, error2.message);
78922
- console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error2));
78923
- }
79022
+ return await this._getPriceEkubo(
79023
+ token,
79024
+ new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals)
79025
+ );
78924
79026
  case "Avnu":
78925
- try {
78926
- const result2 = await this._getAvnuPrice(token, new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals));
78927
- this.methodToUse[token.symbol] = "Avnu";
78928
- return result2;
78929
- } catch (error2) {
78930
- console.warn(`Avnu: price err [${token.symbol}]: `, error2.message);
78931
- console.warn(`Avnu: price err [${token.symbol}]: `, Object.keys(error2));
78932
- }
78933
- }
78934
- if (defaultMethod == "all") {
78935
- return await this._getPrice(token, "Coinbase");
79027
+ return await this._getAvnuPrice(
79028
+ token,
79029
+ new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals)
79030
+ );
78936
79031
  }
78937
- throw new FatalError(`Price not found for ${token.symbol}`);
79032
+ }
79033
+ async _getPriceAvnuApi(token) {
79034
+ const priceInfo = await this.avnuApiPricer.getPrice(token.symbol);
79035
+ return priceInfo.price;
78938
79036
  }
78939
79037
  async _getPriceCoinbase(token) {
78940
79038
  const url = this.PRICE_API.replace("{{PRICER_KEY}}", `${token.symbol}-USD`);
@@ -106855,6 +106953,9 @@ spurious results.`);
106855
106953
  },
106856
106954
  apyMethodology: "APY based on 30-day historical performance, including fees and rewards.",
106857
106955
  realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
106956
+ feeBps: {
106957
+ performanceFeeBps: 1e3
106958
+ },
106858
106959
  additionalInfo: {
106859
106960
  newBounds: {
106860
106961
  lower: -1,
@@ -117573,6 +117674,9 @@ spurious results.`);
117573
117674
  notARisks: getNoRiskTags(yoloRiskFactors)
117574
117675
  },
117575
117676
  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.",
117677
+ feeBps: {
117678
+ performanceFeeBps: 1e3
117679
+ },
117576
117680
  additionalInfo: {
117577
117681
  mainToken: yoloConfig.mainToken,
117578
117682
  secondaryToken: yoloConfig.secondaryToken,
@@ -124074,6 +124178,29 @@ spurious results.`);
124074
124178
  ]);
124075
124179
  return [call];
124076
124180
  }
124181
+ async getUserTVL(user, blockIdentifier = "latest") {
124182
+ const shares = await this.contract.call("balanceOf", [user.address], { blockIdentifier });
124183
+ const assets = await this.contract.call(
124184
+ "convert_to_assets",
124185
+ [uint256_exports.bnToUint256(shares)],
124186
+ { blockIdentifier }
124187
+ );
124188
+ const amount = Web3Number.fromWei(
124189
+ assets.toString(),
124190
+ this.metadata.depositTokens[0].decimals
124191
+ );
124192
+ const blockNumber = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : void 0;
124193
+ const price = await this.pricer.getPrice(
124194
+ this.metadata.depositTokens[0].symbol,
124195
+ blockNumber
124196
+ );
124197
+ const usdValue = Number(amount.toFixed(6)) * price.price;
124198
+ return {
124199
+ tokenInfo: this.asset(),
124200
+ amount,
124201
+ usdValue
124202
+ };
124203
+ }
124077
124204
  /**
124078
124205
  * Returns the unused balance in the vault allocator.
124079
124206
  * Note: This function is common for any SVK strategy.
@@ -124265,6 +124392,100 @@ spurious results.`);
124265
124392
  usdValue
124266
124393
  };
124267
124394
  }
124395
+ async getUserRealizedAPY(blockIdentifier = "latest", sinceBlocks = 6e5) {
124396
+ logger2.verbose(
124397
+ `${this.getTag()}: getUserRealizedAPY => starting with blockIdentifier=${blockIdentifier}, sinceBlocks=${sinceBlocks}`
124398
+ );
124399
+ const blockNow = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : (await this.config.provider.getBlockLatestAccepted()).block_number;
124400
+ const blockNowTime = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
124401
+ const blockBefore = Math.max(
124402
+ blockNow - sinceBlocks,
124403
+ this.metadata.launchBlock
124404
+ );
124405
+ const assetsNowRaw = await this.contract.call("total_assets", [], {
124406
+ blockIdentifier
124407
+ });
124408
+ const amountNow = Web3Number.fromWei(
124409
+ assetsNowRaw.toString(),
124410
+ this.metadata.depositTokens[0].decimals
124411
+ );
124412
+ const supplyNowRaw = await this.contract.call("total_supply", [], {
124413
+ blockIdentifier
124414
+ });
124415
+ const supplyNow = Web3Number.fromWei(supplyNowRaw.toString(), 18);
124416
+ const assetsBeforeRaw = await this.contract.call(
124417
+ "total_assets",
124418
+ [],
124419
+ { blockIdentifier: blockBefore }
124420
+ );
124421
+ const amountBefore = Web3Number.fromWei(
124422
+ assetsBeforeRaw.toString(),
124423
+ this.metadata.depositTokens[0].decimals
124424
+ );
124425
+ const supplyBeforeRaw = await this.contract.call(
124426
+ "total_supply",
124427
+ [],
124428
+ { blockIdentifier: blockBefore }
124429
+ );
124430
+ const supplyBefore = Web3Number.fromWei(supplyBeforeRaw.toString(), 18);
124431
+ const blockBeforeInfo = await this.config.provider.getBlockWithTxs(
124432
+ blockBefore
124433
+ );
124434
+ const assetsPerShareNow = amountNow.multipliedBy(1e18).dividedBy(supplyNow.toString());
124435
+ const assetsPerShareBf = amountBefore.multipliedBy(1e18).dividedBy(supplyBefore.toString());
124436
+ const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
124437
+ logger2.verbose(`${this.getTag()} [getUserRealizedAPY] assetsNow: ${amountNow.toString()}`);
124438
+ logger2.verbose(`${this.getTag()} [getUserRealizedAPY] assetsBefore: ${amountBefore.toString()}`);
124439
+ logger2.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareNow: ${assetsPerShareNow.toString()}`);
124440
+ logger2.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareBf: ${assetsPerShareBf.toString()}`);
124441
+ logger2.verbose(`${this.getTag()} [getUserRealizedAPY] Supply before: ${supplyBefore.toString()}`);
124442
+ logger2.verbose(`${this.getTag()} [getUserRealizedAPY] Supply now: ${supplyNow.toString()}`);
124443
+ logger2.verbose(`${this.getTag()} [getUserRealizedAPY] Time diff in seconds: ${timeDiffSeconds}`);
124444
+ const apyForGivenBlocks = Number(
124445
+ assetsPerShareNow.minus(assetsPerShareBf).multipliedBy(1e4).dividedBy(assetsPerShareBf)
124446
+ ) / 1e4;
124447
+ return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
124448
+ }
124449
+ async getUserPositionCards(input) {
124450
+ const { user, investmentFlows = [] } = input;
124451
+ const [userTVL] = await Promise.all([
124452
+ this.getUserTVL(user)
124453
+ ]);
124454
+ const cards = [
124455
+ {
124456
+ title: "Your Holdings",
124457
+ tooltip: "Your Holdings",
124458
+ value: this.formatTokenAmountForCard(userTVL.amount, userTVL.tokenInfo),
124459
+ subValue: `\u2248 ${this.formatUSDForCard(userTVL.usdValue)}`,
124460
+ subValueColor: "positive"
124461
+ }
124462
+ ];
124463
+ let lifetimeAmount = userTVL.amount.multipliedBy(0);
124464
+ let lifetimeTokenInfo = userTVL.tokenInfo;
124465
+ let lifetimeUsdValue = 0;
124466
+ if (investmentFlows.length > 0) {
124467
+ try {
124468
+ const earningsResult = this.getLifetimeEarnings(userTVL, investmentFlows);
124469
+ lifetimeAmount = earningsResult.lifetimeEarnings;
124470
+ lifetimeTokenInfo = earningsResult.tokenInfo.tokenInfo;
124471
+ const userAmount = userTVL.amount.toNumber();
124472
+ if (Number.isFinite(userAmount) && userAmount > 0) {
124473
+ const pricePerToken = userTVL.usdValue / userAmount;
124474
+ lifetimeUsdValue = lifetimeAmount.toNumber() * pricePerToken;
124475
+ }
124476
+ } catch (error2) {
124477
+ logger2.warn(`${this.getTag()}::getUserPositionCards lifetime earnings fallback`, error2);
124478
+ }
124479
+ }
124480
+ cards.push({
124481
+ title: "Lifetime Earnings",
124482
+ tooltip: "Lifetime Earnings",
124483
+ value: this.formatTokenAmountForCard(lifetimeAmount, lifetimeTokenInfo),
124484
+ subValue: `\u2248 ${this.formatUSDForCard(lifetimeUsdValue)}`,
124485
+ subValueColor: this.getSubValueColorFromSignedNumber(lifetimeUsdValue)
124486
+ });
124487
+ return cards;
124488
+ }
124268
124489
  async getPrevAUM() {
124269
124490
  const currentAUM = await this.contract.call("aum", []);
124270
124491
  const prevAum = Web3Number.fromWei(currentAUM.toString(), this.asset().decimals);
@@ -124378,29 +124599,6 @@ spurious results.`);
124378
124599
  ]);
124379
124600
  return [call];
124380
124601
  }
124381
- async getUserTVL(user, blockIdentifier = "latest") {
124382
- const shares = await this.contract.call("balanceOf", [user.address], { blockIdentifier });
124383
- const assets = await this.contract.call(
124384
- "convert_to_assets",
124385
- [uint256_exports.bnToUint256(shares)],
124386
- { blockIdentifier }
124387
- );
124388
- const amount = Web3Number.fromWei(
124389
- assets.toString(),
124390
- this.metadata.depositTokens[0].decimals
124391
- );
124392
- const blockNumber = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : void 0;
124393
- let price = await this.pricer.getPrice(
124394
- this.metadata.depositTokens[0].symbol,
124395
- blockNumber
124396
- );
124397
- const usdValue = Number(amount.toFixed(6)) * price.price;
124398
- return {
124399
- tokenInfo: this.asset(),
124400
- amount,
124401
- usdValue
124402
- };
124403
- }
124404
124602
  async getVesuAPYs() {
124405
124603
  const vesuAdapters = this.getVesuAdapters();
124406
124604
  const allVesuPools = await VesuAdapter.getVesuPools();
@@ -124441,13 +124639,16 @@ spurious results.`);
124441
124639
  */
124442
124640
  async netAPY() {
124443
124641
  if (this.metadata.isPreview) {
124444
- return { net: 0, splits: [{
124445
- apy: 0,
124446
- id: "base"
124447
- }, {
124448
- apy: 0,
124449
- id: "defispring"
124450
- }] };
124642
+ return {
124643
+ net: 0,
124644
+ splits: [{
124645
+ apy: 0,
124646
+ id: "base"
124647
+ }, {
124648
+ apy: 0,
124649
+ id: "defispring"
124650
+ }]
124651
+ };
124451
124652
  }
124452
124653
  const { positions, baseAPYs, rewardAPYs } = await this.getVesuAPYs();
124453
124654
  const unusedBalanceAPY = await this.getUnusedBalanceAPY();
@@ -124462,25 +124663,31 @@ spurious results.`);
124462
124663
  }
124463
124664
  async returnNetAPY(baseAPYs, rewardAPYs, weights, prevAUMUSD) {
124464
124665
  if (weights.every((p) => p == 0)) {
124465
- return { net: 0, splits: [{
124466
- apy: 0,
124467
- id: "base"
124468
- }, {
124469
- apy: 0,
124470
- id: "defispring"
124471
- }] };
124666
+ return {
124667
+ net: 0,
124668
+ splits: [{
124669
+ apy: 0,
124670
+ id: "base"
124671
+ }, {
124672
+ apy: 0,
124673
+ id: "defispring"
124674
+ }]
124675
+ };
124472
124676
  }
124473
124677
  const baseAPY = this.computeAPY(baseAPYs, weights, prevAUMUSD);
124474
124678
  const rewardAPY = this.computeAPY(rewardAPYs, weights, prevAUMUSD);
124475
124679
  const netAPY = baseAPY + rewardAPY;
124476
124680
  logger2.verbose(`${this.metadata.name}::netAPY: net: ${netAPY}, baseAPY: ${baseAPY}, rewardAPY: ${rewardAPY}`);
124477
- return { net: netAPY, splits: [{
124478
- apy: baseAPY,
124479
- id: "base"
124480
- }, {
124481
- apy: rewardAPY,
124482
- id: "defispring"
124483
- }] };
124681
+ return {
124682
+ net: netAPY,
124683
+ splits: [{
124684
+ apy: baseAPY,
124685
+ id: "base"
124686
+ }, {
124687
+ apy: rewardAPY,
124688
+ id: "defispring"
124689
+ }]
124690
+ };
124484
124691
  }
124485
124692
  async getUnusedBalanceAPY() {
124486
124693
  return {
@@ -124494,104 +124701,6 @@ spurious results.`);
124494
124701
  logger2.verbose(`${this.getTag()} computeAPY: apys: ${JSON.stringify(apys)}, weights: ${JSON.stringify(weights)}, weightedSum: ${weightedSum}, currentAUM: ${currentAUM}`);
124495
124702
  return weightedSum / currentAUM.toNumber();
124496
124703
  }
124497
- /**
124498
- * Calculates user realized APY based on trueSharesBasedAPY method.
124499
- * Returns the APY as a number.
124500
- */
124501
- async getUserRealizedAPY(blockIdentifier = "latest", sinceBlocks = 6e5) {
124502
- logger2.verbose(
124503
- `${this.getTag()}: getUserRealizedAPY => starting with blockIdentifier=${blockIdentifier}, sinceBlocks=${sinceBlocks}`
124504
- );
124505
- let blockNow = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : (await this.config.provider.getBlockLatestAccepted()).block_number;
124506
- const blockNowTime = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
124507
- const blockBefore = Math.max(
124508
- blockNow - sinceBlocks,
124509
- this.metadata.launchBlock
124510
- );
124511
- const assetsNowRaw = await this.contract.call("total_assets", [], {
124512
- blockIdentifier
124513
- });
124514
- const amountNow = Web3Number.fromWei(
124515
- assetsNowRaw.toString(),
124516
- this.metadata.depositTokens[0].decimals
124517
- );
124518
- const supplyNowRaw = await this.contract.call("total_supply", [], {
124519
- blockIdentifier
124520
- });
124521
- const supplyNow = Web3Number.fromWei(supplyNowRaw.toString(), 18);
124522
- const assetsBeforeRaw = await this.contract.call(
124523
- "total_assets",
124524
- [],
124525
- { blockIdentifier: blockBefore }
124526
- );
124527
- const amountBefore = Web3Number.fromWei(
124528
- assetsBeforeRaw.toString(),
124529
- this.metadata.depositTokens[0].decimals
124530
- );
124531
- const supplyBeforeRaw = await this.contract.call(
124532
- "total_supply",
124533
- [],
124534
- { blockIdentifier: blockBefore }
124535
- );
124536
- const supplyBefore = Web3Number.fromWei(supplyBeforeRaw.toString(), 18);
124537
- const blockBeforeInfo = await this.config.provider.getBlockWithTxs(
124538
- blockBefore
124539
- );
124540
- const assetsPerShareNow = amountNow.multipliedBy(1e18).dividedBy(supplyNow.toString());
124541
- const assetsPerShareBf = amountBefore.multipliedBy(1e18).dividedBy(supplyBefore.toString());
124542
- const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
124543
- logger2.verbose(`${this.getTag()} [getUserRealizedAPY] assetsNow: ${amountNow.toString()}`);
124544
- logger2.verbose(`${this.getTag()} [getUserRealizedAPY] assetsBefore: ${amountBefore.toString()}`);
124545
- logger2.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareNow: ${assetsPerShareNow.toString()}`);
124546
- logger2.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareBf: ${assetsPerShareBf.toString()}`);
124547
- logger2.verbose(`${this.getTag()} [getUserRealizedAPY] Supply before: ${supplyBefore.toString()}`);
124548
- logger2.verbose(`${this.getTag()} [getUserRealizedAPY] Supply now: ${supplyNow.toString()}`);
124549
- logger2.verbose(`${this.getTag()} [getUserRealizedAPY] Time diff in seconds: ${timeDiffSeconds}`);
124550
- const apyForGivenBlocks = Number(
124551
- assetsPerShareNow.minus(assetsPerShareBf).multipliedBy(1e4).dividedBy(assetsPerShareBf)
124552
- ) / 1e4;
124553
- return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
124554
- }
124555
- async getUserPositionCards(input) {
124556
- const { user, investmentFlows = [] } = input;
124557
- const [userTVL] = await Promise.all([
124558
- this.getUserTVL(user)
124559
- ]);
124560
- const cards = [
124561
- {
124562
- title: "Your Holdings",
124563
- tooltip: "Your Holdings",
124564
- value: this.formatTokenAmountForCard(userTVL.amount, userTVL.tokenInfo),
124565
- subValue: `\u2248 ${this.formatUSDForCard(userTVL.usdValue)}`,
124566
- subValueColor: "positive"
124567
- }
124568
- ];
124569
- let lifetimeAmount = userTVL.amount.multipliedBy(0);
124570
- let lifetimeTokenInfo = userTVL.tokenInfo;
124571
- let lifetimeUsdValue = 0;
124572
- if (investmentFlows.length > 0) {
124573
- try {
124574
- const earningsResult = this.getLifetimeEarnings(userTVL, investmentFlows);
124575
- lifetimeAmount = earningsResult.lifetimeEarnings;
124576
- lifetimeTokenInfo = earningsResult.tokenInfo.tokenInfo;
124577
- const userAmount = userTVL.amount.toNumber();
124578
- if (Number.isFinite(userAmount) && userAmount > 0) {
124579
- const pricePerToken = userTVL.usdValue / userAmount;
124580
- lifetimeUsdValue = lifetimeAmount.toNumber() * pricePerToken;
124581
- }
124582
- } catch (error2) {
124583
- logger2.warn(`${this.getTag()}::getUserPositionCards lifetime earnings fallback`, error2);
124584
- }
124585
- }
124586
- cards.push({
124587
- title: "Lifetime Earnings",
124588
- tooltip: "Lifetime Earnings",
124589
- value: this.formatTokenAmountForCard(lifetimeAmount, lifetimeTokenInfo),
124590
- subValue: `\u2248 ${this.formatUSDForCard(lifetimeUsdValue)}`,
124591
- subValueColor: this.getSubValueColorFromSignedNumber(lifetimeUsdValue)
124592
- });
124593
- return cards;
124594
- }
124595
124704
  /**
124596
124705
  * Calculates the total TVL of the strategy.
124597
124706
  * @returns Object containing the total amount in token units and USD value
@@ -124668,13 +124777,17 @@ spurious results.`);
124668
124777
  };
124669
124778
  const aumToken = vesuAum.plus(balance.amount);
124670
124779
  if (aumToken.isZero()) {
124671
- return { net, splits: [{
124672
- aum: zeroAmt,
124673
- id: "finalised" /* FINALISED */
124674
- }, {
124675
- aum: zeroAmt,
124676
- id: "defispring" /* DEFISPRING */
124677
- }], prevAum };
124780
+ return {
124781
+ net,
124782
+ splits: [{
124783
+ aum: zeroAmt,
124784
+ id: "finalised" /* FINALISED */
124785
+ }, {
124786
+ aum: zeroAmt,
124787
+ id: "defispring" /* DEFISPRING */
124788
+ }],
124789
+ prevAum
124790
+ };
124678
124791
  }
124679
124792
  logger2.verbose(`${this.getTag()} Actual AUM: ${aumToken}`);
124680
124793
  const rewardAssets = await this.getRewardsAUM(prevAum);
@@ -125327,6 +125440,9 @@ spurious results.`);
125327
125440
  auditUrl: AUDIT_URL3,
125328
125441
  protocols: [Protocols.VESU],
125329
125442
  realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
125443
+ feeBps: {
125444
+ performanceFeeBps: 1e3
125445
+ },
125330
125446
  curator: UnwrapLabsCurator,
125331
125447
  settings: createUniversalSettings(params.tokenSymbol, params.maxTVLDecimals),
125332
125448
  contractDetails: getContractDetails(params.vaultSettings),
@@ -125965,11 +126081,15 @@ spurious results.`);
125965
126081
  remarks: "defispring" /* DEFISPRING */,
125966
126082
  protocol: Protocols.NONE
125967
126083
  };
125968
- return { net: {
125969
- tokenInfo: underlying,
125970
- amount: netAUM,
125971
- usdValue: netAUM.toNumber() * assetPrice.price
125972
- }, prevAum, splits: [realAUM, estimatedAUMDelta] };
126084
+ return {
126085
+ net: {
126086
+ tokenInfo: underlying,
126087
+ amount: netAUM,
126088
+ usdValue: netAUM.toNumber() * assetPrice.price
126089
+ },
126090
+ prevAum,
126091
+ splits: [realAUM, estimatedAUMDelta]
126092
+ };
125973
126093
  }
125974
126094
  async getTVLUnrealized() {
125975
126095
  return await this.getAUM(true);
@@ -125987,6 +126107,62 @@ spurious results.`);
125987
126107
  tokenInfo: this.asset()
125988
126108
  };
125989
126109
  }
126110
+ async getUserPositionCards(input) {
126111
+ const cards = await super.getUserPositionCards(input);
126112
+ try {
126113
+ const [unrealizedResult, userTVL, realizedApyRaw] = await Promise.all([
126114
+ this.getUserUnrealizedGains(input.user),
126115
+ this.getUserTVL(input.user),
126116
+ this.getUserRealizedAPY().catch(() => null)
126117
+ ]);
126118
+ const amount = unrealizedResult.unrealizedGains;
126119
+ let usdValue = 0;
126120
+ const userAmount = userTVL.amount.toNumber();
126121
+ if (Number.isFinite(userAmount) && userAmount > 0) {
126122
+ usdValue = userTVL.usdValue / userAmount * amount.toNumber();
126123
+ }
126124
+ cards.push({
126125
+ title: "Unrealized Gains",
126126
+ tooltip: "Unrealized gains based on current market prices vs Endur prices. If you withdraw now, you will forgo these gains.",
126127
+ value: this.formatTokenAmountForCard(amount, unrealizedResult.tokenInfo),
126128
+ subValue: `\u2248 ${this.formatUSDForCard(usdValue)}`,
126129
+ subValueColor: this.getSubValueColorFromSignedNumber(usdValue)
126130
+ });
126131
+ const realizedApy = typeof realizedApyRaw === "number" ? this.formatPercentForCard(realizedApyRaw) : "N/A";
126132
+ cards.push({
126133
+ title: "Realized APY",
126134
+ tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
126135
+ value: realizedApy
126136
+ });
126137
+ } catch (error2) {
126138
+ logger2.warn(`${this.getTag()}::getUserPositionCards unrealized gains fallback`, error2);
126139
+ cards.push({
126140
+ title: "Unrealized Gains",
126141
+ tooltip: "Unrealized gains based on current market prices vs Endur prices. If you withdraw now, you will forgo these gains.",
126142
+ value: this.formatTokenAmountForCard(
126143
+ Web3Number.fromWei("0", this.asset().decimals),
126144
+ this.asset()
126145
+ ),
126146
+ subValue: `\u2248 ${this.formatUSDForCard(0)}`,
126147
+ subValueColor: "default"
126148
+ });
126149
+ cards.push({
126150
+ title: "Realized APY",
126151
+ tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
126152
+ value: "N/A"
126153
+ });
126154
+ }
126155
+ if (this.asset().symbol === "xSTRK") {
126156
+ const index = cards.findIndex((card) => card.title === "Lifetime Earnings");
126157
+ if (index >= 0) {
126158
+ cards[index] = {
126159
+ ...cards[index],
126160
+ 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."
126161
+ };
126162
+ }
126163
+ }
126164
+ return cards;
126165
+ }
125990
126166
  };
125991
126167
  function VaultDescription(lstSymbol, underlyingSymbol) {
125992
126168
  const containerStyle = {
@@ -126394,6 +126570,9 @@ spurious results.`);
126394
126570
  isPreview,
126395
126571
  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.",
126396
126572
  realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
126573
+ feeBps: {
126574
+ performanceFeeBps: 1e3
126575
+ },
126397
126576
  tags: lstSymbol.includes("BTC") ? ["BTC" /* BTC */, "Maxx" /* LEVERED */] : ["Maxx" /* LEVERED */],
126398
126577
  security: HYPER_LST_SECURITY,
126399
126578
  redemptionInfo: HYPER_LST_REDEMPTION_INFO,
@@ -126606,6 +126785,23 @@ spurious results.`);
126606
126785
  usdValue
126607
126786
  };
126608
126787
  }
126788
+ async getUserPositionCards(input) {
126789
+ const cards = await super.getUserPositionCards(input);
126790
+ const realizedApyRaw = await this.getUserRealizedAPY().catch((error2) => {
126791
+ logger2.warn(
126792
+ `${this.getTag()}::getUserPositionCards realized APY fallback`,
126793
+ error2
126794
+ );
126795
+ return null;
126796
+ });
126797
+ const realizedApy = typeof realizedApyRaw === "number" ? this.formatPercentForCard(realizedApyRaw) : "N/A";
126798
+ cards.push({
126799
+ title: "Realized APY",
126800
+ tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
126801
+ value: realizedApy
126802
+ });
126803
+ return cards;
126804
+ }
126609
126805
  async getAUM() {
126610
126806
  const underlying = this.asset();
126611
126807
  const depositTokenPrice = await this.pricer.getPrice(underlying.symbol);
@@ -127195,15 +127391,15 @@ spurious results.`);
127195
127391
  question: "Which protocols are used?",
127196
127392
  answer: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
127197
127393
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Vesu" }),
127198
- " for collateral and borrowing, ",
127199
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Avnu" }),
127394
+ " for collateral and borrowing,",
127200
127395
  " ",
127201
- "for swaps, ",
127396
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Avnu" }),
127397
+ " for swaps, ",
127202
127398
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Endur" }),
127203
- " for ",
127204
- lstSymbol,
127205
- ", and the Troves",
127399
+ " for",
127206
127400
  " ",
127401
+ lstSymbol,
127402
+ ", and the Troves ",
127207
127403
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("strong", { children: [
127208
127404
  "Hyper-",
127209
127405
  lstSymbol
@@ -127291,6 +127487,9 @@ spurious results.`);
127291
127487
  ]
127292
127488
  },
127293
127489
  contractDetails: getContractDetails(settings2),
127490
+ feeBps: {
127491
+ performanceFeeBps: 1500
127492
+ },
127294
127493
  faqs: getBoostedCarryFAQs(
127295
127494
  depositToken.symbol,
127296
127495
  debtToken.symbol,