@1delta/margin-fetcher 5.0.59 → 5.0.61

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
@@ -1,7 +1,7 @@
1
- import { parseAbi, keccak256, encodeAbiParameters, formatEther, BaseError, erc20Abi, stringToHex, isAddress, pad, encodeFunctionData, formatUnits, getAddress, decodeFunctionResult, decodeAbiParameters, concat, AbiEncodingLengthMismatchError, concatHex, toBytes, slice, hexToString, parseAbiParameters, InvalidAddressError, boolToHex, integerRegex, numberToHex, bytesRegex, BytesSizeMismatchError, arrayRegex, UnsupportedPackedAbiType } from './chunk-JUYF2XLF.js';
1
+ import { parseAbi, keccak256, encodeAbiParameters, formatEther, BaseError, erc20Abi, stringToHex, isAddress, pad, encodeFunctionData, formatUnits, getAddress, decodeFunctionResult, decodeAbiParameters, concat, parseAbiParameters, AbiEncodingLengthMismatchError, concatHex, toBytes, slice, hexToString, InvalidAddressError, boolToHex, integerRegex, numberToHex, bytesRegex, BytesSizeMismatchError, arrayRegex, UnsupportedPackedAbiType } from './chunk-JUYF2XLF.js';
2
2
  import './chunk-BYTNVMX7.js';
3
3
  import './chunk-PR4QN5HX.js';
4
- import { Lender, isExactly, isMidnight, isTerm, isTermMax, isTeller, isListaDao, isLiquityFamily, isRiver, isInverse, isCooler, isDssType, isCompoundV3Type, isFluid, isGearboxV3, isLlamaLend, isFrankencoin, isResupply, isCurvance, isTwyne, isFraxlend, LIQUITY_FAMILY_LENDERS, isAaveType, isCompoundV3, isMultiMarket, isSiloV2Type, isSiloV3Type, isDolomite, hasCrossMarginRisk, isEulerType, isAaveV4Type, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isMorphoBlue, isAaveV2Type, isAaveV32Type, isAaveV3Type, isUsdd, isSky, isYLDR, isLista, hasSubAccounts, isTectonicType, isKineticType, isBenqiType } from '@1delta/lender-registry';
4
+ import { Lender, isExactly, isMidnight, isTerm, isTermMax, isTeller, isListaDao, isLiquityFamily, isRiver, isInverse, isCooler, isDssType, isCompoundV3Type, isFluid, isGearboxV3, isLlamaLend, isFrankencoin, isResupply, isCurvance, isTwyne, isFraxlend, LIQUITY_FAMILY_LENDERS, isAaveType, isCompoundV3, isMultiMarket, isSiloV2Type, isSiloV3Type, isDolomite, isMorphoType, isUsdd, isSky, hasCrossMarginRisk, isEulerType, isAaveV4Type, isInit, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isMorphoBlue, isAaveV2Type, isAaveV32Type, isAaveV3Type, isYLDR, isLista, hasSubAccounts, isTectonicType, isKineticType, isBenqiType } from '@1delta/lender-registry';
5
5
  export { hasCrossMarginRisk, isAaveType, isAaveV2Type, isAaveV32Type, isAaveV3Type, isCompoundV3, isCompoundV3Type, isInit, isMorphoType, isMultiMarket, isYLDR } from '@1delta/lender-registry';
6
6
  import { fetchTokenLists, fetchTokenList, aavePools, compoundV3Pools, initConfig, morphoPools, compoundV2Pools, eulerVaults, siloMarkets, siloV2LenderKey, siloMarketsV3, siloV3LenderKey, aaveV4Spokes, aaveV4SpokeLenderKey, fluidResolvers, gearboxResolvers, dolomiteConfigs, midnightConfig, termConfig, termMarketsByChain, exactlyConfig, liquityLendersByChain, riverLendersByChain, inverseLendersByChain, coolerLendersByChain, llamaLendLendersByChain, usddLendersByChain, skyLendersByChain, frankencoinLendersByChain, resupplyLendersByChain, curvanceLendersByChain, fraxlendLendersByChain, twyneLendersByChain, tellerConfigByChain, tellerPoolsByChain, termMaxConfigByChain, aaveReserves, compoundV3Reserves, resolveTermApiBase, liquityConfigFor, liquityBranchesByChain, riverConfigFor, riverChainData, termMaxApiBaseUrl, termMaxLenderKey, inverseConfigFor, inverseChainData, coolerConfigFor, llamaLendConfigFor, llamaLendChainData, llamaLendApiBaseUrl, resupplyConfigFor, fraxlendConfigFor, dssConfigFor, dssChainData, dssDebtToken, dssDebtJoin, frankencoinConfigFor, frankencoinChainData, aaveOracles, morphoTypeMarkets, resolveMidnightApiBase, llamaLendMarketByVault, getSiloV2MarketEntry, getSiloV3MarketEntry, dolomiteEmode, curvanceConfigFor, aaveTokens, morphoTypeVaults, listaCollateralProvider, eulerConfigs, gearboxMarketCompressor, gearboxMarketConfigurators, gearboxV3LenderKey, midnightMarketsByChain, twyneConfigFor, twyneChainData, parseAaveV4SpokeLenderKey, fraxlendPairsFor, gearboxAccountCompressor, compoundV2Tokens, exactlyMarketsByChain, aaveOraclesConfig, compoundV2Oracles, compoundV2TokenArray, compoundV2OraclesConfig, compoundV3OraclesData, compoundV3BaseData, compoundV2Reserves, aaveV4Oracles, morphoTypeOracles } from '@1delta/data-sdk';
7
7
  import lodash from 'lodash';
@@ -6325,10 +6325,45 @@ var ENABLED_COMPOUNDS = [
6325
6325
  Lender.SEGMENT,
6326
6326
  Lender.COMPOUND_V2,
6327
6327
  Lender.FLUX_FINANCE,
6328
- Lender.CAPY_FI
6328
+ Lender.CAPY_FI,
6329
+ // Long-tail forks read through a shared CompoundLens on their chain
6330
+ // (addresses/compoundV2.ts). Enabled only where a lens exists AND the
6331
+ // markets are open; the rest of the `lender-metadata` long tail stays off
6332
+ // this list — see the table in
6333
+ // `lending/public-data/compound-v2/README.md`.
6334
+ Lender.DEMETER,
6335
+ Lender.LANDER,
6336
+ Lender.FILDA,
6337
+ Lender.SOLIDLIZARD,
6338
+ // Reachable since the CompoundV2MarketLens deployment on Optimism, Linea and
6339
+ // Base (2026-08-24). Xpert is deliberately NOT here: 4 of its 6 Base markets
6340
+ // revert their own `exchangeRateStored`, so the lens reads them as zero and
6341
+ // serving them would publish a market with no exchange rate.
6342
+ Lender.IRON_BANK,
6343
+ Lender.MENDI,
6344
+ Lender.PAXO,
6345
+ Lender.SONNE,
6346
+ Lender.ASO_FINANCE,
6347
+ Lender.BLUME,
6348
+ Lender.KAWA,
6349
+ Lender.XPERT,
6350
+ // Manta and zkSync Era joined the lens rollout. KEOM_STONE is deliberately
6351
+ // absent: 1 of its 2 markets (kSTONE) exposes no exchange-rate getter at all,
6352
+ // so half the pool would publish with `exchangeRate = 0`.
6353
+ Lender.KEOM,
6354
+ Lender.REACTOR_FUSION
6329
6355
  ];
6330
6356
  var DISABLED_COMPOUNDS = {
6331
- [Chain.ETHEREUM_MAINNET]: [Lender.CREAM_FINANCE]
6357
+ [Chain.ETHEREUM_MAINNET]: [Lender.CREAM_FINANCE],
6358
+ // FilDA's IoTeX deployment: no lens on that chain, and all 9 markets are
6359
+ // mint+borrow paused with `seizeGuardianPaused` set globally. Its BNB
6360
+ // deployment is open and stays enabled.
6361
+ [Chain.IOTEX_NETWORK_MAINNET]: [Lender.FILDA],
6362
+ // Xpert on Base: 4 of its 6 markets revert their OWN `exchangeRateStored`
6363
+ // (checked against two independent RPCs), so any lens reads them as zero and
6364
+ // serving them would publish markets with no exchange rate. Its Ink
6365
+ // deployment reads 5/5 clean and stays enabled.
6366
+ [Chain.BASE]: [Lender.XPERT]
6332
6367
  };
