@1delta/margin-fetcher 0.0.226 → 0.0.228

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.
Files changed (53) hide show
  1. package/dist/abis/silo-v2/Silo.d.ts +101 -0
  2. package/dist/abis/silo-v2/Silo.d.ts.map +1 -0
  3. package/dist/abis/silo-v2/SiloConfig.d.ts +78 -0
  4. package/dist/abis/silo-v2/SiloConfig.d.ts.map +1 -0
  5. package/dist/abis/silo-v2/SiloLens.d.ts +50 -0
  6. package/dist/abis/silo-v2/SiloLens.d.ts.map +1 -0
  7. package/dist/abis/silo-v2/index.d.ts +4 -0
  8. package/dist/abis/silo-v2/index.d.ts.map +1 -0
  9. package/dist/index.js +1848 -94
  10. package/dist/index.js.map +1 -1
  11. package/dist/lending/public-data/fetchLender.d.ts.map +1 -1
  12. package/dist/lending/public-data/fetchLenderAll.d.ts.map +1 -1
  13. package/dist/lending/public-data/fetchLenderExt.d.ts.map +1 -1
  14. package/dist/lending/public-data/lista/getMarketsFromChain.d.ts.map +1 -1
  15. package/dist/lending/public-data/silo-v2/convertPublic.d.ts +28 -0
  16. package/dist/lending/public-data/silo-v2/convertPublic.d.ts.map +1 -0
  17. package/dist/lending/public-data/silo-v2/fetchPublic.d.ts +70 -0
  18. package/dist/lending/public-data/silo-v2/fetchPublic.d.ts.map +1 -0
  19. package/dist/lending/public-data/silo-v2/publicCallBuild.d.ts +23 -0
  20. package/dist/lending/public-data/silo-v2/publicCallBuild.d.ts.map +1 -0
  21. package/dist/lending/public-data/silo-v2/publicCallParse.d.ts +25 -0
  22. package/dist/lending/public-data/silo-v2/publicCallParse.d.ts.map +1 -0
  23. package/dist/lending/public-data/silo-v3/convertPublic.d.ts +18 -0
  24. package/dist/lending/public-data/silo-v3/convertPublic.d.ts.map +1 -0
  25. package/dist/lending/public-data/silo-v3/publicCallBuild.d.ts +19 -0
  26. package/dist/lending/public-data/silo-v3/publicCallBuild.d.ts.map +1 -0
  27. package/dist/lending/public-data/silo-v3/publicCallParse.d.ts +16 -0
  28. package/dist/lending/public-data/silo-v3/publicCallParse.d.ts.map +1 -0
  29. package/dist/lending/user-data/abis.d.ts.map +1 -1
  30. package/dist/lending/user-data/fetch-balances/parse.d.ts.map +1 -1
  31. package/dist/lending/user-data/fetch-balances/prepare.d.ts.map +1 -1
  32. package/dist/lending/user-data/silo-v2/userCallBuild.d.ts +21 -0
  33. package/dist/lending/user-data/silo-v2/userCallBuild.d.ts.map +1 -0
  34. package/dist/lending/user-data/silo-v2/userCallParse.d.ts +23 -0
  35. package/dist/lending/user-data/silo-v2/userCallParse.d.ts.map +1 -0
  36. package/dist/lending/user-data/utils/types.d.ts +20 -0
  37. package/dist/lending/user-data/utils/types.d.ts.map +1 -1
  38. package/dist/prices/oracle-prices/fetchOraclePrices.d.ts.map +1 -1
  39. package/dist/prices/oracle-prices/fetchers/index.d.ts +2 -0
  40. package/dist/prices/oracle-prices/fetchers/index.d.ts.map +1 -1
  41. package/dist/prices/oracle-prices/fetchers/siloV2.d.ts +108 -0
  42. package/dist/prices/oracle-prices/fetchers/siloV2.d.ts.map +1 -0
  43. package/dist/prices/oracle-prices/fetchers/siloV2Graphql.d.ts +36 -0
  44. package/dist/prices/oracle-prices/fetchers/siloV2Graphql.d.ts.map +1 -0
  45. package/dist/prices/oracle-prices/fetchers/siloV3.d.ts +52 -0
  46. package/dist/prices/oracle-prices/fetchers/siloV3.d.ts.map +1 -0
  47. package/dist/prices/oracle-prices/fetchers/siloV3Graphql.d.ts +19 -0
  48. package/dist/prices/oracle-prices/fetchers/siloV3Graphql.d.ts.map +1 -0
  49. package/dist/prices/oracle-prices/index.d.ts +2 -0
  50. package/dist/prices/oracle-prices/index.d.ts.map +1 -1
  51. package/dist/utils/index.d.ts +1 -1
  52. package/dist/utils/index.d.ts.map +1 -1
  53. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { parseAbi, formatEther, BaseError, encodeFunctionData, formatUnits, decodeFunctionResult, decodeAbiParameters, AbiEncodingLengthMismatchError, concatHex, isAddress, InvalidAddressError, pad, stringToHex, boolToHex, integerRegex, numberToHex, bytesRegex, BytesSizeMismatchError, arrayRegex, UnsupportedPackedAbiType } from './chunk-ZVIJSUIM.js';
2
2
  import './chunk-BYTNVMX7.js';
3
3
  import './chunk-PR4QN5HX.js';
4
- import { Lender, isAaveType, isCompoundV3, isMultiMarket, isAaveV4Type, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isAaveV2Type, isAaveV32Type, isAaveV3Type, isEulerType, isYLDR, isCompoundV3Type, isLista, isTectonicType, isBenqiType } from '@1delta/lender-registry';
4
+ import { Lender, isAaveType, isCompoundV3, isMultiMarket, isSiloV2Type, isSiloV3Type, isAaveV4Type, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isAaveV2Type, isAaveV32Type, isAaveV3Type, isEulerType, isYLDR, isCompoundV3Type, isLista, isTectonicType, isBenqiType } from '@1delta/lender-registry';
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 } from '@1delta/providers';
@@ -6277,7 +6277,11 @@ globalThis[GLOBAL_LENDER_DATA_KEY] = {
6277
6277
  eulerVaults: {},
6278
6278
  aaveV4Spokes: {},
6279
6279
  aaveV4Oracles: {},
6280
- aaveV4Peripherals: {}
6280
+ aaveV4Peripherals: {},
6281
+ siloMarkets: {},
6282
+ siloPeripherals: {},
6283
+ siloMarketsV3: {},
6284
+ siloPeripheralsV3: {}
6281
6285
  };
