@1delta/margin-fetcher 0.0.275 → 0.0.277

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
@@ -5,7 +5,7 @@ import { Lender, isAaveType, isCompoundV3, isMultiMarket, isSiloV2Type, isSiloV3
5
5
  export { isAaveType, isAaveV2Type, isAaveV32Type, isAaveV3Type, isCompoundV3, isCompoundV3Type, isInit, isMorphoType, isMultiMarket, isYLDR } from '@1delta/lender-registry';
6
6
  import lodash from 'lodash';
7
7
  import { getEvmChain, getEvmClient, getEvmClientUniversal, multicallRetryUniversal, getEvmClientWithCustomRpcsUniversal } from '@1delta/providers';
8
- import { FluidLendingResolverAbi, FluidVaultResolverAbi, MetaMorphoAbi, MoolahVaultAbi, MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, DolomiteMarginAbi, GearboxMarketCompressorV310Abi, MorphoBlueAbi, GearboxCreditAccountCompressorV310Abi } from '@1delta/abis';
8
+ import { MetaMorphoAbi, FluidLendingResolverAbi, FluidVaultResolverAbi, MoolahVaultAbi, MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, DolomiteMarginAbi, GearboxMarketCompressorV310Abi, MorphoBlueAbi, GearboxCreditAccountCompressorV310Abi } from '@1delta/abis';
9
9
  export { MorphoLensAbi } from '@1delta/abis';
10
10
  import { prepareDebitDataMulticall, prepareLenderDebitMulticall, parseDebitDataResult, parseLenderDebitResult, getPermit2ContractAddress, getCompoundV3CometAddress as getCompoundV3CometAddress$1, getMorphoAddress, getAaveCollateralTokenAddress, getSiloHalfForUnderlying, InitMarginAddresses, getLstAcceptedInputs } from '@1delta/calldata-sdk';
11
11
  import { proxyNativeFetch } from '@1delta/proxy-fetch';
@@ -35891,6 +35891,20 @@ var buildGearboxV3PoolsCall = (chainId) => {
35891
35891
  ];
35892
35892
  };
35893
35893
 
35894
+ // src/vaults/sharePrice.ts
35895
+ function deriveConvertToAssets(totalAssetsRaw, totalSupplyRaw, shareDecimals) {
35896
+ try {
35897
+ const ta = BigInt(totalAssetsRaw ?? 0);
35898
+ const ts = BigInt(totalSupplyRaw ?? 0);
35899
+ if (ts <= 0n) return "0";
35900
+ const dec = Math.max(0, Math.round(Number(shareDecimals) || 0));
35901
+ const probe = 10n ** BigInt(dec);
35902
+ return (ta * probe / ts).toString();
35903
+ } catch {
35904
+ return "0";
35905
+ }
35906
+ }
35907
+
35894
35908
  // src/vaults/gearbox/publicCallParse.ts
35895
35909
  var WETH_MAINNET = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";