6333
6368
  var isExcludedLender = (lender) => {
6334
6369
  if (lender === Lender.PLOUTOS) return true;
@@ -12821,7 +12856,8 @@ var SUMER_LENS = {
12821
12856
  };
12822
12857
  var MOONWELL_LENS = {
12823
12858
  [Chain.OP_MAINNET]: "0xD6C66868f937f00604d0FB860241970D6CC2CBfE",
12824
- [Chain.BASE]: "0x6834770aba6c2028f448e3259ddee4bcb879d459"
12859
+ [Chain.BASE]: "0x6834770aba6c2028f448e3259ddee4bcb879d459",
12860
+ [Chain.ETHEREUM_MAINNET]: "0x2d85b9c48a8c582f0AA244e134e9C6f30Cf7786e"
12825
12861
  };
12826
12862
  var ENCLABS_LENS = {
12827
12863
  [Chain.SONIC_MAINNET]: "0x3567B16050cB90236997eF47B1941502e85d65f3",
@@ -12868,15 +12904,45 @@ var SEGMENT_LENS = {
12868
12904
  var ROBUST_LENS = {
12869
12905
  [Chain.ETHEREUM_MAINNET]: "0x92ee472A52A79AB407aED9FE0deB512d230baF87"
12870
12906
  };
12907
+ var COMPOUND_V2_MARKET_LENS = "0xD16EC79B110f27AA2EEEc913087823Df032121E4";
12908
+ var MARKET_LENS = {
12909
+ [Chain.OP_MAINNET]: COMPOUND_V2_MARKET_LENS,
12910
+ [Chain.XDC_NETWORK]: COMPOUND_V2_MARKET_LENS,
12911
+ [Chain.SEI_NETWORK]: COMPOUND_V2_MARKET_LENS,
12912
+ [Chain.MORPH]: COMPOUND_V2_MARKET_LENS,
12913
+ [Chain.BASE]: COMPOUND_V2_MARKET_LENS,
12914
+ [Chain.AVALANCHE_C_CHAIN]: COMPOUND_V2_MARKET_LENS,
12915
+ [Chain.INK]: COMPOUND_V2_MARKET_LENS,
12916
+ [Chain.LINEA]: COMPOUND_V2_MARKET_LENS,
12917
+ [Chain.BLAST]: COMPOUND_V2_MARKET_LENS,
12918
+ [Chain.MANTA_PACIFIC_MAINNET]: COMPOUND_V2_MARKET_LENS,
12919
+ /**
12920
+ * zkSync Era is the one chain where the address differs. zk-stack chains
12921
+ * derive contract addresses from a registered bytecode hash rather than
12922
+ * `keccak(0xff ‖ factory ‖ salt ‖ initCodeHash)`, so the CREATE2 factory path
12923
+ * is skipped there (see the deploy script) and this is the nonce-derived
12924
+ * address of the same runtime — byte-identical to the other nine, verified
12925
+ * against the compiled artifact.
12926
+ */
12927
+ [Chain.ZKSYNC_MAINNET]: "0x6Bc6aCB905c1216B0119C87Bf9E178ce298310FA"
12928
+ };
12871
12929
  var CREAM_LENS = {
12872
12930
  [Chain.ETHEREUM_MAINNET]: "0x92ee472A52A79AB407aED9FE0deB512d230baF87",
12873
12931
  [Chain.BNB_SMART_CHAIN_MAINNET]: "0x1A014Ffe0cd187A298a7E79BA5ab05538686ea4a",
12874
12932
  [Chain.POLYGON_MAINNET]: "0x139Dd8Bb6355d20342e08ff013150b1aE5040a42",
12875
- [Chain.ARBITRUM_ONE]: "0x139Dd8Bb6355d20342e08ff013150b1aE5040a42"
12933
+ [Chain.ARBITRUM_ONE]: "0x139Dd8Bb6355d20342e08ff013150b1aE5040a42",
12934
+ // Cream's Base deployment has no lens of its own; ours serves it.
12935
+ [Chain.BASE]: COMPOUND_V2_MARKET_LENS
12876
12936
  };
12877
12937
  var GAMMA_LENS = {
12878
12938
  [Chain.BNB_SMART_CHAIN_MAINNET]: "0xcaf6856f6Ec1B66EE89dD296D2020dfA431D8f6B"
12879
12939
  };
12940
+ var SHARED_LENS_BNB = {
12941
+ [Chain.BNB_SMART_CHAIN_MAINNET]: "0x560dD9b47d40E0cd0aEDA326e46BeD25249d936A"
12942
+ };
12943
+ var SHARED_LENS_ARBITRUM = {
12944
+ [Chain.ARBITRUM_ONE]: "0x14Ec7324753340Bd8685496da14c4B173ac05b18"
12945
+ };
12880
12946
  var COMPOUND_V2_LENS = {
12881
12947
  [Lender.VENUS]: VENUS_LENS,
12882
12948
  [Lender.VENUS_ETH]: VENUS_LENS,
@@ -12901,7 +12967,25 @@ var COMPOUND_V2_LENS = {
12901
12967
  [Lender.SEGMENT]: SEGMENT_LENS,
12902
12968
  [Lender.CREAM_FINANCE]: CREAM_LENS,
12903
12969
  [Lender.GAMMA]: GAMMA_LENS,
12904
- [Lender.CAPY_FI]: ROBUST_LENS
12970
+ [Lender.CAPY_FI]: ROBUST_LENS,
12971
+ [Lender.DEMETER]: SHARED_LENS_BNB,
12972
+ [Lender.LANDER]: SHARED_LENS_BNB,
12973
+ // FilDA also has an IoTeX deployment; it is NOT wired here (no lens on that
12974
+ // chain, and all 9 of its IoTeX markets are mint+borrow paused) and is held
12975
+ // back by `DISABLED_COMPOUNDS` in `utils/index.ts`.
12976
+ [Lender.FILDA]: SHARED_LENS_BNB,
12977
+ [Lender.SOLIDLIZARD]: SHARED_LENS_ARBITRUM,
12978
+ // Served by our own CompoundV2MarketLens deployment.
12979
+ [Lender.IRON_BANK]: MARKET_LENS,
12980
+ [Lender.MENDI]: MARKET_LENS,
12981
+ [Lender.PAXO]: MARKET_LENS,
12982
+ [Lender.SONNE]: MARKET_LENS,
12983
+ [Lender.ASO_FINANCE]: MARKET_LENS,
12984
+ [Lender.BLUME]: MARKET_LENS,
12985
+ [Lender.KAWA]: MARKET_LENS,
12986
+ [Lender.XPERT]: MARKET_LENS,
12987
+ [Lender.KEOM]: MARKET_LENS,
12988
+ [Lender.REACTOR_FUSION]: MARKET_LENS
12905
12989
  };
12906
12990
  function getCompoundV2Comptroller(chainId, lender = Lender.VENUS) {
12907
12991
  return compoundV2Pools()?.[lender]?.[chainId];
@@ -15028,7 +15112,24 @@ var COMPTROLLER_PAUSE_READ_LENDERS = [
15028
15112
  Lender.GAMMA,
15029
15113
  Lender.CAPY_FI,
15030
15114
  Lender.LODESTAR,
15031
- Lender.TENDER
15115
+ Lender.TENDER,
15116
+ // Long-tail forks on the shared lenses — same plain `cTokenMetadata`, same
15117
+ // missing pause field. Their Comptrollers DO answer both guardian getters
15118
+ // (verified 2026-08-24), so the live read resolves every market.
15119
+ Lender.DEMETER,
15120
+ Lender.LANDER,
15121
+ Lender.FILDA,
15122
+ Lender.SOLIDLIZARD,
15123
+ Lender.IRON_BANK,
15124
+ Lender.MENDI,
15125
+ Lender.PAXO,
15126
+ Lender.SONNE,
15127
+ Lender.ASO_FINANCE,
15128
+ Lender.BLUME,
15129
+ Lender.KAWA,
15130
+ Lender.XPERT,
15131
+ Lender.KEOM,
15132
+ Lender.REACTOR_FUSION
15032
15133
  ];
15033
15134
  var usesComptrollerPauseReads = (lender) => COMPTROLLER_PAUSE_READ_LENDERS.includes(lender);
15034
15135
  var parsePausedFlag = (raw) => typeof raw === "boolean" ? raw : void 0;
@@ -15041,6 +15142,7 @@ var resolveMarketPause = (token, live) => {
15041
15142
 
15042
15143
  // src/lending/public-data/compound-v2/publicCallBuild.ts
15043
15144
  var buildCompoundV2StyleLenderReserveCall = (chainId, lender) => {
15145
+ if (!getCompoundV2Lens(chainId, lender)) return [];
15044
15146
  if (lender === Lender.TAKARA) {
15045
15147
  const lens = getCompoundV2Lens(chainId, lender);
15046
15148
  return [
@@ -15178,7 +15280,10 @@ function getCall(lender, chainId) {
15178
15280
  params: [tk]
15179
15281
  });
15180
15282
  }
15181
- if (lender === Lender.CREAM_FINANCE || lender === Lender.GAMMA || lender === Lender.TENDER || lender === Lender.COMPOUND_V2 || lender === Lender.CAPY_FI || lender === Lender.FLUX_FINANCE || lender === Lender.WE_PIGGY) {
15283
+ if (lender === Lender.CREAM_FINANCE || lender === Lender.GAMMA || lender === Lender.TENDER || lender === Lender.COMPOUND_V2 || lender === Lender.CAPY_FI || lender === Lender.FLUX_FINANCE || lender === Lender.WE_PIGGY || // long-tail forks served by a shared lens on their chain — see
15284
+ // SHARED_LENS_BNB / SHARED_LENS_ARBITRUM in addresses/compoundV2.ts
15285
+ lender === Lender.DEMETER || lender === Lender.LANDER || lender === Lender.FILDA || lender === Lender.SOLIDLIZARD || // served by our own CompoundV2MarketLens deployment (same 14-field struct)
15286
+ lender === Lender.IRON_BANK || lender === Lender.MENDI || lender === Lender.PAXO || lender === Lender.SONNE || lender === Lender.ASO_FINANCE || lender === Lender.BLUME || lender === Lender.KAWA || lender === Lender.XPERT || lender === Lender.KEOM || lender === Lender.REACTOR_FUSION) {
15182
15287
  return (tk) => ({
15183
15288
  abi: CreamLensAbi,
15184
15289
  address: lens,
@@ -15559,9 +15664,20 @@ var RESERVE_MANTISSA_DECIMALS = 18;
15559
15664
  var DEFAULT_CLOSE_FACTOR = 0.5;
15560
15665
  var DEFAULT_LIQUIDATION_PENALTY = 0.08;
15561
15666
 
15667
+ // src/lending/public-data/compound-v2/convert/liquidity.ts
15668
+ var cashLiquidity = (raw, decimals) => raw === void 0 || raw === null ? void 0 : Number(parseRawAmount(raw.toString(), decimals));
15669
+
15562
15670
  // src/lending/public-data/compound-v2/convert/standard.ts
15563
15671
  var COMPOUND_V2_NAME_OVERRIDES = {
15564
- "0xccf4429db6322d5c611ee964527d42e5d685dd6a": "Compound"
15672
+ "1:0xccf4429db6322d5c611ee964527d42e5d685dd6a": "Compound",
15673
+ // PAXO (WeFi) on XDC runs three assets twice, split by purpose. Verified
15674
+ // on-chain 2026-08-24 against each cToken's `name()` / `symbol()`.
15675
+ // vBuyFXD, against vFXD "WEFI FXD"
15676
+ "50:0xfc839b46019606b425f8b4c65b4479c3315de5c6": "Paxo FXD Buy",
15677
+ // vBuyEURS, against vEURS "EURS Vault"
15678
+ "50:0xb7c3b74f897adce04db33d9438d60a8fcf70cbc1": "Paxo EURS Buy",
15679
+ // vBorrowWXDC, against vWXDC "WEFI WXDC"
15680
+ "50:0xcc402f9573132b006d6b63b5d5b5a986767959a5": "Paxo WXDC Borrow"
15565
15681
  };
15566
15682
  function convertSingleEntry(opts) {
15567
15683
  const {
@@ -15607,7 +15723,7 @@ function convertSingleEntry(opts) {
15607
15723
  const totalDebt = Number(
15608
15724
  parseRawAmount(currentEntry?.totalBorrows?.toString(), decs)
15609
15725
  );
15610
- const liquidity = totalSupplyUnderlying - totalDebt;
15726
+ const liquidity = cashLiquidity(currentEntry?.totalCash ?? currentEntry?.cash, decs) ?? totalSupplyUnderlying - totalDebt;
15611
15727
  const price2 = prices[asset.assetGroup] ?? 0;
15612
15728
  const pausedActions = { ...currentEntry.pausedActions };
15613
15729
  if (opts.pause?.mintPaused !== void 0)
@@ -15619,7 +15735,7 @@ function convertSingleEntry(opts) {
15619
15735
  const collateralActive = Boolean(currentEntry?.isListed);
15620
15736
  const borrowingEnabled = Boolean(currentEntry?.isBorrowAllowed) && !pausedActions[2 /* BORROW */];
15621
15737
  const marketUid = createMarketUid(chainId, lender, cToken);
15622
- const name = COMPOUND_V2_NAME_OVERRIDES[cToken.toLowerCase()] ?? lenderShortName(lender) + " " + (asset?.symbol ?? "");
15738
+ const name = COMPOUND_V2_NAME_OVERRIDES[`${chainId}:${cToken.toLowerCase()}`] ?? lenderShortName(lender) + " " + (asset?.symbol ?? "");
15623
15739
  return {
15624
15740
  marketUid,
15625
15741
  name,
@@ -15696,7 +15812,7 @@ function convertSumerEntry(opts) {
15696
15812
  const totalDebt = Number(
15697
15813
  parseRawAmount(currentEntry.totalBorrows?.toString(), decs)
15698
15814
  );
15699
- const liquidity = totalSupplyUnderlying - totalDebt;
15815
+ const liquidity = cashLiquidity(currentEntry?.totalCash, decs) ?? totalSupplyUnderlying - totalDebt;
15700
15816
  const price2 = prices[asset.assetGroup] ?? 0;
15701
15817
  const poolId = asset.address;
15702
15818
  const collateralActive = Boolean(currentEntry.isListed);
@@ -15872,19 +15988,15 @@ function convertTectonicEntry(opts) {
15872
15988
  parseRawAmount(info.collateralFactor.toString(), RESERVE_MANTISSA_DECIMALS)
15873
15989
  );
15874
15990
  const liquidationPenalty = Math.max(
15875
- Number(
15876
- parseRawAmount(info.liquidationPenalty.toString(), PRICE_DECIMALS)
15877
- ) - 1,
15991
+ Number(parseRawAmount(info.liquidationPenalty.toString(), PRICE_DECIMALS)) - 1,
15878
15992
  0
15879
15993
  );
15880
15994
  const exchangeRateCurrent = Number(
15881
15995
  parseRawAmount(info.exchangeRate.toString(), PRICE_DECIMALS)
15882
15996
  );
15883
15997
  const totalSupplyUnderlying = Number(parseRawAmount(info.totalSupply.toString(), decs)) * exchangeRateCurrent;
15884
- const totalDebt = Number(
15885
- parseRawAmount(info.totalBorrow.toString(), decs)
15886
- );
15887
- const liquidity = totalSupplyUnderlying - totalDebt;
15998
+ const totalDebt = Number(parseRawAmount(info.totalBorrow.toString(), decs));
15999
+ const liquidity = cashLiquidity(info.availableLiquidity, decs) ?? totalSupplyUnderlying - totalDebt;
15888
16000
  const poolId = asset.address;
15889
16001
  const marketUid = createMarketUid(chainId, lender, cToken);
15890
16002
  return {
@@ -16049,10 +16161,8 @@ function convertBenqiEntry(opts) {
16049
16161
  const totalDeposits = Number(
16050
16162
  parseRawAmount(parsed.totalUnderlyingSupply.toString(), decs)
16051
16163
  );
16052
- const totalDebt = Number(
16053
- parseRawAmount(parsed.totalBorrows.toString(), decs)
16054
- );
16055
- const liquidity = totalDeposits - totalDebt;
16164
+ const totalDebt = Number(parseRawAmount(parsed.totalBorrows.toString(), decs));
16165
+ const liquidity = cashLiquidity(parsed.cash, decs) ?? totalDeposits - totalDebt;
16056
16166
  const poolId = asset.address;
16057
16167
  const marketUid = createMarketUid(chainId, lender, cToken);
16058
16168
  const collateralActive = !parsed.mintPaused;
@@ -16123,10 +16233,8 @@ function convertKineticEntry(opts) {
16123
16233
  const totalDeposits = Number(
16124
16234
  parseRawAmount(parsed.totalUnderlyingSupply.toString(), decs)
16125
16235
  );
16126
- const totalDebt = Number(
16127
- parseRawAmount(parsed.totalBorrows.toString(), decs)
16128
- );
16129
- const liquidity = totalDeposits - totalDebt;
16236
+ const totalDebt = Number(parseRawAmount(parsed.totalBorrows.toString(), decs));
16237
+ const liquidity = cashLiquidity(parsed.cash, decs) ?? totalDeposits - totalDebt;
16130
16238
  const poolId = asset.address;
16131
16239
  const marketUid = createMarketUid(chainId, lender, cToken);
16132
16240
  const collateralActive = !parsed.mintPaused;
@@ -16215,7 +16323,10 @@ function parseBaseFields(meta) {
16215
16323
  totalBorrows: pick(meta, "totalBorrows", 5) ?? 0n,
16216
16324
  totalReserves: pick(meta, "totalReserves", 6) ?? 0n,
16217
16325
  totalSupply: pick(meta, "totalSupply", 7) ?? 0n,
16218
- totalCash: pick(meta, "totalCash", 8) ?? 0n,
16326
+ // deliberately NOT `?? 0n`: an absent cash field must stay `undefined`
16327
+ // so the converter falls back to the derived figure instead of
16328
+ // reporting a live market as empty. See `convert/liquidity.ts`.
16329
+ totalCash: pick(meta, "totalCash", 8),
16219
16330
  isListed: pick(meta, "isListed", 9) ?? true,
16220
16331
  collateralFactorMantissa: pick(meta, "collateralFactorMantissa", 10) ?? 0n,
16221
16332
  underlyingAssetAddress: pick(meta, "underlyingAssetAddress", 11) ?? "",
@@ -16282,7 +16393,10 @@ function parseCreamV2BaseFields(meta) {
16282
16393
  totalBorrows: pick(meta, "totalBorrows", 5) ?? 0n,
16283
16394
  totalReserves: pick(meta, "totalReserves", 6) ?? 0n,
16284
16395
  totalSupply: pick(meta, "totalSupply", 7) ?? 0n,
16285
- totalCash: pick(meta, "totalCash", 8) ?? 0n,
16396
+ // deliberately NOT `?? 0n`: an absent cash field must stay `undefined`
16397
+ // so the converter falls back to the derived figure instead of
16398
+ // reporting a live market as empty. See `convert/liquidity.ts`.
16399
+ totalCash: pick(meta, "totalCash", 8),
16286
16400
  isListed: pick(meta, "isListed", 10) ?? true,
16287
16401
  collateralFactorMantissa: pick(meta, "collateralFactorMantissa", 11) ?? 0n,
16288
16402
  underlyingAssetAddress: pick(meta, "underlyingAssetAddress", 12) ?? "",
@@ -16316,6 +16430,439 @@ function readCreamV2CTokenMetadata(meta, token) {
16316
16430
  )
16317
16431
  };
16318
16432
  }
16433
+ var MULTICALL_DEFAULT_BATCH_SIZE = 4096;
16434
+ var CELO_MULTICALL_ADDRESS = "0x633987602DE5C4F337e3DbF265303A1080324204";
16435
+ var BNB_MULTICALL_ADDRESS = "0x963Df249eD09c358A4819E39d9Cd5736c3087184";
16436
+ var MANTLE_MULTICALL_ADDRESS = "0x2A51f2F647E1883F88C992244dEd171238693107";
16437
+ var ARBITRUM_ONE_MULTICALL_ADDRESS = "0xadF885960B47eA2CD9B55E6DAc6B42b7Cb2806dB";
16438
+ var LINEA_MULTICALL_ADDRESS = "0xac1cE734566f390A94b00eb9bf561c2625BF44ea";
16439
+ var AVALANCHE_MULTICALL_ADDRESS = "0x0139141Cd4Ee88dF3Cdb65881D411bAE271Ef0C2";
16440
+ var BASE_MULTICALL_ADDRESS = "0x091e99cb1C49331a94dD62755D168E941AbD0693";
16441
+ var BLAST_MULTICALL_ADDRESS = "0xdC7f370de7631cE9e2c2e1DCDA6B3B5744Cf4705";
16442
+ var TAIKO_MULTICALL_ADDRESS = "0x8E24CfC19c6C00c524353CB8816f5f1c2F33c201";
16443
+ var HEMI_MULTICALL_ADDRESS = "0x352A86168e6988A1aDF9A15Cb00017AAd3B67155";
16444
+ var GNOSIS_MULTICALL_ADDRESS = "0x4dfa9a980efE4802E969AC33968E3d6E59B8a19e";
16445
+ var MODE_MULTICALL_ADDRESS = "0xAB39cE30D98a59DFDa40A630b074170800bfF179";
16446
+ var FANTOM_MULTICALL_ADDRESS = "0xDb51CffFf3B989d0cB6b58AbF173371b6F2d0D24";
16447
+ var SCROLL_MULTICALL_ADDRESS = "0x3b615B1AC55bc34e51a81D3dea67467F32bcb8C2";
16448
+ var SHAPE_MULTICALL_ADDRESS = "0x356A450B32f5030ae7083702b86FaFbBe7490411";
16449
+ var SONIC_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
16450
+ var INK_MULTICALL_ADDRESS = "0xA0fCec583AeE6176527C07B198e5561722332014";
16451
+ var METIS_MULTICALL_ADDRESS = "0x7a59ddbB76521E8982Fa3A08598C9a83b14A6C07";
16452
+ var IOTA_MULTICALL_ADDRESS = "0x9683D433621A83aA7dd290106e1da85251317F55";
16453
+ var KAVA_MULTICALL_ADDRESS = "0x8B741B0D79BE80E135C880F7583d427B4D41F015";
16454
+ var SAGA_MULTICALL_ADDRESS = "0x743E03cceB4af2efA3CC76838f6E8B50B63F184c";
16455
+ var CYBER_MULTICALL_ADDRESS = "0x906d6eB9CF8f64e100e44f8f491b833a8d40B530";
16456
+ var METAL_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
16457
+ var ZERO_MULTICALL_ADDRESS = "0x9CA4dcb2505fbf536F6c54AA0a77C79f4fBC35C0";
16458
+ var BOB_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
16459
+ var WORLDCHAIN_MULTICALL_ADDRESS = "0x0a22c04215c97E3F532F4eF30e0aD9458792dAB9";
16460
+ var LISK_MULTICALL_ADDRESS = "0xE3dbcD53f4Ce1b06Ab200f4912BD35672e68f1FA";
16461
+ var REDSTONE_MULTICALL_ADDRESS = "0xd57B52452a0FDfE3ff8e0A40Bd10D00D0bfe0723";
16462
+ var MANTA_MULTICALL_ADDRESS = "0x52dFC0D9960F11A9Ca9FF616e791B91188446a60";
16463
+ var ZORA_MULTICALL_ADDRESS = "0xA51c76bEE6746cB487a7e9312E43e2b8f4A37C15";
16464
+ var CORE_MULTICALL_ADDRESS = "0xFe9F82D820757787895Da00B1dBD35c3B8b04894";
16465
+ var MORPH_MULTICALL_ADDRESS = "0xAcD82113982479B25E7c1D09858F0130921Dbbca";
16466
+ var TELOS_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
16467
+ var MULTICALL_ADDRESS = {
16468
+ [Chain.OP_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
16469
+ [Chain.POLYGON_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
16470
+ [Chain.ETHEREUM_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
16471
+ [Chain.ARBITRUM_ONE]: ARBITRUM_ONE_MULTICALL_ADDRESS,
16472
+ [Chain.BASE]: BASE_MULTICALL_ADDRESS,
16473
+ [Chain.CELO_MAINNET]: CELO_MULTICALL_ADDRESS,
16474
+ [Chain.BNB_SMART_CHAIN_MAINNET]: BNB_MULTICALL_ADDRESS,
16475
+ [Chain.MANTLE]: MANTLE_MULTICALL_ADDRESS,
16476
+ [Chain.BLAST]: BLAST_MULTICALL_ADDRESS,
16477
+ [Chain.LINEA]: LINEA_MULTICALL_ADDRESS,
16478
+ [Chain.AVALANCHE_C_CHAIN]: AVALANCHE_MULTICALL_ADDRESS,
16479
+ [Chain.TAIKO_ALETHIA]: TAIKO_MULTICALL_ADDRESS,
16480
+ [Chain.HEMI_NETWORK]: HEMI_MULTICALL_ADDRESS,
16481
+ [Chain.GNOSIS]: GNOSIS_MULTICALL_ADDRESS,
16482
+ [Chain.CORE_BLOCKCHAIN_MAINNET]: CORE_MULTICALL_ADDRESS,
16483
+ [Chain.METIS_ANDROMEDA_MAINNET]: METIS_MULTICALL_ADDRESS,
16484
+ [Chain.MODE]: MODE_MULTICALL_ADDRESS,
16485
+ [Chain.INK]: INK_MULTICALL_ADDRESS,
16486
+ [Chain.IOTA_EVM]: IOTA_MULTICALL_ADDRESS,
16487
+ [Chain.SONIC_MAINNET]: SONIC_MULTICALL_ADDRESS,
16488
+ [Chain.FANTOM_OPERA]: FANTOM_MULTICALL_ADDRESS,
16489
+ [Chain.SCROLL]: SCROLL_MULTICALL_ADDRESS,
16490
+ [Chain.SHAPE]: SHAPE_MULTICALL_ADDRESS,
16491
+ [Chain.CYBER_MAINNET]: CYBER_MULTICALL_ADDRESS,
16492
+ [Chain.ZORA]: ZORA_MULTICALL_ADDRESS,
16493
+ [Chain.MANTA_PACIFIC_MAINNET]: MANTA_MULTICALL_ADDRESS,
16494
+ [Chain.REDSTONE]: REDSTONE_MULTICALL_ADDRESS,
16495
+ [Chain.KAVA]: KAVA_MULTICALL_ADDRESS,
16496
+ [Chain.METAL_L2]: METAL_MULTICALL_ADDRESS,
16497
+ [Chain.LISK]: LISK_MULTICALL_ADDRESS,
16498
+ [Chain.BOB]: BOB_MULTICALL_ADDRESS,
16499
+ [Chain.ZERO_NETWORK]: ZERO_MULTICALL_ADDRESS,
16500
+ [Chain.SAGA]: SAGA_MULTICALL_ADDRESS,
16501
+ [Chain.MORPH]: MORPH_MULTICALL_ADDRESS,
16502
+ [Chain.TELOS_EVM_MAINNET]: TELOS_MULTICALL_ADDRESS,
16503
+ [Chain.WORLD_CHAIN]: WORLDCHAIN_MULTICALL_ADDRESS
16504
+ };
16505
+
16506
+ // src/utils/multicall.ts
16507
+ var { isArray } = lodash;
16508
+ var maxRetries = 3;
16509
+ var MULTICALL_FAILURE = "0x";
16510
+ var isFailedCall = (value) => value === void 0 || value === null || value === MULTICALL_FAILURE;
16511
+ var MULTICALL_REPAIR_ROUNDS = 3;
16512
+ var MAX_CALLS_PER_SHARD = 300;
16513
+ var ONE_REQUEST_BATCH_BYTES = 1e6;
16514
+ var MAX_INFLIGHT_REQUESTS = 6;
16515
+ var HEDGE_DELAY_MS = 1200;
16516
+ var SHARD_TIMEOUT_MS = 4e3;
16517
+ var MIN_ADAPTIVE_SHARD = 25;
16518
+ var ADAPTIVE_CAP_TTL_MS = 6e4;
16519
+ var endpointCallCap = /* @__PURE__ */ new Map();
16520
+ var capFor = (url, requested) => {
16521
+ const hit = endpointCallCap.get(url);
16522
+ if (!hit) return requested;
16523
+ if (Date.now() - hit.at > ADAPTIVE_CAP_TTL_MS) {
16524
+ endpointCallCap.delete(url);
16525
+ return requested;
16526
+ }
16527
+ return Math.min(requested, hit.calls);
16528
+ };
16529
+ var noteEndpointRefusal = (url, calls) => {
16530
+ if (calls <= MIN_ADAPTIVE_SHARD) return;
16531
+ const next = Math.max(MIN_ADAPTIVE_SHARD, Math.floor(calls / 2));
16532
+ const current = endpointCallCap.get(url);
16533
+ if (current && Date.now() - current.at <= ADAPTIVE_CAP_TTL_MS && current.calls <= next)
16534
+ return;
16535
+ endpointCallCap.set(url, { calls: next, at: Date.now() });
16536
+ };
16537
+ var DETERMINISTIC_ERROR_NAMES = /* @__PURE__ */ new Set([
16538
+ "ContractFunctionRevertedError",
16539
+ "RawContractError",
16540
+ "AbiDecodingZeroDataError",
16541
+ "AbiDecodingDataSizeTooSmallError",
16542
+ "AbiFunctionNotFoundError"
16543
+ ]);
16544
+ var isDeterministicCallError = (error) => {
16545
+ let err = error;
16546
+ for (let depth = 0; err && depth < 8; depth++) {
16547
+ if (DETERMINISTIC_ERROR_NAMES.has(err.name)) return true;
16548
+ const message = String(err.shortMessage ?? err.message ?? "").toLowerCase();
16549
+ if (message.includes("execution reverted") || message.includes("returned no data"))
16550
+ return true;
16551
+ err = err.cause;
16552
+ }
16553
+ return false;
16554
+ };
16555
+ var REPAIR_BACKOFF_BASE_MS = 100;
16556
+ var REPAIR_BACKOFF_JITTER_MS = 60;
16557
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
16558
+ var backoffForRound = (round) => REPAIR_BACKOFF_BASE_MS * 2 ** round + Math.random() * REPAIR_BACKOFF_JITTER_MS;
16559
+ var endpointUrl = (client, rpcId) => client?.transport?.url ?? `rpc#${rpcId}`;
16560
+ var resolveEndpoint = (chainId, getEvmClient17, startRpcId, tried, maxProbe = 12, timeoutMs) => {
16561
+ let fallback = null;
16562
+ for (let probe = 0; probe < maxProbe; probe++) {
16563
+ const rpcId = startRpcId + probe;
16564
+ let client;
16565
+ try {
16566
+ client = getEvmClient17(chainId, rpcId, { timeoutMs });
16567
+ } catch {
16568
+ break;
16569
+ }
16570
+ const url = endpointUrl(client, rpcId);
16571
+ if (!tried?.has(url)) {
16572
+ tried?.add(url);
16573
+ return { client, rpcId, url, reused: false };
16574
+ }
16575
+ fallback ??= { client, rpcId, url, reused: true };
16576
+ }
16577
+ return fallback;
16578
+ };
16579
+ var toSlots = (returnData, allowFailure) => {
16580
+ if (!allowFailure)
16581
+ return returnData.map((value) => ({ value, permanent: false }));
16582
+ return returnData.map(
16583
+ ({ result, status, error }) => status === "success" ? { value: result, permanent: false } : {
16584
+ value: MULTICALL_FAILURE,
16585
+ permanent: isDeterministicCallError(error)
16586
+ }
16587
+ );
16588
+ };
16589
+ var recordPermanentFailures = (slots, offset, collector) => {
16590
+ if (!collector) return;
16591
+ for (let i = 0; i < slots.length; i++) {
16592
+ if (slots[i].permanent) collector.add(offset + i);
16593
+ }
16594
+ };
16595
+ var repairFailedSlots = async (chainId, contracts, slots, getEvmClient17, nextRpcId, batchSize, logs, rounds = MULTICALL_REPAIR_ROUNDS, options) => {
16596
+ let searchFrom = nextRpcId;
16597
+ for (let round = 0; round < rounds; round++) {
16598
+ const failedIdx = [];
16599
+ for (let i = 0; i < slots.length; i++) {
16600
+ if (isFailedCall(slots[i].value) && !slots[i].permanent) failedIdx.push(i);
16601
+ }
16602
+ if (failedIdx.length === 0) return slots;
16603
+ const endpoint = resolveEndpoint(
16604
+ chainId,
16605
+ getEvmClient17,
16606
+ searchFrom,
16607
+ options?.tried
16608
+ );
16609
+ if (!endpoint) {
16610
+ if (logs)
16611
+ console.log(
16612
+ `multicall repair: no usable endpoint for chain ${chainId}, giving up with ${failedIdx.length} failed slots`
16613
+ );
16614
+ return slots;
16615
+ }
16616
+ searchFrom = endpoint.rpcId + 1;
16617
+ await sleep(backoffForRound(round));
16618
+ try {
16619
+ const returnData = await endpoint.client.multicall({
16620
+ allowFailure: true,
16621
+ batchSize,
16622
+ contracts: failedIdx.map((i) => contracts[i])
16623
+ });
16624
+ let repaired = 0;
16625
+ returnData.forEach((entry, k) => {
16626
+ const idx = failedIdx[k];
16627
+ if (entry?.status === "success") {
16628
+ slots[idx] = { value: entry.result, permanent: false };
16629
+ repaired++;
16630
+ } else if (isDeterministicCallError(entry?.error)) {
16631
+ slots[idx].permanent = true;
16632
+ }
16633
+ });
16634
+ if (repaired === 0)
16635
+ options?.onEndpointFailure?.({
16636
+ chainId,
16637
+ url: endpoint.url,
16638
+ rpcId: endpoint.rpcId,
16639
+ kind: "slots"
16640
+ });
16641
+ } catch (error) {
16642
+ options?.onEndpointFailure?.({
16643
+ chainId,
16644
+ url: endpoint.url,
16645
+ rpcId: endpoint.rpcId,
16646
+ kind: "transport"
16647
+ });
16648
+ if (logs)
16649
+ console.log(
16650
+ `error in multicall failure-repair round ${round} chain ${chainId}`,
16651
+ error
16652
+ );
16653
+ }
16654
+ }
16655
+ return slots;
16656
+ };
16657
+ var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient17, poolSize, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false, retryFailed = false, permanentFailures, options) => {
16658
+ const abiIsArray = isArray(abi[0]);
16659
+ const contracts = calls.map(({ address, name, params }, i) => ({
16660
+ abi: abiIsArray ? abi?.[i] : abi,
16661
+ address,
16662
+ functionName: name,
16663
+ args: params
16664
+ }));
16665
+ const requestBytes = batchSize < MULTICALL_DEFAULT_BATCH_SIZE ? batchSize : ONE_REQUEST_BATCH_BYTES;
16666
+ const workerBudget = Math.max(1, Math.floor(MAX_INFLIGHT_REQUESTS / 2));
16667
+ const workers = Math.max(1, Math.min(poolSize, workerBudget));
16668
+ const shardSize = Math.max(
16669
+ 1,
16670
+ Math.min(MAX_CALLS_PER_SHARD, Math.ceil(contracts.length / workers))
16671
+ );
16672
+ const batches = [];
16673
+ for (let i = 0; i < contracts.length; i += shardSize) {
16674
+ batches.push({ start: i, items: contracts.slice(i, i + shardSize) });
16675
+ }
16676
+ const results = new Array(contracts.length);
16677
+ const request = async (endpoint, items) => {
16678
+ try {
16679
+ const returnData = await endpoint.client.multicall({
16680
+ allowFailure,
16681
+ batchSize: requestBytes,
16682
+ contracts: items
16683
+ });
16684
+ const slots = toSlots(returnData, allowFailure);
16685
+ if (allowFailure && slots.length > 0 && slots.every((s) => isFailedCall(s.value) && !s.permanent)) {
16686
+ if (logs)
16687
+ console.log(
16688
+ `sharded multicall: rpc ${endpoint.rpcId} answered ${items.length} calls with nothing`
16689
+ );
16690
+ options?.onEndpointFailure?.({
16691
+ chainId,
16692
+ url: endpoint.url,
16693
+ rpcId: endpoint.rpcId,
16694
+ kind: "slots"
16695
+ });
16696
+ noteEndpointRefusal(endpoint.url, items.length);
16697
+ return null;
16698
+ }
16699
+ return slots;
16700
+ } catch (error) {
16701
+ if (logs) console.log("error in sharded multicall request", error);
16702
+ options?.onEndpointFailure?.({
16703
+ chainId,
16704
+ url: endpoint.url,
16705
+ rpcId: endpoint.rpcId,
16706
+ kind: "transport"
16707
+ });
16708
+ noteEndpointRefusal(endpoint.url, items.length);
16709
+ return null;
16710
+ }
16711
+ };
16712
+ const firstUsable = (attempts) => new Promise((resolve) => {
16713
+ let pending = attempts.length;
16714
+ let settled = false;
16715
+ const lose = () => {
16716
+ if (!settled && --pending === 0) resolve(null);
16717
+ };
16718
+ for (const attempt of attempts) {
16719
+ attempt.then((won) => {
16720
+ if (settled) return;
16721
+ if (won) {
16722
+ settled = true;
16723
+ resolve(won);
16724
+ } else lose();
16725
+ }, lose);
16726
+ }
16727
+ });
16728
+ const attemptHedged = async (items, startRpcId, tried) => {
16729
+ const primary = resolveEndpoint(
16730
+ chainId,
16731
+ getEvmClient17,
16732
+ startRpcId,
16733
+ tried,
16734
+ 12,
16735
+ SHARD_TIMEOUT_MS
16736
+ );
16737
+ if (!primary) {
16738
+ if (logs)
16739
+ console.log(
16740
+ `sharded multicall: no untried endpoint left for chain ${chainId}`
16741
+ );
16742
+ return null;
16743
+ }
16744
+ let timer;
16745
+ let hedgeStarted = false;
16746
+ let beginHedge = () => {
16747
+ };
16748
+ const hedged = new Promise((resolve) => {
16749
+ beginHedge = () => {
16750
+ if (hedgeStarted) return;
16751
+ hedgeStarted = true;
16752
+ clearTimeout(timer);
16753
+ const alt = resolveEndpoint(
16754
+ chainId,
16755
+ getEvmClient17,
16756
+ primary.rpcId + 1,
16757
+ tried,
16758
+ 12,
16759
+ SHARD_TIMEOUT_MS
16760
+ );
16761
+ if (!alt) return resolve(null);
16762
+ const altItems = items.slice(0, capFor(alt.url, items.length));
16763
+ if (altItems.length < items.length) return resolve(null);
16764
+ request(alt, items).then(
16765
+ (slots) => resolve(slots ? { slots, rpcId: alt.rpcId } : null)
16766
+ );
16767
+ };
16768
+ });
16769
+ timer = setTimeout(() => beginHedge(), HEDGE_DELAY_MS);
16770
+ const direct = request(primary, items).then((slots) => {
16771
+ if (slots) return { slots, rpcId: primary.rpcId };
16772
+ beginHedge();
16773
+ return null;
16774
+ });
16775
+ const won = await firstUsable([direct, hedged]);
16776
+ clearTimeout(timer);
16777
+ return won;
16778
+ };
16779
+ const runBatch = async (batch, rpcId, attemptsLeft, tried) => {
16780
+ if (!batch.items.length) return;
16781
+ const won = await attemptHedged(batch.items, rpcId, tried);
16782
+ if (!won) {
16783
+ if (attemptsLeft > 0 && batch.items.length > 1) {
16784
+ const half = Math.ceil(batch.items.length / 2);
16785
+ await sleep(backoffForRound(0));
16786
+ await runBatch(
16787
+ { start: batch.start, items: batch.items.slice(0, half) },
16788
+ rpcId,
16789
+ attemptsLeft - 1,
16790
+ tried
16791
+ );
16792
+ await runBatch(
16793
+ { start: batch.start + half, items: batch.items.slice(half) },
16794
+ rpcId + 1,
16795
+ attemptsLeft - 1,
16796
+ tried
16797
+ );
16798
+ }
16799
+ return;
16800
+ }
16801
+ let slots = won.slots;
16802
+ if (allowFailure && retryFailed) {
16803
+ slots = await repairFailedSlots(
16804
+ chainId,
16805
+ batch.items,
16806
+ slots,
16807
+ getEvmClient17,
16808
+ won.rpcId + 1,
16809
+ requestBytes,
16810
+ logs,
16811
+ MULTICALL_REPAIR_ROUNDS,
16812
+ { tried, onEndpointFailure: options?.onEndpointFailure }
16813
+ );
16814
+ }
16815
+ recordPermanentFailures(slots, batch.start, permanentFailures);
16816
+ for (let j = 0; j < slots.length; j++) {
16817
+ results[batch.start + j] = slots[j].value;
16818
+ }
16819
+ };
16820
+ let cursor = 0;
16821
+ const worker = async (workerId) => {
16822
+ while (true) {
16823
+ const idx = cursor++;
16824
+ if (idx >= batches.length) break;
16825
+ const batch = batches[idx];
16826
+ const tried = /* @__PURE__ */ new Set();
16827
+ const start = resolveEndpoint(
16828
+ chainId,
16829
+ getEvmClient17,
16830
+ workerId,
16831
+ void 0,
16832
+ 12,
16833
+ SHARD_TIMEOUT_MS
16834
+ );
16835
+ const cap = start ? capFor(start.url, batch.items.length) : batch.items.length;
16836
+ for (let off = 0; off < batch.items.length; off += cap) {
16837
+ await runBatch(
16838
+ {
16839
+ start: batch.start + off,
16840
+ items: batch.items.slice(off, off + cap)
16841
+ },
16842
+ workerId,
16843
+ retries,
16844
+ tried
16845
+ );
16846
+ }
16847
+ }
16848
+ };
16849
+ await Promise.all(
16850
+ Array.from(
16851
+ { length: Math.min(workers, batches.length) },
16852
+ (_3, w) => worker(w)
16853
+ )
16854
+ );
16855
+ return results;
16856
+ };
16857
+ function prepareMulticallInputs(abi, calls) {
16858
+ const abiIsArray = isArray(abi[0]);
16859
+ return calls.map(({ address, name, params }, i) => ({
16860
+ address,
16861
+ functionName: name,
16862
+ params: params || [],
16863
+ abi: abiIsArray ? abi[i] : abi
16864
+ }));
16865
+ }
16319
16866
 
16320
16867
  // src/lending/public-data/compound-v2/publicCallParse.ts
16321
16868
  var parseMantissaWad = (raw) => {
@@ -16492,6 +17039,7 @@ var getCompoundV2DataConverter = (lender, chainId, prices, additionalYields, tok
16492
17039
  const asset = tokenList[underlying];
16493
17040
  if (!asset) continue;
16494
17041
  const entryRaw = data[i];
17042
+ if (isFailedCall(entryRaw)) continue;
16495
17043
  const entry = convertSingleEntry({
16496
17044
  entryRaw,
16497
17045
  reader,
@@ -16533,7 +17081,12 @@ function getReader(lender, chainId) {
16533
17081
  if (lender === Lender.CREAM_FINANCE && (chainId === Chain.POLYGON_MAINNET || chainId === Chain.ARBITRUM_ONE)) {
16534
17082
  return (x, t) => readCreamV2CTokenMetadata(x, t);
16535
17083
  }
16536
- if (lender === Lender.COMPOUND_V2 || lender === Lender.FLUX_FINANCE || lender === Lender.WE_PIGGY || lender === Lender.CREAM_FINANCE || lender === Lender.CAPY_FI || lender === Lender.GAMMA) {
17084
+ if (lender === Lender.COMPOUND_V2 || lender === Lender.FLUX_FINANCE || lender === Lender.WE_PIGGY || lender === Lender.CREAM_FINANCE || lender === Lender.CAPY_FI || lender === Lender.GAMMA || // long-tail forks read through a shared 14-field lens — MUST mirror the
17085
+ // `CreamLensAbi` branch in publicCallBuild.ts `getCall`. A lender in that
17086
+ // branch and missing here builds fine and then dies in the converter with
17087
+ // `reader is not a function`, which is not a length mismatch and so is not
17088
+ // caught by the parser's own guard.
17089
+ lender === Lender.DEMETER || lender === Lender.LANDER || lender === Lender.FILDA || lender === Lender.SOLIDLIZARD || lender === Lender.IRON_BANK || lender === Lender.MENDI || lender === Lender.PAXO || lender === Lender.SONNE || lender === Lender.ASO_FINANCE || lender === Lender.BLUME || lender === Lender.KAWA || lender === Lender.XPERT || lender === Lender.KEOM || lender === Lender.REACTOR_FUSION) {
16537
17090
  return (x, t) => readCompoundV2CTokenMetadata(x, t);
16538
17091
  }
16539
17092
  }
@@ -19897,7 +20450,18 @@ var getDolomitePublicDataConverter = (lender, chainId, _prices, additionalYields
19897
20450
  config,
19898
20451
  closeFactor: 1,
19899
20452
  borrowingEnabled: !isClosing,
19900
- depositsEnabled: !isClosing
20453
+ // `isClosing` gates BORROWS ONLY — DolomiteMargin's own comment on the
20454
+ // field is "whether additional borrows are allowed", and
20455
+ // `_verifyFinalState` only asserts the market's total borrow par did
20456
+ // not grow. Supplying is untouched, which is the whole point of the
20457
+ // flag: Dolomite marks yield-bearing assets (weETH, sUSDe, wstETH, the
20458
+ // dGM/dPT wrappers) borrow-disabled precisely so they can be SUPPLIED
20459
+ // as collateral. Mapping it onto deposits made 60/77 Arbitrum, 39/48
20460
+ // Berachain and 14/23 Ethereum markets report "deposits disabled" —
20461
+ // and the term sheet then printed a red "Currently unavailable" over
20462
+ // the collateral leg of a loop that builds and executes fine. The
20463
+ // borrow half is already carried correctly by `config[*].debtDisabled`.
20464
+ depositsEnabled: true
19901
20465
  };
19902
20466
  });
19903
20467
  return { data: result, chainId };
@@ -21265,7 +21829,9 @@ function termOrderStoreBaseUrl(chainId) {
21265
21829
  return DEFAULT_TERM_ORDER_STORE;
21266
21830
  }
21267
21831
  var ZERO_ADDRESS6 = "0x0000000000000000000000000000000000000000";
21268
- var DEFAULT_TIMEOUT_MS = 5e3;
21832
+ var DEFAULT_TIMEOUT_MS = 8e3;
21833
+ var STORE_LKG_TTL_MS = 30 * 6e4;
21834
+ var storeLastGood = /* @__PURE__ */ new Map();
21269
21835
  function fillableRemaining(order, nowSec9) {
21270
21836
  if (order.taker && order.taker.toLowerCase() !== ZERO_ADDRESS6) return 0n;
21271
21837
  if (order.hasSufficientApproval === false) return 0n;
@@ -21292,10 +21858,27 @@ async function fetchTermStoreOrders(chainId, fetchImpl = fetch, filter = "fillab
21292
21858
  const base = termOrderStoreBaseUrl(chainId);
21293
21859
  const url = `${base}/orders?chainId=${chainId}`;
21294
21860
  try {
21295
- const res = await fetchImpl.call(globalThis, url, {
21296
- signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS)
21297
- });
21298
- if (!res.ok) return null;
21861
+ let res;
21862
+ for (let attempt = 0; attempt < 2; attempt++) {
21863
+ try {
21864
+ res = await fetchImpl.call(globalThis, url, {
21865
+ headers: {
21866
+ accept: "application/json",
21867
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36"
21868
+ },
21869
+ signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS)
21870
+ });
21871
+ if (res.ok) break;
21872
+ } catch (e) {
21873
+ if (attempt === 1) throw e;
21874
+ }
21875
+ }
21876
+ if (!res?.ok) {
21877
+ console.warn(
21878
+ `[term-order-store] chain ${chainId}: HTTP ${res?.status ?? "ERR"} from ${base} \u2014 serving last-known-good if fresh`
21879
+ );
21880
+ return filter === "fillable" ? staleStoreOrDegrade(chainId) : null;
21881
+ }
21299
21882
  const json = await res.json();
21300
21883
  const orders = Array.isArray(json?.orders) ? json.orders : Array.isArray(json) ? json : [];
21301
21884
  const nowSec9 = Math.floor(Date.now() / 1e3);
@@ -21310,11 +21893,22 @@ async function fetchTermStoreOrders(chainId, fetchImpl = fetch, filter = "fillab
21310
21893
  if (list) list.push(order);
21311
21894
  else byServicer.set(key3, [order]);
21312
21895
  }
21896
+ if (filter === "fillable") {
21897
+ storeLastGood.set(chainId, { byServicer, at: Date.now() });
21898
+ }
21313
21899
  return byServicer;
21314
- } catch {
21315
- return null;
21900
+ } catch (e) {
21901
+ console.warn(
21902
+ `[term-order-store] chain ${chainId}: fetch failed (${e?.message ?? e}) \u2014 serving last-known-good if fresh`
21903
+ );
21904
+ return filter === "fillable" ? staleStoreOrDegrade(chainId) : null;
21316
21905
  }
21317
21906
  }
21907
+ function staleStoreOrDegrade(chainId) {
21908
+ const hit = storeLastGood.get(chainId);
21909
+ if (hit && Date.now() - hit.at <= STORE_LKG_TTL_MS) return hit.byServicer;
21910
+ return null;
21911
+ }
21318
21912
  function toLevels(orders, loanDecimals, nowSec9) {
21319
21913
  const scale3 = 10 ** loanDecimals;
21320
21914
  return orders.map((o) => {
@@ -21618,6 +22212,7 @@ function convertTermMarketsToResponse(raw, chainId, prices = {}, _additionalYiel
21618
22212
  config.collateralParams.forEach((c) => {
21619
22213
  const collAddr = c.token.toLowerCase();
21620
22214
  const ltv = termMaintenanceRatioToLtv(c.maintenanceRatio);
22215
+ const initialLtv = c.initialRatio ? termMaintenanceRatioToLtv(c.initialRatio) : ltv;
21621
22216
  const liquidationPenalty = termLiquidatedDamagesToPenalty(c.liquidatedDamages) || liquidationPenaltyFromLltv(ltv);
21622
22217
  const collUid = createMarketUid(chainId, m, collAddr);
21623
22218
  entry.data[collUid] = {
@@ -21646,7 +22241,7 @@ function convertTermMarketsToResponse(raw, chainId, prices = {}, _additionalYiel
21646
22241
  config: {
21647
22242
  0: {
21648
22243
  category: 0,
21649
- borrowCollateralFactor: ltv,
22244
+ borrowCollateralFactor: initialLtv,
21650
22245
  collateralFactor: ltv,
21651
22246
  borrowFactor: 1,
21652
22247
  liquidationPenalty,
@@ -28327,7 +28922,9 @@ function convertDolomiteSubgraphMarkets(raw, chainId, prices, additionalYields,
28327
28922
  config,
28328
28923
  closeFactor: 1,
28329
28924
  borrowingEnabled: !isClosing,
28330
- depositsEnabled: !isClosing
28925
+ // Deposits are NOT gated by this flag — see the note in `publicCallParse`.
28926
+ // The subgraph names it `isBorrowingDisabled`, which says so outright.
28927
+ depositsEnabled: true
28331
28928
  };
28332
28929
  }
28333
28930
  return { data: result, chainId };
@@ -28886,440 +29483,7 @@ var buildAaveV2UserCall = (chainId, lender, account) => {
28886
29483
  }
28887
29484
  }
28888
29485
  };
28889
- var MULTICALL_DEFAULT_BATCH_SIZE = 4096;
28890
- var CELO_MULTICALL_ADDRESS = "0x633987602DE5C4F337e3DbF265303A1080324204";
28891
- var BNB_MULTICALL_ADDRESS = "0x963Df249eD09c358A4819E39d9Cd5736c3087184";
28892
- var MANTLE_MULTICALL_ADDRESS = "0x2A51f2F647E1883F88C992244dEd171238693107";
28893
- var ARBITRUM_ONE_MULTICALL_ADDRESS = "0xadF885960B47eA2CD9B55E6DAc6B42b7Cb2806dB";
28894
- var LINEA_MULTICALL_ADDRESS = "0xac1cE734566f390A94b00eb9bf561c2625BF44ea";
28895
- var AVALANCHE_MULTICALL_ADDRESS = "0x0139141Cd4Ee88dF3Cdb65881D411bAE271Ef0C2";
28896
- var BASE_MULTICALL_ADDRESS = "0x091e99cb1C49331a94dD62755D168E941AbD0693";
28897
- var BLAST_MULTICALL_ADDRESS = "0xdC7f370de7631cE9e2c2e1DCDA6B3B5744Cf4705";
28898
- var TAIKO_MULTICALL_ADDRESS = "0x8E24CfC19c6C00c524353CB8816f5f1c2F33c201";
28899
- var HEMI_MULTICALL_ADDRESS = "0x352A86168e6988A1aDF9A15Cb00017AAd3B67155";
28900
- var GNOSIS_MULTICALL_ADDRESS = "0x4dfa9a980efE4802E969AC33968E3d6E59B8a19e";
28901
- var MODE_MULTICALL_ADDRESS = "0xAB39cE30D98a59DFDa40A630b074170800bfF179";
28902
- var FANTOM_MULTICALL_ADDRESS = "0xDb51CffFf3B989d0cB6b58AbF173371b6F2d0D24";
28903
- var SCROLL_MULTICALL_ADDRESS = "0x3b615B1AC55bc34e51a81D3dea67467F32bcb8C2";
28904
- var SHAPE_MULTICALL_ADDRESS = "0x356A450B32f5030ae7083702b86FaFbBe7490411";
28905
- var SONIC_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28906
- var INK_MULTICALL_ADDRESS = "0xA0fCec583AeE6176527C07B198e5561722332014";
28907
- var METIS_MULTICALL_ADDRESS = "0x7a59ddbB76521E8982Fa3A08598C9a83b14A6C07";
28908
- var IOTA_MULTICALL_ADDRESS = "0x9683D433621A83aA7dd290106e1da85251317F55";
28909
- var KAVA_MULTICALL_ADDRESS = "0x8B741B0D79BE80E135C880F7583d427B4D41F015";
28910
- var SAGA_MULTICALL_ADDRESS = "0x743E03cceB4af2efA3CC76838f6E8B50B63F184c";
28911
- var CYBER_MULTICALL_ADDRESS = "0x906d6eB9CF8f64e100e44f8f491b833a8d40B530";
28912
- var METAL_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28913
- var ZERO_MULTICALL_ADDRESS = "0x9CA4dcb2505fbf536F6c54AA0a77C79f4fBC35C0";
28914
- var BOB_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28915
- var WORLDCHAIN_MULTICALL_ADDRESS = "0x0a22c04215c97E3F532F4eF30e0aD9458792dAB9";
28916
- var LISK_MULTICALL_ADDRESS = "0xE3dbcD53f4Ce1b06Ab200f4912BD35672e68f1FA";
28917
- var REDSTONE_MULTICALL_ADDRESS = "0xd57B52452a0FDfE3ff8e0A40Bd10D00D0bfe0723";
28918
- var MANTA_MULTICALL_ADDRESS = "0x52dFC0D9960F11A9Ca9FF616e791B91188446a60";
28919
- var ZORA_MULTICALL_ADDRESS = "0xA51c76bEE6746cB487a7e9312E43e2b8f4A37C15";
28920
- var CORE_MULTICALL_ADDRESS = "0xFe9F82D820757787895Da00B1dBD35c3B8b04894";
28921
- var MORPH_MULTICALL_ADDRESS = "0xAcD82113982479B25E7c1D09858F0130921Dbbca";
28922
- var TELOS_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28923
- var MULTICALL_ADDRESS = {
28924
- [Chain.OP_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
28925
- [Chain.POLYGON_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
28926
- [Chain.ETHEREUM_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
28927
- [Chain.ARBITRUM_ONE]: ARBITRUM_ONE_MULTICALL_ADDRESS,
28928
- [Chain.BASE]: BASE_MULTICALL_ADDRESS,
28929
- [Chain.CELO_MAINNET]: CELO_MULTICALL_ADDRESS,
28930
- [Chain.BNB_SMART_CHAIN_MAINNET]: BNB_MULTICALL_ADDRESS,
28931
- [Chain.MANTLE]: MANTLE_MULTICALL_ADDRESS,
28932
- [Chain.BLAST]: BLAST_MULTICALL_ADDRESS,
28933
- [Chain.LINEA]: LINEA_MULTICALL_ADDRESS,
28934
- [Chain.AVALANCHE_C_CHAIN]: AVALANCHE_MULTICALL_ADDRESS,
28935
- [Chain.TAIKO_ALETHIA]: TAIKO_MULTICALL_ADDRESS,
28936
- [Chain.HEMI_NETWORK]: HEMI_MULTICALL_ADDRESS,
28937
- [Chain.GNOSIS]: GNOSIS_MULTICALL_ADDRESS,
28938
- [Chain.CORE_BLOCKCHAIN_MAINNET]: CORE_MULTICALL_ADDRESS,
28939
- [Chain.METIS_ANDROMEDA_MAINNET]: METIS_MULTICALL_ADDRESS,
28940
- [Chain.MODE]: MODE_MULTICALL_ADDRESS,
28941
- [Chain.INK]: INK_MULTICALL_ADDRESS,
28942
- [Chain.IOTA_EVM]: IOTA_MULTICALL_ADDRESS,
28943
- [Chain.SONIC_MAINNET]: SONIC_MULTICALL_ADDRESS,
28944
- [Chain.FANTOM_OPERA]: FANTOM_MULTICALL_ADDRESS,
28945
- [Chain.SCROLL]: SCROLL_MULTICALL_ADDRESS,
28946
- [Chain.SHAPE]: SHAPE_MULTICALL_ADDRESS,
28947
- [Chain.CYBER_MAINNET]: CYBER_MULTICALL_ADDRESS,
28948
- [Chain.ZORA]: ZORA_MULTICALL_ADDRESS,
28949
- [Chain.MANTA_PACIFIC_MAINNET]: MANTA_MULTICALL_ADDRESS,
28950
- [Chain.REDSTONE]: REDSTONE_MULTICALL_ADDRESS,
28951
- [Chain.KAVA]: KAVA_MULTICALL_ADDRESS,
28952
- [Chain.METAL_L2]: METAL_MULTICALL_ADDRESS,
28953
- [Chain.LISK]: LISK_MULTICALL_ADDRESS,
28954
- [Chain.BOB]: BOB_MULTICALL_ADDRESS,
28955
- [Chain.ZERO_NETWORK]: ZERO_MULTICALL_ADDRESS,
28956
- [Chain.SAGA]: SAGA_MULTICALL_ADDRESS,
28957
- [Chain.MORPH]: MORPH_MULTICALL_ADDRESS,
28958
- [Chain.TELOS_EVM_MAINNET]: TELOS_MULTICALL_ADDRESS,
28959
- [Chain.WORLD_CHAIN]: WORLDCHAIN_MULTICALL_ADDRESS
28960
- };
28961
-
28962
- // src/utils/multicall.ts
28963
- var { isArray } = lodash;
28964
- var maxRetries = 3;
28965
- var MULTICALL_FAILURE = "0x";
28966
- var isFailedCall = (value) => value === void 0 || value === null || value === MULTICALL_FAILURE;
28967
- var MULTICALL_REPAIR_ROUNDS = 3;
28968
- var MAX_CALLS_PER_SHARD = 300;
28969
- var ONE_REQUEST_BATCH_BYTES = 1e6;
28970
- var MAX_INFLIGHT_REQUESTS = 6;
28971
- var HEDGE_DELAY_MS = 1200;
28972
- var SHARD_TIMEOUT_MS = 4e3;
28973
- var MIN_ADAPTIVE_SHARD = 25;
28974
- var ADAPTIVE_CAP_TTL_MS = 6e4;
28975
- var endpointCallCap = /* @__PURE__ */ new Map();
28976
- var capFor = (url, requested) => {
28977
- const hit = endpointCallCap.get(url);
28978
- if (!hit) return requested;
28979
- if (Date.now() - hit.at > ADAPTIVE_CAP_TTL_MS) {
28980
- endpointCallCap.delete(url);
28981
- return requested;
28982
- }
28983
- return Math.min(requested, hit.calls);
28984
- };
28985
- var noteEndpointRefusal = (url, calls) => {
28986
- if (calls <= MIN_ADAPTIVE_SHARD) return;
28987
- const next = Math.max(MIN_ADAPTIVE_SHARD, Math.floor(calls / 2));
28988
- const current = endpointCallCap.get(url);
28989
- if (current && Date.now() - current.at <= ADAPTIVE_CAP_TTL_MS && current.calls <= next)
28990
- return;
28991
- endpointCallCap.set(url, { calls: next, at: Date.now() });
28992
- };
28993
- var DETERMINISTIC_ERROR_NAMES = /* @__PURE__ */ new Set([
28994
- "ContractFunctionRevertedError",
28995
- "RawContractError",
28996
- "AbiDecodingZeroDataError",
28997
- "AbiDecodingDataSizeTooSmallError",
28998
- "AbiFunctionNotFoundError"
28999
- ]);
29000
- var isDeterministicCallError = (error) => {
29001
- let err = error;
29002
- for (let depth = 0; err && depth < 8; depth++) {
29003
- if (DETERMINISTIC_ERROR_NAMES.has(err.name)) return true;
29004
- const message = String(err.shortMessage ?? err.message ?? "").toLowerCase();
29005
- if (message.includes("execution reverted") || message.includes("returned no data"))
29006
- return true;
29007
- err = err.cause;
29008
- }
29009
- return false;
29010
- };
29011
- var REPAIR_BACKOFF_BASE_MS = 100;
29012
- var REPAIR_BACKOFF_JITTER_MS = 60;
29013
- var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
29014
- var backoffForRound = (round) => REPAIR_BACKOFF_BASE_MS * 2 ** round + Math.random() * REPAIR_BACKOFF_JITTER_MS;
29015
- var endpointUrl = (client, rpcId) => client?.transport?.url ?? `rpc#${rpcId}`;
29016
- var resolveEndpoint = (chainId, getEvmClient17, startRpcId, tried, maxProbe = 12, timeoutMs) => {
29017
- let fallback = null;
29018
- for (let probe = 0; probe < maxProbe; probe++) {
29019
- const rpcId = startRpcId + probe;
29020
- let client;
29021
- try {
29022
- client = getEvmClient17(chainId, rpcId, { timeoutMs });
29023
- } catch {
29024
- break;
29025
- }
29026
- const url = endpointUrl(client, rpcId);
29027
- if (!tried?.has(url)) {
29028
- tried?.add(url);
29029
- return { client, rpcId, url, reused: false };
29030
- }
29031
- fallback ??= { client, rpcId, url, reused: true };
29032
- }
29033
- return fallback;
29034
- };
29035
- var toSlots = (returnData, allowFailure) => {
29036
- if (!allowFailure)
29037
- return returnData.map((value) => ({ value, permanent: false }));
29038
- return returnData.map(
29039
- ({ result, status, error }) => status === "success" ? { value: result, permanent: false } : {
29040
- value: MULTICALL_FAILURE,
29041
- permanent: isDeterministicCallError(error)
29042
- }
29043
- );
29044
- };
29045
- var recordPermanentFailures = (slots, offset, collector) => {
29046
- if (!collector) return;
29047
- for (let i = 0; i < slots.length; i++) {
29048
- if (slots[i].permanent) collector.add(offset + i);
29049
- }
29050
- };
29051
- var repairFailedSlots = async (chainId, contracts, slots, getEvmClient17, nextRpcId, batchSize, logs, rounds = MULTICALL_REPAIR_ROUNDS, options) => {
29052
- let searchFrom = nextRpcId;
29053
- for (let round = 0; round < rounds; round++) {
29054
- const failedIdx = [];
29055
- for (let i = 0; i < slots.length; i++) {
29056
- if (isFailedCall(slots[i].value) && !slots[i].permanent) failedIdx.push(i);
29057
- }
29058
- if (failedIdx.length === 0) return slots;
29059
- const endpoint = resolveEndpoint(
29060
- chainId,
29061
- getEvmClient17,
29062
- searchFrom,
29063
- options?.tried
29064
- );
29065
- if (!endpoint) {
29066
- if (logs)
29067
- console.log(
29068
- `multicall repair: no usable endpoint for chain ${chainId}, giving up with ${failedIdx.length} failed slots`
29069
- );
29070
- return slots;
29071
- }
29072
- searchFrom = endpoint.rpcId + 1;
29073
- await sleep(backoffForRound(round));
29074
- try {
29075
- const returnData = await endpoint.client.multicall({
29076
- allowFailure: true,
29077
- batchSize,
29078
- contracts: failedIdx.map((i) => contracts[i])
29079
- });
29080
- let repaired = 0;
29081
- returnData.forEach((entry, k) => {
29082
- const idx = failedIdx[k];
29083
- if (entry?.status === "success") {
29084
- slots[idx] = { value: entry.result, permanent: false };
29085
- repaired++;
29086
- } else if (isDeterministicCallError(entry?.error)) {
29087
- slots[idx].permanent = true;
29088
- }
29089
- });
29090
- if (repaired === 0)
29091
- options?.onEndpointFailure?.({
29092
- chainId,
29093
- url: endpoint.url,
29094
- rpcId: endpoint.rpcId,
29095
- kind: "slots"
29096
- });
29097
- } catch (error) {
29098
- options?.onEndpointFailure?.({
29099
- chainId,
29100
- url: endpoint.url,
29101
- rpcId: endpoint.rpcId,
29102
- kind: "transport"
29103
- });
29104
- if (logs)
29105
- console.log(
29106
- `error in multicall failure-repair round ${round} chain ${chainId}`,
29107
- error
29108
- );
29109
- }
29110
- }
29111
- return slots;
29112
- };
29113
- var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient17, poolSize, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false, retryFailed = false, permanentFailures, options) => {
29114
- const abiIsArray = isArray(abi[0]);
29115
- const contracts = calls.map(({ address, name, params }, i) => ({
29116
- abi: abiIsArray ? abi?.[i] : abi,
29117
- address,
29118
- functionName: name,
29119
- args: params
29120
- }));
29121
- const requestBytes = batchSize < MULTICALL_DEFAULT_BATCH_SIZE ? batchSize : ONE_REQUEST_BATCH_BYTES;
29122
- const workerBudget = Math.max(1, Math.floor(MAX_INFLIGHT_REQUESTS / 2));
29123
- const workers = Math.max(1, Math.min(poolSize, workerBudget));
29124
- const shardSize = Math.max(
29125
- 1,
29126
- Math.min(MAX_CALLS_PER_SHARD, Math.ceil(contracts.length / workers))
29127
- );
29128
- const batches = [];
29129
- for (let i = 0; i < contracts.length; i += shardSize) {
29130
- batches.push({ start: i, items: contracts.slice(i, i + shardSize) });
29131
- }
29132
- const results = new Array(contracts.length);
29133
- const request = async (endpoint, items) => {
29134
- try {
29135
- const returnData = await endpoint.client.multicall({
29136
- allowFailure,
29137
- batchSize: requestBytes,
29138
- contracts: items
29139
- });
29140
- const slots = toSlots(returnData, allowFailure);
29141
- if (allowFailure && slots.length > 0 && slots.every((s) => isFailedCall(s.value) && !s.permanent)) {
29142
- if (logs)
29143
- console.log(
29144
- `sharded multicall: rpc ${endpoint.rpcId} answered ${items.length} calls with nothing`
29145
- );
29146
- options?.onEndpointFailure?.({
29147
- chainId,
29148
- url: endpoint.url,
29149
- rpcId: endpoint.rpcId,
29150
- kind: "slots"
29151
- });
29152
- noteEndpointRefusal(endpoint.url, items.length);
29153
- return null;
29154
- }
29155
- return slots;
29156
- } catch (error) {
29157
- if (logs) console.log("error in sharded multicall request", error);
29158
- options?.onEndpointFailure?.({
29159
- chainId,
29160
- url: endpoint.url,
29161
- rpcId: endpoint.rpcId,
29162
- kind: "transport"
29163
- });
29164
- noteEndpointRefusal(endpoint.url, items.length);
29165
- return null;
29166
- }
29167
- };
29168
- const firstUsable = (attempts) => new Promise((resolve) => {
29169
- let pending = attempts.length;
29170
- let settled = false;
29171
- const lose = () => {
29172
- if (!settled && --pending === 0) resolve(null);
29173
- };
29174
- for (const attempt of attempts) {
29175
- attempt.then((won) => {
29176
- if (settled) return;
29177
- if (won) {
29178
- settled = true;
29179
- resolve(won);
29180
- } else lose();
29181
- }, lose);
29182
- }
29183
- });
29184
- const attemptHedged = async (items, startRpcId, tried) => {
29185
- const primary = resolveEndpoint(
29186
- chainId,
29187
- getEvmClient17,
29188
- startRpcId,
29189
- tried,
29190
- 12,
29191
- SHARD_TIMEOUT_MS
29192
- );
29193
- if (!primary) {
29194
- if (logs)
29195
- console.log(
29196
- `sharded multicall: no untried endpoint left for chain ${chainId}`
29197
- );
29198
- return null;
29199
- }
29200
- let timer;
29201
- let hedgeStarted = false;
29202
- let beginHedge = () => {
29203
- };
29204
- const hedged = new Promise((resolve) => {
29205
- beginHedge = () => {
29206
- if (hedgeStarted) return;
29207
- hedgeStarted = true;
29208
- clearTimeout(timer);
29209
- const alt = resolveEndpoint(
29210
- chainId,
29211
- getEvmClient17,
29212
- primary.rpcId + 1,
29213
- tried,
29214
- 12,
29215
- SHARD_TIMEOUT_MS
29216
- );
29217
- if (!alt) return resolve(null);
29218
- const altItems = items.slice(0, capFor(alt.url, items.length));
29219
- if (altItems.length < items.length) return resolve(null);
29220
- request(alt, items).then(
29221
- (slots) => resolve(slots ? { slots, rpcId: alt.rpcId } : null)
29222
- );
29223
- };
29224
- });
29225
- timer = setTimeout(() => beginHedge(), HEDGE_DELAY_MS);
29226
- const direct = request(primary, items).then((slots) => {
29227
- if (slots) return { slots, rpcId: primary.rpcId };
29228
- beginHedge();
29229
- return null;
29230
- });
29231
- const won = await firstUsable([direct, hedged]);
29232
- clearTimeout(timer);
29233
- return won;
29234
- };
29235
- const runBatch = async (batch, rpcId, attemptsLeft, tried) => {
29236
- if (!batch.items.length) return;
29237
- const won = await attemptHedged(batch.items, rpcId, tried);
29238
- if (!won) {
29239
- if (attemptsLeft > 0 && batch.items.length > 1) {
29240
- const half = Math.ceil(batch.items.length / 2);
29241
- await sleep(backoffForRound(0));
29242
- await runBatch(
29243
- { start: batch.start, items: batch.items.slice(0, half) },
29244
- rpcId,
29245
- attemptsLeft - 1,
29246
- tried
29247
- );
29248
- await runBatch(
29249
- { start: batch.start + half, items: batch.items.slice(half) },
29250
- rpcId + 1,
29251
- attemptsLeft - 1,
29252
- tried
29253
- );
29254
- }
29255
- return;
29256
- }
29257
- let slots = won.slots;
29258
- if (allowFailure && retryFailed) {
29259
- slots = await repairFailedSlots(
29260
- chainId,
29261
- batch.items,
29262
- slots,
29263
- getEvmClient17,
29264
- won.rpcId + 1,
29265
- requestBytes,
29266
- logs,
29267
- MULTICALL_REPAIR_ROUNDS,
29268
- { tried, onEndpointFailure: options?.onEndpointFailure }
29269
- );
29270
- }
29271
- recordPermanentFailures(slots, batch.start, permanentFailures);
29272
- for (let j = 0; j < slots.length; j++) {
29273
- results[batch.start + j] = slots[j].value;
29274
- }
29275
- };
29276
- let cursor = 0;
29277
- const worker = async (workerId) => {
29278
- while (true) {
29279
- const idx = cursor++;
29280
- if (idx >= batches.length) break;
29281
- const batch = batches[idx];
29282
- const tried = /* @__PURE__ */ new Set();
29283
- const start = resolveEndpoint(
29284
- chainId,
29285
- getEvmClient17,
29286
- workerId,
29287
- void 0,
29288
- 12,
29289
- SHARD_TIMEOUT_MS
29290
- );
29291
- const cap = start ? capFor(start.url, batch.items.length) : batch.items.length;
29292
- for (let off = 0; off < batch.items.length; off += cap) {
29293
- await runBatch(
29294
- {
29295
- start: batch.start + off,
29296
- items: batch.items.slice(off, off + cap)
29297
- },
29298
- workerId,
29299
- retries,
29300
- tried
29301
- );
29302
- }
29303
- }
29304
- };
29305
- await Promise.all(
29306
- Array.from(
29307
- { length: Math.min(workers, batches.length) },
29308
- (_3, w) => worker(w)
29309
- )
29310
- );
29311
- return results;
29312
- };
29313
- function prepareMulticallInputs(abi, calls) {
29314
- const abiIsArray = isArray(abi[0]);
29315
- return calls.map(({ address, name, params }, i) => ({
29316
- address,
29317
- functionName: name,
29318
- params: params || [],
29319
- abi: abiIsArray ? abi[i] : abi
29320
- }));
29321
- }
29322
- var POSITION_LENS_V3 = "0xb05B8adB2675A43513A0198B962F5abAF3bc9edf";
29486
+ var POSITION_LENS_V6 = "0x110ff05D2822DBBe1a5404d2a485267e2Ed962C6";
29323
29487
  var LENS_FAMILY = {
29324
29488
  COMPOUND_V2: 1,
29325
29489
  SILO: 2,
@@ -29345,6 +29509,17 @@ var LENS_FAMILY = {
29345
29509
  * `getUserDataCompact` — verified against the live deployment — so the existing
29346
29510
  * decoder keeps working unchanged. Not in any deployed PositionLens yet: until
29347
29511
  * one declares it, Morpho keeps using `MORPHO_LENS`.
29512
+ *
29513
+ * KNOWN GAP, both contracts: `borrowAssets` is `toAssetsUp` over `market()`
29514
+ * totals, which are as-of the market's `lastUpdate` — the pending accrual
29515
+ * since then is missing, and on a dormant market that gap is unbounded (a
29516
+ * 141-day-stale Base market understated by 0.62 %, which broke a bundler3
29517
+ * close sized off it). Fine for display, NEVER for funding — anything sizing
29518
+ * a repay/flash must accrue via `IRM.borrowRateView` first (TS reference:
29519
+ * worker-api `readMorphoUserState`). The next lens cut should accrue in the
29520
+ * contract or emit the market totals + `lastUpdate` so the client can. See
29521
+ * USER_DATA_READ_PATH.md §3 "Morpho — the lens reports debt WITHOUT pending
29522
+ * accrual".
29348
29523
  */
29349
29524
  MORPHO: 7,
29350
29525
  /** Aave V4, per spoke. Not in any deployed contract. */
@@ -29371,40 +29546,36 @@ var LENS_FAMILY = {
29371
29546
  */
29372
29547
  RESUPPLY: 15
29373
29548
  };
29374
- var V3_WITHHELD = /* @__PURE__ */ new Set([
29375
- LENS_FAMILY.AAVE,
29376
- LENS_FAMILY.AAVE_V4
29377
- ]);
29378
- var V3_FAMILIES = new Set(
29379
- Object.values(LENS_FAMILY).filter(
29380
- (f) => !V3_WITHHELD.has(f)
29381
- )
29549
+ var ALL_FAMILIES = new Set(
29550
+ Object.values(LENS_FAMILY)
29382
29551
  );
29383
- var v3 = () => ({
29384
- address: POSITION_LENS_V3,
29385
- families: V3_FAMILIES
29552
+ var v6 = () => ({
29553
+ address: POSITION_LENS_V6,
29554
+ families: ALL_FAMILIES
29386
29555
  });
29387
29556
  var POSITION_LENS = {
29388
- [Chain.ETHEREUM_MAINNET]: v3(),
29389
- [Chain.ARBITRUM_ONE]: v3(),
29390
- [Chain.AVALANCHE_C_CHAIN]: v3(),
29391
- [Chain.BNB_SMART_CHAIN_MAINNET]: v3(),
29392
- [Chain.BASE]: v3(),
29393
- [Chain.SONIC_MAINNET]: v3(),
29394
- [Chain.SEI_NETWORK]: v3(),
29395
- [Chain.KATANA]: v3(),
29396
- [Chain.HYPEREVM]: v3(),
29397
- [Chain.MANTLE]: v3(),
29398
- [Chain.XDC_NETWORK]: v3(),
29399
- [Chain.OP_MAINNET]: v3(),
29400
- [Chain.POLYGON_MAINNET]: v3(),
29401
- [Chain.LINEA]: v3(),
29402
- [Chain.SONEIUM]: v3(),
29403
- [Chain.PLASMA_MAINNET]: v3(),
29404
- [Chain.HEMI_NETWORK]: v3(),
29405
- [Chain.SCROLL]: v3(),
29406
- [Chain.FLARE_MAINNET]: v3(),
29407
- [Chain.KAIA_MAINNET]: v3()
29557
+ [Chain.ETHEREUM_MAINNET]: v6(),
29558
+ [Chain.ARBITRUM_ONE]: v6(),
29559
+ [Chain.AVALANCHE_C_CHAIN]: v6(),
29560
+ [Chain.BNB_SMART_CHAIN_MAINNET]: v6(),
29561
+ [Chain.BASE]: v6(),
29562
+ [Chain.SONIC_MAINNET]: v6(),
29563
+ [Chain.SEI_NETWORK]: v6(),
29564
+ [Chain.KATANA]: v6(),
29565
+ [Chain.HYPEREVM]: v6(),
29566
+ [Chain.MANTLE]: v6(),
29567
+ [Chain.XDC_NETWORK]: v6(),
29568
+ [Chain.OP_MAINNET]: v6(),
29569
+ [Chain.POLYGON_MAINNET]: v6(),
29570
+ [Chain.LINEA]: v6(),
29571
+ [Chain.SONEIUM]: v6(),
29572
+ [Chain.PLASMA_MAINNET]: v6(),
29573
+ [Chain.HEMI_NETWORK]: v6(),
29574
+ [Chain.SCROLL]: v6(),
29575
+ [Chain.FLARE_MAINNET]: v6(),
29576
+ [Chain.KAIA_MAINNET]: v6(),
29577
+ [Chain.CORE_BLOCKCHAIN_MAINNET]: v6(),
29578
+ [Chain.MONAD_MAINNET]: v6()
29408
29579
  };
29409
29580
  var getPositionLensFor = (chainId, family) => {
29410
29581
  const dep = POSITION_LENS[chainId];
@@ -29443,14 +29614,17 @@ function toBytes2(hex) {
29443
29614
  const h = hex.startsWith("0x") ? hex.slice(2) : hex;
29444
29615
  if (h.length === 0) return new Uint8Array(0);
29445
29616
  const out = new Uint8Array(h.length / 2);
29446
- for (let i = 0; i < out.length; i++) out[i] = parseInt(h.slice(i * 2, i * 2 + 2), 16);
29617
+ for (let i = 0; i < out.length; i++)
29618
+ out[i] = parseInt(h.slice(i * 2, i * 2 + 2), 16);
29447
29619
  return out;
29448
29620
  }
29449
29621
  function decodeLensRows(blob, wordCount, headerBytes = 0, flagBytes = 1) {
29450
29622
  const buf = toBytes2(blob);
29451
29623
  const minimum = headerBytes + 2;
29452
29624
  if (buf.length < minimum) {
29453
- throw new Error(`position-lens: blob too short (${buf.length} < ${minimum})`);
29625
+ throw new Error(
29626
+ `position-lens: blob too short (${buf.length} < ${minimum})`
29627
+ );
29454
29628
  }
29455
29629
  const header = buf.slice(0, headerBytes);
29456
29630
  const count = Number(readBE(buf, headerBytes, 2));
@@ -29476,6 +29650,49 @@ function decodeLensRows(blob, wordCount, headerBytes = 0, flagBytes = 1) {
29476
29650
  }
29477
29651
  return { header, rows };
29478
29652
  }
29653
+ function decodeVariableLensRows(blob, fixedWords, headerBytes = 0) {
29654
+ const buf = toBytes2(blob);
29655
+ const minimum = headerBytes + 2;
29656
+ if (buf.length < minimum) {
29657
+ throw new Error(
29658
+ `position-lens: blob too short (${buf.length} < ${minimum})`
29659
+ );
29660
+ }
29661
+ const header = buf.slice(0, headerBytes);
29662
+ const count = Number(readBE(buf, headerBytes, 2));
29663
+ const rows = [];
29664
+ let off = minimum;
29665
+ for (let i = 0; i < count; i++) {
29666
+ if (off + 3 > buf.length) {
29667
+ throw new Error(`position-lens: row ${i} header runs past the blob`);
29668
+ }
29669
+ const index = Number(readBE(buf, off, 2));
29670
+ const tailCount = buf[off + 2];
29671
+ off += 3;
29672
+ const words = fixedWords + tailCount;
29673
+ if (off + words * WORD > buf.length) {
29674
+ throw new Error(
29675
+ `position-lens: row ${i} claims ${tailCount} tail words, only ${(buf.length - off) / WORD} remain`
29676
+ );
29677
+ }
29678
+ const all = [];
29679
+ for (let k = 0; k < words; k++) {
29680
+ all.push(readBE(buf, off, WORD));
29681
+ off += WORD;
29682
+ }
29683
+ rows.push({
29684
+ index,
29685
+ fixed: all.slice(0, fixedWords),
29686
+ tail: all.slice(fixedWords)
29687
+ });
29688
+ }
29689
+ if (off !== buf.length) {
29690
+ throw new Error(
29691
+ `position-lens: ${buf.length - off} trailing bytes after ${count} rows`
29692
+ );
29693
+ }
29694
+ return { header, rows };
29695
+ }
29479
29696
 
29480
29697
  // src/lending/user-data/aave-v3-type/lens.ts
29481
29698
  var ZERO2 = "0x0000000000000000000000000000000000000000";
@@ -29816,7 +30033,7 @@ var getCompoundV2UserDataConverter = (lender, chainId, account, metaMap) => {
29816
30033
  COMPOUND_V2_LENS_WORDS,
29817
30034
  COMPOUND_V2_LENS_HEADER_BYTES
29818
30035
  );
29819
- if (header[0] !== 1) return void 0;
30036
+ if ((header[0] & 1) === 0) return void 0;
29820
30037
  states = new Map(
29821
30038
  rows.map((r) => [
29822
30039
  r.index,
@@ -29950,14 +30167,16 @@ var EULER_API_CHAINS = /* @__PURE__ */ new Set([
29950
30167
  // BSC
29951
30168
  "130",
29952
30169
  // Unichain
30170
+ "143",
30171
+ // Monad — served; was missing while carrying 134 vaults
29953
30172
  "146",
29954
- // Sonic
30173
+ // Sonic — 404 as of 2026-08-22 (was served); kept, see above
29955
30174
  "239",
29956
- // TAC
30175
+ // TAC — 404 as of 2026-08-22
29957
30176
  "999",
29958
30177
  // HyperEVM
29959
30178
  "1923",
29960
- // Swell
30179
+ // Swell — 404 as of 2026-08-22
29961
30180
  "8453",
29962
30181
  // Base
29963
30182
  "9745",
@@ -29966,10 +30185,12 @@ var EULER_API_CHAINS = /* @__PURE__ */ new Set([
29966
30185
  // Arbitrum
29967
30186
  "43114",
29968
30187
  // Avalanche
30188
+ "59144",
30189
+ // Linea — served; was missing while carrying 88 vaults
29969
30190
  "60808",
29970
- // BOB
30191
+ // BOB — 404 as of 2026-08-22
29971
30192
  "80094"
29972
- // Berachain
30193
+ // Berachain — 404 as of 2026-08-22
29973
30194
  ]);
29974
30195
  var eulerApiSupportsChain = (chainId) => EULER_API_CHAINS.has(chainId);
29975
30196
  async function fetchEulerPositionsFromApi(chainId, owner, forceFresh = true) {
@@ -30125,9 +30346,9 @@ var buildAaveV4UserCall = (chainId, lender, account) => {
30125
30346
  return calls;
30126
30347
  };
30127
30348
  var resolveSiloRoster = (chainId, lender, params) => {
30128
- const v32 = isSiloV3Type(lender);
30129
- const entryFor = v32 ? getSiloV3MarketEntry : getSiloV2MarketEntry;
30130
- const keyFor = v32 ? siloV3LenderKey : siloV2LenderKey;
30349
+ const v3 = isSiloV3Type(lender);
30350
+ const entryFor = v3 ? getSiloV3MarketEntry : getSiloV2MarketEntry;
30351
+ const keyFor = v3 ? siloV3LenderKey : siloV2LenderKey;
30131
30352
  if (Array.isArray(params) && params.length > 0) {
30132
30353
  const out = [];
30133
30354
  for (const key3 of params) {
@@ -30138,7 +30359,7 @@ var resolveSiloRoster = (chainId, lender, params) => {
30138
30359
  }
30139
30360
  const single = entryFor(chainId, lender);
30140
30361
  if (single) return [{ key: lender, market: single }];
30141
- const all = (v32 ? siloMarketsV3() : siloMarkets())?.[chainId] ?? [];
30362
+ const all = (v3 ? siloMarketsV3() : siloMarkets())?.[chainId] ?? [];
30142
30363
  return all.map((market) => ({ key: keyFor(market.siloConfig), market }));
30143
30364
  };
30144
30365
 
@@ -30403,10 +30624,83 @@ var buildMidnightUserCall = (chainId, _lender, account) => {
30403
30624
  }
30404
30625
  return calls;
30405
30626
  };
30627
+ var usesTermLens = (chainId) => getPositionLensFor(chainId, LENS_FAMILY.TERM) !== void 0;
30628
+ var buildTermLensCall = (chainId, markets, account) => {
30629
+ const lens = getPositionLensFor(chainId, LENS_FAMILY.TERM);
30630
+ if (!lens) return [];
30631
+ if (markets.some(
30632
+ (m) => !m.repoToken || !m.servicer || !m.collateralManager || !m.collateralParams
30633
+ )) {
30634
+ return [];
30635
+ }
30636
+ const payload = encodeAbiParameters(
30637
+ [
30638
+ {
30639
+ type: "tuple[]",
30640
+ components: [
30641
+ { name: "repoToken", type: "address" },
30642
+ { name: "servicer", type: "address" },
30643
+ { name: "collateralManager", type: "address" },
30644
+ { name: "collateralTokens", type: "address[]" }
30645
+ ]
30646
+ }
30647
+ ],
30648
+ [
30649
+ markets.map((m) => ({
30650
+ repoToken: m.repoToken,
30651
+ servicer: m.servicer,
30652
+ collateralManager: m.collateralManager,
30653
+ collateralTokens: m.collateralParams.map((c) => c.token)
30654
+ }))
30655
+ ]
30656
+ );
30657
+ return [
30658
+ {
30659
+ address: lens,
30660
+ name: "getUserData",
30661
+ params: [[{ family: LENS_FAMILY.TERM, payload }], account],
30662
+ abi: PositionLensAbi
30663
+ }
30664
+ ];
30665
+ };
30666
+ var rebuildTermData = (blobs, markets) => {
30667
+ if (isFailedCall(blobs) || !Array.isArray(blobs) || blobs.length !== 1) {
30668
+ return void 0;
30669
+ }
30670
+ let rows;
30671
+ try {
30672
+ rows = decodeVariableLensRows(blobs[0], 3, 0).rows;
30673
+ } catch {
30674
+ return void 0;
30675
+ }
30676
+ const out = [];
30677
+ const offsets = [];
30678
+ for (const m of markets) {
30679
+ offsets.push(out.length);
30680
+ out.push(0n, 0n, 0n);
30681
+ for (let c = 0; c < m.collateralParams.length; c++) out.push(0n);
30682
+ }
30683
+ for (const r of rows) {
30684
+ if (r.index >= markets.length) return void 0;
30685
+ const base = offsets[r.index];
30686
+ out[base] = r.fixed[0];
30687
+ out[base + 1] = r.fixed[1];
30688
+ out[base + 2] = r.fixed[2];
30689
+ if (r.tail.length !== markets[r.index].collateralParams.length) return void 0;
30690
+ for (let c = 0; c < r.tail.length; c++) out[base + 3 + c] = r.tail[c];
30691
+ }
30692
+ return out;
30693
+ };
30694
+
30695
+ // src/lending/user-data/term/userCallBuild.ts
30406
30696
  var termMarketCallCount = (collateralCount) => 3 + collateralCount;
30407
30697
  var buildTermUserCall = (chainId, _lender, account) => {
30408
30698
  const markets = termMarketsByChain(chainId);
30409
30699
  if (markets.length === 0) return [];
30700
+ if (usesTermLens(chainId)) {
30701
+ const lensCall = buildTermLensCall(chainId, markets, account);
30702
+ if (lensCall.length) return lensCall;
30703
+ }
30410
30704
  const calls = [];
30411
30705
  for (const market of markets) {
30412
30706
  calls.push({ address: market.repoToken, name: "balanceOf", params: [account] });
@@ -30625,11 +30919,66 @@ function buildDataPhaseCalls(branches, perBranch, account) {
30625
30919
  });
30626
30920
  return calls;
30627
30921
  }
30922
+
30923
+ // src/lending/user-data/river/lens.ts
30924
+ var usesRiverLens = (chainId) => getPositionLensFor(chainId, LENS_FAMILY.RIVER) !== void 0;
30925
+ var isAddress2 = (v) => typeof v === "string" && /^0x[0-9a-fA-F]{40}$/.test(v);
30926
+ var buildRiverLensCall = (chainId, cfg, markets, account) => {
30927
+ const lens = getPositionLensFor(chainId, LENS_FAMILY.RIVER);
30928
+ if (!lens) return [];
30929
+ if (!isAddress2(cfg.xapp) || markets.some((m) => !isAddress2(m.troveManager))) {
30930
+ return [];
30931
+ }
30932
+ const payload = encodeAbiParameters(
30933
+ parseAbiParameters("address[], address"),
30934
+ [markets.map((m) => m.troveManager), cfg.xapp]
30935
+ );
30936
+ return [
30937
+ {
30938
+ address: lens,
30939
+ name: "getUserData",
30940
+ params: [[{ family: LENS_FAMILY.RIVER, payload }], account],
30941
+ abi: PositionLensAbi
30942
+ }
30943
+ ];
30944
+ };
30945
+ var rebuildRiverData = (blobs, marketCount) => {
30946
+ if (isFailedCall(blobs) || !Array.isArray(blobs) || blobs.length !== 1) {
30947
+ return void 0;
30948
+ }
30949
+ let decoded;
30950
+ try {
30951
+ decoded = decodeLensRows(blobs[0], 6, 32, 0);
30952
+ } catch {
30953
+ return void 0;
30954
+ }
30955
+ let spDeposit = 0n;
30956
+ for (const b of decoded.header) spDeposit = spDeposit << 8n | BigInt(b);
30957
+ const out = [];
30958
+ for (let i = 0; i < marketCount; i++) {
30959
+ out.push([0n, 0n, 0n, 0n], 0n, 0n);
30960
+ }
30961
+ for (const r of decoded.rows) {
30962
+ if (r.index >= marketCount) return void 0;
30963
+ const base = r.index * 3;
30964
+ out[base] = [r.words[0], r.words[1], r.words[2], r.words[3]];
30965
+ out[base + 1] = r.words[4];
30966
+ out[base + 2] = r.words[5];
30967
+ }
30968
+ out.push(spDeposit);
30969
+ return out;
30970
+ };
30971
+
30972
+ // src/lending/user-data/river/userCallBuild.ts
30628
30973
  var RIVER_CALLS_PER_MARKET = 3;
30629
30974
  var buildRiverUserCall = (chainId, lender, account) => {
30630
30975
  const cfg = riverConfigFor(lender, chainId);
30631
30976
  const markets = riverChainData(lender, chainId)?.markets ?? [];
30632
30977
  if (!cfg || markets.length === 0) return [];
30978
+ if (usesRiverLens(chainId)) {
30979
+ const lensCall = buildRiverLensCall(chainId, cfg, markets, account);
30980
+ if (lensCall.length) return lensCall;
30981
+ }
30633
30982
  const calls = markets.flatMap((m) => [
30634
30983
  {
30635
30984
  address: m.troveManager,
@@ -30935,10 +31284,67 @@ function __resetResupplyUserCaches() {
30935
31284
  rosterCache3.clear();
30936
31285
  discoveryCache2.clear();
30937
31286
  }
31287
+
31288
+ // src/lending/user-data/fraxlend/lens.ts
31289
+ var usesFraxlendLens = (chainId) => getPositionLensFor(chainId, LENS_FAMILY.FRAXLEND) !== void 0;
31290
+ var isAddress3 = (v) => typeof v === "string" && /^0x[0-9a-fA-F]{40}$/.test(v);
31291
+ var buildFraxlendLensCall = (chainId, pairs, account) => {
31292
+ const lens = getPositionLensFor(chainId, LENS_FAMILY.FRAXLEND);
31293
+ if (!lens) return [];
31294
+ if (pairs.some((p) => !isAddress3(p.address))) return [];
31295
+ const payload = encodeAbiParameters(parseAbiParameters("address[]"), [
31296
+ pairs.map((p) => p.address)
31297
+ ]);
31298
+ return [
31299
+ {
31300
+ address: lens,
31301
+ name: "getUserData",
31302
+ params: [[{ family: LENS_FAMILY.FRAXLEND, payload }], account],
31303
+ abi: PositionLensAbi
31304
+ }
31305
+ ];
31306
+ };
31307
+ var rebuildFraxlendData = (blobs, pairCount) => {
31308
+ if (isFailedCall(blobs) || !Array.isArray(blobs) || blobs.length !== 1) {
31309
+ return void 0;
31310
+ }
31311
+ let decoded;
31312
+ try {
31313
+ decoded = decodeLensRows(blobs[0], 9, 0, 0);
31314
+ } catch {
31315
+ return void 0;
31316
+ }
31317
+ const out = [];
31318
+ for (let i = 0; i < pairCount; i++) {
31319
+ out.push(0n, 0n, 0n, [0n, 0n, 0n, 0n, [0n, 0n], [0n, 0n]]);
31320
+ }
31321
+ for (const r of decoded.rows) {
31322
+ if (r.index >= pairCount) return void 0;
31323
+ const base = r.index * 4;
31324
+ out[base] = r.words[0];
31325
+ out[base + 1] = r.words[1];
31326
+ out[base + 2] = r.words[2];
31327
+ out[base + 3] = [
31328
+ 0n,
31329
+ 0n,
31330
+ 0n,
31331
+ 0n,
31332
+ [r.words[5], r.words[6]],
31333
+ [r.words[7], r.words[8]]
31334
+ ];
31335
+ }
31336
+ return out;
31337
+ };
31338
+
31339
+ // src/lending/user-data/fraxlend/userCallBuild.ts
30938
31340
  var FRAXLEND_CALLS_PER_PAIR = 4;
30939
31341
  var buildFraxlendUserCall = (chainId, lender, account) => {
30940
31342
  const pairs = fraxlendPairsFor(lender, chainId);
30941
31343
  if (pairs.length === 0) return [];
31344
+ if (usesFraxlendLens(chainId)) {
31345
+ const lensCall = buildFraxlendLensCall(chainId, pairs, account);
31346
+ if (lensCall.length) return lensCall;
31347
+ }
30942
31348
  return pairs.flatMap((p) => [
30943
31349
  { address: p.address, name: "userCollateralBalance", params: [account] },
30944
31350
  { address: p.address, name: "userBorrowShares", params: [account] },
@@ -31121,7 +31527,7 @@ function getCachedTwyneDiscovery(chainId, lender, account) {
31121
31527
  return discoveryCache4.get(discoveryKey3(chainId, lender, account));
31122
31528
  }
31123
31529
  var lower2 = (a) => String(a).toLowerCase();
31124
- var isAddress2 = (v) => typeof v === "string" && /^0x[0-9a-fA-F]{40}$/.test(v);
31530
+ var isAddress4 = (v) => typeof v === "string" && /^0x[0-9a-fA-F]{40}$/.test(v);
31125
31531
  async function discover(chainId, lender, account) {
31126
31532
  const key3 = discoveryKey3(chainId, lender, account);
31127
31533
  const cached = discoveryCache4.get(key3);
@@ -31141,7 +31547,7 @@ async function discover(chainId, lender, account) {
31141
31547
  abi: TwyneCollateralVaultFactoryAbi,
31142
31548
  allowFailure: true
31143
31549
  });
31144
- const created = Array.isArray(listRaw) ? listRaw.filter(isAddress2).map(lower2) : [];
31550
+ const created = Array.isArray(listRaw) ? listRaw.filter(isAddress4).map(lower2) : [];
31145
31551
  if (created.length === 0) {
31146
31552
  discoveryCache4.set(key3, empty);
31147
31553
  return empty;
@@ -31172,8 +31578,8 @@ async function discover(chainId, lender, account) {
31172
31578
  const iv = refs[i * 3];
31173
31579
  const target = refs[i * 3 + 1];
31174
31580
  const owner = refs[i * 3 + 2];
31175
- if (!isAddress2(iv) || !isAddress2(target)) return;
31176
- if (isAddress2(owner) && lower2(owner) !== lower2(account)) return;
31581
+ if (!isAddress4(iv) || !isAddress4(target)) return;
31582
+ if (isAddress4(owner) && lower2(owner) !== lower2(account)) return;
31177
31583
  const marketKey2 = `${lower2(iv)}|${lower2(target)}`;
31178
31584
  if (!known.has(marketKey2)) return;
31179
31585
  vaults.push({
@@ -31413,6 +31819,53 @@ var buildFrankencoinUserCall = async (chainId, lender, account) => {
31413
31819
  }
31414
31820
  return calls;
31415
31821
  };
31822
+ var ROW_BYTES2 = 117;
31823
+ var usesTellerLens = (chainId) => getPositionLensFor(chainId, LENS_FAMILY.TELLER) !== void 0;
31824
+ async function discoverTellerBidsViaLens(chainId, tellerV2, account) {
31825
+ const lens = getPositionLensFor(chainId, LENS_FAMILY.TELLER);
31826
+ if (!lens || !tellerV2) return void 0;
31827
+ const payload = encodeAbiParameters(parseAbiParameters("address, uint256"), [
31828
+ tellerV2,
31829
+ 0n
31830
+ ]);
31831
+ let blob;
31832
+ try {
31833
+ const res = await multicallRetryUniversal({
31834
+ chain: chainId,
31835
+ calls: [
31836
+ {
31837
+ address: lens,
31838
+ name: "getUserData",
31839
+ params: [[{ family: LENS_FAMILY.TELLER, payload }], account]
31840
+ }
31841
+ ],
31842
+ abi: PositionLensAbi,
31843
+ allowFailure: true
31844
+ });
31845
+ const blobs = res?.[0];
31846
+ if (!Array.isArray(blobs) || blobs.length !== 1) return void 0;
31847
+ blob = blobs[0];
31848
+ } catch {
31849
+ return void 0;
31850
+ }
31851
+ if (typeof blob !== "string" || !blob.startsWith("0x") || blob.length < 6) {
31852
+ return void 0;
31853
+ }
31854
+ const buf = Buffer.from(blob.slice(2), "hex");
31855
+ const count = buf.readUInt16BE(0);
31856
+ if (buf.length !== 2 + count * ROW_BYTES2) return void 0;
31857
+ const out = [];
31858
+ for (let i = 0; i < count; i++) {
31859
+ const o = 2 + i * ROW_BYTES2;
31860
+ out.push({
31861
+ bidId: BigInt("0x" + buf.subarray(o, o + 32).toString("hex")).toString(),
31862
+ lender: getAddress("0x" + buf.subarray(o + 32, o + 52).toString("hex"))
31863
+ });
31864
+ }
31865
+ return out;
31866
+ }
31867
+
31868
+ // src/lending/user-data/teller/userCallBuild.ts
31416
31869
  var TELLER_CALLS_PER_BID = 4;
31417
31870
  var CACHE_TTL_MS3 = 5 * 6e4;
31418
31871
  var discoveryCache7 = /* @__PURE__ */ new Map();
@@ -31440,6 +31893,27 @@ var buildTellerUserCall = async (chainId, _lender, account) => {
31440
31893
  if (!proto?.tellerV2 || !proto?.collateralManager || pools.length === 0) {
31441
31894
  return [];
31442
31895
  }
31896
+ const poolByAddrEarly = /* @__PURE__ */ new Map();
31897
+ for (const p of pools) poolByAddrEarly.set(p.pool.toLowerCase(), p);
31898
+ if (usesTellerLens(chainId)) {
31899
+ const viaLens = await discoverTellerBidsViaLens(
31900
+ chainId,
31901
+ proto.tellerV2,
31902
+ account
31903
+ );
31904
+ if (viaLens) {
31905
+ const keptLens = [];
31906
+ for (const b of viaLens) {
31907
+ const pool = poolByAddrEarly.get(b.lender.toLowerCase());
31908
+ if (pool) keptLens.push({ bidId: b.bidId, pool });
31909
+ }
31910
+ discoveryCache7.set(cacheKey4(chainId, account), {
31911
+ bids: keptLens,
31912
+ at: Date.now()
31913
+ });
31914
+ return buildTellerDataPhase(proto, keptLens);
31915
+ }
31916
+ }
31443
31917
  let ids = [];
31444
31918
  try {
31445
31919
  const res = await multicallRetryUniversal({
@@ -31487,6 +31961,9 @@ var buildTellerUserCall = async (chainId, _lender, account) => {
31487
31961
  if (pool) kept.push({ bidId: id, pool });
31488
31962
  });
31489
31963
  discoveryCache7.set(cacheKey4(chainId, account), { bids: kept, at: Date.now() });
31964
+ return buildTellerDataPhase(proto, kept);
31965
+ };
31966
+ function buildTellerDataPhase(proto, kept, _account) {
31490
31967
  if (kept.length === 0) return [];
31491
31968
  const ts = nowSec5();
31492
31969
  const calls = [];
@@ -31509,7 +31986,7 @@ var buildTellerUserCall = async (chainId, _lender, account) => {
31509
31986
  });
31510
31987
  }
31511
31988
  return calls;
31512
- };
31989
+ }
31513
31990
  var TERMMAX_MARKETS_PER_CALL = 180;
31514
31991
  var CACHE_TTL_MS4 = 5 * 6e4;
31515
31992
  var discoveryCache8 = /* @__PURE__ */ new Map();
@@ -34141,8 +34618,12 @@ var getTermUserDataConverter = (_lender, chainId, account, meta) => {
34141
34618
  (sum3, m) => sum3 + termMarketCallCount(m.collateralParams.length),
34142
34619
  0
34143
34620
  );
34621
+ const viaLens = usesTermLens(chainId);
34144
34622
  return [
34145
- (data) => {
34623
+ (raw) => {
34624
+ if (!raw) return void 0;
34625
+ if (viaLens && raw.length !== 1) return void 0;
34626
+ const data = viaLens ? rebuildTermData(raw[0], markets) : raw;
34146
34627
  if (!data || data.length < totalCalls) return void 0;
34147
34628
  const out = {};
34148
34629
  let cursor = 0;
@@ -34241,7 +34722,10 @@ var getTermUserDataConverter = (_lender, chainId, account, meta) => {
34241
34722
  }
34242
34723
  return Object.keys(out).length > 0 ? out : void 0;
34243
34724
  },
34244
- totalCalls
34725
+ // The CALL count the framework hands us: one blob on the lens path, the whole
34726
+ // per-repo walk otherwise. `totalCalls` stays the SLOT count the cursor
34727
+ // arithmetic above is written against.
34728
+ viaLens ? 1 : totalCalls
34245
34729
  ];
34246
34730
  };
34247
34731
  var nowSec6 = () => Math.floor(Date.now() / 1e3);
@@ -34655,9 +35139,13 @@ var getRiverUserDataConverter = (lender, chainId, account, meta) => {
34655
35139
  const cfg = riverConfigFor(lender, chainId);
34656
35140
  const markets = riverChainData(lender, chainId)?.markets ?? [];
34657
35141
  const expected = cfg && markets.length > 0 ? markets.length * RIVER_CALLS_PER_MARKET + 1 : 0;
35142
+ const viaLens = expected > 0 && usesRiverLens(chainId);
34658
35143
  return [
34659
- (data) => {
35144
+ (raw) => {
34660
35145
  if (!cfg || expected === 0) return void 0;
35146
+ if (!raw) return void 0;
35147
+ if (viaLens && raw.length !== 1) return void 0;
35148
+ const data = viaLens ? rebuildRiverData(raw[0], markets.length) : raw;
34661
35149
  if (!data || data.length < expected) return void 0;
34662
35150
  const debtAddr = cfg.debtToken.toLowerCase();
34663
35151
  const debtDecimals = cfg.debtDecimals ?? 18;
@@ -34773,7 +35261,10 @@ var getRiverUserDataConverter = (lender, chainId, account, meta) => {
34773
35261
  });
34774
35262
  return Object.keys(out).length > 0 ? out : void 0;
34775
35263
  },
34776
- expected
35264
+ // The CALL count the framework hands us: one blob on the lens path, the
35265
+ // whole per-manager walk otherwise. `expected` stays the SLOT count the
35266
+ // cursor arithmetic above is written against.
35267
+ viaLens ? 1 : expected
34777
35268
  ];
34778
35269
  };
34779
35270
  var big9 = (v) => {
@@ -35367,9 +35858,13 @@ function fraxlendToAmount(shares, totalAmount, totalShares, roundUp) {
35367
35858
  var getFraxlendUserDataConverter = (lender, chainId, account, meta) => {
35368
35859
  const pairs = fraxlendPairsFor(lender, chainId);
35369
35860
  const expected = pairs.length * FRAXLEND_CALLS_PER_PAIR;
35861
+ const viaLens = expected > 0 && usesFraxlendLens(chainId);
35370
35862
  return [
35371
- (data) => {
35863
+ (raw) => {
35372
35864
  if (expected === 0) return void 0;
35865
+ if (!raw) return void 0;
35866
+ if (viaLens && raw.length !== 1) return void 0;
35867
+ const data = viaLens ? rebuildFraxlendData(raw[0], pairs.length) : raw;
35373
35868
  if (!data || data.length < expected) return void 0;
35374
35869
  const out = {};
35375
35870
  pairs.forEach((pair, i) => {
@@ -35498,7 +35993,9 @@ var getFraxlendUserDataConverter = (lender, chainId, account, meta) => {
35498
35993
  });
35499
35994
  return Object.keys(out).length > 0 ? out : void 0;
35500
35995
  },
35501
- expected
35996
+ // One blob on the lens path, the whole per-pair walk otherwise. `expected`
35997
+ // stays the SLOT count the cursor arithmetic above is written against.
35998
+ viaLens ? 1 : expected
35502
35999
  ];
35503
36000
  };
35504
36001
  var WAD14 = 10n ** 18n;
@@ -75897,6 +76394,6 @@ function earnPositionTotals(items) {
75897
76394
  };
75898
76395
  }
75899
76396
 
75900
- export { ApiBookSource, DEFAULT_MIDNIGHT_API, DEFAULT_OUTLIER_GUARD, DEFAULT_PROFILE_ID, DEFAULT_STALE_REJECT_SECONDS, DEFAULT_TERMMAX_API, DEFAULT_TERM_ORDER_STORE, EARN_DESCRIPTIONS, EARN_LABELS, EMPTY_BALANCE, EXACTLY_LENDER_KEY, FRACTION_RATE_PROVIDERS, GMX_API_HOSTS, GMX_READ_CONTRACTS, GMX_SUPPORTED_CHAINS, HYPERCORE_VAULT_REGISTRY, IDLE_MARKET_ID, INTERFACE_IDS, LAGOON_API_URL, LAGOON_CHAIN_IDS, MORPHO_LENS, MULTICALL_FAILURE, MaxParamThresholds, PASSTHROUGH_RATE_EPSILON, PENDLE_ASSETS_URL, PENDLE_CHAIN_IDS, PENDLE_MARKETS_URL, SDK_FRACTION_RATE_PROVIDERS, SPECTRA_NETWORKS, SPECTRA_RATE_MAX_PERCENT, SPECTRA_RATE_MIN_PERCENT, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, TELLER_CALLS_PER_BID, DECIMAL_BASE as TERMMAX_DECIMAL_BASE, TERMMAX_LIQUIDATION_PENALTY, TERMMAX_LIQUIDATION_WINDOW_SECS, TERMMAX_LIQUIDATOR_BONUS, TERMMAX_MARKETS_PER_CALL, TERMMAX_PARTIAL_CLOSE_FACTOR, TERMMAX_PARTIAL_LIQUIDATION_THRESHOLD_USD, TERM_ADAPTERS, TERM_PROFILES, TERM_SHEET_SCHEMA_VERSION, TermMaxApiSource, TermSubgraphSource, UPSHIFT_CHAIN_IDS, UPSHIFT_VAULTS_URL, VAULT_PROVIDERS, VAULT_PROVIDER_PROFILE, VAULT_PROVIDER_TRAITS, VAULT_SHARE_PRICE_PROBE, VAULT_VENUE_PREFIX, VOLATILE_VAULT_OVERRIDES, YEARN_CHAIN_IDS, YEARN_YDAEMON_BASE, __resetResupplyUserCaches, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyPositionDelta, attachImplications, attachPricesToFlashLiquidity, borrowDescription, borrowFindings, borrowHeadline, buildExposures2 as buildExposures, buildFluidFTokensCall, buildLendingPositionUid, buildLiquityUserCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, buildTellerUserCall, buildTermMaxUserCall, buildTermSheet, buildTermSheetsForGroup, buildVaultEarnUid, buildVaultLookup, buildVaultTermSheet, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyFreshness, classifyReliability, classifyVault, clearPendleMarketsCache, clearSpectraMarketsCache, collateralSymbolsByVenue, collectFeedObservations, computeBorrowDelta2 as computeBorrowDelta, computeCloseTradeDeltas, computeCollateralSwapDeltas, computeDebtSwapDeltas, computeDepositDelta2 as computeDepositDelta, computeEModeAnalysis, computeOpenTradeDeltas, computePostTradeMetrics, computeRepayDelta2 as computeRepayDelta, computeSumerBorrowDelta, computeSumerDepositDelta, computeSumerRepayDelta, computeSumerWaterfall, computeSumerWithdrawDelta, computeVaultApr, computeWithdrawDelta2 as computeWithdrawDelta, computeZapTradeDeltas, consensusReference, convertCoolerMarketsToResponse, convertDssMarketsToResponse, convertExactlyMarketsToResponse, convertFrankencoinMarketsToResponse, convertFraxlendPairsToResponse, convertInverseMarketsToResponse, convertLenderUserDataResult, convertLiquityMarketsToResponse, convertLlamaLendMarketsToResponse, convertResupplyMarketsToResponse, convertRiverMarketsToResponse, convertTellerMarketsToResponse, convertTermMarketsToResponse, convertTermMaxMarketsToResponse, convertUsddMarketsToResponse, createMarketUid, createMidnightBookSource, createMulticallRpcCall, createRawRpcCalls, createTermBookSource, createTermMaxDataSource, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, deriveBorrowTags, deriveSupplyTags, detectInterfaceKinds, dexResolverFor, disambiguateEarnNames, dssIlkBytes32, dssKeyParts, dssLenderKey, duration, earnDescription, earnLabel, earnMarketFromPool, earnMarketFromVault, earnMarketLabel, earnPositionFromLenderEntry, earnPositionFromVaultBalance, earnPositionTotals, earnRowSubtitle, earnUidFromMarketUid, earnVaultTerms, earnVenueKind, encodeBalanceFetcherCalldata, enrichTermSheet, enrichmentIndexFromRows, exactlyPairLtv, exactlyPenaltyRateToAprPercent, exactlyWadRateToPercent, feePhrase, feedKeyOf, feedStatKey, fetchCoolerMarkets, fetchDolomiteAccountNumbers, fetchDssMarkets, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchExactlyMarkets, fetchFlashLiquidityForChain, fetchFluidDexState, fetchFluidFTokens, fetchFrankencoinMarkets, fetchFraxlendPairs, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchGmxExecutionFees, fetchGmxTickerPrices, fetchGmxVaults, fetchHypercoreVaults, fetchInverseMarkets, fetchLagoonApiVaults, fetchLagoonVaults, fetchLiquityMarkets, fetchListaVaultsFromChain, fetchLlamaLendMarkets, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromChain, fetchOraclePrices, fetchPendleApiAssets, fetchPendleApiMarkets, fetchPendlePrices, fetchPendlePtMarkets, fetchResupplyMarkets, fetchRiverMarkets, fetchSiloVaults, fetchSpectraApiMarkets, fetchSpectraPtMarkets, fetchTellerMarkets, fetchTermMarkets, fetchTermMaxMarkets, fetchTermStoreOrders, fetchTokenBalances, fetchTokenMetadata, fetchUpshiftApiVaults, fetchUpshiftVaults, fetchUsddMarkets, fetchYearnApiVaults, fetchYearnVaults, fillableRemaining, filterActiveLenders, filterLendersByProtocol, finalizeInfo, findingsFor, formatRaw, frankencoinKeyParts, frankencoinLenderKey, fraxlendAssetPerCollateral, fraxlendKeyParts, fraxlendLenderKey, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, getCachedFluidDexState, getCachedLiquityTroves, getCachedTellerBids, getCachedTermMaxDiscovery, getCachedTermMaxMarket, getCachedTermMaxMarkets, getCoreValidators, getFluidFTokensConverter, getGmxApiHost, getGmxReadContracts, getGmxUserPositions, getHealthFactor, getHypercoreUserPositions, getHypercoreVaultRegistry, getLenderAssets, getLenderPublicData, getLenderPublicDataAll, getLenderPublicDataViaApi, getLenderUserDataMulti, getLenderUserDataResult, getLendersForChain, getLstDelegation, getLstValidators, getLstWithdrawalRegistry, getLstWithdrawalRequests, getMaxAmountClose, getMaxAmountCollateralSwap, getMaxAmountDebtSwap, getMaxAmountOpen, getMergedUserData, getMorphoTypeMarketConverter, getReadFailurePolicy, getResolvedDolomiteAccountNumbers, getStCeloValidatorGroups, getSubAccountAddress, getSubAccountIndex, getTermProfile, getVaultPublicDataAll, getVaultWithdrawalRequests, hasCritical, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasPendleMarkets, hasSpectraMarkets, hasUpshiftVaults, hasYearnVaults, ilkToKeySegment, implausibleRatePercent, inverseKeyParts, inverseLenderKey, isBoundNeed, isFailedCall, isIlliquid, isLendingPosition, isLiveMarket as isLivePendleMarket, isLiveSpectraMarket, isSecondaryMarketOnly, isStablecoinSymbol, isVaultPosition, isVaultVenue, isYearnV3, keySegmentToIlk, keysFromMaps, lenderApiOnly, lenderFamily, liquityCandidateTroveIds, liquityKeyParts, liquityLenderKey, llamaLendKeyParts, llamaLendLenderKey, meetsLiquidityFloor, mergeDeep, multicall3Abi2 as multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, parseBalanceFetcherResult, parseEarnUid, parseMergedResult, parseMulticallRpcResponses, parseExpirySeconds as parsePendleExpirySeconds, parseRawRpcBatchResponses, parseRawRpcResponses, parseCurveFee as parseSpectraCurveFee, parsePtRate as parseSpectraPtRate, parseTermMaxLtv, parseTokenBalanceResult, pct, assetKey as pendleAssetKey, pickPool as pickSpectraPool, positivePart2 as positivePart, predictInverseEscrow, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, probeAaveFeedTimestamps, pruneFeedStats, rankFindings, ratePercent, readVaultSharePrices, rejectOutliers as rejectPriceOutliers, resolveAdapter, resolveDerivation, resolveEarnIdentity, resolveModeConfig, resolveStCeloDepositGroup, resolveVaultProfileId, resupplyKeyParts, resupplyLenderKey, resupplyMarketLabel, riverKeyParts, riverLenderKey, sanePercent as saneSpectraPercent, savingsAddresses, savingsBalanceKind, secondaryMarketVault, selectAssetGroupPrices, shortDate, spectraAddress, spectraNetwork, spectraPoolsUrl, splitChainScopedAddress as splitPendleChainScopedAddress, stampCapabilities, stampEarnSubtitles, stampVaultClassification, stampVaultTermSheets, stripLeadingBrand, supplyDescription, supplyFindings, supplyHeadline, swapRoutedProvidersArePriceConsistent, tellerBpsToPercent, tellerImpliedLtv, tellerLenderKey, tellerPoolFromLenderKey, termApiBaseUrl, termLenderKey, termMaxApiBase, borrowNif as termMaxBorrowNif, curveApr as termMaxCurveApr, curveAprNumber as termMaxCurveAprNumber, daysToMaturity as termMaxDaysToMaturity, lendNif as termMaxLendNif, mintGtFeeRatio as termMaxMintGtFeeRatio, ratioToNumber as termMaxRatioToNumber, ratioToPercent as termMaxRatioToPercent, termOfferRateToAprPct, termOrderStoreBaseUrl, tickToAprNumber, tickToPrice, toDigest, toTermFillNow, toTermSheetInput, toVaultTermInput, trancheFromCounterparty, tryParseEarnUid, unflattenLenderData, updateFeedStats, usdValue, usddIlkBytes32, usddKeyParts, usddLenderKey, validateTermSheet, validateTermSheets, validateUserData, vaultSharesToAssets, vaultTermInputFromEarnMarket, vaultTermInputFromSourceRow, vaultTraits, vaultVenue, venueBrand, venueBrandKey, withMaturityLabel, withTrancheLabel };
76397
+ export { ApiBookSource, DEFAULT_MIDNIGHT_API, DEFAULT_OUTLIER_GUARD, DEFAULT_PROFILE_ID, DEFAULT_STALE_REJECT_SECONDS, DEFAULT_TERMMAX_API, DEFAULT_TERM_ORDER_STORE, EARN_DESCRIPTIONS, EARN_LABELS, EMPTY_BALANCE, EXACTLY_LENDER_KEY, FRACTION_RATE_PROVIDERS, GMX_API_HOSTS, GMX_READ_CONTRACTS, GMX_SUPPORTED_CHAINS, HYPERCORE_VAULT_REGISTRY, IDLE_MARKET_ID, INTERFACE_IDS, LAGOON_API_URL, LAGOON_CHAIN_IDS, MORPHO_LENS, MULTICALL_FAILURE, MaxParamThresholds, PASSTHROUGH_RATE_EPSILON, PENDLE_ASSETS_URL, PENDLE_CHAIN_IDS, PENDLE_MARKETS_URL, SDK_FRACTION_RATE_PROVIDERS, SPECTRA_NETWORKS, SPECTRA_RATE_MAX_PERCENT, SPECTRA_RATE_MIN_PERCENT, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, TELLER_CALLS_PER_BID, DECIMAL_BASE as TERMMAX_DECIMAL_BASE, TERMMAX_LIQUIDATION_PENALTY, TERMMAX_LIQUIDATION_WINDOW_SECS, TERMMAX_LIQUIDATOR_BONUS, TERMMAX_MARKETS_PER_CALL, TERMMAX_PARTIAL_CLOSE_FACTOR, TERMMAX_PARTIAL_LIQUIDATION_THRESHOLD_USD, TERM_ADAPTERS, TERM_PROFILES, TERM_SHEET_SCHEMA_VERSION, TermMaxApiSource, TermSubgraphSource, UPSHIFT_CHAIN_IDS, UPSHIFT_VAULTS_URL, VAULT_PROVIDERS, VAULT_PROVIDER_PROFILE, VAULT_PROVIDER_TRAITS, VAULT_SHARE_PRICE_PROBE, VAULT_VENUE_PREFIX, VOLATILE_VAULT_OVERRIDES, YEARN_CHAIN_IDS, YEARN_YDAEMON_BASE, __resetResupplyUserCaches, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyPositionDelta, attachImplications, attachPricesToFlashLiquidity, borrowDescription, borrowFindings, borrowHeadline, buildExposures2 as buildExposures, buildFluidFTokensCall, buildLendingPositionUid, buildLiquityUserCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, buildTellerUserCall, buildTermMaxUserCall, buildTermSheet, buildTermSheetsForGroup, buildVaultEarnUid, buildVaultLookup, buildVaultTermSheet, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyFreshness, classifyReliability, classifyVault, clearPendleMarketsCache, clearSpectraMarketsCache, collateralSymbolsByVenue, collectFeedObservations, computeBorrowDelta2 as computeBorrowDelta, computeCloseTradeDeltas, computeCollateralSwapDeltas, computeDebtSwapDeltas, computeDepositDelta2 as computeDepositDelta, computeEModeAnalysis, computeOpenTradeDeltas, computePostTradeMetrics, computeRepayDelta2 as computeRepayDelta, computeSumerBorrowDelta, computeSumerDepositDelta, computeSumerRepayDelta, computeSumerWaterfall, computeSumerWithdrawDelta, computeVaultApr, computeWithdrawDelta2 as computeWithdrawDelta, computeZapTradeDeltas, consensusReference, convertCoolerMarketsToResponse, convertDssMarketsToResponse, convertExactlyMarketsToResponse, convertFrankencoinMarketsToResponse, convertFraxlendPairsToResponse, convertInverseMarketsToResponse, convertLenderUserDataResult, convertLiquityMarketsToResponse, convertLlamaLendMarketsToResponse, convertResupplyMarketsToResponse, convertRiverMarketsToResponse, convertTellerMarketsToResponse, convertTermMarketsToResponse, convertTermMaxMarketsToResponse, convertUsddMarketsToResponse, createMarketUid, createMidnightBookSource, createMulticallRpcCall, createRawRpcCalls, createTermBookSource, createTermMaxDataSource, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, deriveBorrowTags, deriveSupplyTags, detectInterfaceKinds, dexResolverFor, disambiguateEarnNames, dssIlkBytes32, dssKeyParts, dssLenderKey, duration, earnDescription, earnLabel, earnMarketFromPool, earnMarketFromVault, earnMarketLabel, earnPositionFromLenderEntry, earnPositionFromVaultBalance, earnPositionTotals, earnRowSubtitle, earnUidFromMarketUid, earnVaultTerms, earnVenueKind, encodeBalanceFetcherCalldata, enrichTermSheet, enrichmentIndexFromRows, exactlyPairLtv, exactlyPenaltyRateToAprPercent, exactlyWadRateToPercent, feePhrase, feedKeyOf, feedStatKey, fetchCoolerMarkets, fetchDolomiteAccountNumbers, fetchDssMarkets, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchExactlyMarkets, fetchFlashLiquidityForChain, fetchFluidDexState, fetchFluidFTokens, fetchFrankencoinMarkets, fetchFraxlendPairs, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchGmxExecutionFees, fetchGmxTickerPrices, fetchGmxVaults, fetchHypercoreVaults, fetchInverseMarkets, fetchLagoonApiVaults, fetchLagoonVaults, fetchLiquityMarkets, fetchListaVaultsFromChain, fetchLlamaLendMarkets, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromChain, fetchOraclePrices, fetchPendleApiAssets, fetchPendleApiMarkets, fetchPendlePrices, fetchPendlePtMarkets, fetchResupplyMarkets, fetchRiverMarkets, fetchSiloVaults, fetchSpectraApiMarkets, fetchSpectraPtMarkets, fetchTellerMarkets, fetchTermMarkets, fetchTermMaxMarkets, fetchTermStoreOrders, fetchTokenBalances, fetchTokenMetadata, fetchUpshiftApiVaults, fetchUpshiftVaults, fetchUsddMarkets, fetchYearnApiVaults, fetchYearnVaults, fillableRemaining, filterActiveLenders, filterLendersByProtocol, finalizeInfo, findingsFor, formatRaw, frankencoinKeyParts, frankencoinLenderKey, fraxlendAssetPerCollateral, fraxlendKeyParts, fraxlendLenderKey, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, getCachedFluidDexState, getCachedLiquityTroves, getCachedTellerBids, getCachedTermMaxDiscovery, getCachedTermMaxMarket, getCachedTermMaxMarkets, getCoreValidators, getFluidFTokensConverter, getGmxApiHost, getGmxReadContracts, getGmxUserPositions, getHealthFactor, getHypercoreUserPositions, getHypercoreVaultRegistry, getLenderAssets, getLenderPublicData, getLenderPublicDataAll, getLenderPublicDataViaApi, getLenderUserDataMulti, getLenderUserDataResult, getLendersForChain, getLstDelegation, getLstValidators, getLstWithdrawalRegistry, getLstWithdrawalRequests, getMaxAmountClose, getMaxAmountCollateralSwap, getMaxAmountDebtSwap, getMaxAmountOpen, getMergedUserData, getMorphoTypeMarketConverter, getReadFailurePolicy, getResolvedDolomiteAccountNumbers, getStCeloValidatorGroups, getSubAccountAddress, getSubAccountIndex, getTermProfile, getVaultPublicDataAll, getVaultWithdrawalRequests, hasCritical, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasPendleMarkets, hasSpectraMarkets, hasUpshiftVaults, hasYearnVaults, ilkToKeySegment, implausibleRatePercent, inverseKeyParts, inverseLenderKey, isBoundNeed, isFailedCall, isIlliquid, isLendingPosition, isLiveMarket as isLivePendleMarket, isLiveSpectraMarket, isSecondaryMarketOnly, isStablecoinSymbol, isVaultPosition, isVaultVenue, isYearnV3, keySegmentToIlk, keysFromMaps, lenderApiOnly, lenderFamily, liquityCandidateTroveIds, liquityKeyParts, liquityLenderKey, llamaLendKeyParts, llamaLendLenderKey, meetsLiquidityFloor, mergeDeep, multicall3Abi2 as multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, organizeUserQueries, parseBalanceFetcherResult, parseEarnUid, parseMergedResult, parseMulticallRpcResponses, parseExpirySeconds as parsePendleExpirySeconds, parseRawRpcBatchResponses, parseRawRpcResponses, parseCurveFee as parseSpectraCurveFee, parsePtRate as parseSpectraPtRate, parseTermMaxLtv, parseTokenBalanceResult, pct, assetKey as pendleAssetKey, pickPool as pickSpectraPool, positivePart2 as positivePart, predictInverseEscrow, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, probeAaveFeedTimestamps, pruneFeedStats, rankFindings, ratePercent, readVaultSharePrices, rejectOutliers as rejectPriceOutliers, resolveAdapter, resolveDerivation, resolveEarnIdentity, resolveModeConfig, resolveStCeloDepositGroup, resolveVaultProfileId, resupplyKeyParts, resupplyLenderKey, resupplyMarketLabel, riverKeyParts, riverLenderKey, sanePercent as saneSpectraPercent, savingsAddresses, savingsBalanceKind, secondaryMarketVault, selectAssetGroupPrices, shortDate, spectraAddress, spectraNetwork, spectraPoolsUrl, splitChainScopedAddress as splitPendleChainScopedAddress, stampCapabilities, stampEarnSubtitles, stampVaultClassification, stampVaultTermSheets, stripLeadingBrand, supplyDescription, supplyFindings, supplyHeadline, swapRoutedProvidersArePriceConsistent, tellerBpsToPercent, tellerImpliedLtv, tellerLenderKey, tellerPoolFromLenderKey, termApiBaseUrl, termLenderKey, termMaxApiBase, borrowNif as termMaxBorrowNif, curveApr as termMaxCurveApr, curveAprNumber as termMaxCurveAprNumber, daysToMaturity as termMaxDaysToMaturity, lendNif as termMaxLendNif, mintGtFeeRatio as termMaxMintGtFeeRatio, ratioToNumber as termMaxRatioToNumber, ratioToPercent as termMaxRatioToPercent, termOfferRateToAprPct, termOrderStoreBaseUrl, tickToAprNumber, tickToPrice, toDigest, toTermFillNow, toTermSheetInput, toVaultTermInput, trancheFromCounterparty, tryParseEarnUid, unflattenLenderData, updateFeedStats, usdValue, usddIlkBytes32, usddKeyParts, usddLenderKey, validateTermSheet, validateTermSheets, validateUserData, vaultSharesToAssets, vaultTermInputFromEarnMarket, vaultTermInputFromSourceRow, vaultTraits, vaultVenue, venueBrand, venueBrandKey, withMaturityLabel, withTrancheLabel };
75901
76398
  //# sourceMappingURL=index.js.map
75902
76399
  //# sourceMappingURL=index.js.map