6282
6286
  function getGlobalData2() {
6283
6287
  return globalThis[GLOBAL_LENDER_DATA_KEY];
@@ -6303,6 +6307,8 @@ var eulerConfigs = () => getGlobalData2()?.eulerConfigs;
6303
6307
  var eulerVaults = () => getGlobalData2()?.eulerVaults;
6304
6308
  var aaveV4Spokes = () => getGlobalData2()?.aaveV4Spokes;
6305
6309
  var aaveV4Oracles = () => getGlobalData2()?.aaveV4Oracles;
6310
+ var siloMarkets = () => getGlobalData2()?.siloMarkets;
6311
+ var siloMarketsV3 = () => getGlobalData2()?.siloMarketsV3;
6306
6312
  function aaveV4SpokeLenderKey(spoke) {
6307
6313
  if (!spoke || !spoke.startsWith("0x") || spoke.length !== 42) {
6308
6314
  throw new Error(`aaveV4SpokeLenderKey: invalid spoke address ${spoke}`);
@@ -6314,6 +6320,46 @@ function parseAaveV4SpokeLenderKey(lenderKey) {
6314
6320
  if (!match) return void 0;
6315
6321
  return { spokeAddrLower: "0x" + match[1].toLowerCase() };
6316
6322
  }
6323
+ function siloV2LenderKey(siloConfig) {
6324
+ if (!siloConfig || !siloConfig.startsWith("0x") || siloConfig.length !== 42) {
6325
+ throw new Error(`siloV2LenderKey: invalid siloConfig address ${siloConfig}`);
6326
+ }
6327
+ return `SILO_V2_${siloConfig.slice(2).toUpperCase()}`;
6328
+ }
6329
+ function parseSiloV2LenderKey(lenderKey) {
6330
+ const match = lenderKey.match(/^SILO_V2_([0-9A-F]{40})$/);
6331
+ if (!match) return void 0;
6332
+ return { siloConfigAddrLower: "0x" + match[1].toLowerCase() };
6333
+ }
6334
+ function getSiloV2MarketEntry(chainId, lenderKey) {
6335
+ const parsed = parseSiloV2LenderKey(lenderKey);
6336
+ if (!parsed) return void 0;
6337
+ const list = getGlobalData2()?.siloMarkets?.[chainId];
6338
+ if (!list) return void 0;
6339
+ return list.find(
6340
+ (m) => m.siloConfig.toLowerCase() === parsed.siloConfigAddrLower
6341
+ );
6342
+ }
6343
+ function siloV3LenderKey(siloConfig) {
6344
+ if (!siloConfig || !siloConfig.startsWith("0x") || siloConfig.length !== 42) {
6345
+ throw new Error(`siloV3LenderKey: invalid siloConfig address ${siloConfig}`);
6346
+ }
6347
+ return `SILO_V3_${siloConfig.slice(2).toUpperCase()}`;
6348
+ }
6349
+ function parseSiloV3LenderKey(lenderKey) {
6350
+ const match = lenderKey.match(/^SILO_V3_([0-9A-F]{40})$/);
6351
+ if (!match) return void 0;
6352
+ return { siloConfigAddrLower: "0x" + match[1].toLowerCase() };
6353
+ }
6354
+ function getSiloV3MarketEntry(chainId, lenderKey) {
6355
+ const parsed = parseSiloV3LenderKey(lenderKey);
6356
+ if (!parsed) return void 0;
6357
+ const list = getGlobalData2()?.siloMarketsV3?.[chainId];
6358
+ if (!list) return void 0;
6359
+ return list.find(
6360
+ (m) => m.siloConfig.toLowerCase() === parsed.siloConfigAddrLower
6361
+ );
6362
+ }
6317
6363
  var getListUrl = (chainId) => `https://raw.githubusercontent.com/1delta-DAO/token-lists/main/${chainId}.json`;
6318
6364
  async function fetchTokenList(chainId) {
6319
6365
  const data = await fetch(getListUrl(chainId));
@@ -7544,6 +7590,10 @@ var getLendersForChain = (c) => {
7544
7590
  if (data[c]?.length > 0) lenders.push(l);
7545
7591
  });
7546
7592
  }
7593
+ const siloChainPairs = siloMarkets()?.[c] ?? [];
7594
+ for (const market of siloChainPairs) {
7595
+ lenders.push(siloV2LenderKey(market.siloConfig));
7596
+ }
7547
7597
  const v4ChainSpokes = aaveV4Spokes()?.[c] ?? {};
7548
7598
  for (const spokeAddr of Object.keys(v4ChainSpokes)) {
7549
7599
  lenders.push(aaveV4SpokeLenderKey(spokeAddr));
@@ -13003,7 +13053,11 @@ function getListaMarketDataConverter(lender, chainId, prices, additionalYields =
13003
13053
  };
13004
13054
  const ltv = parseLtv(lltv);
13005
13055
  const metaCollateral = tokens[collateralAssetAddress] ?? collateralAsset;
13006
- const collateralMarketUid = createMarketUid(chainId, m, collateralAssetAddress);
13056
+ const collateralMarketUid = createMarketUid(
13057
+ chainId,
13058
+ m,
13059
+ collateralAssetAddress
13060
+ );
13007
13061
  data[m].data[collateralMarketUid] = {
13008
13062
  marketUid: collateralMarketUid,
13009
13063
  name: "Collateral " + (metaCollateral?.symbol ?? ""),
@@ -18553,6 +18607,399 @@ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields,
18553
18607
  };
18554
18608
  return [converter, expectedCalls];
18555
18609
  };
18610
+
18611
+ // src/abis/silo-v2/Silo.ts
18612
+ var SiloAbi = [
18613
+ {
18614
+ type: "function",
18615
+ name: "totalAssets",
18616
+ stateMutability: "view",
18617
+ inputs: [],
18618
+ outputs: [{ name: "", type: "uint256" }]
18619
+ },
18620
+ {
18621
+ type: "function",
18622
+ name: "getDebtAssets",
18623
+ stateMutability: "view",
18624
+ inputs: [],
18625
+ outputs: [{ name: "", type: "uint256" }]
18626
+ },
18627
+ {
18628
+ type: "function",
18629
+ name: "getCollateralAssets",
18630
+ stateMutability: "view",
18631
+ inputs: [],
18632
+ outputs: [{ name: "", type: "uint256" }]
18633
+ },
18634
+ {
18635
+ type: "function",
18636
+ name: "asset",
18637
+ stateMutability: "view",
18638
+ inputs: [],
18639
+ outputs: [{ name: "", type: "address" }]
18640
+ },
18641
+ {
18642
+ type: "function",
18643
+ name: "balanceOf",
18644
+ stateMutability: "view",
18645
+ inputs: [{ name: "account", type: "address" }],
18646
+ outputs: [{ name: "", type: "uint256" }]
18647
+ },
18648
+ {
18649
+ type: "function",
18650
+ name: "convertToAssets",
18651
+ stateMutability: "view",
18652
+ inputs: [{ name: "shares", type: "uint256" }],
18653
+ outputs: [{ name: "", type: "uint256" }]
18654
+ },
18655
+ {
18656
+ type: "function",
18657
+ name: "maxRepay",
18658
+ stateMutability: "view",
18659
+ inputs: [{ name: "borrower", type: "address" }],
18660
+ outputs: [{ name: "", type: "uint256" }]
18661
+ }
18662
+ ];
18663
+ var SiloConvertToAssetsTypedAbi = [
18664
+ {
18665
+ type: "function",
18666
+ name: "convertToAssets",
18667
+ stateMutability: "view",
18668
+ inputs: [
18669
+ { name: "shares", type: "uint256" },
18670
+ { name: "assetType", type: "uint8" }
18671
+ ],
18672
+ outputs: [{ name: "", type: "uint256" }]
18673
+ }
18674
+ ];
18675
+
18676
+ // src/abis/silo-v2/SiloLens.ts
18677
+ var SiloLensAbi = [
18678
+ {
18679
+ type: "function",
18680
+ name: "getDepositAPR",
18681
+ stateMutability: "view",
18682
+ inputs: [{ name: "_silo", type: "address" }],
18683
+ outputs: [{ name: "depositAPR", type: "uint256" }]
18684
+ },
18685
+ {
18686
+ type: "function",
18687
+ name: "getBorrowAPR",
18688
+ stateMutability: "view",
18689
+ inputs: [{ name: "_silo", type: "address" }],
18690
+ outputs: [{ name: "borrowAPR", type: "uint256" }]
18691
+ },
18692
+ {
18693
+ type: "function",
18694
+ name: "getUtilization",
18695
+ stateMutability: "view",
18696
+ inputs: [{ name: "_silo", type: "address" }],
18697
+ outputs: [{ name: "utilization", type: "uint256" }]
18698
+ },
18699
+ {
18700
+ type: "function",
18701
+ name: "getRawLiquidity",
18702
+ stateMutability: "view",
18703
+ inputs: [{ name: "_silo", type: "address" }],
18704
+ outputs: [{ name: "liquidity", type: "uint256" }]
18705
+ }
18706
+ ];
18707
+
18708
+ // src/lending/public-data/silo-v2/publicCallBuild.ts
18709
+ var SILO_V2_CALLS_PER_SIDE = 2;
18710
+ var SILO_V2_CALLS_PER_PAIR = SILO_V2_CALLS_PER_SIDE * 2;
18711
+ function buildSiloV2LenderReserveCall(_chainId, lender) {
18712
+ const market = getSiloV2MarketEntry(_chainId, lender);
18713
+ if (!market) return [];
18714
+ const calls = [];
18715
+ for (const half of [market.silo0, market.silo1]) {
18716
+ calls.push(
18717
+ {
18718
+ address: half.silo,
18719
+ name: "totalAssets",
18720
+ params: [],
18721
+ abi: SiloAbi
18722
+ },
18723
+ {
18724
+ address: half.silo,
18725
+ name: "getDebtAssets",
18726
+ params: [],
18727
+ abi: SiloAbi
18728
+ }
18729
+ );
18730
+ }
18731
+ return calls;
18732
+ }
18733
+
18734
+ // src/lending/public-data/silo-v2/publicCallParse.ts
18735
+ var getSiloV2ReservesDataConverter = (lender, chainId, prices, additionalYields, tokenList = {}) => {
18736
+ const market = getSiloV2MarketEntry(chainId, lender);
18737
+ if (!market) return [() => void 0, 0];
18738
+ return [
18739
+ (data) => {
18740
+ if (!data || data.length !== SILO_V2_CALLS_PER_PAIR) return void 0;
18741
+ const out = {};
18742
+ const sides = [
18743
+ { self: market.silo0, other: market.silo1 },
18744
+ { self: market.silo1, other: market.silo0 }
18745
+ ];
18746
+ const toBigInt6 = (v) => {
18747
+ if (v === void 0 || v === null || v === "0x") return 0n;
18748
+ if (typeof v === "bigint") return v;
18749
+ try {
18750
+ return BigInt(v);
18751
+ } catch {
18752
+ return 0n;
18753
+ }
18754
+ };
18755
+ for (let s = 0; s < 2; s++) {
18756
+ const { self, other } = sides[s];
18757
+ const slot = s * SILO_V2_CALLS_PER_SIDE;
18758
+ const totalAssetsRaw = toBigInt6(data[slot]);
18759
+ const debtAssetsRaw = toBigInt6(data[slot + 1]);
18760
+ const decimals = self.decimals;
18761
+ const totalDeposits = Number(formatUnits(totalAssetsRaw, decimals));
18762
+ const totalDebt = Number(formatUnits(debtAssetsRaw, decimals));
18763
+ const totalLiquidity = totalDeposits - totalDebt;
18764
+ const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : 0;
18765
+ const depositRatePct = 0;
18766
+ const variableBorrowRatePct = 0;
18767
+ const tokenAddrLc = self.token.toLowerCase();
18768
+ const assetMeta = tokenList[tokenAddrLc];
18769
+ const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
18770
+ const price = prices[oracleKey] ?? 0;
18771
+ const collateralLt = Number(other.lt) / 1e18;
18772
+ const collateralMaxLtv = Number(other.maxLtv) / 1e18;
18773
+ const selfLt = Number(self.lt) / 1e18;
18774
+ const borrowingEnabled = collateralLt > 0;
18775
+ const collateralActive = selfLt > 0;
18776
+ const marketUid = createMarketUid(chainId, lender, self.silo);
18777
+ out[marketUid] = {
18778
+ marketUid,
18779
+ name: market.name ? `Silo V2 ${market.name} ${assetMeta?.symbol ?? ""}` : `Silo V2 ${assetMeta?.symbol ?? ""}`,
18780
+ poolId: self.silo.toLowerCase(),
18781
+ underlying: tokenAddrLc,
18782
+ asset: {
18783
+ ...assetMeta ?? {},
18784
+ chainId,
18785
+ decimals,
18786
+ address: tokenAddrLc,
18787
+ symbol: assetMeta?.symbol ?? self.symbol ?? "",
18788
+ name: assetMeta?.name ?? self.symbol ?? ""
18789
+ },
18790
+ // token amounts
18791
+ totalDeposits,
18792
+ totalDebt,
18793
+ totalDebtStable: 0,
18794
+ totalLiquidity,
18795
+ borrowLiquidity: totalLiquidity,
18796
+ // USD amounts
18797
+ totalDepositsUSD: totalDeposits * price,
18798
+ totalDebtUSD: totalDebt * price,
18799
+ totalDebtStableUSD: 0,
18800
+ totalLiquidityUSD: totalLiquidity * price,
18801
+ borrowLiquidityUSD: totalLiquidity * price,
18802
+ utilization,
18803
+ depositRate: depositRatePct,
18804
+ variableBorrowRate: variableBorrowRatePct,
18805
+ stableBorrowRate: 0,
18806
+ intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
18807
+ rewards: void 0,
18808
+ decimals,
18809
+ // Each Silo v2 per-pair lender represents exactly ONE pair, so
18810
+ // there is only one collateral counterparty (the OTHER silo) and
18811
+ // a single config entry. Key it as `'0'` to match the Morpho
18812
+ // convention (`config[0]` is the single mode with the market's
18813
+ // LLTV) — the counterparty silo address is still surfaced via
18814
+ // `params.counterpartySilo`.
18815
+ config: {
18816
+ 0: {
18817
+ category: 0,
18818
+ borrowCollateralFactor: collateralMaxLtv,
18819
+ collateralFactor: collateralLt,
18820
+ borrowFactor: 1,
18821
+ collateralDisabled: !borrowingEnabled,
18822
+ debtDisabled: !collateralActive
18823
+ }
18824
+ },
18825
+ collateralActive,
18826
+ borrowingEnabled,
18827
+ depositsEnabled: true,
18828
+ hasStable: false,
18829
+ isActive: true,
18830
+ isFrozen: false,
18831
+ params: {
18832
+ metadata: {
18833
+ silo: self.silo,
18834
+ counterpartySilo: other.silo,
18835
+ siloConfig: market.siloConfig,
18836
+ oracle: self.solvencyOracle,
18837
+ irm: self.interestRateModel,
18838
+ shareTokens: {
18839
+ collateral: self.collateralShareToken,
18840
+ protected: self.protectedShareToken,
18841
+ debt: self.debtShareToken
18842
+ },
18843
+ fees: {
18844
+ dao: self.daoFee,
18845
+ deployer: self.deployerFee,
18846
+ liquidation: self.liquidationFee,
18847
+ flashloan: self.flashloanFee
18848
+ }
18849
+ }
18850
+ }
18851
+ };
18852
+ }
18853
+ return { data: out, chainId };
18854
+ },
18855
+ SILO_V2_CALLS_PER_PAIR
18856
+ ];
18857
+ };
18858
+
18859
+ // src/lending/public-data/silo-v3/publicCallBuild.ts
18860
+ var SILO_V3_CALLS_PER_SIDE = 2;
18861
+ var SILO_V3_CALLS_PER_PAIR = SILO_V3_CALLS_PER_SIDE * 2;
18862
+ function buildSiloV3LenderReserveCall(_chainId, lender) {
18863
+ const market = getSiloV3MarketEntry(_chainId, lender);
18864
+ if (!market) return [];
18865
+ const calls = [];
18866
+ for (const half of [market.silo0, market.silo1]) {
18867
+ calls.push(
18868
+ {
18869
+ address: half.silo,
18870
+ name: "totalAssets",
18871
+ params: [],
18872
+ abi: SiloAbi
18873
+ },
18874
+ {
18875
+ address: half.silo,
18876
+ name: "getDebtAssets",
18877
+ params: [],
18878
+ abi: SiloAbi
18879
+ }
18880
+ );
18881
+ }
18882
+ return calls;
18883
+ }
18884
+
18885
+ // src/lending/public-data/silo-v3/publicCallParse.ts
18886
+ var getSiloV3ReservesDataConverter = (lender, chainId, prices, additionalYields, tokenList = {}) => {
18887
+ const market = getSiloV3MarketEntry(chainId, lender);
18888
+ if (!market) return [() => void 0, 0];
18889
+ return [
18890
+ (data) => {
18891
+ if (!data || data.length !== SILO_V3_CALLS_PER_PAIR) return void 0;
18892
+ const out = {};
18893
+ const sides = [
18894
+ { self: market.silo0, other: market.silo1 },
18895
+ { self: market.silo1, other: market.silo0 }
18896
+ ];
18897
+ const toBigInt6 = (v) => {
18898
+ if (v === void 0 || v === null || v === "0x") return 0n;
18899
+ if (typeof v === "bigint") return v;
18900
+ try {
18901
+ return BigInt(v);
18902
+ } catch {
18903
+ return 0n;
18904
+ }
18905
+ };
18906
+ for (let s = 0; s < 2; s++) {
18907
+ const { self, other } = sides[s];
18908
+ const slot = s * SILO_V3_CALLS_PER_SIDE;
18909
+ const totalAssetsRaw = toBigInt6(data[slot]);
18910
+ const debtAssetsRaw = toBigInt6(data[slot + 1]);
18911
+ const decimals = self.decimals;
18912
+ const totalDeposits = Number(formatUnits(totalAssetsRaw, decimals));
18913
+ const totalDebt = Number(formatUnits(debtAssetsRaw, decimals));
18914
+ const totalLiquidity = totalDeposits - totalDebt;
18915
+ const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : 0;
18916
+ const depositRatePct = 0;
18917
+ const variableBorrowRatePct = 0;
18918
+ const tokenAddrLc = self.token.toLowerCase();
18919
+ const assetMeta = tokenList[tokenAddrLc];
18920
+ const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
18921
+ const price = prices[oracleKey] ?? 0;
18922
+ const collateralLt = Number(other.lt) / 1e18;
18923
+ const collateralMaxLtv = Number(other.maxLtv) / 1e18;
18924
+ const selfLt = Number(self.lt) / 1e18;
18925
+ const borrowingEnabled = collateralLt > 0;
18926
+ const collateralActive = selfLt > 0;
18927
+ const marketUid = createMarketUid(chainId, lender, self.silo);
18928
+ out[marketUid] = {
18929
+ marketUid,
18930
+ name: market.name ? `Silo V3 ${market.name} ${assetMeta?.symbol ?? ""}` : `Silo V3 ${assetMeta?.symbol ?? ""}`,
18931
+ poolId: self.silo.toLowerCase(),
18932
+ underlying: tokenAddrLc,
18933
+ asset: {
18934
+ ...assetMeta ?? {},
18935
+ chainId,
18936
+ decimals,
18937
+ address: tokenAddrLc,
18938
+ symbol: assetMeta?.symbol ?? self.symbol ?? "",
18939
+ name: assetMeta?.name ?? self.symbol ?? ""
18940
+ },
18941
+ totalDeposits,
18942
+ totalDebt,
18943
+ totalDebtStable: 0,
18944
+ totalLiquidity,
18945
+ borrowLiquidity: totalLiquidity,
18946
+ totalDepositsUSD: totalDeposits * price,
18947
+ totalDebtUSD: totalDebt * price,
18948
+ totalDebtStableUSD: 0,
18949
+ totalLiquidityUSD: totalLiquidity * price,
18950
+ borrowLiquidityUSD: totalLiquidity * price,
18951
+ utilization,
18952
+ depositRate: depositRatePct,
18953
+ variableBorrowRate: variableBorrowRatePct,
18954
+ stableBorrowRate: 0,
18955
+ intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
18956
+ rewards: void 0,
18957
+ decimals,
18958
+ config: {
18959
+ 0: {
18960
+ category: 0,
18961
+ borrowCollateralFactor: collateralMaxLtv,
18962
+ collateralFactor: collateralLt,
18963
+ borrowFactor: 1,
18964
+ collateralDisabled: !borrowingEnabled,
18965
+ debtDisabled: !collateralActive
18966
+ }
18967
+ },
18968
+ collateralActive,
18969
+ borrowingEnabled,
18970
+ depositsEnabled: true,
18971
+ hasStable: false,
18972
+ isActive: true,
18973
+ isFrozen: false,
18974
+ params: {
18975
+ metadata: {
18976
+ silo: self.silo,
18977
+ counterpartySilo: other.silo,
18978
+ siloConfig: market.siloConfig,
18979
+ oracle: self.solvencyOracle,
18980
+ irm: self.interestRateModel,
18981
+ shareTokens: {
18982
+ collateral: self.collateralShareToken,
18983
+ protected: self.protectedShareToken,
18984
+ debt: self.debtShareToken
18985
+ },
18986
+ fees: {
18987
+ dao: self.daoFee,
18988
+ deployer: self.deployerFee,
18989
+ liquidation: self.liquidationFee,
18990
+ flashloan: self.flashloanFee
18991
+ }
18992
+ }
18993
+ }
18994
+ };
18995
+ }
18996
+ return { data: out, chainId };
18997
+ },
18998
+ SILO_V3_CALLS_PER_PAIR
18999
+ ];
19000
+ };
19001
+
19002
+ // src/lending/public-data/fetchLender.ts
18556
19003
  function getMorphoTypeMarketConverter(lender, chainId, prices, additionalYields, tokenList = {}, marketsOverride) {
18557
19004
  if (lender.startsWith("LISTA_DAO"))
18558
19005
  return getListaMarketDataConverter(
@@ -18587,6 +19034,8 @@ function buildLenderCall(chainId, lender) {
18587
19034
  return buildCompoundV2StyleLenderReserveCall(chainId, lender);
18588
19035
  if (isEulerType(lender)) return buildEulerV2LenderReserveCall(chainId, lender);
18589
19036
  if (isAaveV4Type(lender)) return buildAaveV4LenderReserveCall(chainId, lender);
19037
+ if (isSiloV2Type(lender)) return buildSiloV2LenderReserveCall(chainId, lender);
19038
+ if (isSiloV3Type(lender)) return buildSiloV3LenderReserveCall(chainId, lender);
18590
19039
  return [];
18591
19040
  }
18592
19041
  function getLenderDataConverter(lender, chainId, prices, additionalYields, tokenList = {}) {
@@ -18655,6 +19104,22 @@ function getLenderDataConverter(lender, chainId, prices, additionalYields, token
18655
19104
  additionalYields,
18656
19105
  tokenList
18657
19106
  );
19107
+ if (isSiloV2Type(lender))
19108
+ return getSiloV2ReservesDataConverter(
19109
+ lender,
19110
+ chainId,
19111
+ prices,
19112
+ additionalYields,
19113
+ tokenList
19114
+ );
19115
+ if (isSiloV3Type(lender))
19116
+ return getSiloV3ReservesDataConverter(
19117
+ lender,
19118
+ chainId,
19119
+ prices,
19120
+ additionalYields,
19121
+ tokenList
19122
+ );
18658
19123
  return [() => null, 0];
18659
19124
  }
18660
19125
  var getAbi = (lender) => {
@@ -18675,6 +19140,8 @@ var getAbi = (lender) => {
18675
19140
  if (isMorphoType(lender)) return MorphoLensAbi;
18676
19141
  if (isEulerType(lender)) return vaultLensAbi;
18677
19142
  if (isAaveV4Type(lender)) return [...AaveV4SpokeAbi, ...AaveV4OracleAbi, ...AaveV4HubAbi];
19143
+ if (isSiloV2Type(lender)) return [...SiloAbi, ...SiloLensAbi];
19144
+ if (isSiloV3Type(lender)) return [...SiloAbi, ...SiloLensAbi];
18678
19145
  if (isSumerType(lender)) return [...SumerLensAbi, ...SumerComptrollerAbi];
18679
19146
  if (lender === Lender.TAKARA) return [...TakaraMarketStateAbi];
18680
19147
  if (isCompoundV2Type(lender)) return VenusLensAbi;
@@ -18735,58 +19202,539 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
18735
19202
  }
18736
19203
  return lenderData;
18737
19204
  };
18738
- async function getLenderDataFromApi(lender, chainId, prices, additionalYields, includeUnlisted = false) {
18739
- if (isMorphoType(lender))
18740
- return await fetchMorphoMarkets(chainId, includeUnlisted);
18741
- return {};
18742
- }
18743
- function convertLenderDataFromApi(lender, chainId, data, prices, additionalYields, list = {}) {
18744
- if (isMorphoType(lender))
18745
- return convertMarketsToMorphoResponse(data, chainId, additionalYields, list);
18746
- return {};
19205
+
19206
+ // src/lending/public-data/silo-v2/fetchPublic.ts
19207
+ var BASE_URL2 = "https://api-v3.silo.finance";
19208
+ var SILO_API_SUPPORTED_CHAIN_IDS = /* @__PURE__ */ new Set([
19209
+ "1",
19210
+ // Ethereum
19211
+ "42161",
19212
+ // Arbitrum
19213
+ "43114",
19214
+ // Avalanche
19215
+ "50",
19216
+ // XDC
19217
+ "1776"
19218
+ // Injective
19219
+ ]);
19220
+ var query2 = (chainId, limit) => `
19221
+ query GetSilos {
19222
+ silos(where: {chainId_in: [${chainId}]}, limit: ${limit}) {
19223
+ items {
19224
+ id
19225
+ chainId
19226
+ configAddress
19227
+ name
19228
+ protocol {
19229
+ protocolVersion
19230
+ }
19231
+ market1 {
19232
+ index
19233
+ inputTokenId
19234
+ inputToken { id symbol decimals }
19235
+ lt
19236
+ maxLtv
19237
+ liquidationTargetLtv
19238
+ daoFee
19239
+ deployerFee
19240
+ liquidationFee
19241
+ flashLoanFee
19242
+ borrowRate
19243
+ depositRate
19244
+ supply
19245
+ borrowed
19246
+ supplyUsd
19247
+ borrowedUsd
19248
+ liquidityUsd
19249
+ utilization
19250
+ solvencyOracleAddress
19251
+ maxLtvOracleAddress
19252
+ interestRateModelId
19253
+ sTokenId
19254
+ spTokenId
19255
+ dTokenId
19256
+ solvencyOracle {
19257
+ id
19258
+ quote
19259
+ quoteTimestamp
19260
+ baseTokenId
19261
+ quoteTokenId
19262
+ }
19263
+ maxLtvOracle {
19264
+ id
19265
+ quote
19266
+ quoteTimestamp
19267
+ }
19268
+ }
19269
+ market2 {
19270
+ index
19271
+ inputTokenId
19272
+ inputToken { id symbol decimals }
19273
+ lt
19274
+ maxLtv
19275
+ liquidationTargetLtv
19276
+ daoFee
19277
+ deployerFee
19278
+ liquidationFee
19279
+ flashLoanFee
19280
+ borrowRate
19281
+ depositRate
19282
+ supply
19283
+ borrowed
19284
+ supplyUsd
19285
+ borrowedUsd
19286
+ liquidityUsd
19287
+ utilization
19288
+ solvencyOracleAddress
19289
+ maxLtvOracleAddress
19290
+ interestRateModelId
19291
+ sTokenId
19292
+ spTokenId
19293
+ dTokenId
19294
+ solvencyOracle {
19295
+ id
19296
+ quote
19297
+ quoteTimestamp
19298
+ baseTokenId
19299
+ quoteTokenId
19300
+ }
19301
+ maxLtvOracle {
19302
+ id
19303
+ quote
19304
+ quoteTimestamp
19305
+ }
19306
+ }
19307
+ }
19308
+ }
18747
19309
  }
18748
- var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYields, tokenList = async () => {
18749
- return {};
18750
- }, includeUnlisted = false) => {
18751
- let promises = [];
18752
- for (const lender of lenders) {
18753
- promises.push(
18754
- getLenderDataFromApi(
18755
- lender,
18756
- chainId,
18757
- prices,
18758
- additionalYields,
18759
- includeUnlisted
18760
- )
19310
+ `;
19311
+ async function fetchSiloMarkets(chainId, options) {
19312
+ if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return [];
19313
+ const limit = options?.limit ?? 500;
19314
+ const response = await fetch(BASE_URL2, {
19315
+ method: "POST",
19316
+ headers: { "Content-Type": "application/json" },
19317
+ body: JSON.stringify({ query: query2(chainId, limit) })
19318
+ });
19319
+ if (!response.ok) {
19320
+ throw new Error(
19321
+ `[silo-api] Network error: ${response.status} - ${response.statusText}`
18761
19322
  );
18762
19323
  }
18763
- const settled = await Promise.allSettled([tokenList(), ...promises]);
18764
- const listResult = settled[0];
18765
- const list = listResult.status === "fulfilled" ? listResult.value : {};
18766
- if (listResult.status === "rejected") {
18767
- console.warn(
18768
- `[lending] tokenList fetch failed on chain ${chainId}:`,
18769
- listResult.reason
19324
+ const payload = await response.json();
19325
+ if (payload?.errors?.length) {
19326
+ throw new Error(
19327
+ `[silo-api] GraphQL error: ${payload.errors.map((e) => e?.message).join("; ")}`
18770
19328
  );
18771
19329
  }
18772
- const lenderData = {};
18773
- for (let i = 0; i < lenders.length; i++) {
19330
+ const items = payload?.data?.silos?.items ?? [];
19331
+ if (!options?.protocolVersion) return items;
19332
+ return items.filter(
19333
+ (s) => s.protocol?.protocolVersion === options.protocolVersion
19334
+ );
19335
+ }
19336
+
19337
+ // src/lending/public-data/silo-v2/convertPublic.ts
19338
+ function convertSiloMarketsToPublicResponse(apiItems, chainId, prices, additionalYields = {
19339
+ intrinsicYields: {},
19340
+ lenderRewards: {},
19341
+ loaded: true
19342
+ }, tokenList = {}) {
19343
+ const out = {};
19344
+ for (const item of apiItems) {
19345
+ if (item.protocol && item.protocol.protocolVersion !== "v2") continue;
19346
+ let lenderKey;
18774
19347
  try {
18775
- const result = settled[i + 1];
18776
- if (result.status === "rejected") {
18777
- console.warn(
18778
- `[lending] API fetch failed for ${lenders[i]} on chain ${chainId}:`,
18779
- result.reason?.message ?? result.reason
18780
- );
18781
- continue;
18782
- }
18783
- const lender = lenders[i];
18784
- if (isMultiMarket(lender)) {
18785
- const dataObtained = result.value;
18786
- const converted = convertLenderDataFromApi(
18787
- lender,
18788
- chainId,
18789
- dataObtained,
19348
+ lenderKey = siloV2LenderKey(item.configAddress);
19349
+ } catch {
19350
+ continue;
19351
+ }
19352
+ const registryEntry = getSiloV2MarketEntry(chainId, lenderKey);
19353
+ if (!registryEntry) continue;
19354
+ const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
19355
+ const sides = [
19356
+ { api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
19357
+ { api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
19358
+ ];
19359
+ const data = {};
19360
+ for (const { api, self, other } of sides) {
19361
+ const decimals = api.inputToken?.decimals ?? self.decimals;
19362
+ const tokenAddrLc = (api.inputTokenId ?? self.token).toLowerCase();
19363
+ const totalDeposits = safeNumber(api.supply);
19364
+ const totalDebt = safeNumber(api.borrowed);
19365
+ const totalLiquidity = totalDeposits - totalDebt;
19366
+ const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : safeNumber(api.utilization);
19367
+ const variableBorrowRatePct = safeNumber(api.borrowRate) * 100;
19368
+ const depositRatePct = safeNumber(api.depositRate) * 100;
19369
+ const assetMeta = tokenList[tokenAddrLc];
19370
+ const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
19371
+ const fallbackPrice = prices[oracleKey] ?? 0;
19372
+ const totalDepositsUSD = api.supplyUsd != null && api.supplyUsd > 0 ? api.supplyUsd : totalDeposits * fallbackPrice;
19373
+ const totalDebtUSD = api.borrowedUsd != null && api.borrowedUsd > 0 ? api.borrowedUsd : totalDebt * fallbackPrice;
19374
+ const totalLiquidityUSD = Math.max(totalDepositsUSD - totalDebtUSD, 0);
19375
+ const collateralLt = safeLtvOrFee(api, "lt", other.lt);
19376
+ const collateralMaxLtv = safeLtvOrFee(api, "maxLtv", other.maxLtv);
19377
+ const selfLt = bigintToLtv(api.lt ?? self.lt);
19378
+ const collateralLtFromApi = sides[0].api === api ? bigintToLtv(apiSide1.lt) : bigintToLtv(apiSide0.lt);
19379
+ const collateralMaxLtvFromApi = sides[0].api === api ? bigintToLtv(apiSide1.maxLtv) : bigintToLtv(apiSide0.maxLtv);
19380
+ const borrowingEnabled = (collateralLtFromApi || collateralLt) > 0;
19381
+ const collateralActive = selfLt > 0;
19382
+ const siloAddrLc = self.silo.toLowerCase();
19383
+ const marketUid = createMarketUid(chainId, lenderKey, siloAddrLc);
19384
+ data[marketUid] = {
19385
+ marketUid,
19386
+ name: item.name ? `Silo V2 ${item.name} ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}` : `Silo V2 ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}`,
19387
+ poolId: siloAddrLc,
19388
+ underlying: tokenAddrLc,
19389
+ asset: {
19390
+ ...assetMeta ?? {},
19391
+ chainId,
19392
+ decimals,
19393
+ address: tokenAddrLc,
19394
+ symbol: assetMeta?.symbol ?? api.inputToken?.symbol ?? self.symbol ?? "",
19395
+ name: assetMeta?.name ?? api.inputToken?.symbol ?? self.symbol ?? ""
19396
+ },
19397
+ // token amounts
19398
+ totalDeposits,
19399
+ totalDebt,
19400
+ totalDebtStable: 0,
19401
+ totalLiquidity,
19402
+ borrowLiquidity: totalLiquidity,
19403
+ // USD amounts
19404
+ totalDepositsUSD,
19405
+ totalDebtUSD,
19406
+ totalDebtStableUSD: 0,
19407
+ totalLiquidityUSD,
19408
+ borrowLiquidityUSD: totalLiquidityUSD,
19409
+ utilization,
19410
+ depositRate: depositRatePct,
19411
+ variableBorrowRate: variableBorrowRatePct,
19412
+ stableBorrowRate: 0,
19413
+ intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
19414
+ rewards: void 0,
19415
+ decimals,
19416
+ config: {
19417
+ 0: {
19418
+ category: 0,
19419
+ borrowCollateralFactor: collateralMaxLtvFromApi || collateralMaxLtv,
19420
+ collateralFactor: collateralLtFromApi || collateralLt,
19421
+ borrowFactor: 1,
19422
+ collateralDisabled: !borrowingEnabled,
19423
+ debtDisabled: !collateralActive
19424
+ }
19425
+ },
19426
+ collateralActive,
19427
+ borrowingEnabled,
19428
+ depositsEnabled: true,
19429
+ hasStable: false,
19430
+ isActive: true,
19431
+ isFrozen: false,
19432
+ params: {
19433
+ metadata: {
19434
+ silo: self.silo.toLowerCase(),
19435
+ counterpartySilo: other.silo.toLowerCase(),
19436
+ siloConfig: registryEntry.siloConfig.toLowerCase(),
19437
+ oracle: (api.solvencyOracleAddress ?? self.solvencyOracle).toLowerCase(),
19438
+ irm: (api.interestRateModelId ?? self.interestRateModel).toLowerCase(),
19439
+ shareTokens: {
19440
+ collateral: self.collateralShareToken,
19441
+ protected: self.protectedShareToken,
19442
+ debt: self.debtShareToken
19443
+ },
19444
+ fees: {
19445
+ dao: api.daoFee ?? self.daoFee,
19446
+ deployer: api.deployerFee ?? self.deployerFee,
19447
+ liquidation: api.liquidationFee ?? self.liquidationFee,
19448
+ flashloan: api.flashLoanFee ?? self.flashloanFee
19449
+ }
19450
+ }
19451
+ }
19452
+ };
19453
+ }
19454
+ out[lenderKey] = { data, chainId };
19455
+ }
19456
+ return out;
19457
+ }
19458
+ function safeNumber(v) {
19459
+ if (v == null) return 0;
19460
+ const n = typeof v === "number" ? v : Number(v);
19461
+ return Number.isFinite(n) ? n : 0;
19462
+ }
19463
+ function bigintToLtv(v) {
19464
+ if (!v) return 0;
19465
+ try {
19466
+ return Number(BigInt(v)) / 1e18;
19467
+ } catch {
19468
+ const n = Number(v);
19469
+ return Number.isFinite(n) ? n / 1e18 : 0;
19470
+ }
19471
+ }
19472
+ function safeLtvOrFee(api, field5, fallback) {
19473
+ return bigintToLtv(api[field5] ?? fallback);
19474
+ }
19475
+
19476
+ // src/lending/public-data/silo-v3/convertPublic.ts
19477
+ function convertSiloV3MarketsToPublicResponse(apiItems, chainId, prices, additionalYields = {
19478
+ intrinsicYields: {},
19479
+ lenderRewards: {},
19480
+ loaded: true
19481
+ }, tokenList = {}) {
19482
+ const out = {};
19483
+ for (const item of apiItems) {
19484
+ if (item.protocol && item.protocol.protocolVersion !== "v3") continue;
19485
+ let lenderKey;
19486
+ try {
19487
+ lenderKey = siloV3LenderKey(item.configAddress);
19488
+ } catch {
19489
+ continue;
19490
+ }
19491
+ const registryEntry = getSiloV3MarketEntry(chainId, lenderKey);
19492
+ if (!registryEntry) continue;
19493
+ const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
19494
+ const sides = [
19495
+ { api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
19496
+ { api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
19497
+ ];
19498
+ const data = {};
19499
+ for (const { api, self, other } of sides) {
19500
+ const decimals = api.inputToken?.decimals ?? self.decimals;
19501
+ const tokenAddrLc = (api.inputTokenId ?? self.token).toLowerCase();
19502
+ const totalDeposits = safeNumber2(api.supply);
19503
+ const totalDebt = safeNumber2(api.borrowed);
19504
+ const totalLiquidity = totalDeposits - totalDebt;
19505
+ const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : safeNumber2(api.utilization);
19506
+ const variableBorrowRatePct = safeNumber2(api.borrowRate) * 100;
19507
+ const depositRatePct = safeNumber2(api.depositRate) * 100;
19508
+ const assetMeta = tokenList[tokenAddrLc];
19509
+ const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
19510
+ const fallbackPrice = prices[oracleKey] ?? 0;
19511
+ const totalDepositsUSD = api.supplyUsd != null && api.supplyUsd > 0 ? api.supplyUsd : totalDeposits * fallbackPrice;
19512
+ const totalDebtUSD = api.borrowedUsd != null && api.borrowedUsd > 0 ? api.borrowedUsd : totalDebt * fallbackPrice;
19513
+ const totalLiquidityUSD = Math.max(totalDepositsUSD - totalDebtUSD, 0);
19514
+ const collateralLt = safeLtvOrFee2(api, "lt", other.lt);
19515
+ const collateralMaxLtv = safeLtvOrFee2(api, "maxLtv", other.maxLtv);
19516
+ const selfLt = bigintToLtv2(api.lt ?? self.lt);
19517
+ const collateralLtFromApi = sides[0].api === api ? bigintToLtv2(apiSide1.lt) : bigintToLtv2(apiSide0.lt);
19518
+ const collateralMaxLtvFromApi = sides[0].api === api ? bigintToLtv2(apiSide1.maxLtv) : bigintToLtv2(apiSide0.maxLtv);
19519
+ const borrowingEnabled = (collateralLtFromApi || collateralLt) > 0;
19520
+ const collateralActive = selfLt > 0;
19521
+ const siloAddrLc = self.silo.toLowerCase();
19522
+ const marketUid = createMarketUid(chainId, lenderKey, siloAddrLc);
19523
+ data[marketUid] = {
19524
+ marketUid,
19525
+ name: item.name ? `Silo V3 ${item.name} ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}` : `Silo V3 ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}`,
19526
+ poolId: siloAddrLc,
19527
+ underlying: tokenAddrLc,
19528
+ asset: {
19529
+ ...assetMeta ?? {},
19530
+ chainId,
19531
+ decimals,
19532
+ address: tokenAddrLc,
19533
+ symbol: assetMeta?.symbol ?? api.inputToken?.symbol ?? self.symbol ?? "",
19534
+ name: assetMeta?.name ?? api.inputToken?.symbol ?? self.symbol ?? ""
19535
+ },
19536
+ totalDeposits,
19537
+ totalDebt,
19538
+ totalDebtStable: 0,
19539
+ totalLiquidity,
19540
+ borrowLiquidity: totalLiquidity,
19541
+ totalDepositsUSD,
19542
+ totalDebtUSD,
19543
+ totalDebtStableUSD: 0,
19544
+ totalLiquidityUSD,
19545
+ borrowLiquidityUSD: totalLiquidityUSD,
19546
+ utilization,
19547
+ depositRate: depositRatePct,
19548
+ variableBorrowRate: variableBorrowRatePct,
19549
+ stableBorrowRate: 0,
19550
+ intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
19551
+ rewards: void 0,
19552
+ decimals,
19553
+ config: {
19554
+ 0: {
19555
+ category: 0,
19556
+ borrowCollateralFactor: collateralMaxLtvFromApi || collateralMaxLtv,
19557
+ collateralFactor: collateralLtFromApi || collateralLt,
19558
+ borrowFactor: 1,
19559
+ collateralDisabled: !borrowingEnabled,
19560
+ debtDisabled: !collateralActive
19561
+ }
19562
+ },
19563
+ collateralActive,
19564
+ borrowingEnabled,
19565
+ depositsEnabled: true,
19566
+ hasStable: false,
19567
+ isActive: true,
19568
+ isFrozen: false,
19569
+ params: {
19570
+ metadata: {
19571
+ silo: self.silo.toLowerCase(),
19572
+ counterpartySilo: other.silo.toLowerCase(),
19573
+ siloConfig: registryEntry.siloConfig.toLowerCase(),
19574
+ oracle: (api.solvencyOracleAddress ?? self.solvencyOracle).toLowerCase(),
19575
+ irm: (api.interestRateModelId ?? self.interestRateModel).toLowerCase(),
19576
+ shareTokens: {
19577
+ collateral: self.collateralShareToken,
19578
+ protected: self.protectedShareToken,
19579
+ debt: self.debtShareToken
19580
+ },
19581
+ fees: {
19582
+ dao: api.daoFee ?? self.daoFee,
19583
+ deployer: api.deployerFee ?? self.deployerFee,
19584
+ liquidation: api.liquidationFee ?? self.liquidationFee,
19585
+ flashloan: api.flashLoanFee ?? self.flashloanFee
19586
+ }
19587
+ }
19588
+ }
19589
+ };
19590
+ }
19591
+ out[lenderKey] = { data, chainId };
19592
+ }
19593
+ return out;
19594
+ }
19595
+ function safeNumber2(v) {
19596
+ if (v == null) return 0;
19597
+ const n = typeof v === "number" ? v : Number(v);
19598
+ return Number.isFinite(n) ? n : 0;
19599
+ }
19600
+ function bigintToLtv2(v) {
19601
+ if (!v) return 0;
19602
+ try {
19603
+ return Number(BigInt(v)) / 1e18;
19604
+ } catch {
19605
+ const n = Number(v);
19606
+ return Number.isFinite(n) ? n / 1e18 : 0;
19607
+ }
19608
+ }
19609
+ function safeLtvOrFee2(api, field5, fallback) {
19610
+ return bigintToLtv2(api[field5] ?? fallback);
19611
+ }
19612
+
19613
+ // src/lending/public-data/fetchLenderExt.ts
19614
+ async function getLenderDataFromApi(lender, chainId, prices, additionalYields, includeUnlisted = false) {
19615
+ if (isMorphoType(lender))
19616
+ return await fetchMorphoMarkets(chainId, includeUnlisted);
19617
+ return {};
19618
+ }
19619
+ function convertLenderDataFromApi(lender, chainId, data, prices, additionalYields, list = {}) {
19620
+ if (isMorphoType(lender))
19621
+ return convertMarketsToMorphoResponse(data, chainId, additionalYields, list);
19622
+ return {};
19623
+ }
19624
+ var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYields, tokenList = async () => {
19625
+ return {};
19626
+ }, includeUnlisted = false) => {
19627
+ const siloV2Lenders = lenders.filter((l) => isSiloV2Type(l));
19628
+ const siloV3Lenders = lenders.filter((l) => isSiloV3Type(l));
19629
+ const otherLenders = lenders.filter(
19630
+ (l) => !isSiloV2Type(l) && !isSiloV3Type(l)
19631
+ );
19632
+ const siloV2Promise = siloV2Lenders.length > 0 ? fetchSiloMarkets(chainId, { protocolVersion: "v2" }).then((items) => ({
19633
+ __silo_items__: items
19634
+ })) : Promise.resolve({});
19635
+ const siloV3Promise = siloV3Lenders.length > 0 ? fetchSiloMarkets(chainId, { protocolVersion: "v3" }).then((items) => ({
19636
+ __silo_items__: items
19637
+ })) : Promise.resolve({});
19638
+ let promises = [];
19639
+ for (const lender of otherLenders) {
19640
+ promises.push(
19641
+ getLenderDataFromApi(
19642
+ lender,
19643
+ chainId,
19644
+ prices,
19645
+ additionalYields,
19646
+ includeUnlisted
19647
+ )
19648
+ );
19649
+ }
19650
+ const settled = await Promise.allSettled([
19651
+ tokenList(),
19652
+ siloV2Promise,
19653
+ siloV3Promise,
19654
+ ...promises
19655
+ ]);
19656
+ const listResult = settled[0];
19657
+ const list = listResult.status === "fulfilled" ? listResult.value : {};
19658
+ if (listResult.status === "rejected") {
19659
+ console.warn(
19660
+ `[lending] tokenList fetch failed on chain ${chainId}:`,
19661
+ listResult.reason
19662
+ );
19663
+ }
19664
+ const lenderData = {};
19665
+ const siloV2Result = settled[1];
19666
+ if (siloV2Lenders.length > 0) {
19667
+ if (siloV2Result.status === "fulfilled") {
19668
+ const items = siloV2Result.value?.__silo_items__ ?? [];
19669
+ try {
19670
+ const converted = convertSiloMarketsToPublicResponse(
19671
+ items,
19672
+ chainId,
19673
+ prices,
19674
+ additionalYields,
19675
+ list
19676
+ );
19677
+ for (const lk of siloV2Lenders) {
19678
+ if (converted[lk]) lenderData[lk] = converted[lk];
19679
+ }
19680
+ } catch (e) {
19681
+ console.warn(
19682
+ `[lending] Silo v2 API convert failed on chain ${chainId}:`,
19683
+ e?.message ?? e
19684
+ );
19685
+ }
19686
+ } else {
19687
+ console.warn(
19688
+ `[lending] Silo v2 API fetch failed on chain ${chainId}:`,
19689
+ siloV2Result.reason?.message ?? siloV2Result.reason
19690
+ );
19691
+ }
19692
+ }
19693
+ const siloV3Result = settled[2];
19694
+ if (siloV3Lenders.length > 0) {
19695
+ if (siloV3Result.status === "fulfilled") {
19696
+ const items = siloV3Result.value?.__silo_items__ ?? [];
19697
+ try {
19698
+ const converted = convertSiloV3MarketsToPublicResponse(
19699
+ items,
19700
+ chainId,
19701
+ prices,
19702
+ additionalYields,
19703
+ list
19704
+ );
19705
+ for (const lk of siloV3Lenders) {
19706
+ if (converted[lk]) lenderData[lk] = converted[lk];
19707
+ }
19708
+ } catch (e) {
19709
+ console.warn(
19710
+ `[lending] Silo v3 API convert failed on chain ${chainId}:`,
19711
+ e?.message ?? e
19712
+ );
19713
+ }
19714
+ } else {
19715
+ console.warn(
19716
+ `[lending] Silo v3 API fetch failed on chain ${chainId}:`,
19717
+ siloV3Result.reason?.message ?? siloV3Result.reason
19718
+ );
19719
+ }
19720
+ }
19721
+ for (let i = 0; i < otherLenders.length; i++) {
19722
+ try {
19723
+ const result = settled[i + 3];
19724
+ if (result.status === "rejected") {
19725
+ console.warn(
19726
+ `[lending] API fetch failed for ${otherLenders[i]} on chain ${chainId}:`,
19727
+ result.reason?.message ?? result.reason
19728
+ );
19729
+ continue;
19730
+ }
19731
+ const lender = otherLenders[i];
19732
+ if (isMultiMarket(lender)) {
19733
+ const dataObtained = result.value;
19734
+ const converted = convertLenderDataFromApi(
19735
+ lender,
19736
+ chainId,
19737
+ dataObtained,
18790
19738
  prices,
18791
19739
  additionalYields,
18792
19740
  list
@@ -18808,7 +19756,7 @@ var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYield
18808
19756
  }
18809
19757
  return lenderData;
18810
19758
  };
18811
- function lenderCanUseApi(lender, chainId) {
19759
+ function lenderApiOnly(lender, chainId) {
18812
19760
  if (lender === Lender.MORPHO_BLUE) {
18813
19761
  if (chainId === Chain.SONEIUM) return false;
18814
19762
  if (chainId === Chain.HEMI_NETWORK) return false;
@@ -18819,9 +19767,17 @@ function lenderCanUseApi(lender, chainId) {
18819
19767
  }
18820
19768
  return false;
18821
19769
  }
19770
+ function lenderApiWithOnChainFallback(lender, chainId) {
19771
+ if (isSiloV2Type(lender) || isSiloV3Type(lender)) {
19772
+ return SILO_API_SUPPORTED_CHAIN_IDS.has(chainId);
19773
+ }
19774
+ return false;
19775
+ }
18822
19776
  var getLenderPublicDataAll = async (chainId, lenders, prices, additionalYields, multicallRetry, tokenList, includeUnlistedMorphoMarkets = false) => {
18823
- const lendersApi = lenders.filter((l) => lenderCanUseApi(l, chainId));
18824
- const lendersOnChain = lenders.filter((l) => !lenderCanUseApi(l, chainId));
19777
+ const lendersApi = lenders.filter(
19778
+ (l) => lenderApiOnly(l, chainId) || lenderApiWithOnChainFallback(l, chainId)
19779
+ );
19780
+ const lendersOnChain = lenders.filter((l) => !lenderApiOnly(l, chainId));
18825
19781
  const onChain = getLenderPublicData(
18826
19782
  chainId,
18827
19783
  lendersOnChain,
@@ -19134,7 +20090,7 @@ function fetchEulerSubAccountIndexes(chainId, owner) {
19134
20090
  async function fetchSubAccountsFromSubgraph(chainId, owner) {
19135
20091
  const url = EULER_SUBGRAPH_URLS[chainId];
19136
20092
  if (!url) return [0];
19137
- const query2 = `{
20093
+ const query3 = `{
19138
20094
  accounts(first: 100, where: { owner: "${owner.toLowerCase()}" }) {
19139
20095
  id
19140
20096
  subAccount
@@ -19143,7 +20099,7 @@ async function fetchSubAccountsFromSubgraph(chainId, owner) {
19143
20099
  const response = await fetch(url, {
19144
20100
  method: "POST",
19145
20101
  headers: { "Content-Type": "application/json" },
19146
- body: JSON.stringify({ query: query2 })
20102
+ body: JSON.stringify({ query: query3 })
19147
20103
  });
19148
20104
  if (!response.ok) return [0];
19149
20105
  const data = await response.json();
@@ -19246,6 +20202,55 @@ var buildAaveV4UserCall = (chainId, lender, account) => {
19246
20202
  return calls;
19247
20203
  };
19248
20204
 
20205
+ // src/lending/user-data/silo-v2/userCallBuild.ts
20206
+ var ASSET_TYPE_PROTECTED = 0;
20207
+ var ASSET_TYPE_COLLATERAL = 1;
20208
+ var SILO_V2_USER_CALLS_PER_SIDE = 5;
20209
+ var SILO_V2_USER_CALLS_PER_PAIR = SILO_V2_USER_CALLS_PER_SIDE * 2;
20210
+ var buildSiloV2UserCall = (chainId, lender, account) => {
20211
+ const market = getSiloV2MarketEntry(chainId, lender);
20212
+ if (!market) return [];
20213
+ const calls = [];
20214
+ for (const half of [market.silo0, market.silo1]) {
20215
+ const oneUnit = BigInt(10) ** BigInt(half.decimals);
20216
+ calls.push(
20217
+ // [0] collateral shares (silo IS the collateral share token)
20218
+ {
20219
+ address: half.silo,
20220
+ name: "balanceOf",
20221
+ params: [account]
20222
+ },
20223
+ // [1] protected shares (separate ERC-20)
20224
+ {
20225
+ address: half.protectedShareToken,
20226
+ name: "balanceOf",
20227
+ params: [account]
20228
+ },
20229
+ // [2] collateral rate: assets per unit of collateral shares
20230
+ {
20231
+ address: half.silo,
20232
+ name: "convertToAssets",
20233
+ params: [oneUnit, ASSET_TYPE_COLLATERAL],
20234
+ abi: SiloConvertToAssetsTypedAbi
20235
+ },
20236
+ // [3] protected rate: assets per unit of protected shares
20237
+ {
20238
+ address: half.silo,
20239
+ name: "convertToAssets",
20240
+ params: [oneUnit, ASSET_TYPE_PROTECTED],
20241
+ abi: SiloConvertToAssetsTypedAbi
20242
+ },
20243
+ // [4] debt position (already in assets, includes accrued interest)
20244
+ {
20245
+ address: half.silo,
20246
+ name: "maxRepay",
20247
+ params: [account]
20248
+ }
20249
+ );
20250
+ }
20251
+ return calls;
20252
+ };
20253
+
19249
20254
  // src/lending/user-data/fetch-balances/prepare.ts
19250
20255
  async function buildUserCall(chainId, lender, account, params) {
19251
20256
  if (isAaveV4Type(lender)) return buildAaveV4UserCall(chainId, lender, account);
@@ -19258,6 +20263,8 @@ async function buildUserCall(chainId, lender, account, params) {
19258
20263
  return buildCompoundV3UserCall(chainId, lender, account);
19259
20264
  if (isEulerType(lender))
19260
20265
  return buildEulerUserCall(chainId, lender, account, params?.subAccountIndexes);
20266
+ if (isSiloV2Type(lender))
20267
+ return buildSiloV2UserCall(chainId, lender, account);
19261
20268
  return buildCompoundV2UserCall(chainId, lender, account);
19262
20269
  }
19263
20270
  function organizeUserQueries(queries) {
@@ -20760,6 +21767,104 @@ function createAaveV4Entry(base, data, key, meta, spokeAddr) {
20760
21767
  };
20761
21768
  }
20762
21769
 
21770
+ // src/lending/user-data/silo-v2/userCallParse.ts
21771
+ var getSiloV2UserDataConverter = (lender, chainId, account, metaMap) => {
21772
+ const market = getSiloV2MarketEntry(chainId, lender);
21773
+ if (!market) return [() => void 0, 0];
21774
+ return [
21775
+ (data) => {
21776
+ if (!data || data.length !== SILO_V2_USER_CALLS_PER_PAIR)
21777
+ return void 0;
21778
+ const sides = [
21779
+ { self: market.silo0, other: market.silo1 },
21780
+ { self: market.silo1, other: market.silo0 }
21781
+ ];
21782
+ const lendingPositions = {};
21783
+ let addedDeposits = 0;
21784
+ let addedDebt = 0;
21785
+ let hasAnyPosition = false;
21786
+ for (let s = 0; s < 2; s++) {
21787
+ const { self } = sides[s];
21788
+ const slot = s * SILO_V2_USER_CALLS_PER_SIDE;
21789
+ const collateralShares = toBigInt5(data[slot]);
21790
+ const protectedShares = toBigInt5(data[slot + 1]);
21791
+ const collateralRate = toBigInt5(data[slot + 2]);
21792
+ const protectedRate = toBigInt5(data[slot + 3]);
21793
+ const repayRaw = toBigInt5(data[slot + 4]);
21794
+ const decimals = self.decimals;
21795
+ const oneUnit = BigInt(10) ** BigInt(decimals);
21796
+ const collateralAssets = oneUnit > 0n ? collateralShares * collateralRate / oneUnit : 0n;
21797
+ const protectedAssets = oneUnit > 0n ? protectedShares * protectedRate / oneUnit : 0n;
21798
+ const depositAssetsRaw = collateralAssets + protectedAssets;
21799
+ if (depositAssetsRaw === 0n && repayRaw === 0n) continue;
21800
+ hasAnyPosition = true;
21801
+ const marketUid = createMarketUid(chainId, lender, self.silo);
21802
+ const meta = metaMap?.[marketUid];
21803
+ const metaDecimals = meta?.asset?.decimals ?? decimals;
21804
+ const depositsStr = parseRawAmount(
21805
+ depositAssetsRaw.toString(),
21806
+ metaDecimals
21807
+ );
21808
+ const debtStr = parseRawAmount(repayRaw.toString(), metaDecimals);
21809
+ const depositsNum = Number(depositsStr);
21810
+ const debtNum = Number(debtStr);
21811
+ const displayPrice = meta ? getDisplayPrice(meta) : 0;
21812
+ const oraclePrice = meta ? getOraclePrice(meta) : 0;
21813
+ const priceHist = meta?.price?.priceUsd24h ?? displayPrice;
21814
+ const depositsUSD = depositsNum * displayPrice;
21815
+ const debtUSD = debtNum * displayPrice;
21816
+ const depositsUSDOracle = depositsNum * oraclePrice;
21817
+ const debtUSDOracle = debtNum * oraclePrice;
21818
+ addedDeposits += depositsNum * priceHist;
21819
+ addedDebt += debtNum * priceHist;
21820
+ const selfLt = Number(self.lt) / 1e18;
21821
+ const collateralEnabled = selfLt > 0 && depositAssetsRaw > 0n;
21822
+ lendingPositions[marketUid] = {
21823
+ marketUid,
21824
+ underlying: self.token.toLowerCase(),
21825
+ deposits: depositsStr,
21826
+ debt: debtStr,
21827
+ debtStable: "0",
21828
+ depositsUSD,
21829
+ debtUSD,
21830
+ debtStableUSD: 0,
21831
+ depositsUSDOracle,
21832
+ debtUSDOracle,
21833
+ debtStableUSDOracle: 0,
21834
+ stableBorrowRate: "0",
21835
+ collateralEnabled,
21836
+ claimableRewards: 0
21837
+ };
21838
+ }
21839
+ if (!hasAnyPosition) return void 0;
21840
+ const payload = {
21841
+ chainId,
21842
+ account,
21843
+ lendingPositions,
21844
+ rewards: [],
21845
+ userEMode: 0
21846
+ };
21847
+ return createBaseTypeUserState(
21848
+ payload,
21849
+ metaMap,
21850
+ addedDeposits,
21851
+ addedDebt,
21852
+ lender
21853
+ );
21854
+ },
21855
+ SILO_V2_USER_CALLS_PER_PAIR
21856
+ ];
21857
+ };
21858
+ function toBigInt5(v) {
21859
+ if (v === void 0 || v === null || v === "0x") return 0n;
21860
+ if (typeof v === "bigint") return v;
21861
+ try {
21862
+ return BigInt(v);
21863
+ } catch {
21864
+ return 0n;
21865
+ }
21866
+ }
21867
+
20763
21868
  // src/lending/user-data/fetch-balances/parse.ts
20764
21869
  function getUserDataConverter(lender, chainId, account, params, meta) {
20765
21870
  if (isAaveV4Type(lender))
@@ -20794,6 +21899,8 @@ function getUserDataConverter(lender, chainId, account, params, meta) {
20794
21899
  );
20795
21900
  if (isEulerType(lender))
20796
21901
  return getEulerUserDataConverter(lender, chainId, account, meta?.[lender], params?.subAccountIndexes);
21902
+ if (isSiloV2Type(lender))
21903
+ return getSiloV2UserDataConverter(lender, chainId, account, meta?.[lender]);
20797
21904
  return getCompoundV2UserDataConverter(
20798
21905
  lender,
20799
21906
  chainId,
@@ -20815,19 +21922,19 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
20815
21922
  const queries = organizeUserQueries(queriesRaw);
20816
21923
  const lenderData = {};
20817
21924
  let currentSlice = 0;
20818
- for (const query2 of queries) {
21925
+ for (const query3 of queries) {
20819
21926
  const [converter, sliceLength] = getUserDataConverter(
20820
- query2.lender,
21927
+ query3.lender,
20821
21928
  chainId,
20822
- query2.account,
20823
- query2.params,
21929
+ query3.account,
21930
+ query3.params,
20824
21931
  lenderState
20825
21932
  );
20826
21933
  try {
20827
21934
  const data = rawResults.slice(currentSlice, currentSlice + sliceLength);
20828
21935
  const convertedData = converter(data);
20829
21936
  if (convertedData) {
20830
- if (isMultiMarket(query2.lender)) {
21937
+ if (isMultiMarket(query3.lender)) {
20831
21938
  Object.keys(convertedData).forEach((market) => {
20832
21939
  const filtered = filterEmptyUserData(convertedData[market]);
20833
21940
  if (filtered) {
@@ -20838,8 +21945,8 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
20838
21945
  } else {
20839
21946
  const filtered = filterEmptyUserData(convertedData);
20840
21947
  if (filtered) {
20841
- filtered.lender = query2.lender;
20842
- lenderData[query2.lender] = filtered;
21948
+ filtered.lender = query3.lender;
21949
+ lenderData[query3.lender] = filtered;
20843
21950
  }
20844
21951
  }
20845
21952
  }
@@ -25473,6 +26580,7 @@ var getAbi2 = (lender) => {
25473
26580
  if (isEulerType(lender)) return accountLensAbi;
25474
26581
  if (isCompoundV2Type(lender))
25475
26582
  return [...ComptrollerAbi, ...CompoundV2CollateralToken];
26583
+ if (isSiloV2Type(lender)) return [...SiloAbi];
25476
26584
  return [];
25477
26585
  };
25478
26586
 
@@ -25579,15 +26687,15 @@ function unflattenLenderData(pools) {
25579
26687
  var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient3, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, retries = 3, logs = false) => {
25580
26688
  const queries = organizeUserQueries(queriesRaw);
25581
26689
  const builtCalls = await Promise.all(
25582
- queries.map(async (query2) => {
25583
- const abi = getAbi2(query2.lender);
26690
+ queries.map(async (query3) => {
26691
+ const abi = getAbi2(query3.lender);
25584
26692
  const callData = await buildUserCall(
25585
26693
  chainId,
25586
- query2.lender,
25587
- query2.account,
25588
- query2.params
26694
+ query3.lender,
26695
+ query3.account,
26696
+ query3.params
25589
26697
  );
25590
- return callData.map((call) => ({ call, abi }));
26698
+ return callData.map((call) => ({ call, abi: call.abi ?? abi }));
25591
26699
  })
25592
26700
  );
25593
26701
  const calls = builtCalls.flat();
@@ -25608,15 +26716,15 @@ var prepareLenderUserDataRpcCalls = async (chainId, queriesRaw, batchSize = MULT
25608
26716
  const multicallAddress = getEvmChain(chainId).contracts?.multicall3?.address;
25609
26717
  const queries = organizeUserQueries(queriesRaw);
25610
26718
  const builtCalls = await Promise.all(
25611
- queries.map(async (query2) => {
25612
- const abi = getAbi2(query2.lender);
26719
+ queries.map(async (query3) => {
26720
+ const abi = getAbi2(query3.lender);
25613
26721
  const callData = await buildUserCall(
25614
26722
  chainId,
25615
- query2.lender,
25616
- query2.account,
25617
- query2.params
26723
+ query3.lender,
26724
+ query3.account,
26725
+ query3.params
25618
26726
  );
25619
- return callData.map((call) => ({ call, abi }));
26727
+ return callData.map((call) => ({ call, abi: call.abi ?? abi }));
25620
26728
  })
25621
26729
  );
25622
26730
  const calls = builtCalls.flat();
@@ -25725,13 +26833,13 @@ async function prepareMergedRpcCalls(chainId, balanceQueries, permissionParams,
25725
26833
  );
25726
26834
  let balanceCalls = [];
25727
26835
  const organizedQueries = organizeUserQueries(balanceQueries);
25728
- for (const query2 of organizedQueries) {
25729
- const abi = getAbi2(query2.lender);
26836
+ for (const query3 of organizedQueries) {
26837
+ const abi = getAbi2(query3.lender);
25730
26838
  const callData = await buildUserCall(
25731
26839
  chainId,
25732
- query2.lender,
25733
- query2.account,
25734
- query2.params
26840
+ query3.lender,
26841
+ query3.account,
26842
+ query3.params
25735
26843
  );
25736
26844
  const mappedCalls = callData.map((call) => ({ call, abi }));
25737
26845
  balanceCalls = [...balanceCalls, ...mappedCalls];
@@ -25790,13 +26898,13 @@ async function prepareMergedMulticallParams(chainId, balanceQueries, permissionP
25790
26898
  const permissionAbis = permissionCalls.map(() => permissionResult.abi);
25791
26899
  let balanceCalls = [];
25792
26900
  const organizedQueries = organizeUserQueries(balanceQueries);
25793
- for (const query2 of organizedQueries) {
25794
- const abi = getAbi2(query2.lender);
26901
+ for (const query3 of organizedQueries) {
26902
+ const abi = getAbi2(query3.lender);
25795
26903
  const callData = await buildUserCall(
25796
26904
  chainId,
25797
- query2.lender,
25798
- query2.account,
25799
- query2.params
26905
+ query3.lender,
26906
+ query3.account,
26907
+ query3.params
25800
26908
  );
25801
26909
  const mappedCalls = callData.map((call) => ({ call, abi }));
25802
26910
  balanceCalls = [...balanceCalls, ...mappedCalls];
@@ -28593,12 +29701,12 @@ function getMorphoCalls(chainId, context) {
28593
29701
  const queries = getMorphoMarketsForChain(chainId, context?.marketOverrides);
28594
29702
  if (queries.length === 0) return [];
28595
29703
  const oracleGroups = /* @__PURE__ */ new Map();
28596
- for (const query2 of queries) {
28597
- const oracleLc = query2.oracle.toLowerCase();
29704
+ for (const query3 of queries) {
29705
+ const oracleLc = query3.oracle.toLowerCase();
28598
29706
  if (!oracleGroups.has(oracleLc)) {
28599
29707
  oracleGroups.set(oracleLc, []);
28600
29708
  }
28601
- oracleGroups.get(oracleLc).push(query2);
29709
+ oracleGroups.get(oracleLc).push(query3);
28602
29710
  }
28603
29711
  return Array.from(oracleGroups.values()).map((markets) => {
28604
29712
  const call = {
@@ -29334,6 +30442,550 @@ var aaveV4Fetcher = {
29334
30442
  getAbi: getAaveV4Abi
29335
30443
  };
29336
30444
 
30445
+ // src/prices/oracle-prices/fetchers/siloV2.ts
30446
+ var SiloOracleAbi = [
30447
+ {
30448
+ inputs: [
30449
+ { name: "_baseAmount", type: "uint256" },
30450
+ { name: "_baseToken", type: "address" }
30451
+ ],
30452
+ name: "quote",
30453
+ outputs: [{ name: "quoteAmount", type: "uint256" }],
30454
+ stateMutability: "view",
30455
+ type: "function"
30456
+ },
30457
+ {
30458
+ inputs: [],
30459
+ name: "quoteToken",
30460
+ outputs: [{ name: "", type: "address" }],
30461
+ stateMutability: "view",
30462
+ type: "function"
30463
+ }
30464
+ ];
30465
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
30466
+ function lookupUSD(context, asset) {
30467
+ const lc = asset.toLowerCase();
30468
+ const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
30469
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
30470
+ }
30471
+ function getSiloV2Calls(chainId) {
30472
+ const allMarkets = siloMarkets()?.[chainId];
30473
+ if (!allMarkets || allMarkets.length === 0) return [];
30474
+ const tokensWithRealOracle = /* @__PURE__ */ new Set();
30475
+ for (const market of allMarkets) {
30476
+ for (const half of [market.silo0, market.silo1]) {
30477
+ if (half.solvencyOracle && half.solvencyOracle !== ZERO_ADDRESS) {
30478
+ tokensWithRealOracle.add(half.token.toLowerCase());
30479
+ }
30480
+ }
30481
+ }
30482
+ const calls = [];
30483
+ const callIndexMap = {};
30484
+ const quoteTokenIndexMap = {};
30485
+ const entries = [];
30486
+ for (const market of allMarkets) {
30487
+ const lenderKey = siloV2LenderKey(market.siloConfig);
30488
+ const halves = [market.silo0, market.silo1];
30489
+ const isStatic = halves.map(
30490
+ (h) => !h.solvencyOracle || h.solvencyOracle === ZERO_ADDRESS
30491
+ );
30492
+ if (isStatic[0] && isStatic[1]) {
30493
+ const t0 = halves[0].token.toLowerCase();
30494
+ const t1 = halves[1].token.toLowerCase();
30495
+ if (!tokensWithRealOracle.has(t0) && !tokensWithRealOracle.has(t1)) {
30496
+ continue;
30497
+ }
30498
+ }
30499
+ for (let i = 0; i < 2; i++) {
30500
+ const half = halves[i];
30501
+ const partner = halves[1 - i];
30502
+ const tokenLc = half.token.toLowerCase();
30503
+ const partnerLc = partner.token.toLowerCase();
30504
+ if (isStatic[i]) {
30505
+ entries.push({
30506
+ token: tokenLc,
30507
+ decimals: half.decimals,
30508
+ silo: half.silo.toLowerCase(),
30509
+ lenderKey,
30510
+ oracle: ZERO_ADDRESS,
30511
+ partnerToken: partnerLc,
30512
+ isStatic: true
30513
+ });
30514
+ continue;
30515
+ }
30516
+ const oracleLc = half.solvencyOracle.toLowerCase();
30517
+ entries.push({
30518
+ token: tokenLc,
30519
+ decimals: half.decimals,
30520
+ silo: half.silo.toLowerCase(),
30521
+ lenderKey,
30522
+ oracle: oracleLc,
30523
+ partnerToken: partnerLc,
30524
+ isStatic: false
30525
+ });
30526
+ const quoteKey = `${oracleLc}:${tokenLc}`;
30527
+ if (!(quoteKey in callIndexMap)) {
30528
+ callIndexMap[quoteKey] = calls.length;
30529
+ calls.push({
30530
+ address: half.solvencyOracle,
30531
+ name: "quote",
30532
+ params: [BigInt(10) ** BigInt(half.decimals), half.token]
30533
+ });
30534
+ }
30535
+ if (!(oracleLc in quoteTokenIndexMap)) {
30536
+ quoteTokenIndexMap[oracleLc] = calls.length;
30537
+ calls.push({
30538
+ address: half.solvencyOracle,
30539
+ name: "quoteToken",
30540
+ params: []
30541
+ });
30542
+ }
30543
+ }
30544
+ }
30545
+ if (entries.length === 0) return [];
30546
+ return [
30547
+ {
30548
+ calls,
30549
+ meta: { entries, callIndexMap, quoteTokenIndexMap },
30550
+ lender: "SILO_V2"
30551
+ }
30552
+ ];
30553
+ }
30554
+ function parseSiloV2Results(data, meta, context) {
30555
+ const entries = [];
30556
+ const seen = /* @__PURE__ */ new Set();
30557
+ for (const entry of meta.entries) {
30558
+ const dedupKey = `${entry.lenderKey}:${entry.token}`;
30559
+ if (seen.has(dedupKey)) continue;
30560
+ try {
30561
+ let priceUSD = 0;
30562
+ let rawPrice = 1;
30563
+ if (entry.isStatic) {
30564
+ const ownUSD = lookupUSD(context, entry.token);
30565
+ const partnerUSD = lookupUSD(context, entry.partnerToken);
30566
+ priceUSD = ownUSD || partnerUSD;
30567
+ if (!priceUSD) continue;
30568
+ rawPrice = 1;
30569
+ } else {
30570
+ const quoteCallIdx = meta.callIndexMap[`${entry.oracle}:${entry.token}`];
30571
+ if (quoteCallIdx === void 0) continue;
30572
+ const rawQuote = data[quoteCallIdx];
30573
+ if (!rawQuote || rawQuote === "0x") continue;
30574
+ const quoteAmount = BigInt(rawQuote.toString());
30575
+ if (quoteAmount === 0n) continue;
30576
+ const qtIdx = meta.quoteTokenIndexMap[entry.oracle];
30577
+ if (qtIdx === void 0) continue;
30578
+ const rawQt = data[qtIdx];
30579
+ if (!rawQt || rawQt === "0x") continue;
30580
+ const quoteTokenAddr = rawQt.toLowerCase();
30581
+ const qtMeta = context.tokenList?.[quoteTokenAddr];
30582
+ const qtDecimals = qtMeta?.decimals ?? 18;
30583
+ const priceInQt = Number(quoteAmount) / Number(10n ** BigInt(qtDecimals));
30584
+ if (isNaN(priceInQt) || priceInQt === 0) continue;
30585
+ const qtUSD = lookupUSD(context, quoteTokenAddr);
30586
+ if (!qtUSD) continue;
30587
+ rawPrice = priceInQt;
30588
+ priceUSD = priceInQt * qtUSD;
30589
+ }
30590
+ if (isNaN(priceUSD) || priceUSD === 0) continue;
30591
+ entries.push({
30592
+ asset: entry.token,
30593
+ price: rawPrice,
30594
+ priceUSD,
30595
+ marketUid: createMarketUid(
30596
+ context.chainId,
30597
+ entry.lenderKey,
30598
+ entry.silo
30599
+ ),
30600
+ targetLender: entry.lenderKey,
30601
+ ...entry.isStatic ? { staticBase: true, baseAsset: entry.token } : {}
30602
+ });
30603
+ seen.add(dedupKey);
30604
+ } catch {
30605
+ }
30606
+ }
30607
+ return entries;
30608
+ }
30609
+ function getSiloV2Abi() {
30610
+ return SiloOracleAbi;
30611
+ }
30612
+ var siloV2Fetcher = {
30613
+ getCalls: getSiloV2Calls,
30614
+ parse: parseSiloV2Results,
30615
+ getAbi: getSiloV2Abi
30616
+ };
30617
+
30618
+ // src/prices/oracle-prices/fetchers/siloV3.ts
30619
+ var SiloOracleAbi2 = [
30620
+ {
30621
+ inputs: [
30622
+ { name: "_baseAmount", type: "uint256" },
30623
+ { name: "_baseToken", type: "address" }
30624
+ ],
30625
+ name: "quote",
30626
+ outputs: [{ name: "quoteAmount", type: "uint256" }],
30627
+ stateMutability: "view",
30628
+ type: "function"
30629
+ },
30630
+ {
30631
+ inputs: [],
30632
+ name: "quoteToken",
30633
+ outputs: [{ name: "", type: "address" }],
30634
+ stateMutability: "view",
30635
+ type: "function"
30636
+ }
30637
+ ];
30638
+ var ZERO_ADDRESS2 = "0x0000000000000000000000000000000000000000";
30639
+ function lookupUSD2(context, asset) {
30640
+ const lc = asset.toLowerCase();
30641
+ const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
30642
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
30643
+ }
30644
+ function getSiloV3Calls(chainId) {
30645
+ const allMarkets = siloMarketsV3()?.[chainId];
30646
+ if (!allMarkets || allMarkets.length === 0) return [];
30647
+ const tokensWithRealOracle = /* @__PURE__ */ new Set();
30648
+ for (const market of allMarkets) {
30649
+ for (const half of [market.silo0, market.silo1]) {
30650
+ if (half.solvencyOracle && half.solvencyOracle !== ZERO_ADDRESS2) {
30651
+ tokensWithRealOracle.add(half.token.toLowerCase());
30652
+ }
30653
+ }
30654
+ }
30655
+ const calls = [];
30656
+ const callIndexMap = {};
30657
+ const quoteTokenIndexMap = {};
30658
+ const entries = [];
30659
+ for (const market of allMarkets) {
30660
+ const lenderKey = siloV3LenderKey(market.siloConfig);
30661
+ const halves = [market.silo0, market.silo1];
30662
+ const isStatic = halves.map(
30663
+ (h) => !h.solvencyOracle || h.solvencyOracle === ZERO_ADDRESS2
30664
+ );
30665
+ if (isStatic[0] && isStatic[1]) {
30666
+ const t0 = halves[0].token.toLowerCase();
30667
+ const t1 = halves[1].token.toLowerCase();
30668
+ if (!tokensWithRealOracle.has(t0) && !tokensWithRealOracle.has(t1)) {
30669
+ continue;
30670
+ }
30671
+ }
30672
+ for (let i = 0; i < 2; i++) {
30673
+ const half = halves[i];
30674
+ const partner = halves[1 - i];
30675
+ const tokenLc = half.token.toLowerCase();
30676
+ const partnerLc = partner.token.toLowerCase();
30677
+ if (isStatic[i]) {
30678
+ entries.push({
30679
+ token: tokenLc,
30680
+ decimals: half.decimals,
30681
+ silo: half.silo.toLowerCase(),
30682
+ lenderKey,
30683
+ oracle: ZERO_ADDRESS2,
30684
+ partnerToken: partnerLc,
30685
+ isStatic: true
30686
+ });
30687
+ continue;
30688
+ }
30689
+ const oracleLc = half.solvencyOracle.toLowerCase();
30690
+ entries.push({
30691
+ token: tokenLc,
30692
+ decimals: half.decimals,
30693
+ silo: half.silo.toLowerCase(),
30694
+ lenderKey,
30695
+ oracle: oracleLc,
30696
+ partnerToken: partnerLc,
30697
+ isStatic: false
30698
+ });
30699
+ const quoteKey = `${oracleLc}:${tokenLc}`;
30700
+ if (!(quoteKey in callIndexMap)) {
30701
+ callIndexMap[quoteKey] = calls.length;
30702
+ calls.push({
30703
+ address: half.solvencyOracle,
30704
+ name: "quote",
30705
+ params: [BigInt(10) ** BigInt(half.decimals), half.token]
30706
+ });
30707
+ }
30708
+ if (!(oracleLc in quoteTokenIndexMap)) {
30709
+ quoteTokenIndexMap[oracleLc] = calls.length;
30710
+ calls.push({
30711
+ address: half.solvencyOracle,
30712
+ name: "quoteToken",
30713
+ params: []
30714
+ });
30715
+ }
30716
+ }
30717
+ }
30718
+ if (entries.length === 0) return [];
30719
+ return [
30720
+ {
30721
+ calls,
30722
+ meta: { entries, callIndexMap, quoteTokenIndexMap },
30723
+ lender: "SILO_V3"
30724
+ }
30725
+ ];
30726
+ }
30727
+ function parseSiloV3Results(data, meta, context) {
30728
+ const entries = [];
30729
+ const seen = /* @__PURE__ */ new Set();
30730
+ for (const entry of meta.entries) {
30731
+ const dedupKey = `${entry.lenderKey}:${entry.token}`;
30732
+ if (seen.has(dedupKey)) continue;
30733
+ try {
30734
+ let priceUSD = 0;
30735
+ let rawPrice = 1;
30736
+ if (entry.isStatic) {
30737
+ const ownUSD = lookupUSD2(context, entry.token);
30738
+ const partnerUSD = lookupUSD2(context, entry.partnerToken);
30739
+ priceUSD = ownUSD || partnerUSD;
30740
+ if (!priceUSD) continue;
30741
+ rawPrice = 1;
30742
+ } else {
30743
+ const quoteCallIdx = meta.callIndexMap[`${entry.oracle}:${entry.token}`];
30744
+ if (quoteCallIdx === void 0) continue;
30745
+ const rawQuote = data[quoteCallIdx];
30746
+ if (!rawQuote || rawQuote === "0x") continue;
30747
+ const quoteAmount = BigInt(rawQuote.toString());
30748
+ if (quoteAmount === 0n) continue;
30749
+ const qtIdx = meta.quoteTokenIndexMap[entry.oracle];
30750
+ if (qtIdx === void 0) continue;
30751
+ const rawQt = data[qtIdx];
30752
+ if (!rawQt || rawQt === "0x") continue;
30753
+ const quoteTokenAddr = rawQt.toLowerCase();
30754
+ const qtMeta = context.tokenList?.[quoteTokenAddr];
30755
+ const qtDecimals = qtMeta?.decimals ?? 18;
30756
+ const priceInQt = Number(quoteAmount) / Number(10n ** BigInt(qtDecimals));
30757
+ if (isNaN(priceInQt) || priceInQt === 0) continue;
30758
+ const qtUSD = lookupUSD2(context, quoteTokenAddr);
30759
+ if (!qtUSD) continue;
30760
+ rawPrice = priceInQt;
30761
+ priceUSD = priceInQt * qtUSD;
30762
+ }
30763
+ if (isNaN(priceUSD) || priceUSD === 0) continue;
30764
+ entries.push({
30765
+ asset: entry.token,
30766
+ price: rawPrice,
30767
+ priceUSD,
30768
+ marketUid: createMarketUid(
30769
+ context.chainId,
30770
+ entry.lenderKey,
30771
+ entry.silo
30772
+ ),
30773
+ targetLender: entry.lenderKey,
30774
+ ...entry.isStatic ? { staticBase: true, baseAsset: entry.token } : {}
30775
+ });
30776
+ seen.add(dedupKey);
30777
+ } catch {
30778
+ }
30779
+ }
30780
+ return entries;
30781
+ }
30782
+ function getSiloV3Abi() {
30783
+ return SiloOracleAbi2;
30784
+ }
30785
+ var siloV3Fetcher = {
30786
+ getCalls: getSiloV3Calls,
30787
+ parse: parseSiloV3Results,
30788
+ getAbi: getSiloV3Abi
30789
+ };
30790
+
30791
+ // src/prices/oracle-prices/fetchers/siloV2Graphql.ts
30792
+ async function fetchSiloV2GraphQLMarkets(chainId) {
30793
+ if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return null;
30794
+ try {
30795
+ const items = await fetchSiloMarkets(chainId, { protocolVersion: "v2" });
30796
+ return items;
30797
+ } catch (e) {
30798
+ console.warn(
30799
+ `[prices] Silo v2 GraphQL fetch failed on chain ${chainId}:`,
30800
+ e?.message ?? e
30801
+ );
30802
+ return null;
30803
+ }
30804
+ }
30805
+ function safeNumber3(v) {
30806
+ if (v == null) return 0;
30807
+ const n = typeof v === "number" ? v : Number(v);
30808
+ return Number.isFinite(n) ? n : 0;
30809
+ }
30810
+ function lookupUSD3(context, asset) {
30811
+ const lc = asset.toLowerCase();
30812
+ const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
30813
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
30814
+ }
30815
+ function parseSiloV2GraphQLResults(items, context) {
30816
+ const ZERO_ADDRESS3 = "0x0000000000000000000000000000000000000000";
30817
+ const out = [];
30818
+ const seen = /* @__PURE__ */ new Set();
30819
+ for (const item of items) {
30820
+ let lenderKey;
30821
+ try {
30822
+ lenderKey = siloV2LenderKey(item.configAddress);
30823
+ } catch {
30824
+ continue;
30825
+ }
30826
+ const registryEntry = getSiloV2MarketEntry(context.chainId, lenderKey);
30827
+ if (!registryEntry) continue;
30828
+ const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
30829
+ const sideTuples = [
30830
+ { api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
30831
+ { api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
30832
+ ];
30833
+ for (const { api: side, self, other } of sideTuples) {
30834
+ const tokenLc = (side.inputTokenId ?? side.inputToken?.id ?? self.token).toLowerCase();
30835
+ if (!tokenLc) continue;
30836
+ const partnerTokenLc = other.token.toLowerCase();
30837
+ const dedupKey = `${lenderKey}:${tokenLc}`;
30838
+ if (seen.has(dedupKey)) continue;
30839
+ const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS3).toLowerCase();
30840
+ const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS3;
30841
+ const siloAddrLc = self.silo.toLowerCase();
30842
+ try {
30843
+ let priceUSD = 0;
30844
+ let rawPrice = 1;
30845
+ const supplyNum = safeNumber3(side.supply);
30846
+ const supplyUsdNum = side.supplyUsd != null ? Number(side.supplyUsd) : 0;
30847
+ const borrowedNum = safeNumber3(side.borrowed);
30848
+ const borrowedUsdNum = side.borrowedUsd != null ? Number(side.borrowedUsd) : 0;
30849
+ if (supplyNum > 0 && supplyUsdNum > 0) {
30850
+ priceUSD = supplyUsdNum / supplyNum;
30851
+ rawPrice = isStatic ? 1 : priceUSD;
30852
+ } else if (borrowedNum > 0 && borrowedUsdNum > 0) {
30853
+ priceUSD = borrowedUsdNum / borrowedNum;
30854
+ rawPrice = isStatic ? 1 : priceUSD;
30855
+ } else if (isStatic) {
30856
+ const ownUSD = lookupUSD3(context, tokenLc);
30857
+ const partnerUSD = partnerTokenLc ? lookupUSD3(context, partnerTokenLc) : 0;
30858
+ priceUSD = ownUSD || partnerUSD;
30859
+ if (!priceUSD) continue;
30860
+ rawPrice = 1;
30861
+ } else {
30862
+ const quoteStr = side.solvencyOracle?.quote;
30863
+ if (!quoteStr) continue;
30864
+ const quoteNum = Number(quoteStr);
30865
+ if (!Number.isFinite(quoteNum) || quoteNum === 0) continue;
30866
+ const quoteTokenLc = (side.solvencyOracle?.quoteTokenId ?? "").toLowerCase();
30867
+ if (!quoteTokenLc) continue;
30868
+ const qtUSD = lookupUSD3(context, quoteTokenLc);
30869
+ if (!qtUSD) continue;
30870
+ rawPrice = quoteNum;
30871
+ priceUSD = quoteNum * qtUSD;
30872
+ }
30873
+ if (!Number.isFinite(priceUSD) || priceUSD === 0) continue;
30874
+ out.push({
30875
+ asset: tokenLc,
30876
+ price: rawPrice,
30877
+ priceUSD,
30878
+ marketUid: createMarketUid(context.chainId, lenderKey, siloAddrLc),
30879
+ targetLender: lenderKey,
30880
+ ...isStatic ? { staticBase: true, baseAsset: tokenLc } : {}
30881
+ });
30882
+ seen.add(dedupKey);
30883
+ } catch {
30884
+ }
30885
+ }
30886
+ }
30887
+ return out;
30888
+ }
30889
+
30890
+ // src/prices/oracle-prices/fetchers/siloV3Graphql.ts
30891
+ async function fetchSiloV3GraphQLMarkets(chainId) {
30892
+ if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return null;
30893
+ try {
30894
+ const items = await fetchSiloMarkets(chainId, { protocolVersion: "v3" });
30895
+ return items;
30896
+ } catch (e) {
30897
+ console.warn(
30898
+ `[prices] Silo v3 GraphQL fetch failed on chain ${chainId}:`,
30899
+ e?.message ?? e
30900
+ );
30901
+ return null;
30902
+ }
30903
+ }
30904
+ function safeNumber4(v) {
30905
+ if (v == null) return 0;
30906
+ const n = typeof v === "number" ? v : Number(v);
30907
+ return Number.isFinite(n) ? n : 0;
30908
+ }
30909
+ function lookupUSD4(context, asset) {
30910
+ const lc = asset.toLowerCase();
30911
+ const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
30912
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
30913
+ }
30914
+ function parseSiloV3GraphQLResults(items, context) {
30915
+ const ZERO_ADDRESS3 = "0x0000000000000000000000000000000000000000";
30916
+ const out = [];
30917
+ const seen = /* @__PURE__ */ new Set();
30918
+ for (const item of items) {
30919
+ let lenderKey;
30920
+ try {
30921
+ lenderKey = siloV3LenderKey(item.configAddress);
30922
+ } catch {
30923
+ continue;
30924
+ }
30925
+ const registryEntry = getSiloV3MarketEntry(context.chainId, lenderKey);
30926
+ if (!registryEntry) continue;
30927
+ const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
30928
+ const sideTuples = [
30929
+ { api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
30930
+ { api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
30931
+ ];
30932
+ for (const { api: side, self, other } of sideTuples) {
30933
+ const tokenLc = (side.inputTokenId ?? side.inputToken?.id ?? self.token).toLowerCase();
30934
+ if (!tokenLc) continue;
30935
+ const partnerTokenLc = other.token.toLowerCase();
30936
+ const dedupKey = `${lenderKey}:${tokenLc}`;
30937
+ if (seen.has(dedupKey)) continue;
30938
+ const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS3).toLowerCase();
30939
+ const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS3;
30940
+ const siloAddrLc = self.silo.toLowerCase();
30941
+ try {
30942
+ let priceUSD = 0;
30943
+ let rawPrice = 1;
30944
+ const supplyNum = safeNumber4(side.supply);
30945
+ const supplyUsdNum = side.supplyUsd != null ? Number(side.supplyUsd) : 0;
30946
+ const borrowedNum = safeNumber4(side.borrowed);
30947
+ const borrowedUsdNum = side.borrowedUsd != null ? Number(side.borrowedUsd) : 0;
30948
+ if (supplyNum > 0 && supplyUsdNum > 0) {
30949
+ priceUSD = supplyUsdNum / supplyNum;
30950
+ rawPrice = isStatic ? 1 : priceUSD;
30951
+ } else if (borrowedNum > 0 && borrowedUsdNum > 0) {
30952
+ priceUSD = borrowedUsdNum / borrowedNum;
30953
+ rawPrice = isStatic ? 1 : priceUSD;
30954
+ } else if (isStatic) {
30955
+ const ownUSD = lookupUSD4(context, tokenLc);
30956
+ const partnerUSD = partnerTokenLc ? lookupUSD4(context, partnerTokenLc) : 0;
30957
+ priceUSD = ownUSD || partnerUSD;
30958
+ if (!priceUSD) continue;
30959
+ rawPrice = 1;
30960
+ } else {
30961
+ const quoteStr = side.solvencyOracle?.quote;
30962
+ if (!quoteStr) continue;
30963
+ const quoteNum = Number(quoteStr);
30964
+ if (!Number.isFinite(quoteNum) || quoteNum === 0) continue;
30965
+ const quoteTokenLc = (side.solvencyOracle?.quoteTokenId ?? "").toLowerCase();
30966
+ if (!quoteTokenLc) continue;
30967
+ const qtUSD = lookupUSD4(context, quoteTokenLc);
30968
+ if (!qtUSD) continue;
30969
+ rawPrice = quoteNum;
30970
+ priceUSD = quoteNum * qtUSD;
30971
+ }
30972
+ if (!Number.isFinite(priceUSD) || priceUSD === 0) continue;
30973
+ out.push({
30974
+ asset: tokenLc,
30975
+ price: rawPrice,
30976
+ priceUSD,
30977
+ marketUid: createMarketUid(context.chainId, lenderKey, siloAddrLc),
30978
+ targetLender: lenderKey,
30979
+ ...isStatic ? { staticBase: true, baseAsset: tokenLc } : {}
30980
+ });
30981
+ seen.add(dedupKey);
30982
+ } catch {
30983
+ }
30984
+ }
30985
+ }
30986
+ return out;
30987
+ }
30988
+
29337
30989
  // src/prices/oracle-prices/fetchOraclePrices.ts
29338
30990
  function countFailures(data, offset, count) {
29339
30991
  let failures = 0;
@@ -29484,6 +31136,16 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29484
31136
  }),
29485
31137
  getCallsErrors
29486
31138
  ) : [];
31139
+ const siloV2Results = isActive("silov2") ? safeGetCalls(
31140
+ "siloV2",
31141
+ () => siloV2Fetcher.getCalls(chainId),
31142
+ getCallsErrors
31143
+ ) : [];
31144
+ const siloV3Results = isActive("silov3") ? safeGetCalls(
31145
+ "siloV3",
31146
+ () => siloV3Fetcher.getCalls(chainId),
31147
+ getCallsErrors
31148
+ ) : [];
29487
31149
  const aaveGroup = buildGroup(
29488
31150
  "aave",
29489
31151
  aaveResults,
@@ -29526,6 +31188,18 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29526
31188
  morphoFetcher.parse,
29527
31189
  ProxyOracleAbi
29528
31190
  );
31191
+ const siloV2Group = buildGroup(
31192
+ "siloV2",
31193
+ siloV2Results,
31194
+ siloV2Fetcher.parse,
31195
+ getSiloV2Abi()
31196
+ );
31197
+ const siloV3Group = buildGroup(
31198
+ "siloV3",
31199
+ siloV3Results,
31200
+ siloV3Fetcher.parse,
31201
+ getSiloV3Abi()
31202
+ );
29529
31203
  const allGroups = [
29530
31204
  aaveGroup,
29531
31205
  compoundV2Group,
@@ -29533,7 +31207,9 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29533
31207
  listaGroup,
29534
31208
  eulerGroup,
29535
31209
  aaveV4Group,
29536
- morphoGroup
31210
+ morphoGroup,
31211
+ siloV2Group,
31212
+ siloV3Group
29537
31213
  ];
29538
31214
  const totalCalls = allGroups.reduce((s, g) => s + g.calls.length, 0);
29539
31215
  if (totalCalls === 0 && !isActive("morpho")) {
@@ -29552,6 +31228,8 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29552
31228
  }
29553
31229
  const chainBatchSize = batchSize?.[chainId];
29554
31230
  const morphoGqlPromise = isActive("morpho") ? fetchMorphoGraphQLPrices(chainId) : Promise.resolve(null);
31231
+ const siloV2GqlPromise = fetchSiloV2GraphQLMarkets(chainId);
31232
+ const siloV3GqlPromise = fetchSiloV3GraphQLMarkets(chainId);
29555
31233
  const [
29556
31234
  aaveData,
29557
31235
  compoundV2Data,
@@ -29559,7 +31237,9 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29559
31237
  listaData,
29560
31238
  eulerData,
29561
31239
  aaveV4Data,
29562
- morphoGqlEntries
31240
+ morphoGqlEntries,
31241
+ siloV2GqlItems,
31242
+ siloV3GqlItems
29563
31243
  ] = await Promise.all([
29564
31244
  executeGroup(
29565
31245
  aaveGroup,
@@ -29609,10 +31289,40 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29609
31289
  allowFailure,
29610
31290
  rpcOverrides
29611
31291
  ),
29612
- morphoGqlPromise
31292
+ morphoGqlPromise,
31293
+ siloV2GqlPromise,
31294
+ siloV3GqlPromise
29613
31295
  ]);
31296
+ if (siloV2GqlItems == null && siloV2Group.calls.length > 0) {
31297
+ console.warn(
31298
+ `[prices] chain ${chainId}: Silo v2 GraphQL unavailable, falling back to on-chain (${siloV2Group.trackers.length} trackers)`
31299
+ );
31300
+ }
31301
+ const siloV2Data = siloV2GqlItems != null ? { results: [], error: void 0 } : await executeGroup(
31302
+ siloV2Group,
31303
+ chainId,
31304
+ chainBatchSize,
31305
+ retries,
31306
+ allowFailure,
31307
+ rpcOverrides
31308
+ );
31309
+ if (siloV3GqlItems == null && siloV3Group.calls.length > 0) {
31310
+ console.warn(
31311
+ `[prices] chain ${chainId}: Silo v3 GraphQL unavailable, falling back to on-chain (${siloV3Group.trackers.length} trackers)`
31312
+ );
31313
+ }
31314
+ const siloV3Data = siloV3GqlItems != null ? { results: [], error: void 0 } : await executeGroup(
31315
+ siloV3Group,
31316
+ chainId,
31317
+ chainBatchSize,
31318
+ retries,
31319
+ allowFailure,
31320
+ rpcOverrides
31321
+ );
29614
31322
  if (morphoGqlEntries == null && isActive("morpho")) {
29615
- console.warn(`[prices] chain ${chainId}: Morpho GraphQL returned null, falling back to on-chain (${morphoGroup.trackers.length} trackers)`);
31323
+ console.warn(
31324
+ `[prices] chain ${chainId}: Morpho GraphQL returned null, falling back to on-chain (${morphoGroup.trackers.length} trackers)`
31325
+ );
29616
31326
  }
29617
31327
  const morphoData = morphoGqlEntries != null ? { results: [], error: void 0 } : await executeGroup(
29618
31328
  morphoGroup,
@@ -29630,6 +31340,8 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29630
31340
  { group: listaGroup, data: listaData },
29631
31341
  { group: eulerGroup, data: eulerData },
29632
31342
  { group: aaveV4Group, data: aaveV4Data },
31343
+ ...siloV2GqlItems != null ? [] : [{ group: siloV2Group, data: siloV2Data }],
31344
+ ...siloV3GqlItems != null ? [] : [{ group: siloV3Group, data: siloV3Data }],
29633
31345
  ...useMorphoGql ? [] : [{ group: morphoGroup, data: morphoData }]
29634
31346
  ];
29635
31347
  for (const { group, data } of groupResults) {
@@ -29714,6 +31426,48 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29714
31426
  true,
29715
31427
  (t) => !!t.meta.baseAssetSource
29716
31428
  );
31429
+ if (siloV2GqlItems != null) {
31430
+ const context = { chainId, usdPrices, tokenList };
31431
+ const entries = parseSiloV2GraphQLResults(siloV2GqlItems, context);
31432
+ const diag2 = {
31433
+ lender: "SILO_V2 (GraphQL)",
31434
+ callCount: 0,
31435
+ failedCalls: 0,
31436
+ parsedEntries: entries.length
31437
+ };
31438
+ for (const entry of entries) {
31439
+ const lender = entry.targetLender ?? "SILO_V2";
31440
+ if (!chainResult[lender]) chainResult[lender] = [];
31441
+ chainResult[lender].push(entry);
31442
+ const oracleKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset}`;
31443
+ usdPrices[oracleKey] = entry.priceUSD;
31444
+ usdPrices[entry.asset] = entry.priceUSD;
31445
+ }
31446
+ trackerDiags.push(diag2);
31447
+ } else {
31448
+ parseTrackers(siloV2Group, siloV2Data.results);
31449
+ }
31450
+ if (siloV3GqlItems != null) {
31451
+ const context = { chainId, usdPrices, tokenList };
31452
+ const entries = parseSiloV3GraphQLResults(siloV3GqlItems, context);
31453
+ const diag2 = {
31454
+ lender: "SILO_V3 (GraphQL)",
31455
+ callCount: 0,
31456
+ failedCalls: 0,
31457
+ parsedEntries: entries.length
31458
+ };
31459
+ for (const entry of entries) {
31460
+ const lender = entry.targetLender ?? "SILO_V3";
31461
+ if (!chainResult[lender]) chainResult[lender] = [];
31462
+ chainResult[lender].push(entry);
31463
+ const oracleKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset}`;
31464
+ usdPrices[oracleKey] = entry.priceUSD;
31465
+ usdPrices[entry.asset] = entry.priceUSD;
31466
+ }
31467
+ trackerDiags.push(diag2);
31468
+ } else {
31469
+ parseTrackers(siloV3Group, siloV3Data.results);
31470
+ }
29717
31471
  if (useMorphoGql) {
29718
31472
  const morphoGqlDiag = {
29719
31473
  lender: "MORPHO_BLUE (GraphQL)",
@@ -30589,21 +32343,21 @@ function prepareTokenBalanceRpcCalls(chainId, account, tokens, blockTag = "lates
30589
32343
  encodedCalldata
30590
32344
  };
30591
32345
  }
30592
- function parseTokenBalanceResult(rawResult, query2) {
32346
+ function parseTokenBalanceResult(rawResult, query3) {
30593
32347
  if (!rawResult || rawResult === "0x") {
30594
32348
  return {};
30595
32349
  }
30596
32350
  const parsed = parseBalanceFetcherResult(
30597
32351
  rawResult,
30598
- [query2.account],
30599
- query2.tokens
32352
+ [query3.account],
32353
+ query3.tokens
30600
32354
  );
30601
32355
  if (parsed.balances.length === 0) {
30602
32356
  return {};
30603
32357
  }
30604
32358
  const result = {};
30605
32359
  const userBalances = parsed.balances[0].balances;
30606
- for (const token of query2.tokens) {
32360
+ for (const token of query3.tokens) {
30607
32361
  const balanceEntry = userBalances[token];
30608
32362
  if (balanceEntry) {
30609
32363
  result[token] = {