35896
35910
  var normalizeUnderlying6 = (addr, chainId) => {
@@ -35928,9 +35942,15 @@ function parseMarkets(markets, chainId, prices, tokenList) {
35928
35942
  const assetMeta = tokenList[underlying];
35929
35943
  const decimals = Number(assetMeta?.decimals ?? pool.decimals ?? 18);
35930
35944
  const totalAssetsRaw = pool.expectedLiquidity?.toString() ?? "0";
35945
+ const totalSupplyRaw = pool.totalSupply?.toString() ?? "0";
35931
35946
  const totalAssetsFormatted = Number(
35932
35947
  parseRawAmount(totalAssetsRaw, decimals)
35933
35948
  );
35949
+ const convertToAssets = deriveConvertToAssets(
35950
+ totalAssetsRaw,
35951
+ totalSupplyRaw,
35952
+ decimals
35953
+ );
35934
35954
  const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(underlying, chainId);
35935
35955
  const priceUsd = prices[oracleKey] ?? prices[underlying] ?? 0;
35936
35956
  const liquidityRaw = pool.availableLiquidity?.toString() ?? "0";
@@ -35950,7 +35970,8 @@ function parseMarkets(markets, chainId, prices, tokenList) {
35950
35970
  ),
35951
35971
  decimals,
35952
35972
  totalAssets: totalAssetsRaw,
35953
- totalSupply: pool.totalSupply?.toString() ?? "0",
35973
+ totalSupply: totalSupplyRaw,
35974
+ convertToAssets,
35954
35975
  totalBorrowed: pool.totalBorrowed?.toString() ?? "0",
35955
35976
  availableLiquidity: pool.availableLiquidity?.toString() ?? "0",
35956
35977
  expectedLiquidity: pool.expectedLiquidity?.toString() ?? "0",
@@ -35985,6 +36006,7 @@ var fetchGearboxV3Pools = async (chainId, multicallRetry, prices = {}, tokenList
35985
36006
  };
35986
36007
 
35987
36008
  // src/vaults/morpho/fetchFromApi.ts
36009
+ var MORPHO_SHARE_DECIMALS = 18;
35988
36010
  var MORPHO_API_URL = "https://blue-api.morpho.org/graphql";
35989
36011
  var PAGE_SIZE = 200;
35990
36012
  var vaultsQuery = (first, skip, chainId) => `
@@ -36091,7 +36113,13 @@ function parseVault2(v, chainId, prices, tokenList) {
36091
36113
  const assetMeta = tokenList[assetAddr];
36092
36114
  const decimals = Number(v.asset?.decimals ?? assetMeta?.decimals ?? 18);
36093
36115
  const totalAssetsRaw = state.totalAssets?.toString() ?? "0";
36116
+ const totalSupplyRaw = state.totalSupply?.toString() ?? "0";
36094
36117
  const totalAssetsFormatted = Number(parseRawAmount(totalAssetsRaw, decimals));
36118
+ const convertToAssets = deriveConvertToAssets(
36119
+ totalAssetsRaw,
36120
+ totalSupplyRaw,
36121
+ MORPHO_SHARE_DECIMALS
36122
+ );
36095
36123
  const liquidityRaw = v.liquidity?.underlying?.toString() ?? "0";
36096
36124
  const liquidityFormatted = Number(parseRawAmount(liquidityRaw, decimals));
36097
36125
  const liquidityUsd = Number(v.liquidity?.usd ?? 0);
@@ -36118,7 +36146,8 @@ function parseVault2(v, chainId, prices, tokenList) {
36118
36146
  ),
36119
36147
  decimals,
36120
36148
  totalAssets: totalAssetsRaw,
36121
- totalSupply: state.totalSupply?.toString() ?? "0",
36149
+ totalSupply: totalSupplyRaw,
36150
+ convertToAssets,
36122
36151
  supplyRate,
36123
36152
  rewardsRate,
36124
36153
  depositRate: supplyRate + rewardsRate,
@@ -36247,6 +36276,52 @@ function computeVaultAllocation(vaultAddress, decimals, totalAssetsFormatted, fe
36247
36276
  liquidityFormatted: Math.min(totalAssetsFormatted, idle + withdrawable)
36248
36277
  };
36249
36278
  }
36279
+ function computeV2Allocation(decimals, totalAssetsFormatted, feePercent, priceUsd, marketAssetsRaw, rateMap, tokenList, uidCtx) {
36280
+ if (totalAssetsFormatted <= 0) {
36281
+ return { depositRate: 0, exposures: [], liquidityFormatted: 0 };
36282
+ }
36283
+ if (marketAssetsRaw.size === 0) {
36284
+ return {
36285
+ depositRate: 0,
36286
+ exposures: withIdleExposure([], totalAssetsFormatted, priceUsd),
36287
+ liquidityFormatted: totalAssetsFormatted
36288
+ };
36289
+ }
36290
+ let weighted = 0;
36291
+ let allocated = 0;
36292
+ let withdrawable = 0;
36293
+ const exposures = [];
36294
+ for (const [id, assetsRaw] of marketAssetsRaw) {
36295
+ const allocAssets = Number(parseRawAmount(assetsRaw.toString(), decimals));
36296
+ if (allocAssets <= 0) continue;
36297
+ const rate = rateMap.get(id);
36298
+ allocated += allocAssets;
36299
+ const supplyApr = rate?.supplyApr ?? 0;
36300
+ weighted += allocAssets * supplyApr;
36301
+ const marketLiquidity = rate?.liquidity != null ? Number(parseRawAmount(rate.liquidity.toString(), decimals)) : allocAssets;
36302
+ withdrawable += Math.min(allocAssets, Math.max(0, marketLiquidity));
36303
+ const marketUid = marketUidFor(uidCtx, id);
36304
+ const collateralAddress = rate?.collateralAddress ?? "";
36305
+ exposures.push({
36306
+ marketId: id,
36307
+ ...marketUid ? { marketUid } : {},
36308
+ collateralAddress,
36309
+ collateral: collateralAddress ? tokenList[collateralAddress] : void 0,
36310
+ assets: allocAssets,
36311
+ assetsUsd: allocAssets * priceUsd,
36312
+ weightPct: allocAssets / totalAssetsFormatted * 100,
36313
+ supplyApr
36314
+ });
36315
+ }
36316
+ exposures.sort((a, b) => b.weightPct - a.weightPct);
36317
+ const grossApr = weighted / totalAssetsFormatted;
36318
+ const idle = Math.max(0, totalAssetsFormatted - allocated);
36319
+ return {
36320
+ depositRate: grossApr * (1 - feePercent / 100),
36321
+ exposures: withIdleExposure(exposures, totalAssetsFormatted, priceUsd),
36322
+ liquidityFormatted: Math.min(totalAssetsFormatted, idle + withdrawable)
36323
+ };
36324
+ }
36250
36325
 
36251
36326
  // src/vaults/morpho/fetchFromChain.ts
36252
36327
  var { chunk: chunk5 } = lodash;
@@ -36263,13 +36338,36 @@ var VAULT_CALLS = [
36263
36338
  "guardian"
36264
36339
  ];
36265
36340
  var CALLS_PER_VAULT = VAULT_CALLS.length;
36266
- var PHASE1_CALLS = [...VAULT_CALLS, "withdrawQueueLength"];
36341
+ var PHASE1_CALLS = [
36342
+ ...VAULT_CALLS,
36343
+ "withdrawQueueLength",
36344
+ // V1 (MetaMorpho) — reverts on V2
36345
+ "adaptersLength",
36346
+ // V2 (Vaults V2) — reverts on V1
36347
+ "performanceFee"
36348
+ // V2 fee getter (V1 uses `fee()`)
36349
+ ];
36267
36350
  var PHASE1_PER_VAULT = PHASE1_CALLS.length;
36268
36351
  var WITHDRAW_QUEUE_LENGTH_INDEX = CALLS_PER_VAULT;
36352
+ var ADAPTERS_LENGTH_INDEX = CALLS_PER_VAULT + 1;
36353
+ var PERFORMANCE_FEE_INDEX = CALLS_PER_VAULT + 2;
36269
36354
  var MORPHO_LENS_ABI = parseAbi([
36270
36355
  "function getMarketDataCompact(address morpho, bytes32[] calldata marketsIds) external view returns (bytes memory data)"
36271
36356
  ]);
36272
36357
  var MARKET_CHUNK = 100;
36358
+ var VAULT_V2_PHASE1_ABI = parseAbi([
36359
+ "function adaptersLength() view returns (uint256)",
36360
+ "function performanceFee() view returns (uint96)"
36361
+ ]);
36362
+ var VAULT_V2_ABI = parseAbi([
36363
+ "function adapters(uint256) view returns (address)"
36364
+ ]);
36365
+ var VAULT_V2_ADAPTER_ABI = parseAbi([
36366
+ "function marketIdsLength() view returns (uint256)",
36367
+ "function marketIds(uint256) view returns (bytes32)",
36368
+ "function expectedSupplyAssets(bytes32) view returns (uint256)"
36369
+ ]);
36370
+ var PHASE1_ABI = [...MetaMorphoAbi, ...VAULT_V2_PHASE1_ABI];
36273
36371
  var FEE_SCALE = 1e18;
36274
36372
  var isHex40 = (addr) => typeof addr === "string" && /^0x[0-9a-f]{40}$/i.test(addr);
36275
36373
  var isHex64 = (v) => typeof v === "string" && /^0x[0-9a-f]{64}$/i.test(v);
@@ -36283,6 +36381,17 @@ var toStringSafe = (raw, fallback = "") => {
36283
36381
  if (raw === void 0 || raw === null) return fallback;
36284
36382
  return String(raw);
36285
36383
  };
36384
+ var toBigIntSafe2 = (raw) => {
36385
+ if (raw === void 0 || raw === null) return void 0;
36386
+ try {
36387
+ if (typeof raw === "bigint") return raw;
36388
+ if (typeof raw === "number") return BigInt(Math.trunc(raw));
36389
+ if (typeof raw === "string" && /^\d+$/.test(raw)) return BigInt(raw);
36390
+ return void 0;
36391
+ } catch {
36392
+ return void 0;
36393
+ }
36394
+ };
36286
36395
  var toRawAmount = (formatted, decimals) => {
36287
36396
  try {
36288
36397
  return parseUnits(formatted.toFixed(decimals), decimals).toString();
@@ -36321,10 +36430,19 @@ var fetchMorphoVaultsFromChain = async (chainId, multicallRetry, prices = {}, to
36321
36430
  const phase1 = await multicallRetry({
36322
36431
  chain: chainId,
36323
36432
  calls: phase1Calls,
36324
- abi: phase1Calls.map(() => MetaMorphoAbi),
36433
+ abi: phase1Calls.map(() => PHASE1_ABI),
36325
36434
  allowFailure: true
36326
36435
  });
36436
+ const adapterLens = entries.map(
36437
+ (_3, i) => Number(phase1[i * PHASE1_PER_VAULT + ADAPTERS_LENGTH_INDEX])
36438
+ );
36439
+ const isV2 = entries.map(({ entry }, i) => {
36440
+ if (entry.version === "v2") return true;
36441
+ if (entry.version === "v1") return false;
36442
+ return Number.isFinite(adapterLens[i]);
36443
+ });
36327
36444
  const queueLens = entries.map((_3, i) => {
36445
+ if (isV2[i]) return 0;
36328
36446
  const n = Number(phase1[i * PHASE1_PER_VAULT + WITHDRAW_QUEUE_LENGTH_INDEX]);
36329
36447
  return Number.isFinite(n) && n > 0 ? n : 0;
36330
36448
  });
@@ -36368,11 +36486,41 @@ var fetchMorphoVaultsFromChain = async (chainId, multicallRetry, prices = {}, to
36368
36486
  ),
36369
36487
  fetchAssetDecimals(chainId, underlyings, multicallRetry)
36370
36488
  ]);
36489
+ const resolveDecimals = (i) => {
36490
+ const { entry } = entries[i];
36491
+ const underlying = entry.underlying?.toLowerCase() ?? "";
36492
+ const decimalsRaw = phase1[i * PHASE1_PER_VAULT + 2];
36493
+ return assetDecimals.get(underlying) ?? tokenList[underlying]?.decimals ?? Number(decimalsRaw ?? 18);
36494
+ };
36495
+ const v2Inputs = entries.map(({ entry }, i) => ({ entry, i })).filter(({ i }) => isV2[i]).map(({ entry, i }) => {
36496
+ const decimals = resolveDecimals(i);
36497
+ const underlying = entry.underlying?.toLowerCase() ?? "";
36498
+ const totalAssets = toStringSafe(phase1[i * PHASE1_PER_VAULT + 3], "0");
36499
+ const oracleKey = toOracleKey(tokenList[underlying]?.assetGroup) ?? toGenericPriceKey(underlying, chainId);
36500
+ return {
36501
+ vault: entry.vault.toLowerCase(),
36502
+ underlying,
36503
+ decimals,
36504
+ totalAssetsFormatted: Number(parseRawAmount(totalAssets, decimals)),
36505
+ feePercent: toNumberSafe(phase1[i * PHASE1_PER_VAULT + PERFORMANCE_FEE_INDEX]) / FEE_SCALE * 100,
36506
+ priceUsd: prices[oracleKey] ?? prices[underlying] ?? 0,
36507
+ adaptersLength: Math.max(0, Math.trunc(adapterLens[i]) || 0)
36508
+ };
36509
+ });
36510
+ const v2ByVault = await fetchV2Allocations(
36511
+ chainId,
36512
+ multicallRetry,
36513
+ v2Inputs,
36514
+ core,
36515
+ tokenList
36516
+ );
36371
36517
  const out = {};
36372
36518
  for (let i = 0; i < entries.length; i++) {
36373
36519
  const { entry } = entries[i];
36374
36520
  const base = i * PHASE1_PER_VAULT;
36375
36521
  const slice = phase1.slice(base, base + CALLS_PER_VAULT);
36522
+ const v2 = isV2[i] ? v2ByVault.get(entry.vault.toLowerCase()) ?? null : null;
36523
+ const v2FeePercent = isV2[i] ? toNumberSafe(phase1[base + PERFORMANCE_FEE_INDEX]) / FEE_SCALE * 100 : void 0;
36376
36524
  const parsed = parseVault3(
36377
36525
  entry,
36378
36526
  slice,
@@ -36382,12 +36530,132 @@ var fetchMorphoVaultsFromChain = async (chainId, multicallRetry, prices = {}, to
36382
36530
  marketIdsByVault[i],
36383
36531
  rateMap,
36384
36532
  positionMap,
36385
- assetDecimals
36533
+ assetDecimals,
36534
+ v2,
36535
+ v2FeePercent
36386
36536
  );
36387
36537
  if (parsed) out[parsed.address] = parsed;
36388
36538
  }
36389
36539
  return out;
36390
36540
  };
36541
+ async function fetchV2Allocations(chainId, multicallRetry, v2, core, tokenList) {
36542
+ const out = /* @__PURE__ */ new Map();
36543
+ if (v2.length === 0) return out;
36544
+ const aCalls = [];
36545
+ const aVaultIdx = [];
36546
+ v2.forEach((v, vi) => {
36547
+ for (let a = 0; a < v.adaptersLength; a++) {
36548
+ aCalls.push({ address: v.vault, name: "adapters", params: [BigInt(a)] });
36549
+ aVaultIdx.push(vi);
36550
+ }
36551
+ });
36552
+ const adaptersByVault = v2.map(() => []);
36553
+ if (aCalls.length > 0) {
36554
+ const aRes = await multicallRetry({
36555
+ chain: chainId,
36556
+ calls: aCalls,
36557
+ abi: aCalls.map(() => VAULT_V2_ABI),
36558
+ allowFailure: true
36559
+ });
36560
+ aRes.forEach((r, k) => {
36561
+ if (isHex40(r)) adaptersByVault[aVaultIdx[k]].push(r.toLowerCase());
36562
+ });
36563
+ }
36564
+ const allAdapters = [...new Set(adaptersByVault.flat())];
36565
+ if (allAdapters.length === 0) return out;
36566
+ const bRes = await multicallRetry({
36567
+ chain: chainId,
36568
+ calls: allAdapters.map((a) => ({
36569
+ address: a,
36570
+ name: "marketIdsLength",
36571
+ params: []
36572
+ })),
36573
+ abi: allAdapters.map(() => VAULT_V2_ADAPTER_ABI),
36574
+ allowFailure: true
36575
+ });
36576
+ const mkLen = /* @__PURE__ */ new Map();
36577
+ allAdapters.forEach((a, i) => {
36578
+ const n = Number(bRes[i]);
36579
+ mkLen.set(a, Number.isFinite(n) && n > 0 ? n : 0);
36580
+ });
36581
+ const cCalls = [];
36582
+ const cAdapter = [];
36583
+ for (const a of allAdapters) {
36584
+ for (let j = 0; j < (mkLen.get(a) ?? 0); j++) {
36585
+ cCalls.push({ address: a, name: "marketIds", params: [BigInt(j)] });
36586
+ cAdapter.push(a);
36587
+ }
36588
+ }
36589
+ const marketIdsByAdapter = new Map(
36590
+ allAdapters.map((a) => [a, []])
36591
+ );
36592
+ if (cCalls.length > 0) {
36593
+ const cRes = await multicallRetry({
36594
+ chain: chainId,
36595
+ calls: cCalls,
36596
+ abi: cCalls.map(() => VAULT_V2_ADAPTER_ABI),
36597
+ allowFailure: true
36598
+ });
36599
+ cRes.forEach((r, k) => {
36600
+ if (isHex64(r)) marketIdsByAdapter.get(cAdapter[k]).push(r.toLowerCase());
36601
+ });
36602
+ }
36603
+ const dCalls = [];
36604
+ const dMeta = [];
36605
+ for (const a of allAdapters) {
36606
+ for (const mid of marketIdsByAdapter.get(a) ?? []) {
36607
+ dCalls.push({ address: a, name: "expectedSupplyAssets", params: [mid] });
36608
+ dMeta.push({ adapter: a, mid });
36609
+ }
36610
+ }
36611
+ const assetsByAdapter = /* @__PURE__ */ new Map();
36612
+ if (dCalls.length > 0) {
36613
+ const dRes = await multicallRetry({
36614
+ chain: chainId,
36615
+ calls: dCalls,
36616
+ abi: dCalls.map(() => VAULT_V2_ADAPTER_ABI),
36617
+ allowFailure: true
36618
+ });
36619
+ dRes.forEach((r, k) => {
36620
+ const v = toBigIntSafe2(r);
36621
+ if (v === void 0) return;
36622
+ const { adapter, mid } = dMeta[k];
36623
+ if (!assetsByAdapter.has(adapter)) assetsByAdapter.set(adapter, /* @__PURE__ */ new Map());
36624
+ assetsByAdapter.get(adapter).set(mid, v);
36625
+ });
36626
+ }
36627
+ const allMids = [...new Set([...marketIdsByAdapter.values()].flat())];
36628
+ const rateMap = await fetchMorphoMarketRates(
36629
+ chainId,
36630
+ core,
36631
+ allMids,
36632
+ multicallRetry
36633
+ );
36634
+ v2.forEach((v, vi) => {
36635
+ const marketAssetsRaw = /* @__PURE__ */ new Map();
36636
+ for (const a of adaptersByVault[vi]) {
36637
+ const m = assetsByAdapter.get(a);
36638
+ if (!m) continue;
36639
+ for (const [mid, amt] of m) {
36640
+ marketAssetsRaw.set(mid, (marketAssetsRaw.get(mid) ?? 0n) + amt);
36641
+ }
36642
+ }
36643
+ out.set(
36644
+ v.vault,
36645
+ computeV2Allocation(
36646
+ v.decimals,
36647
+ v.totalAssetsFormatted,
36648
+ v.feePercent,
36649
+ v.priceUsd,
36650
+ marketAssetsRaw,
36651
+ rateMap,
36652
+ tokenList,
36653
+ { chainId, underlying: v.underlying, protocol: "MORPHO_BLUE" }
36654
+ )
36655
+ );
36656
+ });
36657
+ return out;
36658
+ }
36391
36659
  async function fetchMorphoMarketRates(chainId, core, marketIds, multicallRetry) {
36392
36660
  const map = /* @__PURE__ */ new Map();
36393
36661
  const lens = MORPHO_LENS[chainId];
@@ -36443,7 +36711,7 @@ async function fetchMorphoMarketRates(chainId, core, marketIds, multicallRetry)
36443
36711
  });
36444
36712
  return map;
36445
36713
  }
36446
- function parseVault3(entry, results, chainId, prices, tokenList, marketIds, rateMap, positionMap, assetDecimals) {
36714
+ function parseVault3(entry, results, chainId, prices, tokenList, marketIds, rateMap, positionMap, assetDecimals, v2Allocation, v2FeePercent) {
36447
36715
  const address = entry?.vault?.toLowerCase();
36448
36716
  const underlying = entry?.underlying?.toLowerCase();
36449
36717
  if (!address || !underlying) return null;
@@ -36464,14 +36732,19 @@ function parseVault3(entry, results, chainId, prices, tokenList, marketIds, rate
36464
36732
  const totalAssets = toStringSafe(totalAssetsRaw, "0");
36465
36733
  const totalSupply = toStringSafe(totalSupplyRaw, "0");
36466
36734
  const totalAssetsFormatted = Number(parseRawAmount(totalAssets, decimals));
36735
+ const convertToAssets = deriveConvertToAssets(
36736
+ totalAssets,
36737
+ totalSupply,
36738
+ Number(decimalsRaw ?? 18)
36739
+ );
36467
36740
  const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(underlying, chainId);
36468
36741
  const priceUsd = prices[oracleKey] ?? prices[underlying] ?? 0;
36469
36742
  const onchainName = toStringSafe(nameRaw).trim();
36470
36743
  const fallbackName = onchainName || (entry.name ?? "").trim();
36471
36744
  const symbol = toStringSafe(symbolRaw);
36472
- const fee = toNumberSafe(feeRaw) / FEE_SCALE * 100;
36745
+ const fee = v2FeePercent !== void 0 ? v2FeePercent : toNumberSafe(feeRaw) / FEE_SCALE * 100;
36473
36746
  const timelock = toNumberSafe(timelockRaw);
36474
- const { depositRate, exposures, liquidityFormatted } = computeVaultAllocation(
36747
+ const { depositRate, exposures, liquidityFormatted } = v2Allocation ?? computeVaultAllocation(
36475
36748
  address,
36476
36749
  decimals,
36477
36750
  totalAssetsFormatted,
@@ -36497,6 +36770,7 @@ function parseVault3(entry, results, chainId, prices, tokenList, marketIds, rate
36497
36770
  decimals,
36498
36771
  totalAssets,
36499
36772
  totalSupply,
36773
+ convertToAssets,
36500
36774
  supplyRate: depositRate,
36501
36775
  rewardsRate: 0,
36502
36776
  depositRate,
@@ -36845,6 +37119,11 @@ function parseVault4(entry, results, curatorAddrRaw, chainId, prices, tokenList,
36845
37119
  const totalAssets = toStringSafe2(totalAssetsRaw, "0");
36846
37120
  const totalSupply = toStringSafe2(totalSupplyRaw, "0");
36847
37121
  const totalAssetsFormatted = Number(parseRawAmount(totalAssets, decimals));
37122
+ const convertToAssets = deriveConvertToAssets(
37123
+ totalAssets,
37124
+ totalSupply,
37125
+ Number(decimalsRaw ?? 18)
37126
+ );
36848
37127
  const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(underlying, chainId);
36849
37128
  const priceUsd = prices[oracleKey] ?? prices[underlying] ?? 0;
36850
37129
  const onchainName = toStringSafe2(nameRaw).trim();
@@ -36877,6 +37156,7 @@ function parseVault4(entry, results, curatorAddrRaw, chainId, prices, tokenList,
36877
37156
  decimals,
36878
37157
  totalAssets,
36879
37158
  totalSupply,
37159
+ convertToAssets,
36880
37160
  supplyRate: depositRate,
36881
37161
  rewardsRate: 0,
36882
37162
  depositRate,
@@ -37020,6 +37300,11 @@ function parseVault5(v, chainId, prices, tokenList, exposures, liquidityFormatte
37020
37300
  const totalAssetsFormatted = Number(v.totalAssets ?? 0) || 0;
37021
37301
  const totalAssetsRaw = toRawAmount3(v.totalAssets, decimals);
37022
37302
  const totalSupplyRaw = toRawAmount3(v.totalSupply, decimals);
37303
+ const convertToAssets = deriveConvertToAssets(
37304
+ totalAssetsRaw,
37305
+ totalSupplyRaw,
37306
+ decimals
37307
+ );
37023
37308
  const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(assetAddr, chainId);
37024
37309
  const priceUsd = prices[oracleKey] ?? prices[assetAddr] ?? 0;
37025
37310
  const supplyRate = Number(v.userApr ?? 0) || 0;
@@ -37044,6 +37329,7 @@ function parseVault5(v, chainId, prices, tokenList, exposures, liquidityFormatte
37044
37329
  protocolId: (v.protocolId ?? v.protocol?.id ?? "").toLowerCase(),
37045
37330
  totalAssets: totalAssetsRaw,
37046
37331
  totalSupply: totalSupplyRaw,
37332
+ convertToAssets,
37047
37333
  supplyRate,
37048
37334
  grossRate,
37049
37335
  rewardsRate: 0,
@@ -37283,6 +37569,11 @@ function parseVault6(v, chainId, prices, tokenList, evkIndex) {
37283
37569
  evkIndex
37284
37570
  );
37285
37571
  const totalSupplyRaw = v.totalSupply?.toString() ?? v.totalShares?.toString() ?? "0";
37572
+ const convertToAssets = deriveConvertToAssets(
37573
+ totalAssetsRaw,
37574
+ totalSupplyRaw,
37575
+ decimals
37576
+ );
37286
37577
  const liquidityBig = computeRealLiquidity(
37287
37578
  v.strategies,
37288
37579
  totalAssetsRaw,
@@ -37298,6 +37589,7 @@ function parseVault6(v, chainId, prices, tokenList, evkIndex) {
37298
37589
  decimals,
37299
37590
  totalAssets: totalAssetsRaw,
37300
37591
  totalSupply: totalSupplyRaw,
37592
+ convertToAssets,
37301
37593
  supplyRate,
37302
37594
  rewardsRate: 0,
37303
37595
  depositRate: supplyRate,
@@ -38577,6 +38869,8 @@ var LST_REGISTRY = {
38577
38869
  // stake PoL assets in an Infrared vault). Exit is DEX-only.
38578
38870
  address: "0xac03caba51e17c86c921e1f6cbfbdc91f8bb2e6b",
38579
38871
  underlying: "0x656b95e550c07a9ffe548bd4085c72418ceb1dba",
38872
+ // BGT is unpriced; the wrapper is 1:1 redeemable to BERA → price via WBERA.
38873
+ priceUnderlying: "0x6969696969696969696969696969696969696969",
38580
38874
  symbol: "iBGT",
38581
38875
  brand: "Infrared",
38582
38876
  decimals: 18,
@@ -38597,6 +38891,8 @@ var LST_REGISTRY = {
38597
38891
  // queue that pays out native BERA (via BGT.redeem).
38598
38892
  address: "0xbaadcc2962417c01af99fb2b7c75706b9bd6babe",
38599
38893
  underlying: "0x656b95e550c07a9ffe548bd4085c72418ceb1dba",
38894
+ // BGT is unpriced; the wrapper is 1:1 redeemable to BERA → price via WBERA.
38895
+ priceUnderlying: "0x6969696969696969696969696969696969696969",
38600
38896
  symbol: "LBGT",
38601
38897
  brand: "BeraPaw",
38602
38898
  decimals: 18,
@@ -38618,6 +38914,8 @@ var LST_REGISTRY = {
38618
38914
  // native BERA (minus fee).
38619
38915
  address: "0x7e768f47dfdd5dae874aac233f1bc5817137e453",
38620
38916
  underlying: "0x656b95e550c07a9ffe548bd4085c72418ceb1dba",
38917
+ // BGT is unpriced; the wrapper is 1:1 redeemable to BERA → price via WBERA.
38918
+ priceUnderlying: "0x6969696969696969696969696969696969696969",
38621
38919
  symbol: "yBGT",
38622
38920
  brand: "Bearn",
38623
38921
  decimals: 18,
@@ -38636,6 +38934,8 @@ var LST_REGISTRY = {
38636
38934
  // redeem path is unverified, so treated as DEX-only exit.
38637
38935
  address: "0x2cec7f1ac87f5345ced3d6c74bbb61bfae231ffb",
38638
38936
  underlying: "0x656b95e550c07a9ffe548bd4085c72418ceb1dba",
38937
+ // BGT is unpriced; the wrapper is 1:1 redeemable to BERA → price via WBERA.
38938
+ priceUnderlying: "0x6969696969696969696969696969696969696969",
38639
38939
  symbol: "stBGT",
38640
38940
  brand: "Stride",
38641
38941
  decimals: 18,
@@ -40242,7 +40542,7 @@ var fetchLstShareTokens = async (chainId, multicallRetry, prices = {}, tokenList
40242
40542
  const addressLc = entry.address.toLowerCase();
40243
40543
  const underlyingLc = entry.underlying.toLowerCase();
40244
40544
  const asset = tokenList[underlyingLc];
40245
- const priceUsd = prices[underlyingLc];
40545
+ const priceUsd = prices[entry.priceUnderlying?.toLowerCase() ?? underlyingLc];
40246
40546
  const supplyRate = aprByAddress[addressLc] ?? 0;
40247
40547
  const rewardsRate = 0;
40248
40548
  const depositRate = supplyRate + rewardsRate;
@@ -44434,10 +44734,12 @@ var classifyVault = (input) => {
44434
44734
  const denomination = isStablecoinSymbol(input.underlyingSymbol) ? "stable" : "volatile";
44435
44735
  return { yieldProfile, denomination };
44436
44736
  };
44437
- var stampVaultClassification = (data, chainId) => {
44737
+ var stampVaultClassification = (data, chainId, tokenList = {}) => {
44438
44738
  const stampBag = (bag, provider) => {
44439
44739
  if (!bag) return;
44440
44740
  for (const v of Object.values(bag)) {
44741
+ const shareAsset = tokenList[v.address?.toLowerCase?.() ?? ""];
44742
+ if (shareAsset) v.shareAsset = shareAsset;
44441
44743
  const c = classifyVault({
44442
44744
  provider,
44443
44745
  chainId,
@@ -44446,6 +44748,18 @@ var stampVaultClassification = (data, chainId) => {
44446
44748
  });
44447
44749
  v.yieldProfile = c.yieldProfile;
44448
44750
  v.denomination = c.denomination;
44751
+ const raw = v.convertToAssets ?? v.pricePerShare;
44752
+ if (raw != null) {
44753
+ v.sharePriceRaw = raw;
44754
+ const assetDec = v.assetDecimals ?? v.decimals;
44755
+ if (assetDec != null) {
44756
+ const formatted = Number(raw) / 10 ** assetDec;
44757
+ if (Number.isFinite(formatted)) {
44758
+ v.sharePrice = formatted;
44759
+ if (v.priceUsd != null) v.sharePriceUSD = formatted * v.priceUsd;
44760
+ }
44761
+ }
44762
+ }
44449
44763
  }
44450
44764
  };
44451
44765
  stampBag(data.fluid, "fluid");
@@ -45718,7 +46032,10 @@ function buildVaultLookup(data) {
45718
46032
  // Carried through from `stampVaultClassification` (set on the
45719
46033
  // provider objects before the lookup is built).
45720
46034
  yieldProfile: v.yieldProfile,
45721
- denomination: v.denomination
46035
+ denomination: v.denomination,
46036
+ sharePriceRaw: v.sharePriceRaw,
46037
+ sharePrice: v.sharePrice,
46038
+ sharePriceUSD: v.sharePriceUSD
45722
46039
  });
45723
46040
  }
45724
46041
  };
@@ -45906,7 +46223,7 @@ var getVaultPublicDataAll = async (chainId, providers, multicallRetry, prices =
45906
46223
  );
45907
46224
  }
45908
46225
  await Promise.all(tasks);
45909
- stampVaultClassification(out, chainId);
46226
+ stampVaultClassification(out, chainId, tokenList);
45910
46227
  return { data: out, lookup: buildVaultLookup(out) };
45911
46228
  };
45912
46229