@1delta/margin-fetcher 5.0.61 → 5.0.62

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,9 +1,9 @@
1
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, 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';
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, isCompoundV2Type, isMultiMarket, isSiloV2Type, isSiloV3Type, isDolomite, isMorphoType, isUsdd, isSky, hasCrossMarginRisk, isEulerType, isAaveV4Type, isInit, 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
- 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';
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, compoundV2TokenArray, gearboxV3LenderKey, midnightMarketsByChain, twyneConfigFor, twyneChainData, parseAaveV4SpokeLenderKey, fraxlendPairsFor, gearboxAccountCompressor, compoundV2Tokens, exactlyMarketsByChain, aaveOraclesConfig, compoundV2Oracles, compoundV2OraclesConfig, compoundV3OraclesData, compoundV3BaseData, compoundV2Reserves, aaveV4Oracles, morphoTypeOracles } from '@1delta/data-sdk';
7
7
  import lodash from 'lodash';
8
8
  import { Chain } from '@1delta/chain-registry';
9
9
  import { multicallRetryUniversal, getEvmClient, getEvmChain, getEvmClientUniversal } from '@1delta/providers';
@@ -7103,18 +7103,15 @@ var formatAaveYieldToNumber = (n) => {
7103
7103
  if (!n) return 0;
7104
7104
  return Number(formatEther(BigInt(n) / BigInt(1e7)));
7105
7105
  };
