Agent navigation — Public methodology: DEX Liquidity Score · Measured volume availability · Discovery Cron · DEX Price Cross-Validation. Operator details have one owner in the implementation appendix.
Methodology Versioning
- Current methodology version: <!-- GENERATED-START: methodology-version-liquidity-score -->
v6.95<!-- GENERATED-END: methodology-version-liquidity-score --> - TVL-basis breaks: a liquidity release that changes how retained TVL is measured (not just weighting or volume admission) must also append its version to
LIQUIDITY_TVL_BASIS_BREAK_VERSIONSinshared/lib/dex-liquidity-evidence.ts, which is append-only. The 30-day stability series never mix epochs across a listed break (see Basis homogeneity under Durability Sub-Component Weights); the source owns the current break list.
Reviewed execution targets require exact retained-pool identity, current independent references and quote-time factory/token/fee, freshness and execution proof. Supplemental discovery or configured targets alone establish neither zero liquidity nor execution capacity. Component weights, resource budgets and retained-TVL measurement are separate contracts.
The public changelog owns release history. Fixed-clock route comparison and owner review, fresh provider/quote observations and separate production resource evidence remain release prerequisites, not completed-equivalence or health claims.
PKT-5 no-admission disclosure: the conditional review activates no new family. V4 Base/BSC/Arbitrum/Polygon/Tempo, HyperSwap, Kodiak and native pending profiles remain score-ineligible; Meteora's writer stays stopped. Repeated mature observations, complete fork/drift/replay proof and native program/dependency closure with independent execution are still missing; HyperSwap also has five unresolved pinned execution-output mismatches. Reviewed addresses, local quotes, elapsed time or target presence waive none of these gates. The owning disposition changes no runtime admission, cadence, methodology version or resource budget.
DEX Liquidity Score
Hourly full publication admits recovered quotes at the next :16 instead of waiting for an even hour. Source requests and the :46 reuse path keep their existing cadence. Full generation and active-target writes run every hour; each uses the existing bounded persistence buffers and retention. Public history remains one reusable daily snapshot, not an hourly series. The reviewed DEX evidence maximum age remains four hours (DEX_LIQUIDITY_EVIDENCE_MAX_AGE_SEC), and measured-history high confidence remains three hours; operational cadence changes do not tighten those scoring bounds.
Published chain-label casing
Persisted DEX rows use the canonical internal chain id from canonicalExitRouteChain() (lowercase registry/alias keys). The chain_tvl_json keys, PoolEntry.chain, and top_pools_json chain values therefore use one canonical casing per chain; aggregate stages must not re-lowercase or substitute display names. Presentation adapters map those ids to CHAIN_META display names only.
Coverage normalization quarantines invalid class/confidence evidence per row as invalid-coverage-evidence, distinct from unobserved markets; it cannot supply a rating or trend. Trend-baseline confidence remains 0.50, durability 0.75, and both-null legacy coverage uses its conservative default. The /liquidity/ leaderboard keeps NR null and places NR rows after every rated row on every column and in either direction, including after observed zero.
In the full /api/dex-liquidity map (not the /api/dex-liquidity-table projection or history), each row carries liquidityScoreUnavailableReason: for a null liquidityScore, a machine code from whoever nulled it (LiquidityScoreUnavailableReasonSchema in shared/types/market.ts): the DEC-19 activity outcome from resolveVolumeActivityComponent (activity-coverage-below-floor, activity-missing, activity-stale, activity-completeness-unknown), no-retained-pools for a placeholder row, or invalid-coverage-evidence when the publisher quarantines the row. The producer records its code in score_components_json (no schema migration); rows scored before the field existed publish null, and consumers show plain NR rather than infer a cause. Rated rows publish null.
External source construction runs hourly at :10. Both :16 and :46 use the same exact source-slot state machine: writing waits; ready scores and publishes; failed or missing terminal output can recover; consumed reuses the accepted generation without rewriting it. An exact accepted publication also prevents replay if the best-effort consumed marker failed. Only successful publication closes the slot; a guard-rejected candidate stays ready. A live producer is never overwritten; readiness remains 90 seconds from the original scheduled delivery time (logical slot time only when no scheduled time was supplied). At that deadline a live source lease yields nonproductive skipped_neutral scoring-stage-producer-running, without renewing freshness. Preparation independently verifies the last accepted generation under its unchanged evidence budget. Turnover follows actual publication, including late :46 publication, never a wait or reuse. Heavy has GRAPH_API_KEY and can reconstruct a missing/terminal stage inline under the source lease and inherited deadline; absent credentials still fail preflight rather than publish a reduced graph. Targets stay private until guarded liquidity publication commits.
| Component | Weight | Source | How Computed |
|---|---|---|---|
| TVL Depth | <!-- GENERATED-START: liquidity-tvlDepth-weight -->30%<!-- GENERATED-END: liquidity-tvlDepth-weight --> | DeFiLlama Yields | Ratio-based log-scale: 35 * log10(depthRatio / 0.0007) where depthRatio = effectiveTvl / circulatingUsd. ~0.5%->30, ~1.5%->47, ~6%->67, ~14%->80, ~25%+->90+. Falls back to 35 * log10(tvl / 700_000) (parity with ratio formula at a $1B implied reference mcap) when circulatingUsd is unavailable. |
| Volume Activity | <!-- GENERATED-START: liquidity-volumeActivity-weight -->20%<!-- GENERATED-END: liquidity-volumeActivity-weight --> | DeFiLlama Yields | Log-scale V/T ratio: 38 * (log10(vtRatio) + 3). ~0.1%->0, ~0.3%->18, ~3.5%->59, ~19%->86, ~43%+->100. Admitted 24h volume / admitted TVL; rated when the window is complete or admitted pools cover ≥ 50% of retained TVL, otherwise null and the composite is NR (DEC-19, v6.9) |
| Pool Quality | <!-- GENERATED-START: liquidity-poolQuality-weight -->20%<!-- GENERATED-END: liquidity-poolQuality-weight --> | Curve API + DeFiLlama | Venue quality retention ratio: (qualityAdjustedTvl/totalTvlUsd - 0.15) / 0.65 * 100, rescaled from 15–80% range to 0–100 (see below). The scoring component uses mechanism and balance-health retention; pair quality affects effective TVL and pool stress. |
| Durability | <!-- GENERATED-START: liquidity-durability-weight -->20%<!-- GENERATED-END: liquidity-durability-weight --> | DeFiLlama Yields + History | <!-- GENERATED-START: liquidity-durability-tvlStability-weight -->35%<!-- GENERATED-END: liquidity-durability-tvlStability-weight --> TVL stability, <!-- GENERATED-START: liquidity-durability-volumeConsistency-weight -->25%<!-- GENERATED-END: liquidity-durability-volumeConsistency-weight --> volume consistency, <!-- GENERATED-START: liquidity-durability-maturity-weight -->25%<!-- GENERATED-END: liquidity-durability-maturity-weight --> maturity, <!-- GENERATED-START: liquidity-durability-organicFraction-weight -->15%<!-- GENERATED-END: liquidity-durability-organicFraction-weight --> organic fraction (sqrt curve) |
| Diversity | <!-- GENERATED-START: liquidity-pairDiversity-weight -->10%<!-- GENERATED-END: liquidity-pairDiversity-weight --> | DeFiLlama Yields | Pool count, diminishing returns: min(100, poolCount x 5) |
Quality Multipliers (v2)
| Pool Type | Multiplier | Detection |
|---|---|---|
| Curve StableSwap A>=500 | 1.0x | registryId not containing crypto + A>=500 |
| Curve StableSwap A<500 | 0.85x | registryId not containing crypto + A<500 |
| Curve CryptoSwap | 0.5x | registryId containing crypto/twocrypto/tricrypto |
| Uniswap V3 1bp | 1.1x | fee tier <= 100 |
| Uniswap V3 5bp | 0.85x | fee tier <= 500 |
| Uniswap V3 30bp+ | 0.4x | fee tier > 500 |
| Fluid DEX | 0.85x | project contains fluid |
| Aerodrome Stable (sAMM) | 0.85x | direct-source label only; DeFiLlama rows never resolve here |
| Aerodrome Volatile (vAMM) | 0.4x | project contains aerodrome, no concentrated-liquidity tag |
| Balancer Stable | 0.85x | project contains balancer + stable pattern |
| Balancer Weighted | 0.4x | project contains balancer, non-stable |
| Raydium CLMM | 0.85x | direct API type, or DL poolMeta marked Concentrated |
| Raydium AMM | 0.4x | standard AMM, wider spreads |
| Orca Whirlpool | 0.85x | concentrated liquidity (direct API or DL) |
| Meteora DLMM | 0.85x | protocol contains meteora |
| PancakeSwap V3 1bp | 1.1x | protocol contains pancakeswap + fee tier <= 1 bp |
| PancakeSwap V3 5bp | 0.85x | protocol contains pancakeswap + fee tier <= 5 bp |
| PancakeSwap V3 25bp | 0.7x | protocol contains pancakeswap + fee tier <= 25 bp |
| PancakeSwap V3 30bp | 0.4x | protocol contains pancakeswap + fee tier <= 30 bp |
| PancakeSwap V3 100bp | 0.25x | protocol contains pancakeswap + fee tier > 30 bp |
| Aerodrome Slipstream 1bp | 1.1x | protocol contains aerodrome-slipstream + fee tier <= 1 bp |
| Aerodrome Slipstream 5bp | 0.85x | protocol contains aerodrome-slipstream + fee tier <= 5 bp |
| Aerodrome Slipstream 30bp+ | 0.4x | protocol contains aerodrome-slipstream + fee tier > 5 bp |
| Velodrome Slipstream 1bp | 1.1x | protocol contains velodrome-slipstream + fee tier <= 1 bp |
| Velodrome Slipstream 5bp | 0.85x | protocol contains velodrome-slipstream + fee tier <= 5 bp |
| Velodrome Slipstream 30bp+ | 0.4x | protocol contains velodrome-slipstream + fee tier > 5 bp |
| Generic AMM | 0.3x | fallback |
Direct concentrated-liquidity fetchers (PancakeSwap V3, Aerodrome/Velodrome Slipstream) derive their -1bp/-5bp/-25bp/-30bp/-100bp bucket from the fee the source actually decoded. When the upstream fee is absent or out of range — a missing or malformed subgraph feeTier, a Sugar pool_fee outside [1, 10000] bps — the row keeps feeRate: null and publishes the neutral <protocol>-unknown-fee bucket (CL_UNKNOWN_FEE_BUCKET in worker/src/cron/dex-liquidity/direct-source-helpers.ts) instead of a fabricated tier, so the bucket never contradicts the row's own null fee. That bucket carries no tier multiplier and falls through to the generic 0.3x weight; pool-shape family and measured-execution targeting are unchanged.
Pool Quality Adjustments
- Balance health: Continuous
Math.pow(balanceRatio, 1.5)instead of binary threshold - Pair quality: Co-token scored using Pharos governance classification (CeFi->1.0, DeFi->0.9, CeFi-Dep->0.8) + static map for volatile assets (WETH->0.65, WBTC->0.6, unknown->0.3). Known quote aliases such as
USD₮0,USDT0,aUSDC,aUSDT,USDbC, and.ebridged variants are normalized to canonical symbols before scoring. Composite Curve LP aliases such as3CrvandFRAXBPinherit the best score from their underlying stablecoin basket. Multi-asset pools use best co-token score - MetaPool TVL dedup: Uses Curve's
usdTotalExcludingBasePoolto prevent double-counting base pool liquidity across metapools; the live Curve response owns the inventory. - Effective TVL:
poolTvl x mechanismMultiplier x balanceHealth x pairQuality, summed across all pools - Zero depth: A measured zero effective-TVL aggregate stays zero in both relative and unavailable-market-cap depth formulas; raw TVL never replaces it.
- Source-lane consistency: Secondary and remembered live pools use the same
parsePoolSymbolsparser as primary pools (USDC-USDT,USDC / USDT, and recognized composite names), unless a measured pair-quality override is supplied. Registry fallback preserves selected measured balance ratios and locked-liquidity fields for DeFiLlama and direct-API rows as well as CoinGecko;balanceMeasuredaccompanies the forwarded balance evidence, not an optimistic default.
For direct APIs, balance health is no longer uniformly neutral. Balancer, Raydium, Orca, and resolver-backed Fluid pools now contribute measured balance ratios when their APIs provide enough token-balance and pricing context. Fluid pools still default to 1.0 balance when the official resolver is unavailable or token decimals cannot be resolved safely.
Data Quality Filters
isBroken === trueCurve pools: skipped- Dead/rugged/deprecated protocols: excluded from
dexProjectsset and the explicit runtime blocklist (currently including Retro and Bunni variants) exposure === "single"pools (lending deposits, not DEX liquidity): skipped- CryptoSwap pools: correctly classified via
registryId - DL Raydium pools: classified from
poolMeta(Concentrated ->raydium-clmm) since v6.0, because DeFiLlama ships every Raydium pool under theraydium-ammproject slug; this lets the DL row and its direct-API CLMM twin share one pool-shape family and deduplicate instead of double-counting
Pool Stress Index (0-100)
Per-pool stress metric: 35x(1-balanceRatio) + 25x(1-organicFraction) + 20xImmaturityPenalty + 20x(1-pairQuality). TVL-weighted average stored as avg_pool_stress.
Durability Score (0-100)
Per-stablecoin durability metric combining: TVL stability from 30-day CV (35%), volume consistency from 30-day CV (25%), oldest pool maturity (25%), and organic fee fraction with sqrt curve (15%). Locked liquidity removed — no reliable data source. Stored as durability_score.
Pool Quality Formula
Pool Quality measures the venue quality retention ratio: the fraction of total TVL that survives after applying mechanism and balance-health multipliers.
poolQuality = min(100, max(0, (qualityAdjustedTvl / totalTvlUsd - 0.15) / 0.65 * 100))
Where qualityAdjustedTvl applies mechanism and balance-health multipliers to raw TVL, and totalTvlUsd is the pre-adjustment sum across all pools. Pair quality is already reflected upstream in effectiveTvl and the pool-stress diagnostics, but it is not part of this retention-ratio component. The linear rescaling maps the 15–80% retention range to 0–100, so a pool set retaining 15% or less of its raw TVL after quality adjustment scores 0, and one retaining 80% or more scores 100.
Exact Curve metapool joins use retained, base-pool-excluded TVL for both numerator and denominator. Balance evidence carries its own notional scope: a full-pool ratio cannot weight excluded-pool TVL. Mismatches omit measured balance diagnostics and use the existing unmeasured neutral fallback. With a scope-matched ratio 0.5, $2M retained TVL and multiplier 0.85 yield about $601,041 quality TVL (30.05% retention, Pool Quality 23), never a $3.005M full-pool numerator.
Durability Sub-Component Weights
- 35% TVL stability —
1 - min(1, CV)over 30-day snapshots (CV = coefficient of variation) - 25% Volume consistency — same CV formula over 30-day daily 24h turnover (volume / TVL). Since v6.9 a recorded day counts when its window is complete (measured volume / retained TVL) or its admitted pools cover at least
DEX_VOLUME_COVERAGE_MINof retained TVL (partialGrossUsd / admittedTvlUsd); below the floor the day is skipped, never estimated. Legacy days without a record keep their stored volume over stored TVL. Fewer than 7 qualifying days in 30 still falls back to the neutral 50 (durabilityVolumeConsistencyDefault). - 25% Maturity — oldest pool age, capped at 365 days:
min(1, oldestDays / 365) × 100 - 15% Organic fraction —
sqrt(organicFraction) × 100(diminishing returns past 50%; 25% organic → 50 score, 50% → 71 score, 100% → 100 score) - Basis homogeneity: each 30-day TVL/turnover series uses one retained-TVL measurement epoch, selected as the latest epoch with at least seven qualifying samples. It never mixes epochs; without seven it falls back to neutral 50. Seven calendar days need not supply seven admitted turnover samples.
liquidityTvlBasisEpochcompares stored versions numerically (missing means earliest), and the append-onlyLIQUIDITY_TVL_BASIS_BREAK_VERSIONSregistry owns breaks. Retained-TVL remeasurement must append a break in the same version-bump change; reweighting, volume admission and discovery-admission changes are not automatically breaks. The structured changelog owns past cutover effects.
Measured volume availability
Rows written before v6.9 remain legacy rows (no availability record, unknown completeness). They are not backfilled or restamped. Measured volume preserves actual provider values and clocks, separately from decaying inventory TVL.
- Shared authority:
shared/lib/dex-volume-availability.tsowns the admission window (DEX_VOLUME_OBSERVATION_MAX_AGE_SEC) and coverage floor (DEX_VOLUME_COVERAGE_MIN) constants, window classification, storage reads, consumer interpretation, the volume-activity formula, and the composite rule. Wire vocabulary lives inshared/types/market.ts(DexVolumeCompleteness,DexVolumeAvailabilityReason,DexVolumeAvailability). - Producer readings: every retained pool carries its raw provider reading and original observation clock (
volumeReading, internal, never published). Live DeFiLlama/direct-API readings retain their source-fetch clocks; registry readings retain the selected row's refresh clock. Resolver preference is highest-trust usable reading within 24h, else within 72h, else freshest stale reading; TVL confidence decay never scales volume. Missing/unparseable trailing volume isnull, not zero; CoinGecko Onchain stores a zero only with explicit zero volume and zero 24h buys/sells. Pre-activation zeros from non-exempt registry sources remain absent underDEX_VOLUME_ZERO_PROVENANCE_SINCE_SEC(2026-09-28 07:29:14 UTC); CoinGecko Onchain retains its exempt provenance. Since v6.93, a row after the captured registry evaluation clock is rejected whole before resolution. Legitimate refreshes between source start and registry-read completion retain their original observations and are evaluated in the same generation, without changing source/quote clocks. - Pool eligibility: a reading is
measuredwhen it has finite non-negative value and a provable observation clock withinDEX_VOLUME_OBSERVATION_MAX_AGE_SEC(72h, inclusive). This unchanged budget is wider than the 24h staged TVL/price freshness window because registry discovery can leave readings one to three days old. The admitted value remains the provider's rolling volume as of its original clock, not a 72h sum or an unbiased census; the record names oldest/newest observation clocks andmaxObservationAgeSec. Older readings arestale, absent/invalid value or clock ismissing, and measured zero remains valid. Since v6.93,applyPoolVolumeEligibility, retention predicates and coin/global summaries useregistryEvaluatedAtSecfrozen in payload v4, not a later publication/reuse clock. Every downstreamvolumeUsd1d/volumeUsd7dis the admitted value ornull; flags andvolumeObservation { status, observedAtSec }retain that admission. - Window completeness over the complete retained contributing pool set (not the visible top ten):
complete(every pool measured; an empty set is vacuously complete at 0),partial(some measured),missing(none measured, at least one missing),stale(none measured, every observation aged),unknown(legacy row without a record, or an unreadable record). Every non-complete state carries a machine-readablereason. - Public fields (in place):
totalVolume24hUsd,totalVolume7dUsd, historyvolume24hand poolvolumeUsd1dare widened to nullable. The measured total is a number only for acompletewindow; otherwise it isnulland the additivevolume24hAvailability/volume7dAvailabilityrecord (history:volume24hAvailability) carriescompleteness,reason, a separately labelledpartialGrossUsd(observed volume over the admitted pools — a lower bound, never the complete statistic), pool counts, the observation-window clock (windowSec,asOfSec,maxObservationAgeSec, oldest/newest observation) and, since v6.9, the bound published with that statistic:admittedTvlUsd(retained scoring TVL of admitted pools),retainedTvlUsd(all retained scoring TVL, post protocol caps) andvolumeCoverage= admitted / retained (nullwhen the set carries no TVL). Records written before v6.9 omit the three coverage fields. Pools may carryvolumeObservation { status, observedAtSec }. Rows without a record omit these fields: consumers read them asunknowncompleteness and keep the historical number, never labelling it measured. - Storage: migration
0249_dex_volume_availability.sqladds nullablevolume_availability_jsontodex_liquidity,dex_liquidity_run_rowsanddex_liquidity_history.NULLmarks a legacy row. Since v6.9 every current, placeholder,__global__and daily-history row writes a record. The NOT NULL legacy volume columns hold the complete sum, else the admitted partial gross, else0, and are never published as measured unless the record sayscomplete.total_volume_7d_measuredmirrors a complete 7d window. Placeholder rows retain no pool, so they record the vacuous complete-zero window. A same-day history row that is carried forward keeps its own record. An unreadable record publishesnullwith reasonavailability-record-unreadable. There is no backfill: legacy completeness cannot be reconstructed from stored totals. - LiquidityScore (DEC-19, coverage-gated since v6.9): Volume Activity applies the existing log-scale formula to admitted 24h volume / admitted TVL; stale and missing pools enter neither the numerator nor the denominator and nothing is estimated, zero-filled or decayed for them. The component — and therefore the composite — is rated when the 24h window is
completeorvolumeCoverage >= DEX_VOLUME_COVERAGE_MIN(0.50, exported fromshared/lib/dex-volume-availability.ts; the exact floor is rated). A complete measured zero scores 0 activity under the full weight denominator. Below the floor (including a coin with no admitted reading,missing/stale, orunknowncompleteness) the component is unavailable (scoreComponents.volumeActivity: null) and the composite LiquidityScore NR (liquidity_score = NULL). No renormalization, no denominator shrink, and no earlier score is carried forward. The 7d window is display-only. Valid components remain displayable beside the NR component. Coverage is an evidence-sufficiency floor, not an unbiasedness proof: unobserved pools may trade differently from observed ones, which is why the floor, the admitted TVL and the observation clocks are published with the score. Publication coverage guards and same-day history reconciliation count NR rows as observed (a rated score, or a non-unobservedcoverage class), not as placeholders. - Downstream readers: the DEX API/history handlers, Depeg Resolver context (current and 30d volume baseline), public dataset snapshot and durability volume-consistency series apply the storage read; durability volume consistency takes coverage-qualified days only (see Durability Sub-Component Weights). Safety Score does not consume the composite LiquidityScore or volume: its native DEX capture carries
updatedAt, exit-route observations and their coverage, so an NR composite alone does not make its Exit evidence unavailable. An NR composite reaches score-dependent readers as unavailable, not as a low score: the Selector's trading profile requiresliquidityScore, so an NR coin is a coverage skip there (shared/lib/selector/exclusions.ts); the Depeg Resolver's legacy K5 thin-liquidity triggers (liquidityScore < 20/< 30) cannot fire for an NR coin, and its current and 30-day volume inputs arenullfor non-complete windows, so K6 wind-down and calm-catastrophic paths that need them cannot fire (shared/lib/depeg-resolver/resolution.ts,worker/src/cron/depeg-resolver/context.ts); and the DEWS liquidity signal is unavailable whileliquidityScoreisnull(worker/src/lib/dews/signal-families.ts). - Frontend display:
src/lib/dex-volume-display.tsrenders a non-complete window as an em dash with aPartial ≥ $Xlabel in card cells. The/liquidity/leaderboard shows the admitted partial gross in-cell as a muted≥ $X, and its hero 24h DEX volume row headlines it as an explicit lower bound (≥ $X, detailPartial lower bound: pools holding N% of TVL); neither drops the≥or presents the bound as the complete total (R1/R7). - Exit portfolio completeness is a separate policy:
isDexExitRouteCoverageWithinRouteBudget()inshared/lib/p4-exit-route-capability-policy.tsowns the existing gap-accounting carve-outs; exact-route scoring keeps the stricterisDexExitRouteCoverageComplete(). Neither borrows the volume coverage floor or Economic Control's circulating-supply materiality threshold. A small missing pool count, top-ten TVL, or missing liquidity value cannot establish an immaterial unobserved remainder. Pools without admitted exact observations add no executable capacity, but an unresolved coverage gap retains its own scoped cause.
Liquidity Page
/liquidity/ uses the instrument header (methodology line labelled "Liquidity Score methodology") and a stacked FeatureHeroSplit:
- Beam: "Secondary exit depth", the global row's
totalTvlUsd; "—" plus a "Depth unavailable" chip when the global row is missing or quarantined. The universe chip counts observed markets (isObservedOnDexinsrc/app/liquidity/model.ts) over the active roster. A degraded or stale response (or an APIWarning) becomes anOpsStatusChipbeside the beam label, naming the snapshot time and the endpoint's fresh budget (API_FRESHNESS_MAX_AGE_SEC.dexLiquidity×FRESHNESS_RATIOS.FRESHwhen the header omits it);warn-110reads "Stale data". The body shows a notice only for a hard error. A quarantined global row withholds its 24h volume with its depth. - Facts: the 7d change is labelled "coins with 7d history" because it is a pool-TVL-weighted change over coins with a 7d baseline, not the global total's own change (the global row has no history series); 24h DEX volume as above; rated and observed-NR counts.
- Visual: the exit route map, unframed on the hero surface (
src/components/exit-route-map.tsx). Doors and lanes show their share of depth; the throat, drawn from HHI, shows the crowding index; below 768px two short door/lane lists, led by the crowding index, replace the scene. At rest the aggregate throat is selected so no route is dimmed. - Ledger: the hero footer (
src/components/exit-route-ledger.tsx) draws venue and chain mix in the map's exact door and lane colours with exact dollar depth, and breaks "Other routes" into its named tail plus a counted remainder (the tail sentence is hidden below 640px). - Below the hero: the leaderboard (rated rows, then unranked observed NR rows with their reason label; a partial window whose admitted sum rounds to $0.00 shows "—", not "≥ $0.00"), then folds for pool quality and for tracked coins not observed on DEX, then a source and snapshot-age footer.
Discovery Cron
Census authority belongs to a successfully completed, exhaustive same-run query, not a provider's advertised chains or a missing next-page marker. Capped/failed queries retain observed pools but cannot certify no pools; supplemental venue indexes cannot prove chain-wide absence. The source/scope contract owns provider routing and resumable-window mechanics.
Successful CG/GT transport suppresses the next fallback only with paginationComplete: true; capped inventories keep their observed pools and still allow GT/DexScreener reads. Osmosis, Noble, Kava and Aquarius quarantine malformed rows while staging healthy matches and reporting positive observed counts under degraded, non-exhaustive checks. Aquarius collapses identical duplicates and quarantines conflicting pool identities.
Aquarius discovery includes the nine reviewed Spiko Soroban registers, including CHFSAFO's exact issuer-listed contract. This is supplemental venue coverage, not an exhaustive Stellar/Soroban census: an empty Aquarius response remains non-exhaustive, while positive pool evidence establishes only observed inventory. Registration does not admit an execution model, manufacture a price, or establish asset-wide no-exit evidence.
Supported footprints without a published liquidity row receive the same due-time census maintenance as explicit zero-pool rows. This is discovery scheduling eligibility, not measured-zero liquidity or market-absence evidence. The existing 18-hour sweep target, two-hour tick, rotating deployment windows and provider budgets remain unchanged; missing or superseded outcomes stay unknown until real provider results persist.
D21 — execution model: discovery stays cron-native after the long-run Queue/Workflow review. Each invocation uses a setup-inclusive bounded work slice, checkpoints the unfinished cohort, and resumes it on the existing two-hour trigger instead of running toward the wrapper deadline. The admitted cohort sequence and per-deployment resume markers survive continuation; a checkpoint never certifies unqueried scope or refreshes evidence timestamps. The discovery execution contract owns budget and checkpoint details.
Address-bound QuoterV2 identity enrichment shares its existing 128-pool cap round-robin across reviewed deployment groups rather than admitting the first group exclusively. Sorted physical addresses rotate hourly within each group, and the first serialized group rotates too, so stable source insertion order cannot permanently starve later pools or chains. The 160-request/90-second budgets, serial RPC execution, exact factory membership checks, and active-versus-shadow admission remain unchanged. Selection, deferred probes, and failed reads prove no execution capacity; only subsequently accepted exact quotes contribute route evidence. Full portfolio coverage is not asserted merely because a bounded enrichment packet completed.
Exact route admission uses the consumer's scoring clock, not the source-stage start: factory/reserve captures performed minutes into that stage and measured cohorts already published before consumption are available evidence rather than lookahead. The measured-cohort read ceiling remains pinned to that consumer clock, and validators retain their future and freshness checks. Original block, reference-price, target, registry-read and generation clocks are not restamped; registry volume continues to use its separately captured read-consumption clock.
DEX Price Cross-Validation
DEX-implied prices publish hourly with the liquidity consumer. Genuine pool prices come only from the deduplicated retained pool set after quality filters/caps, weighted by observed liquidity and source confidence. Exchange tickers are a separate price-only channel weighted by observed flow; they supply no synthetic pool TVL or executable orderbook depth. Missing trusted primary price withholds DEX publication rather than bypassing plausibility/outlier checks.
Price and liquidity have separate clocks. API price fields become unavailable for invalid/stale/future or publication-mismatched evidence; a fresh price cannot make stale liquidity fresh. Depeg corroboration uses a stricter 75-minute/≥$1M source-liquidity gate, while the summary display uses 60 minutes/≥$250K. Ticker-only zero-TVL evidence clears neither floor. A contradictory DEX price can suppress a new false-positive event under the confirmation rules, not automatically close an existing event.