@1delta/margin-fetcher 0.0.271 → 0.0.273

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, MorphoBlueAbi, MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, DolomiteMarginAbi, GearboxMarketCompressorV310Abi, GearboxCreditAccountCompressorV310Abi } from '@1delta/abis';
8
+ import { FluidLendingResolverAbi, FluidVaultResolverAbi, MetaMorphoAbi, 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';
@@ -11123,7 +11123,8 @@ var MORPHO_LENS = {
11123
11123
  [Chain.CORN]: "0x8E24CfC19c6C00c524353CB8816f5f1c2F33c201",
11124
11124
  [Chain.LISK]: "0x8E24CfC19c6C00c524353CB8816f5f1c2F33c201",
11125
11125
  [Chain.ABSTRACT]: "0x8e24cfc19c6c00c524353cb8816f5f1c2f33c201",
11126
- [Chain.INK]: "0x0bd7473CbBf81d9dD936c61117eD230d95006CA2"
11126
+ [Chain.INK]: "0x0bd7473CbBf81d9dD936c61117eD230d95006CA2",
11127
+ [Chain.KAIA_MAINNET]: "0x925716D57c842B50806884EDb295bA3E3A8EBdFE"
11127
11128
  };
11128
11129
  var buildMorphoUserCallWithLens = (chainId, account, lender, marketsToQuery) => {
11129
11130
  const marketSlices = chunk(marketsToQuery, 100);
@@ -36218,14 +36219,93 @@ async function fetchMorphoVaultsFromSubgraph(chainId, prices = {}, tokenList = {
36218
36219
  }
36219
36220
  return out;
36220
36221
  }
36221
-
36222
- // src/vaults/morpho/fetchPublic.ts
36223
- var fetchMorphoVaults = async (chainId, prices = {}, tokenList = {}) => {
36224
- if (hasMorphoVaultSubgraph(chainId)) {
36225
- return fetchMorphoVaultsFromSubgraph(chainId, prices, tokenList);
36222
+ var marketUidFor = (ctx, marketId) => {
36223
+ if (!ctx?.underlying) return void 0;
36224
+ try {
36225
+ return createMarketUid(
36226
+ ctx.chainId,
36227
+ `${ctx.protocol}_${marketId.slice(2).toUpperCase()}`,
36228
+ ctx.underlying
36229
+ );
36230
+ } catch {
36231
+ return void 0;
36226
36232
  }
36227
- return fetchMorphoVaultsFromApi(chainId, prices, tokenList);
36228
36233
  };
36234
+ async function fetchVaultSupplyShares(chainId, core, entries, marketIdsByVault, multicallRetry) {
36235
+ const map = /* @__PURE__ */ new Map();
36236
+ if (!core) return map;
36237
+ const calls = [];
36238
+ const keys = [];
36239
+ entries.forEach((entry, i) => {
36240
+ const vault = entry.vault.toLowerCase();
36241
+ for (const id of marketIdsByVault[i]) {
36242
+ calls.push({ address: core, name: "position", params: [id, entry.vault] });
36243
+ keys.push(`${vault}:${id}`);
36244
+ }
36245
+ });
36246
+ if (calls.length === 0) return map;
36247
+ const res = await multicallRetry({
36248
+ chain: chainId,
36249
+ calls,
36250
+ abi: calls.map(() => MorphoBlueAbi),
36251
+ allowFailure: true
36252
+ });
36253
+ res.forEach((r, k) => {
36254
+ const supplyShares = Array.isArray(r) ? r[0] : r?.supplyShares;
36255
+ if (supplyShares == null) return;
36256
+ try {
36257
+ map.set(keys[k], BigInt(supplyShares));
36258
+ } catch {
36259
+ }
36260
+ });
36261
+ return map;
36262
+ }
36263
+ function computeVaultAllocation(vaultAddress, decimals, totalAssetsFormatted, feePercent, priceUsd, marketIds, rateMap, positionMap, tokenList, uidCtx) {
36264
+ if (totalAssetsFormatted <= 0) {
36265
+ return { depositRate: 0, exposures: [] };
36266
+ }
36267
+ if (marketIds.length === 0) {
36268
+ return {
36269
+ depositRate: 0,
36270
+ exposures: withIdleExposure([], totalAssetsFormatted, priceUsd)
36271
+ };
36272
+ }
36273
+ let weighted = 0;
36274
+ const exposures = [];
36275
+ for (const id of marketIds) {
36276
+ const rate = rateMap.get(id);
36277
+ if (!rate || rate.totalSupplyShares === 0n) continue;
36278
+ const shares = positionMap.get(`${vaultAddress}:${id}`);
36279
+ if (!shares || shares === 0n) continue;
36280
+ const allocAssetsRaw = shares * rate.totalSupplyAssets / rate.totalSupplyShares;
36281
+ const allocAssets = Number(
36282
+ parseRawAmount(allocAssetsRaw.toString(), decimals)
36283
+ );
36284
+ if (allocAssets <= 0) continue;
36285
+ weighted += allocAssets * rate.supplyApr;
36286
+ const marketUid = marketUidFor(uidCtx, id);
36287
+ exposures.push({
36288
+ marketId: id,
36289
+ ...marketUid ? { marketUid } : {},
36290
+ collateralAddress: rate.collateralAddress,
36291
+ collateral: tokenList[rate.collateralAddress],
36292
+ assets: allocAssets,
36293
+ assetsUsd: allocAssets * priceUsd,
36294
+ weightPct: allocAssets / totalAssetsFormatted * 100,
36295
+ supplyApr: rate.supplyApr
36296
+ });
36297
+ }
36298
+ exposures.sort((a, b) => b.weightPct - a.weightPct);
36299
+ const grossApr = weighted / totalAssetsFormatted;
36300
+ return {
36301
+ depositRate: grossApr * (1 - feePercent / 100),
36302
+ // Tag uninvested deposits as an idle entry so the breakdown sums to ~100%.
36303
+ exposures: withIdleExposure(exposures, totalAssetsFormatted, priceUsd)
36304
+ };
36305
+ }
36306
+
36307
+ // src/vaults/morpho/fetchFromChain.ts
36308
+ var { chunk: chunk5 } = lodash;
36229
36309
  var VAULT_CALLS = [
36230
36310
  "name",
36231
36311
  "symbol",
@@ -36239,8 +36319,16 @@ var VAULT_CALLS = [
36239
36319
  "guardian"
36240
36320
  ];
36241
36321
  var CALLS_PER_VAULT = VAULT_CALLS.length;
36322
+ var PHASE1_CALLS = [...VAULT_CALLS, "withdrawQueueLength"];
36323
+ var PHASE1_PER_VAULT = PHASE1_CALLS.length;
36324
+ var WITHDRAW_QUEUE_LENGTH_INDEX = CALLS_PER_VAULT;
36325
+ var MORPHO_LENS_ABI = parseAbi([
36326
+ "function getMarketDataCompact(address morpho, bytes32[] calldata marketsIds) external view returns (bytes memory data)"
36327
+ ]);
36328
+ var MARKET_CHUNK = 100;
36242
36329
  var FEE_SCALE = 1e18;
36243
36330
  var isHex40 = (addr) => typeof addr === "string" && /^0x[0-9a-f]{40}$/i.test(addr);
36331
+ var isHex64 = (v) => typeof v === "string" && /^0x[0-9a-f]{64}$/i.test(v);
36244
36332
  var lcOrUndefined = (addr) => isHex40(addr) ? addr.toLowerCase() : void 0;
36245
36333
  var toNumberSafe = (raw, fallback = 0) => {
36246
36334
  if (raw === void 0 || raw === null) return fallback;
@@ -36272,30 +36360,130 @@ var collectEntries = (chainId, protocols, skip) => {
36272
36360
  var fetchMorphoVaultsFromChain = async (chainId, multicallRetry, prices = {}, tokenList = {}, opts = {}) => {
36273
36361
  const entries = opts.vaultsOverride ? opts.vaultsOverride.map((entry) => ({ protocol: "", entry })) : collectEntries(chainId, opts.protocols, DEFAULT_SKIP_PROTOCOLS);
36274
36362
  if (entries.length === 0) return {};
36275
- const calls = entries.flatMap(
36276
- ({ entry }) => VAULT_CALLS.map((name) => ({
36363
+ const phase1Calls = entries.flatMap(
36364
+ ({ entry }) => PHASE1_CALLS.map((name) => ({
36277
36365
  address: entry.vault,
36278
36366
  name,
36279
36367
  params: []
36280
36368
  }))
36281
36369
  );
36282
- const raw = await multicallRetry({
36370
+ const phase1 = await multicallRetry({
36283
36371
  chain: chainId,
36284
- calls,
36285
- abi: calls.map(() => MetaMorphoAbi),
36372
+ calls: phase1Calls,
36373
+ abi: phase1Calls.map(() => MetaMorphoAbi),
36286
36374
  allowFailure: true
36287
36375
  });
36376
+ const queueLens = entries.map((_3, i) => {
36377
+ const n = Number(phase1[i * PHASE1_PER_VAULT + WITHDRAW_QUEUE_LENGTH_INDEX]);
36378
+ return Number.isFinite(n) && n > 0 ? n : 0;
36379
+ });
36380
+ const phase2Calls = [];
36381
+ const phase2Vault = [];
36382
+ entries.forEach(({ entry }, i) => {
36383
+ for (let q = 0; q < queueLens[i]; q++) {
36384
+ phase2Calls.push({
36385
+ address: entry.vault,
36386
+ name: "withdrawQueue",
36387
+ params: [BigInt(q)]
36388
+ });
36389
+ phase2Vault.push(i);
36390
+ }
36391
+ });
36392
+ const phase2 = phase2Calls.length ? await multicallRetry({
36393
+ chain: chainId,
36394
+ calls: phase2Calls,
36395
+ abi: phase2Calls.map(() => MetaMorphoAbi),
36396
+ allowFailure: true
36397
+ }) : [];
36398
+ const marketIdsByVault = entries.map(() => []);
36399
+ phase2.forEach((res, k) => {
36400
+ if (isHex64(res)) marketIdsByVault[phase2Vault[k]].push(res.toLowerCase());
36401
+ });
36402
+ const core = morphoPools()?.MORPHO_BLUE?.[chainId];
36403
+ const allMarketIds = [...new Set(marketIdsByVault.flat())];
36404
+ const [rateMap, positionMap] = await Promise.all([
36405
+ fetchMorphoMarketRates(chainId, core, allMarketIds, multicallRetry),
36406
+ fetchVaultSupplyShares(
36407
+ chainId,
36408
+ core,
36409
+ entries.map((e) => e.entry),
36410
+ marketIdsByVault,
36411
+ multicallRetry
36412
+ )
36413
+ ]);
36288
36414
  const out = {};
36289
36415
  for (let i = 0; i < entries.length; i++) {
36290
36416
  const { entry } = entries[i];
36291
- const base = i * CALLS_PER_VAULT;
36292
- const slice = raw.slice(base, base + CALLS_PER_VAULT);
36293
- const parsed = parseVault4(entry, slice, chainId, prices, tokenList);
36417
+ const base = i * PHASE1_PER_VAULT;
36418
+ const slice = phase1.slice(base, base + CALLS_PER_VAULT);
36419
+ const parsed = parseVault4(
36420
+ entry,
36421
+ slice,
36422
+ chainId,
36423
+ prices,
36424
+ tokenList,
36425
+ marketIdsByVault[i],
36426
+ rateMap,
36427
+ positionMap
36428
+ );
36294
36429
  if (parsed) out[parsed.address] = parsed;
36295
36430
  }
36296
36431
  return out;
36297
36432
  };
36298
- function parseVault4(entry, results, chainId, prices, tokenList) {
36433
+ async function fetchMorphoMarketRates(chainId, core, marketIds, multicallRetry) {
36434
+ const map = /* @__PURE__ */ new Map();
36435
+ const lens = MORPHO_LENS[chainId];
36436
+ if (!core || !lens || marketIds.length === 0) return map;
36437
+ const groups = chunk5(marketIds, MARKET_CHUNK);
36438
+ const calls = groups.map((group) => ({
36439
+ address: lens,
36440
+ name: "getMarketDataCompact",
36441
+ params: [core, group]
36442
+ }));
36443
+ const raw = await multicallRetry({
36444
+ chain: chainId,
36445
+ calls,
36446
+ abi: calls.map(() => MORPHO_LENS_ABI),
36447
+ allowFailure: true
36448
+ });
36449
+ groups.forEach((group, c) => {
36450
+ const bytes = raw[c];
36451
+ if (!bytes || bytes === "0x") return;
36452
+ let decoded;
36453
+ try {
36454
+ decoded = decodeMarkets(bytes);
36455
+ } catch {
36456
+ return;
36457
+ }
36458
+ decoded.forEach((mkt, j) => {
36459
+ const id = group[j]?.toLowerCase();
36460
+ if (!id) return;
36461
+ const utilization = MathLib.getUtilization({
36462
+ totalSupplyAssets: mkt.totalSupplyAssets,
36463
+ totalBorrowAssets: mkt.totalBorrowAssets
36464
+ });
36465
+ let supplyApy = 0n;
36466
+ try {
36467
+ const borrowApy = MathLib.getBorrowApy(
36468
+ mkt.rateAtTarget,
36469
+ utilization,
36470
+ void 0,
36471
+ Number(mkt.lastUpdate)
36472
+ );
36473
+ supplyApy = MathLib.getSupplyApy(borrowApy, utilization, mkt.fee);
36474
+ } catch {
36475
+ }
36476
+ map.set(id, {
36477
+ supplyApr: apyToApr2(Number(formatEther(supplyApy))) * 100,
36478
+ totalSupplyAssets: mkt.totalSupplyAssets,
36479
+ totalSupplyShares: mkt.totalSupplyShares,
36480
+ collateralAddress: (mkt.collateralToken ?? "").toLowerCase()
36481
+ });
36482
+ });
36483
+ });
36484
+ return map;
36485
+ }
36486
+ function parseVault4(entry, results, chainId, prices, tokenList, marketIds, rateMap, positionMap) {
36299
36487
  const address = entry?.vault?.toLowerCase();
36300
36488
  const underlying = entry?.underlying?.toLowerCase();
36301
36489
  if (!address || !underlying) return null;
@@ -36323,22 +36511,36 @@ function parseVault4(entry, results, chainId, prices, tokenList) {
36323
36511
  const symbol = toStringSafe(symbolRaw);
36324
36512
  const fee = toNumberSafe(feeRaw) / FEE_SCALE * 100;
36325
36513
  const timelock = toNumberSafe(timelockRaw);
36514
+ const { depositRate, exposures } = computeVaultAllocation(
36515
+ address,
36516
+ decimals,
36517
+ totalAssetsFormatted,
36518
+ fee,
36519
+ priceUsd,
36520
+ marketIds,
36521
+ rateMap,
36522
+ positionMap,
36523
+ tokenList,
36524
+ { chainId, underlying, protocol: "MORPHO_BLUE" }
36525
+ );
36326
36526
  return {
36327
36527
  address,
36328
36528
  underlying,
36329
36529
  symbol,
36330
36530
  name: fallbackName,
36331
- displayName: composeVaultDisplayName("Morpho", void 0, assetMeta, fallbackName),
36531
+ displayName: composeVaultDisplayName(
36532
+ "Morpho",
36533
+ void 0,
36534
+ assetMeta,
36535
+ fallbackName
36536
+ ),
36332
36537
  decimals,
36333
36538
  totalAssets,
36334
36539
  totalSupply,
36335
- // On-chain path can't compute the per-allocation supply APR without
36336
- // walking the underlying market list — surface 0 like the Goldsky path
36337
- // does for rewards. Callers that need APR on these vaults should layer
36338
- // it in separately or fall back to the API/subgraph fetchers.
36339
- supplyRate: 0,
36540
+ supplyRate: depositRate,
36340
36541
  rewardsRate: 0,
36341
- depositRate: 0,
36542
+ depositRate,
36543
+ exposures,
36342
36544
  fee,
36343
36545
  timelock,
36344
36546
  whitelisted: true,
@@ -36357,13 +36559,111 @@ function parseVault4(entry, results, chainId, prices, tokenList) {
36357
36559
  liquidityUsd: totalAssetsFormatted * priceUsd
36358
36560
  };
36359
36561
  }
36360
- var { chunk: chunk5 } = lodash;
36562
+
36563
+ // src/vaults/morpho/fetchPublic.ts
36564
+ var hasMorphoOnChainVaults = (chainId) => (morphoTypeVaults()?.MORPHO_BLUE?.[chainId]?.length ?? 0) > 0;
36565
+ var fetchMorphoVaults = async (chainId, multicallRetry, prices = {}, tokenList = {}) => {
36566
+ if (hasMorphoOnChainVaults(chainId)) {
36567
+ return fetchMorphoVaultsFromChain(
36568
+ chainId,
36569
+ multicallRetry,
36570
+ prices,
36571
+ tokenList
36572
+ );
36573
+ }
36574
+ if (hasMorphoVaultSubgraph(chainId)) {
36575
+ return fetchMorphoVaultsFromSubgraph(chainId, prices, tokenList);
36576
+ }
36577
+ return fetchMorphoVaultsFromApi(chainId, prices, tokenList);
36578
+ };
36579
+
36580
+ // src/vaults/curatorName.ts
36581
+ var STOP_WORDS = /* @__PURE__ */ new Set([
36582
+ "vault",
36583
+ "vaults",
36584
+ "savings",
36585
+ "yield",
36586
+ "exclusive",
36587
+ "dao",
36588
+ "x",
36589
+ "pt",
36590
+ "prime",
36591
+ "staked",
36592
+ "core",
36593
+ "lista",
36594
+ // protocol brand; a bare "Lista …" vault has no distinct curator
36595
+ "moolah"
36596
+ ]);
36597
+ var ASSET_TOKENS = /* @__PURE__ */ new Set([
36598
+ "usdc",
36599
+ "usdt",
36600
+ "usd1",
36601
+ "usds",
36602
+ "dai",
36603
+ "usde",
36604
+ "susde",
36605
+ "lisusd",
36606
+ "gho",
36607
+ "frax",
36608
+ "pyusd",
36609
+ "rusd",
36610
+ "usr",
36611
+ "rlp",
36612
+ "eth",
36613
+ "weth",
36614
+ "wsteth",
36615
+ "reth",
36616
+ "steth",
36617
+ "cbeth",
36618
+ "weeth",
36619
+ "ezeth",
36620
+ "btc",
36621
+ "wbtc",
36622
+ "btcb",
36623
+ "cbbtc",
36624
+ "tbtc",
36625
+ "xaut",
36626
+ "xrp",
36627
+ "bnb",
36628
+ "wbnb",
36629
+ "sol",
36630
+ "op",
36631
+ "arb",
36632
+ "avax",
36633
+ "pol",
36634
+ "matic",
36635
+ "sei",
36636
+ "celo",
36637
+ "hype",
36638
+ "plume",
36639
+ "s"
36640
+ ]);
36641
+ function curatorNameFromVaultName(name, assetSymbol) {
36642
+ if (!name) return void 0;
36643
+ const cleaned = name.replace(/\([^)]*\)\s*$/, "").trim();
36644
+ if (!cleaned) return void 0;
36645
+ const tokens = cleaned.split(/[\s/]+/).flatMap((t) => t.split("-")).filter(Boolean);
36646
+ const asset = (assetSymbol ?? "").toLowerCase();
36647
+ const out = [];
36648
+ for (const tok of tokens) {
36649
+ const tl = tok.toLowerCase();
36650
+ if (STOP_WORDS.has(tl)) break;
36651
+ if (asset && tl === asset || ASSET_TOKENS.has(tl)) break;
36652
+ out.push(tok);
36653
+ if (out.length >= 3) break;
36654
+ }
36655
+ const curator = out.join(" ").trim();
36656
+ return curator.length >= 2 ? curator : void 0;
36657
+ }
36658
+
36659
+ // src/vaults/morpho/fetchListaFromChain.ts
36660
+ var { chunk: chunk6 } = lodash;
36361
36661
  var LISTA_PROTOCOL = "LISTA_DAO";
36362
36662
  var LISTA_LENS_ABI = parseAbi([
36363
36663
  "function getListaMarketDataCompact(address morpho, bytes32[] calldata marketsIds) external view returns (bytes memory data)"
36364
36664
  ]);
36365
36665
  var LISTA_MARKET_CHUNK = 100;
36366
- var PHASE1_CALLS = [
36666
+ var PHASE1_CALLS2 = [
36367
36667
  "name",
36368
36668
  "symbol",
36369
36669
  "decimals",
@@ -36374,8 +36674,8 @@ var PHASE1_CALLS = [
36374
36674
  "CURATOR",
36375
36675
  "withdrawQueueLength"
36376
36676
  ];
36377
- var PHASE1_PER_VAULT = PHASE1_CALLS.length;
36378
- var WITHDRAW_QUEUE_LENGTH_INDEX = 8;
36677
+ var PHASE1_PER_VAULT2 = PHASE1_CALLS2.length;
36678
+ var WITHDRAW_QUEUE_LENGTH_INDEX2 = 8;
36379
36679
  var FEE_SCALE2 = 1e18;
36380
36680
  var isHex402 = (addr) => typeof addr === "string" && /^0x[0-9a-f]{40}$/i.test(addr);
36381
36681
  var lcOrUndefined2 = (addr) => {
@@ -36383,7 +36683,7 @@ var lcOrUndefined2 = (addr) => {
36383
36683
  const lower = addr.toLowerCase();
36384
36684
  return lower === zeroAddress ? void 0 : lower;
36385
36685
  };
36386
- var isHex64 = (val) => typeof val === "string" && /^0x[0-9a-f]{64}$/i.test(val);
36686
+ var isHex642 = (val) => typeof val === "string" && /^0x[0-9a-f]{64}$/i.test(val);
36387
36687
  var toNumberSafe2 = (raw, fallback = 0) => {
36388
36688
  if (raw === void 0 || raw === null) return fallback;
36389
36689
  const n = Number(raw);
@@ -36409,7 +36709,7 @@ var fetchListaVaultsFromChain = async (chainId, multicallRetry, prices = {}, tok
36409
36709
  const entries = opts.vaultsOverride ?? collectEntries2(chainId);
36410
36710
  if (entries.length === 0) return {};
36411
36711
  const phase1Calls = entries.flatMap(
36412
- (entry) => PHASE1_CALLS.map((name) => ({
36712
+ (entry) => PHASE1_CALLS2.map((name) => ({
36413
36713
  address: entry.vault,
36414
36714
  name,
36415
36715
  params: []
@@ -36424,10 +36724,10 @@ var fetchListaVaultsFromChain = async (chainId, multicallRetry, prices = {}, tok
36424
36724
  const curatorRoleByVault = [];
36425
36725
  const queueLenByVault = [];
36426
36726
  for (let i = 0; i < entries.length; i++) {
36427
- const role = phase1[i * PHASE1_PER_VAULT + 7];
36428
- curatorRoleByVault.push(isHex64(role) ? role : void 0);
36727
+ const role = phase1[i * PHASE1_PER_VAULT2 + 7];
36728
+ curatorRoleByVault.push(isHex642(role) ? role : void 0);
36429
36729
  queueLenByVault.push(
36430
- toNumberSafe2(phase1[i * PHASE1_PER_VAULT + WITHDRAW_QUEUE_LENGTH_INDEX])
36730
+ toNumberSafe2(phase1[i * PHASE1_PER_VAULT2 + WITHDRAW_QUEUE_LENGTH_INDEX2])
36431
36731
  );
36432
36732
  }
36433
36733
  const phase2Calls = [];
@@ -36460,7 +36760,7 @@ var fetchListaVaultsFromChain = async (chainId, multicallRetry, prices = {}, tok
36460
36760
  const meta = phase2Meta[k];
36461
36761
  if (meta.kind === "curator") {
36462
36762
  if (curatorRoleByVault[meta.vault]) curatorAddrByVault[meta.vault] = res;
36463
- } else if (isHex64(res)) {
36763
+ } else if (isHex642(res)) {
36464
36764
  marketIdsByVault[meta.vault].push(res.toLowerCase());
36465
36765
  }
36466
36766
  });
@@ -36479,7 +36779,7 @@ var fetchListaVaultsFromChain = async (chainId, multicallRetry, prices = {}, tok
36479
36779
  const out = {};
36480
36780
  for (let i = 0; i < entries.length; i++) {
36481
36781
  const entry = entries[i];
36482
- const slice = phase1.slice(i * PHASE1_PER_VAULT, (i + 1) * PHASE1_PER_VAULT);
36782
+ const slice = phase1.slice(i * PHASE1_PER_VAULT2, (i + 1) * PHASE1_PER_VAULT2);
36483
36783
  const parsed = parseVault5(
36484
36784
  entry,
36485
36785
  slice,
@@ -36499,7 +36799,7 @@ async function fetchListaMarketRates(chainId, moolah, marketIds, multicallRetry)
36499
36799
  const map = /* @__PURE__ */ new Map();
36500
36800
  const lens = MORPHO_LENS[chainId];
36501
36801
  if (!moolah || !lens || marketIds.length === 0) return map;
36502
- const groups = chunk5(marketIds, LISTA_MARKET_CHUNK);
36802
+ const groups = chunk6(marketIds, LISTA_MARKET_CHUNK);
36503
36803
  const calls = groups.map((group) => ({
36504
36804
  address: lens,
36505
36805
  name: "getListaMarketDataCompact",
@@ -36550,80 +36850,6 @@ async function fetchListaMarketRates(chainId, moolah, marketIds, multicallRetry)
36550
36850
  });
36551
36851
  return map;
36552
36852
  }
36553
- async function fetchVaultSupplyShares(chainId, moolah, entries, marketIdsByVault, multicallRetry) {
36554
- const map = /* @__PURE__ */ new Map();
36555
- if (!moolah) return map;
36556
- const calls = [];
36557
- const keys = [];
36558
- entries.forEach((entry, i) => {
36559
- const vault = entry.vault.toLowerCase();
36560
- for (const id of marketIdsByVault[i]) {
36561
- calls.push({
36562
- address: moolah,
36563
- name: "position",
36564
- params: [id, entry.vault]
36565
- });
36566
- keys.push(`${vault}:${id}`);
36567
- }
36568
- });
36569
- if (calls.length === 0) return map;
36570
- const res = await multicallRetry({
36571
- chain: chainId,
36572
- calls,
36573
- abi: calls.map(() => MorphoBlueAbi),
36574
- allowFailure: true
36575
- });
36576
- res.forEach((r, k) => {
36577
- const supplyShares = Array.isArray(r) ? r[0] : r?.supplyShares;
36578
- if (supplyShares == null) return;
36579
- try {
36580
- map.set(keys[k], BigInt(supplyShares));
36581
- } catch {
36582
- }
36583
- });
36584
- return map;
36585
- }
36586
- function computeVaultAllocation(vaultAddress, decimals, totalAssetsFormatted, feePercent, priceUsd, marketIds, rateMap, positionMap, tokenList) {
36587
- if (totalAssetsFormatted <= 0) {
36588
- return { depositRate: 0, exposures: [] };
36589
- }
36590
- if (marketIds.length === 0) {
36591
- return {
36592
- depositRate: 0,
36593
- exposures: withIdleExposure([], totalAssetsFormatted, priceUsd)
36594
- };
36595
- }
36596
- let weighted = 0;
36597
- const exposures = [];
36598
- for (const id of marketIds) {
36599
- const rate = rateMap.get(id);
36600
- if (!rate || rate.totalSupplyShares === 0n) continue;
36601
- const shares = positionMap.get(`${vaultAddress}:${id}`);
36602
- if (!shares || shares === 0n) continue;
36603
- const allocAssetsRaw = shares * rate.totalSupplyAssets / rate.totalSupplyShares;
36604
- const allocAssets = Number(
36605
- parseRawAmount(allocAssetsRaw.toString(), decimals)
36606
- );
36607
- if (allocAssets <= 0) continue;
36608
- weighted += allocAssets * rate.supplyApr;
36609
- exposures.push({
36610
- marketId: id,
36611
- collateralAddress: rate.collateralAddress,
36612
- collateral: tokenList[rate.collateralAddress],
36613
- assets: allocAssets,
36614
- assetsUsd: allocAssets * priceUsd,
36615
- weightPct: allocAssets / totalAssetsFormatted * 100,
36616
- supplyApr: rate.supplyApr
36617
- });
36618
- }
36619
- exposures.sort((a, b) => b.weightPct - a.weightPct);
36620
- const grossApr = weighted / totalAssetsFormatted;
36621
- return {
36622
- depositRate: grossApr * (1 - feePercent / 100),
36623
- // Tag uninvested deposits as an idle entry so the breakdown sums to ~100%.
36624
- exposures: withIdleExposure(exposures, totalAssetsFormatted, priceUsd)
36625
- };
36626
- }
36627
36853
  function parseVault5(entry, results, curatorAddrRaw, chainId, prices, tokenList, marketIds, rateMap, positionMap) {
36628
36854
  const address = entry?.vault?.toLowerCase();
36629
36855
  const underlying = entry?.underlying?.toLowerCase();
@@ -36660,7 +36886,8 @@ function parseVault5(entry, results, curatorAddrRaw, chainId, prices, tokenList,
36660
36886
  marketIds,
36661
36887
  rateMap,
36662
36888
  positionMap,
36663
- tokenList
36889
+ tokenList,
36890
+ { chainId, underlying, protocol: "LISTA_DAO" }
36664
36891
  );
36665
36892
  return {
36666
36893
  address,
@@ -36684,6 +36911,9 @@ function parseVault5(entry, results, curatorAddrRaw, chainId, prices, tokenList,
36684
36911
  whitelisted: true,
36685
36912
  owner: void 0,
36686
36913
  curator: lcOrUndefined2(curatorAddrRaw),
36914
+ // Moolah exposes only the curator address; derive a display name from the
36915
+ // (curator-branded) vault name as a best-effort fallback.
36916
+ curatorName: curatorNameFromVaultName(fallbackName, assetMeta?.symbol),
36687
36917
  guardian: void 0,
36688
36918
  asset: assetMeta,
36689
36919
  priceUsd: priceUsd || void 0,
@@ -37062,6 +37292,7 @@ function parseVault7(v, chainId, prices, tokenList, evkIndex) {
37062
37292
  fee,
37063
37293
  owner: readAddress2(v.owner),
37064
37294
  curator: readAddress2(v.curator),
37295
+ curatorName: curatorNameFromVaultName(v.name, assetMeta?.symbol),
37065
37296
  guardian: readAddress2(v.guardian),
37066
37297
  feeRecipient: v.feeReceiver?.toLowerCase() || void 0,
37067
37298
  asset: assetMeta,
@@ -43354,6 +43585,10 @@ query LagoonVaults($where: VaultFilterInput!, $first: Int!, $skip: Int!) {
43354
43585
  name
43355
43586
  symbol
43356
43587
  decimals
43588
+ curators {
43589
+ id
43590
+ name
43591
+ }
43357
43592
  isVisible
43358
43593
  asset {
43359
43594
  address
@@ -43426,8 +43661,7 @@ var pickApr = (apr) => {
43426
43661
  if (apr.monthly != null) return { rate: apr.monthly, window: "monthly" };
43427
43662
  if (apr.weekly != null) return { rate: apr.weekly, window: "weekly" };
43428
43663
  if (apr.yearly != null) return { rate: apr.yearly, window: "yearly" };
43429
- if (apr.inception != null)
43430
- return { rate: apr.inception, window: "inception" };
43664
+ if (apr.inception != null) return { rate: apr.inception, window: "inception" };
43431
43665
  return { rate: 0, window: "none" };
43432
43666
  };
43433
43667
  var num = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
@@ -43460,12 +43694,14 @@ function parseVault8(v, chainId, prices, tokenList) {
43460
43694
  const name = (v.name ?? "").trim();
43461
43695
  const symbol = (v.symbol ?? "").trim();
43462
43696
  const displayName = name || composeVaultDisplayName(BRAND, void 0, assetMeta, symbol);
43697
+ const curatorName = v.curators?.find((c) => c?.name)?.name ?? void 0;
43463
43698
  return {
43464
43699
  address,
43465
43700
  underlying: assetAddr,
43466
43701
  symbol,
43467
43702
  name: name || symbol,
43468
43703
  displayName,
43704
+ ...curatorName ? { curatorName } : {},
43469
43705
  decimals,
43470
43706
  assetDecimals,
43471
43707
  totalAssets: totalAssetsRaw,
@@ -44851,7 +45087,7 @@ var getVaultPublicDataAll = async (chainId, providers, multicallRetry, prices =
44851
45087
  }
44852
45088
  if (requested.has("morpho")) {
44853
45089
  tasks.push(
44854
- fetchMorphoVaults(chainId, prices, tokenList).then((res) => {
45090
+ fetchMorphoVaults(chainId, multicallRetry, prices, tokenList).then((res) => {
44855
45091
  out.morpho = res;
44856
45092
  }).catch((e) => {
44857
45093
  warn4(