7106
- var calculateRateForCompoundType2 = (n) => {
7106
+ var calculateRateForCompoundType2 = (n, unitSeconds) => {
7107
7107
  const rate = Number(formatEther(BigInt(n)));
7108
- return (Math.pow(rate * 60 * 60 * 24 / 12 + 1, 365) - 1) * 100;
7108
+ const perUnit = unitSeconds && unitSeconds > 0 ? unitSeconds : 12;
7109
+ return (Math.pow(rate * 60 * 60 * 24 / perUnit + 1, 365) - 1) * 100;
7109
7110
  };
7110
- var calculateRateForCompoundType = (n, chainId, scale3 = 1 /* SECOND */) => {
7111
+ var calculateRateForCompoundType = (n, chainId, scale3 = 1 /* SECOND */, unitSeconds) => {
7111
7112
  const rate = Number(formatEther(BigInt(n)));
7112
- if (scale3 === 0 /* BLOCK */)
7113
- return (Math.pow(
7114
- rate * 60 * 60 * 24 / (BLOCK_TIMES[chainId] ?? "1") + 1,
7115
- 365
7116
- ) - 1) * 100;
7117
- return (Math.pow(rate * 60 * 60 * 24 + 1, 365) - 1) * 100;
7113
+ const perUnit = unitSeconds && unitSeconds > 0 ? unitSeconds : scale3 === 0 /* BLOCK */ ? Number(BLOCK_TIMES[chainId] ?? 1) : 1;
7114
+ return (Math.pow(rate * 60 * 60 * 24 / perUnit + 1, 365) - 1) * 100;
7118
7115
  };
7119
7116
  var formatAaveRawApyToApr = (raw) => {
7120
7117
  const apy = formatAaveYieldToNumber(raw);
@@ -15305,9 +15302,102 @@ function getCall(lender, chainId) {
15305
15302
  params: [tk]
15306
15303
  });
15307
15304
  }
15305
+ var L1_BLOCK_SECONDS = 12;
15306
+ var L1_MERGE_BLOCK = 15537394;
15307
+ var L1_MERGE_TIMESTAMP = 1663224162;
15308
+ var estimateL1Height = (nowSeconds) => L1_MERGE_BLOCK + (nowSeconds - L1_MERGE_TIMESTAMP) / L1_BLOCK_SECONDS;
15309
+ var CADENCE_SPAN = 20000n;
15310
+ var TTL_MS = 24 * 60 * 60 * 1e3;
15311
+ var clockCache = /* @__PURE__ */ new Map();
15312
+ var cadenceCache = /* @__PURE__ */ new Map();
15313
+ var fresh = (e) => !!e && Date.now() - e.at < TTL_MS;
15314
+ function classifyRateClock(accrualBlockNumber, headBlockNumber, headTimestamp) {
15315
+ const v = Number(accrualBlockNumber);
15316
+ if (!Number.isFinite(v) || v <= 0) return void 0;
15317
+ const candidates = [
15318
+ ["timestamp", Number(headTimestamp)],
15319
+ ["block", Number(headBlockNumber)],
15320
+ // The L1 height is not readable from this chain; derive it from the L2
15321
+ // head's timestamp, which is the same wall clock Ethereum runs on.
15322
+ ["l1-block", estimateL1Height(Number(headTimestamp))]
15323
+ ];
15324
+ let best;
15325
+ let bestRatio = Infinity;
15326
+ for (const [kind, expected] of candidates) {
15327
+ if (!Number.isFinite(expected) || expected <= 0) continue;
15328
+ const ratio = v > expected ? v / expected : expected / v;
15329
+ if (ratio < bestRatio) {
15330
+ bestRatio = ratio;
15331
+ best = kind;
15332
+ }
15333
+ }
15334
+ return bestRatio <= 2 ? best : void 0;
15335
+ }
15336
+ async function chainBlockSeconds(chainId) {
15337
+ const hit = cadenceCache.get(chainId);
15338
+ if (fresh(hit)) return hit.value;
15339
+ let value;
15340
+ try {
15341
+ const client = await getEvmClient(chainId);
15342
+ const head = await client.getBlockNumber();
15343
+ const span = head > CADENCE_SPAN ? CADENCE_SPAN : head / 2n;
15344
+ const [b1, b0] = await Promise.all([
15345
+ client.getBlock({ blockNumber: head }),
15346
+ client.getBlock({ blockNumber: head - span })
15347
+ ]);
15348
+ const secs = Number(b1.timestamp - b0.timestamp) / Number(span);
15349
+ if (secs >= 0.05 && secs <= 60) value = secs;
15350
+ } catch {
15351
+ value = void 0;
15352
+ }
15353
+ cadenceCache.set(chainId, { at: Date.now(), value });
15354
+ return value;
15355
+ }
15356
+ async function resolveRateUnitSeconds(chainId, lender) {
15357
+ const key3 = `${chainId}:${lender}`;
15358
+ let clock = clockCache.get(key3);
15359
+ if (!fresh(clock)) {
15360
+ let value;
15361
+ try {
15362
+ const sample = getCompoundV2Tokens(chainId, lender)[0]?.cToken;
15363
+ if (sample) {
15364
+ const client = await getEvmClient(chainId);
15365
+ const head = await client.getBlock();
15366
+ const accrual = await client.readContract({
15367
+ address: sample,
15368
+ abi: [
15369
+ {
15370
+ inputs: [],
15371
+ name: "accrualBlockNumber",
15372
+ outputs: [{ name: "", type: "uint256" }],
15373
+ stateMutability: "view",
15374
+ type: "function"
15375
+ }
15376
+ ],
15377
+ functionName: "accrualBlockNumber"
15378
+ });
15379
+ value = classifyRateClock(accrual, head.number, head.timestamp);
15380
+ }
15381
+ } catch {
15382
+ value = void 0;
15383
+ }
15384
+ clock = { at: Date.now(), value };
15385
+ clockCache.set(key3, clock);
15386
+ }
15387
+ switch (clock.value) {
15388
+ case "timestamp":
15389
+ return 1;
15390
+ case "l1-block":
15391
+ return L1_BLOCK_SECONDS;
15392
+ case "block":
15393
+ return await chainBlockSeconds(chainId);
15394
+ default:
15395
+ return void 0;
15396
+ }
15397
+ }
15308
15398
 
15309
15399
  // src/lending/public-data/compound-v2/getters/venus.ts
15310
- function readVTokenMetadata(meta, token) {
15400
+ function readVTokenMetadata(meta, token, unitSeconds) {
15311
15401
  const pick3 = (...values) => values.find((v) => v !== void 0);
15312
15402
  return {
15313
15403
  vToken: meta.vToken ?? "",
@@ -15343,7 +15433,8 @@ function readVTokenMetadata(meta, token) {
15343
15433
  meta.supplyRatePerBlockOrTimestamp
15344
15434
  )?.toString() ?? "0",
15345
15435
  token.chainId,
15346
- 0 /* BLOCK */
15436
+ 0 /* BLOCK */,
15437
+ unitSeconds
15347
15438
  ) / 100
15348
15439
  ) * 100,
15349
15440
  variableBorrowRate: apyToApr(
@@ -15353,7 +15444,8 @@ function readVTokenMetadata(meta, token) {
15353
15444
  meta.borrowRatePerBlockOrTimestamp
15354
15445
  )?.toString() ?? "0",
15355
15446
  token.chainId,
15356
- 0 /* BLOCK */
15447
+ 0 /* BLOCK */,
15448
+ unitSeconds
15357
15449
  ) / 100
15358
15450
  ) * 100,
15359
15451
  supplyCap: 0,
@@ -15572,20 +15664,24 @@ function parseTectonicMarketData(input) {
15572
15664
  isBoosted: toBool3(field3(input, "isBoosted", 22)),
15573
15665
  baseRatePerBlock: toBigInt3(field3(input, "baseRatePerBlock", 23)),
15574
15666
  multiplierPerBlock: toBigInt3(field3(input, "multiplierPerBlock", 24)),
15575
- jumpMultiplierPerBlock: toBigInt3(field3(input, "jumpMultiplierPerBlock", 25)),
15667
+ jumpMultiplierPerBlock: toBigInt3(
15668
+ field3(input, "jumpMultiplierPerBlock", 25)
15669
+ ),
15576
15670
  kink: toBigInt3(field3(input, "kink", 26))
15577
15671
  };
15578
15672
  }
15579
- function getTectonicRates(info, chainId) {
15673
+ function getTectonicRates(info, chainId, unitSeconds) {
15580
15674
  const supplyApy = calculateRateForCompoundType(
15581
15675
  info.supplyRatePerBlock.toString(),
15582
15676
  chainId,
15583
- 0 /* BLOCK */
15677
+ 0 /* BLOCK */,
15678
+ unitSeconds
15584
15679
  );
15585
15680
  const borrowApy = calculateRateForCompoundType(
15586
15681
  info.borrowRatePerBlock.toString(),
15587
15682
  chainId,
15588
- 0 /* BLOCK */
15683
+ 0 /* BLOCK */,
15684
+ unitSeconds
15589
15685
  );
15590
15686
  return {
15591
15687
  depositRate: apyToApr(supplyApy / 100) * 100,
@@ -15631,7 +15727,9 @@ function parseKineticMarketMetadata(input) {
15631
15727
  totalBorrows: toBigInt4(field4(input, "totalBorrows", 9)),
15632
15728
  collateralFactor: toBigInt4(field4(input, "collateralFactor", 10)),
15633
15729
  underlyingToken: String(field4(input, "underlyingToken", 11)),
15634
- underlyingTokenDecimals: Number(field4(input, "underlyingTokenDecimals", 12)),
15730
+ underlyingTokenDecimals: Number(
15731
+ field4(input, "underlyingTokenDecimals", 12)
15732
+ ),
15635
15733
  cTokenDecimals: Number(field4(input, "cTokenDecimals", 13)),
15636
15734
  totalReserves: toBigInt4(field4(input, "totalReserves", 16)),
15637
15735
  cash: toBigInt4(field4(input, "cash", 17)),
@@ -16116,9 +16214,7 @@ function parseBenqiEcoMarketMetadata(input) {
16116
16214
  borrowCap: toBigInt5(field5(input, "borrowCap", 6)),
16117
16215
  supplyCap: toBigInt5(field5(input, "supplyCap", 7)),
16118
16216
  totalSupply: toBigInt5(field5(input, "totalSupply", 8)),
16119
- totalUnderlyingSupply: toBigInt5(
16120
- field5(input, "totalUnderlyingSupply", 9)
16121
- ),
16217
+ totalUnderlyingSupply: toBigInt5(field5(input, "totalUnderlyingSupply", 9)),
16122
16218
  totalBorrows: toBigInt5(field5(input, "totalBorrows", 10)),
16123
16219
  collateralFactor: toBigInt5(field5(input, "collateralFactor", 11)),
16124
16220
  underlying: parseToken(field5(input, "underlying", 12)),
@@ -16129,16 +16225,18 @@ function parseBenqiEcoMarketMetadata(input) {
16129
16225
  borrowPaused: toBool5(field5(input, "borrowPaused", 17))
16130
16226
  };
16131
16227
  }
16132
- function getBenqiRates(info, chainId) {
16228
+ function getBenqiRates(info, chainId, unitSeconds) {
16133
16229
  const supplyApy = calculateRateForCompoundType(
16134
16230
  info.supplyRate.toString(),
16135
16231
  chainId,
16136
- 0 /* BLOCK */
16232
+ 0 /* BLOCK */,
16233
+ unitSeconds
16137
16234
  );
16138
16235
  const borrowApy = calculateRateForCompoundType(
16139
16236
  info.borrowRate.toString(),
16140
16237
  chainId,
16141
- 0 /* BLOCK */
16238
+ 0 /* BLOCK */,
16239
+ unitSeconds
16142
16240
  );
16143
16241
  return {
16144
16242
  depositRate: apyToApr(supplyApy / 100) * 100,
@@ -16339,27 +16437,29 @@ function parseBaseFields(meta) {
16339
16437
  pausedActions: DEFAULT_PAUSED_ACTIONS
16340
16438
  };
16341
16439
  }
16342
- function readLodestarCTokenMetadata(meta, token) {
16440
+ function readLodestarCTokenMetadata(meta, token, unitSeconds) {
16343
16441
  const base = parseBaseFields(meta);
16344
16442
  return {
16345
16443
  ...base,
16346
16444
  depositRate: capRate(
16347
16445
  apyToApr(
16348
16446
  calculateRateForCompoundType2(
16349
- base.supplyRatePerBlock?.toString() ?? "0"
16447
+ base.supplyRatePerBlock?.toString() ?? "0",
16448
+ unitSeconds
16350
16449
  ) / 100
16351
16450
  ) * 100
16352
16451
  ),
16353
16452
  variableBorrowRate: capRate(
16354
16453
  apyToApr(
16355
16454
  calculateRateForCompoundType2(
16356
- base.borrowRatePerBlock?.toString() ?? "0"
16455
+ base.borrowRatePerBlock?.toString() ?? "0",
16456
+ unitSeconds
16357
16457
  ) / 100
16358
16458
  ) * 100
16359
16459
  )
16360
16460
  };
16361
16461
  }
16362
- function readCompoundV2CTokenMetadata(meta, token) {
16462
+ function readCompoundV2CTokenMetadata(meta, token, unitSeconds) {
16363
16463
  const base = parseBaseFields(meta);
16364
16464
  return {
16365
16465
  ...base,
@@ -16368,7 +16468,8 @@ function readCompoundV2CTokenMetadata(meta, token) {
16368
16468
  calculateRateForCompoundType(
16369
16469
  base.supplyRatePerBlock?.toString() ?? "0",
16370
16470
  token.chainId,
16371
- 0 /* BLOCK */
16471
+ 0 /* BLOCK */,
16472
+ unitSeconds
16372
16473
  ) / 100
16373
16474
  ) * 100
16374
16475
  ),
@@ -16377,7 +16478,8 @@ function readCompoundV2CTokenMetadata(meta, token) {
16377
16478
  calculateRateForCompoundType(
16378
16479
  base.borrowRatePerBlock?.toString() ?? "0",
16379
16480
  token.chainId,
16380
- 0 /* BLOCK */
16481
+ 0 /* BLOCK */,
16482
+ unitSeconds
16381
16483
  ) / 100
16382
16484
  ) * 100
16383
16485
  )
@@ -16406,7 +16508,7 @@ function parseCreamV2BaseFields(meta) {
16406
16508
  pausedActions: DEFAULT_PAUSED_ACTIONS
16407
16509
  };
16408
16510
  }
16409
- function readCreamV2CTokenMetadata(meta, token) {
16511
+ function readCreamV2CTokenMetadata(meta, token, unitSeconds) {
16410
16512
  const base = parseCreamV2BaseFields(meta);
16411
16513
  return {
16412
16514
  ...base,
@@ -16415,7 +16517,8 @@ function readCreamV2CTokenMetadata(meta, token) {
16415
16517
  calculateRateForCompoundType(
16416
16518
  base.supplyRatePerBlock?.toString() ?? "0",
16417
16519
  token.chainId,
16418
- 0 /* BLOCK */
16520
+ 0 /* BLOCK */,
16521
+ unitSeconds
16419
16522
  ) / 100
16420
16523
  ) * 100
16421
16524
  ),
@@ -16424,7 +16527,8 @@ function readCreamV2CTokenMetadata(meta, token) {
16424
16527
  calculateRateForCompoundType(
16425
16528
  base.borrowRatePerBlock?.toString() ?? "0",
16426
16529
  token.chainId,
16427
- 0 /* BLOCK */
16530
+ 0 /* BLOCK */,
16531
+ unitSeconds
16428
16532
  ) / 100
16429
16533
  ) * 100
16430
16534
  )
@@ -16557,13 +16661,13 @@ var REPAIR_BACKOFF_JITTER_MS = 60;
16557
16661
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
16558
16662
  var backoffForRound = (round) => REPAIR_BACKOFF_BASE_MS * 2 ** round + Math.random() * REPAIR_BACKOFF_JITTER_MS;
16559
16663
  var endpointUrl = (client, rpcId) => client?.transport?.url ?? `rpc#${rpcId}`;
16560
- var resolveEndpoint = (chainId, getEvmClient17, startRpcId, tried, maxProbe = 12, timeoutMs) => {
16664
+ var resolveEndpoint = (chainId, getEvmClient18, startRpcId, tried, maxProbe = 12, timeoutMs) => {
16561
16665
  let fallback = null;
16562
16666
  for (let probe = 0; probe < maxProbe; probe++) {
16563
16667
  const rpcId = startRpcId + probe;
16564
16668
  let client;
16565
16669
  try {
16566
- client = getEvmClient17(chainId, rpcId, { timeoutMs });
16670
+ client = getEvmClient18(chainId, rpcId, { timeoutMs });
16567
16671
  } catch {
16568
16672
  break;
16569
16673
  }
@@ -16592,7 +16696,7 @@ var recordPermanentFailures = (slots, offset, collector) => {
16592
16696
  if (slots[i].permanent) collector.add(offset + i);
16593
16697
  }
16594
16698
  };
16595
- var repairFailedSlots = async (chainId, contracts, slots, getEvmClient17, nextRpcId, batchSize, logs, rounds = MULTICALL_REPAIR_ROUNDS, options) => {
16699
+ var repairFailedSlots = async (chainId, contracts, slots, getEvmClient18, nextRpcId, batchSize, logs, rounds = MULTICALL_REPAIR_ROUNDS, options) => {
16596
16700
  let searchFrom = nextRpcId;
16597
16701
  for (let round = 0; round < rounds; round++) {
16598
16702
  const failedIdx = [];
@@ -16602,7 +16706,7 @@ var repairFailedSlots = async (chainId, contracts, slots, getEvmClient17, nextRp
16602
16706
  if (failedIdx.length === 0) return slots;
16603
16707
  const endpoint = resolveEndpoint(
16604
16708
  chainId,
16605
- getEvmClient17,
16709
+ getEvmClient18,
16606
16710
  searchFrom,
16607
16711
  options?.tried
16608
16712
  );
@@ -16654,7 +16758,7 @@ var repairFailedSlots = async (chainId, contracts, slots, getEvmClient17, nextRp
16654
16758
  }
16655
16759
  return slots;
16656
16760
  };
16657
- var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient17, poolSize, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false, retryFailed = false, permanentFailures, options) => {
16761
+ var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient18, poolSize, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false, retryFailed = false, permanentFailures, options) => {
16658
16762
  const abiIsArray = isArray(abi[0]);
16659
16763
  const contracts = calls.map(({ address, name, params }, i) => ({
16660
16764
  abi: abiIsArray ? abi?.[i] : abi,
@@ -16728,7 +16832,7 @@ var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient17, poolS
16728
16832
  const attemptHedged = async (items, startRpcId, tried) => {
16729
16833
  const primary = resolveEndpoint(
16730
16834
  chainId,
16731
- getEvmClient17,
16835
+ getEvmClient18,
16732
16836
  startRpcId,
16733
16837
  tried,
16734
16838
  12,
@@ -16752,7 +16856,7 @@ var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient17, poolS
16752
16856
  clearTimeout(timer);
16753
16857
  const alt = resolveEndpoint(
16754
16858
  chainId,
16755
- getEvmClient17,
16859
+ getEvmClient18,
16756
16860
  primary.rpcId + 1,
16757
16861
  tried,
16758
16862
  12,
@@ -16804,7 +16908,7 @@ var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient17, poolS
16804
16908
  chainId,
16805
16909
  batch.items,
16806
16910
  slots,
16807
- getEvmClient17,
16911
+ getEvmClient18,
16808
16912
  won.rpcId + 1,
16809
16913
  requestBytes,
16810
16914
  logs,
@@ -16826,7 +16930,7 @@ var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient17, poolS
16826
16930
  const tried = /* @__PURE__ */ new Set();
16827
16931
  const start = resolveEndpoint(
16828
16932
  chainId,
16829
- getEvmClient17,
16933
+ getEvmClient18,
16830
16934
  workerId,
16831
16935
  void 0,
16832
16936
  12,
@@ -16873,7 +16977,7 @@ var parseMantissaWad = (raw) => {
16873
16977
  return void 0;
16874
16978
  }
16875
16979
  };
16876
- var getCompoundV2DataConverter = (lender, chainId, prices, additionalYields, tokenList = {}) => {
16980
+ var getCompoundV2DataConverter = (lender, chainId, prices, additionalYields, tokenList = {}, unitSeconds) => {
16877
16981
  if (lender === Lender.TAKARA) {
16878
16982
  return [
16879
16983
  (data) => {
@@ -16995,7 +17099,7 @@ var getCompoundV2DataConverter = (lender, chainId, prices, additionalYields, tok
16995
17099
  const pauseReads = Boolean(stdComptroller) && usesComptrollerPauseReads(lender);
16996
17100
  const pauseCalls = pauseReads ? tokenCount * 2 : 0;
16997
17101
  const expectedNumberOfCalls = isSumer ? tokenCount + SUMER_GROUP_COUNT : tokenCount + stdComptrollerCalls + pauseCalls;
16998
- const reader = getReader(lender, chainId);
17102
+ const reader = getReader(lender, chainId, unitSeconds);
16999
17103
  return [
17000
17104
  (data) => {
17001
17105
  if (data.length !== expectedNumberOfCalls) return void 0;
@@ -17065,9 +17169,9 @@ var getCompoundV2DataConverter = (lender, chainId, prices, additionalYields, tok
17065
17169
  expectedNumberOfCalls
17066
17170
  ];
17067
17171
  };
17068
- function getReader(lender, chainId) {
17172
+ function getReader(lender, chainId, unitSeconds) {
17069
17173
  if (isVenusType(lender)) {
17070
- return (x, t) => readVTokenMetadata(x, t);
17174
+ return (x, t) => readVTokenMetadata(x, t, unitSeconds);
17071
17175
  }
17072
17176
  if (lender === Lender.MOONWELL) {
17073
17177
  return (x, t) => parseMoonwellMarket(x, t);
@@ -17076,10 +17180,10 @@ function getReader(lender, chainId) {
17076
17180
  return (x, t) => readSumerCTokenMetadata(x, t);
17077
17181
  }
17078
17182
  if (lender === Lender.LODESTAR || lender === Lender.TENDER) {
17079
- return (x, t) => readLodestarCTokenMetadata(x);
17183
+ return (x, t) => readLodestarCTokenMetadata(x, t, unitSeconds);
17080
17184
  }
17081
17185
  if (lender === Lender.CREAM_FINANCE && (chainId === Chain.POLYGON_MAINNET || chainId === Chain.ARBITRUM_ONE)) {
17082
- return (x, t) => readCreamV2CTokenMetadata(x, t);
17186
+ return (x, t) => readCreamV2CTokenMetadata(x, t, unitSeconds);
17083
17187
  }
17084
17188
  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
17189
  // `CreamLensAbi` branch in publicCallBuild.ts `getCall`. A lender in that
@@ -17087,7 +17191,7 @@ function getReader(lender, chainId) {
17087
17191
  // `reader is not a function`, which is not a length mismatch and so is not
17088
17192
  // caught by the parser's own guard.
17089
17193
  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) {
17090
- return (x, t) => readCompoundV2CTokenMetadata(x, t);
17194
+ return (x, t) => readCompoundV2CTokenMetadata(x, t, unitSeconds);
17091
17195
  }
17092
17196
  }
17093
17197
 
@@ -19676,7 +19780,7 @@ var buildFluidCall = (chainId, _lender) => {
19676
19780
  // src/lending/public-data/fluid/apiData.ts
19677
19781
  var FLUID_API_BASE = "https://api.fluid.instadapp.io/v2";
19678
19782
  var SUPPORTED_CHAINS = /* @__PURE__ */ new Set(["1", "56", "137", "8453", "9745", "42161"]);
19679
- var TTL_MS = 6e4;
19783
+ var TTL_MS2 = 6e4;
19680
19784
  var ZERO_ADDRESS4 = "0x0000000000000000000000000000000000000000";
19681
19785
  var cache = {};
19682
19786
  var inflight = /* @__PURE__ */ new Map();
@@ -19724,7 +19828,7 @@ var parseChainPayload = (raw) => {
19724
19828
  var fetchFluidApiData = async (chainId) => {
19725
19829
  if (!SUPPORTED_CHAINS.has(chainId)) return void 0;
19726
19830
  const hit = cache[chainId];
19727
- if (hit && Date.now() - hit.at < TTL_MS) return hit.data;
19831
+ if (hit && Date.now() - hit.at < TTL_MS2) return hit.data;
19728
19832
  const pending = inflight.get(chainId);
19729
19833
  if (pending) return pending;
19730
19834
  const run = (async () => {
@@ -19758,14 +19862,14 @@ var DEX_RESOLVER_FALLBACK = {
19758
19862
  };
19759
19863
  var dexResolverFor = (chainId) => fluidResolvers()?.[chainId]?.dexResolver ?? DEX_RESOLVER_FALLBACK[chainId];
19760
19864
  var ZERO_ADDRESS5 = "0x0000000000000000000000000000000000000000";
19761
- var TTL_MS2 = 6e4;
19865
+ var TTL_MS3 = 6e4;
19762
19866
  var cache2 = {};
19763
19867
  var inflight2 = /* @__PURE__ */ new Map();
19764
19868
  var fetchFluidDexState = async (chainId, multicallRetry, extraDexAddresses = []) => {
19765
19869
  const resolver = dexResolverFor(chainId);
19766
19870
  if (!resolver) return void 0;
19767
19871
  const hit = cache2[chainId];
19768
- if (hit && Date.now() - hit.at < TTL_MS2) return hit.data;
19872
+ if (hit && Date.now() - hit.at < TTL_MS3) return hit.data;
19769
19873
  const pending = inflight2.get(chainId);
19770
19874
  if (pending) return pending;
19771
19875
  const run = (async () => {
@@ -20768,7 +20872,7 @@ function buildLenderCall(chainId, lender) {
20768
20872
  if (isGearboxV3(lender)) return buildGearboxCall(chainId);
20769
20873
  return [];
20770
20874
  }
20771
- function getLenderDataConverter(lender, chainId, prices, additionalYields, tokenList = {}) {
20875
+ function getLenderDataConverter(lender, chainId, prices, additionalYields, tokenList = {}, unitSeconds) {
20772
20876
  if (isAaveV2Type(lender))
20773
20877
  return getAaveV2ReservesDataConverter(
20774
20878
  lender,
@@ -20816,7 +20920,8 @@ function getLenderDataConverter(lender, chainId, prices, additionalYields, token
20816
20920
  chainId,
20817
20921
  prices,
20818
20922
  additionalYields,
20819
- tokenList
20923
+ tokenList,
20924
+ unitSeconds
20820
20925
  );
20821
20926
  if (isEulerType(lender))
20822
20927
  return getEulerV2ReservesDataConverter(
@@ -20957,6 +21062,16 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
20957
21062
  }
20958
21063
  const invalidLenders = [];
20959
21064
  let lenderData = {};
21065
+ const rateUnitSeconds = /* @__PURE__ */ new Map();
21066
+ await Promise.all(
21067
+ validLenders.filter((l) => isCompoundV2Type(l)).map(async (l) => {
21068
+ try {
21069
+ rateUnitSeconds.set(l, await resolveRateUnitSeconds(chainId, l));
21070
+ } catch {
21071
+ rateUnitSeconds.set(l, void 0);
21072
+ }
21073
+ })
21074
+ );
20960
21075
  let currentSlice = 0;
20961
21076
  for (const lender of validLenders) {
20962
21077
  const [converter, sliceLength] = getLenderDataConverter(
@@ -20964,7 +21079,8 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
20964
21079
  chainId,
20965
21080
  prices,
20966
21081
  additionalYields,
20967
- list
21082
+ list,
21083
+ rateUnitSeconds.get(lender)
20968
21084
  );
20969
21085
  if (sliceLength > 0) {
20970
21086
  try {
@@ -21173,16 +21289,16 @@ var LKG_TTL_SEC = 30 * 60;
21173
21289
  var lastGood = /* @__PURE__ */ new Map();
21174
21290
  async function fetchTopAndBookWithFallback(source, chainId, marketId, nowSec9) {
21175
21291
  const key3 = `${chainId}:${marketId}`;
21176
- let fresh = null;
21292
+ let fresh2 = null;
21177
21293
  if (source.getTopAndBook) {
21178
- fresh = await source.getTopAndBook(marketId, MIDNIGHT_BOOK_LEVELS).catch(() => null);
21294
+ fresh2 = await source.getTopAndBook(marketId, MIDNIGHT_BOOK_LEVELS).catch(() => null);
21179
21295
  } else {
21180
21296
  const top = await source.getBookTop(marketId).catch(() => null);
21181
- if (top) fresh = { top, book: { bids: [], asks: [] } };
21297
+ if (top) fresh2 = { top, book: { bids: [], asks: [] } };
21182
21298
  }
21183
- if (fresh) {
21184
- lastGood.set(key3, { top: fresh.top, book: fresh.book, at: nowSec9 });
21185
- return { top: fresh.top, book: fresh.book };
21299
+ if (fresh2) {
21300
+ lastGood.set(key3, { top: fresh2.top, book: fresh2.book, at: nowSec9 });
21301
+ return { top: fresh2.top, book: fresh2.book };
21186
21302
  }
21187
21303
  const cached = lastGood.get(key3);
21188
21304
  if (cached && nowSec9 - cached.at <= LKG_TTL_SEC) {
@@ -21954,21 +22070,21 @@ var LKG_TTL_SEC2 = 30 * 60;
21954
22070
  var lastGood2 = /* @__PURE__ */ new Map();
21955
22071
  async function fetchTopAndBookWithFallback2(source, chainId, config, nowSec9) {
21956
22072
  const key3 = `${chainId}:${config.termRepoId}`;
21957
- let fresh = null;
22073
+ let fresh2 = null;
21958
22074
  if (source.getTopAndBook) {
21959
- fresh = await source.getTopAndBook(config, TERM_BOOK_LEVELS).catch(() => null);
22075
+ fresh2 = await source.getTopAndBook(config, TERM_BOOK_LEVELS).catch(() => null);
21960
22076
  } else {
21961
22077
  const top = await source.getBookTop(config).catch(() => null);
21962
- if (top) fresh = { top, book: { bids: [], asks: [] }, auction: null };
22078
+ if (top) fresh2 = { top, book: { bids: [], asks: [] }, auction: null };
21963
22079
  }
21964
- if (fresh) {
22080
+ if (fresh2) {
21965
22081
  lastGood2.set(key3, {
21966
- top: fresh.top,
21967
- book: fresh.book,
21968
- auction: fresh.auction ?? null,
22082
+ top: fresh2.top,
22083
+ book: fresh2.book,
22084
+ auction: fresh2.auction ?? null,
21969
22085
  at: nowSec9
21970
22086
  });
21971
- return { top: fresh.top, book: fresh.book, auction: fresh.auction ?? null };
22087
+ return { top: fresh2.top, book: fresh2.book, auction: fresh2.auction ?? null };
21972
22088
  }
21973
22089
  const cached = lastGood2.get(key3);
21974
22090
  if (cached && nowSec9 - cached.at <= LKG_TTL_SEC2) {
@@ -23578,10 +23694,10 @@ function refreshLiveMarkets(chainId, source) {
23578
23694
  const running = refreshInFlight.get(chainId);
23579
23695
  if (running) return running;
23580
23696
  lastRefreshAttempt.set(chainId, Date.now());
23581
- const p = source.getChainMarkets(chainId).then((fresh) => {
23582
- if (!fresh) return;
23697
+ const p = source.getChainMarkets(chainId).then((fresh2) => {
23698
+ if (!fresh2) return;
23583
23699
  const nowSec9 = Math.floor(Date.now() / 1e3);
23584
- const live = fresh.filter((m) => m.config.maturity > nowSec9);
23700
+ const live = fresh2.filter((m) => m.config.maturity > nowSec9);
23585
23701
  lastGood3.set(chainId, { markets: live, at: nowSec9 });
23586
23702
  rememberMarkets(chainId, live);
23587
23703
  }).catch(() => void 0).finally(() => refreshInFlight.delete(chainId));
@@ -41769,7 +41885,7 @@ function unflattenLenderData(pools) {
41769
41885
  }
41770
41886
  return result;
41771
41887
  }
41772
- var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient17, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, retries = 3, logs = false, concurrency = 1, permanentFailures, onEndpointFailure) => {
41888
+ var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient18, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, retries = 3, logs = false, concurrency = 1, permanentFailures, onEndpointFailure) => {
41773
41889
  const queries = organizeUserQueries(queriesRaw);
41774
41890
  const builtCalls = await Promise.all(
41775
41891
  queries.map(async (query3) => {
@@ -41779,7 +41895,7 @@ var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient17, allowF
41779
41895
  query3.lender,
41780
41896
  query3.account,
41781
41897
  query3.params,
41782
- getEvmClient17
41898
+ getEvmClient18
41783
41899
  );
41784
41900
  return callData.map((call) => ({ call, abi: call.abi ?? abi }));
41785
41901
  })
@@ -41789,7 +41905,7 @@ var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient17, allowF
41789
41905
  chainId,
41790
41906
  calls.map((call) => call.abi),
41791
41907
  calls.map((call) => call.call),
41792
- getEvmClient17,
41908
+ getEvmClient18,
41793
41909
  concurrency,
41794
41910
  retries,
41795
41911
  allowFailure,
@@ -59478,7 +59594,7 @@ var fetchSiloVaults = async (chainId, prices = {}, tokenList = {}, options) => {
59478
59594
 
59479
59595
  // src/vaults/euler-earn/entityLabels.ts
59480
59596
  var LABELS_BASE = "https://raw.githubusercontent.com/euler-xyz/euler-labels/master";
59481
- var TTL_MS3 = 30 * 60 * 1e3;
59597
+ var TTL_MS4 = 30 * 60 * 1e3;
59482
59598
  var cache3 = /* @__PURE__ */ new Map();
59483
59599
  var inflight4 = /* @__PURE__ */ new Map();
59484
59600
  async function fetchChainEntities(chainId) {
@@ -59504,7 +59620,7 @@ async function fetchChainEntities(chainId) {
59504
59620
  }
59505
59621
  async function fetchEulerEntityNames(chainId) {
59506
59622
  const hit = cache3.get(chainId);
59507
- if (hit && Date.now() - hit.at <= TTL_MS3) return hit.map;
59623
+ if (hit && Date.now() - hit.at <= TTL_MS4) return hit.map;
59508
59624
  const running = inflight4.get(chainId);
59509
59625
  if (running) return running;
59510
59626
  const p = fetchChainEntities(chainId).then((map) => {