Skip to main contentSkip to data table
Pharos
Pharos

Data Flow Map

Source-to-UI map for Pharos stablecoin data, covering market prices, peg monitoring, liquidity, report cards, alerts, and generated public artifacts.

Overview

This map links each major Pharos data domain from upstream source to frontend consumption:

external source -> worker cron / sync -> D1 table or cache key -> API endpoint -> frontend hook -> page(s)

Core Flows

DomainExternal SourcesWorker Ingest / ComputeStorage LayerAPI SurfaceFrontend Hook(s)Primary UI
Stablecoin core list + pricesDefiLlama, CoinGecko, CMC, DexScreener, DexPaprika, CoinGecko Onchain, Alchemy Prices, Moralis token prices, Birdeye token prices, Pyth Network, Binance, Kraken, Bitstamp, Coinbase, RedStone, GeckoTerminal pool probes, Curve on-chain, protocol redemption quotes, Chainlink FX/commodity overlays, FX sources (Frankfurter, Open Exchange Rates, fawazahmed0/currency-api, ExchangeRate-API), and gold-api.com commodity referencesworker/src/cron/sync-fx-rates.ts, worker/src/cron/sync-stablecoins.ts, stage modules under worker/src/cron/sync-stablecoins/, worker/src/lib/address-price-providers/index.ts, worker/src/lib/authoritative-price-sources/, worker/src/lib/price-consensus.ts, worker/src/lib/price-validation.tscache keys: fx-rates, stablecoins; surface_publication_generations after migration for generic publication statusGET /api/stablecoins, GET /api/status (publicationHealth.surfaces["stablecoins"])useStablecoinsHomepage, Compare, Dependency Map, many cards, /status publication health
Aggregate stablecoin chartsDefiLlama aggregate chart history, D1 supply_history overlays for structural supplemental tracked assets, live stablecoins cache for the trailing pointworker/src/cron/sync-stablecoin-charts.ts + read-time hydration in worker/src/api/cache-handlers.tscache key: stablecoin-charts (+ live stablecoins cache at read time)GET /api/stablecoin-chartsuseStablecoinChartsHomepage charts
Stablecoin detail historyDefiLlama detail/chart, CoinGecko fallback, supply_history fallback pathsOn-demand detail handler plus worker/src/cron/snapshot-supply.ts / worker/src/api/backfill-supply-history.tsHandler-computed detail payload, per-coin D1 cache, supply_historyGET /api/stablecoin/:id for public detail-prefetch/API consumers; GET /api/supply-history for chart historyDetail page view model composes useSupplyHistory, useStablecoins, peg/liquidity/report-card/redemption/yield/stress/flow/blacklist/reserve hooks; usePrefetchStablecoin uses /api/stablecoin/:id for hover prefetchStablecoin detail market chart, Compare
Per-coin supply historyCached stablecoins payload snapshot, CoinGecko or DefiLlama backfillsworker/src/cron/snapshot-supply.ts, worker/src/api/backfill-supply-history.tssupply_historyGET /api/supply-historyuseSupplyHistory, useCompareDataModelStablecoin detail page, Compare
Depeg events + peg summaryStablecoin cache prices + DEX corroborationworker/src/cron/detect-depegs.ts (+ pending confirmation)depeg_events, depeg_pendingGET /api/depeg-events, GET /api/peg-summaryuseInfiniteDepegEvents, usePegSummaryDepeg page, homepage peg columns, detail cards
Depeg Duration Resolver + ReviewerConfirmed canonical depeg incidents, stablecoin metadata, supply history, DEWS, liquidity, redemption backstops, first-publication manifests, errata, and later canonical outcomesworker/src/cron/compute-depeg-resolver.ts plus worker/src/cron/compute-depeg-resolver-review.ts helper after DDRv2 sealing/publicationDDRv2 incident/link/lock-state/public-prediction/publication/errata tables, depeg_resolver_assessments, cache["depeg-resolver:snapshot"], cache["depeg-resolver-review:snapshot"], cache["ddr:repair-debt:v1"], worker_repair_tasks (ddr-repair-required-event)GET /api/depeg-resolver, GET /api/depeg-resolver-review, GET /api/status (dataQuality.repairDebt)useDepegResolver, useDepegResolverReviewDepeg page DDR and DDRR modules, /status repair-debt diagnostics
DEX liquidity + DEX implied pricesDefiLlama Yields, DefiLlama Protocols, Curve, Uniswap/Aerodrome/PancakeSwap subgraphs, protocol-native APIs (Fluid, Balancer, Raydium, Orca, Meteora), Fluid DexReservesResolver on supported EVM chains, Aerodrome/Velodrome Slipstream Sugar view contracts on Base/Optimism, plus CG/GT/DexScreener/CG Tickers -> [discovery cron] -> dex_pool_staging (D1)worker/src/cron/dex-discovery/orchestrator.ts (t1/t2/t3 tiered priority + exponential backoff, staleness sorting + live FX/metal validation refs) and worker/src/cron/dex-liquidity/* orchestrator merge (max(0.5, 1 - ageHours / 48) confidence decay, pools older than 24h dropped entirely + live FX/metal validation refs); GeckoTerminal request/parse normalization is shared in worker/src/cron/dex-liquidity/geckoterminal-shared.ts; direct/API/subgraph/view-contract fetchers (fetch-fluid.ts, fetch-balancer.ts, fetch-raydium.ts, fetch-orca.ts, fetch-meteora.ts, fetch-pancakeswap.ts, fetch-slipstream.ts) run during Step 1 of syncDexLiquidity() through worker/src/lib/provider-execution.ts lane/provider policies, normalized via DexApiPool type (worker/src/lib/dex-api-common.ts), preferred over overlapping DL pools only when identity is exact/uniquely derived and either measured 24h volume exists or the trusted Slipstream source exposes no volume field, source family direct_apidex_pool_staging -> dex_liquidity_run_rows / dex_liquidity_publication_generations -> published dex_liquidity, plus dex_liquidity_history, dex_prices, per-source cache["circuit:<source>"] breaker rows aggregated on read into providerCircuitHealthGET /api/dex-liquidity, GET /api/dex-liquidity-history, GET /api/status (publicationHealth.surfaces["dex-liquidity"], providerCircuitHealth, dependencyHealth.dependencies["dex-liquidity"])useDexLiquidity, useDexLiquidityHistoryLiquidity page, Compare, report-card inputs, /status liquidity health, provider-circuit health, publication-health, and dependency root-cause cards
Blacklist / freeze trackerEtherscan v2, TronGrid, RPC providers, frozen operator recovery manifestsworker/src/cron/sync-blacklist.ts + helper modules under worker/src/cron/blacklist/; guarded one-off recovery in worker/scripts/reconcile-night-watch-blacklist.tsblacklist_events, typed/generation-fenced blacklist_sync_state, blacklist_current_balances, blacklist_amount_repair_queue, blacklist_provider_scan_telemetry, blacklist_reconciliation_runsGET /api/blacklist, GET /api/blacklist-summary, GET /api/status (dataQuality.blacklistReconciliation)useBlacklistEventsPage, useBlacklistSummaryFreezeWatch page, public/admin recovery diagnostics
Mint/Burn flow trackerAlchemy logs (configured issuance chains; currently Ethereum plus native Arbitrum for USDai)worker/src/cron/sync-mint-burn.ts + worker/src/cron/mint-burn/run-state.ts, slot dispatch via worker/src/handlers/scheduled/mint-burn-slot.tsmint_burn_events, mint_burn_hourly, mint_burn_sync_stateGET /api/mint-burn-flows, GET /api/mint-burn-eventsuseMintBurnFlows, useMintBurnFlowsCoin, useMintBurnEventsFlows page, homepage flow snapshot, coin overlays
Live reserve compositionProtocol reserve APIs, dashboards, and on-chain/accounting reads via adapter-specific fetchesworker/src/cron/sync-live-reserves.ts; isolated recovery in worker/src/handlers/scheduled/reserve-recovery.tsreserve_composition, reserve_sync_state, generation-fenced worker_scheduled_checkpointsGET /api/stablecoin-reserves/:id, GET /api/report-cards, GET /api/statususeStablecoinReserves, useReportCardsStablecoin detail reserve card, report-card collateral quality inputs, reserve-drift/status surfaces
Redemption backstops + effective exitStablecoin cache, DEX liquidity snapshot, live reserve-sync metadata, and redeemability config registryworker/src/cron/sync-redemption-backstops.tsredemption_backstop, redemption_backstop_historyGET /api/redemption-backstops, GET /api/report-cardsuseRedemptionBackstops, useReportCardsStablecoin detail redemption card, report-card liquidity inputs
Stability Index (PSI)Stablecoin cache + active depeg state + DEWS stress breadthworker/src/cron/stability-index.ts, daily worker/src/cron/snapshot-psi.tsstability_index_samples, stability_indexGET /api/stability-index, GET /api/status (publicationHealth.surfaces["psi"], dependencyHealth.dependencies["psi"])useStabilityIndex, useStabilityIndexDetailStability Index pages, digest snapshot, /status publication/dependency health
DEWS stress signalsStablecoins + liquidity + blacklist + mint/burn + yield + PSI inputsworker/src/cron/compute-dews.tsstress_signals, stress_signal_history, stress_signals_latest, cache dews freshness sentinel, exact publication pointer cache["dews:published-generation"]GET /api/stress-signals, GET /api/status (publicationHealth.surfaces["dews"], dependencyHealth.dependencies["dews"])useStressSignals, useStressSignalDetailDepeg tracker risk panels, homepage radar snapshot, /status publication/dependency health
Yield intelligenceExact compact report_card_cache publication, current full report-card snapshot or computed fallback for API hydration, on-chain rate calls, DefiLlama pools, cached supplemental protocol snapshots, CoinGecko price fallback, New York Fed/FRED/Treasury/central-bank benchmark feeds, risk-free rate cache, plus optional gated vaults.fyi detailed-vault telemetry and allowlisted supplemental rowsworker/src/cron/sync-yield-data.ts, worker/src/cron/sync-yield-supplemental.ts, helper modules under worker/src/cron/yield-sync/, worker/src/cron/fetch-tbill-rate.ts, worker/src/api/yield-rankings-cache.tsyield_data, source-aware yield_history, yield_publication_generations, yield_source_decisions, cache yield-rankings with immutable hourly report-card evidence plus response-only live hydration provenance, structured benchmark cache risk_free_rates, legacy USD mirror risk_free_rate, supplemental/on-chain health cachesGET /api/yield-rankings, GET /api/yield-history, GET /api/yield-adapter-manifest, GET /api/status (publicationHealth.surfaces["yield-rankings"], dependencyHealth.dependencies["yield-rankings"])useYieldRankings, useYieldHistory, useYieldAdapterManifestYield page, stablecoin detail, methodology yield-source monitor, /status yield, publication-health, and dependency root-cause cards
Daily digestAnthropic Claude + PSI snapshot contextworker/src/cron/daily-digest.ts, worker/src/lib/telegram-digest-outbox.tsdaily_digest, exact-payload telegram_digest_outbox, + static build sync to data/digests.jsonGET /api/daily-digest, GET /api/digest-archive, GET /api/digest-snapshotuseDailyDigest, useDigestArchive, useDigestSnapshotDigest page + archive
Bluechip ratingsBluechip rating publicationsworker/src/cron/sync-bluechip.tscache key: bluechip-ratingsGET /api/bluechip-ratingsuseBluechipRatings/about/bluechip/, Compare, stablecoin badges, Screener Picker
USDS freeze statusUSDS contract storage/call probesworker/src/cron/sync-usds-status.tscache key: usds-statusGET /api/usds-statususeUsdsStatusUSDS status card
Public daily dataset snapshotsCompleted D1/cache artifacts: stablecoins cache, report-card cache, prior-day PSI snapshot, exact published DEWS generation, and optional current DEX liquidity rowsworker/src/cron/snapshot-public-dataset.tspublic_snapshotsGET /api/snapshots/index, GET /api/snapshots/:date.json, GET /api/snapshot/:date/stablecoin/:idExternal integrations and historical dataset consumers
Report cards + dependency graphPeg summary + DEX liquidity + redemption backstops + bluechip + stablecoin metadata/dependenciesworker/src/api/report-cards.ts compute fallback; worker/src/cron/publish-report-card-cache.ts exact-set validates and atomically publishes full, compact/yield-safety, and Telegram projections under one generationAPI read path: report-cards:snapshot with compute fallback; downstream artifacts: report-cards:snapshot, report_card_cache, cache["alert:safety-source-cache"]GET /api/report-cards, GET /api/status (publicationHealth.surfaces["report-card-cache"], dependencyHealth.dependencies["report-card-cache"])useReportCardsSafety Scores, Portfolio, Dependency Map, homepage safety snapshot, Yield safety hydration, /status publication/dependency health
Status reliabilityInternal router probes + production-domain HTTP canaries + DB/cache-only structural canaries + status synthesisworker/src/cron/status-self-check.ts, worker/src/cron/data-invariant-canary.ts, worker/src/api/status.ts, worker/src/api/public-status-history.ts, static dependency registry shared/lib/data-dependency-registry.tsstatus_state, status_transitions, status_probe_runs, status_discrepancy_state, worker_canary_runs; derived dependencyHealth is response-onlyPublic: GET /api/health, GET /api/public-status-history; admin: GET /api/status, GET /api/status-history (canaries)Public: useHealth, usePublicEndpointProbes, usePublicStatusHistory; admin: useStatus, useEndpointProbes, useStatusHistory/status public health board, /admin operator dashboard
Telegram pulseTelegram subscribers, pending queue, usage analytics, and delivery diagnosticsworker/src/api/telegram-pulse.ts snapshot publisher on the five-minute Telegram lanecache key: telegram:pulse:snapshotGET /api/telegram-pulseuseTelegramPulse/pharoswatchbot/ pulse strip
Personalized Telegram daily recapCanonical tape_events plus existing D1 subscriber, direct-watchlist, preset, snooze, and global-family state; no provider/API or AI callsworker/src/cron/telegram-recap-planner.ts (DB-only due-page planner), worker/src/lib/telegram-recap-facts.ts, worker/src/lib/telegram-recap-ranking.ts, worker/src/lib/telegram-recap-formatting.tstelegram_recap_preferences, telegram_recap_targets, exact telegram_pending_alerts rows with source_type = personalized_recapNo public API; private commands and signed Mini App state/mutationMini App Settings Daily Recap sectionPrivate Telegram chats, one material recap message per local date
Coverage discoveryCoinGecko category API, DL stablecoins residualsworker/src/cron/discovery-scan.ts (weekly, Monday-only), worker/src/cron/sync-stablecoins/intake.ts (DL residuals)discovery_candidatesGET /api/status (discoveryCandidates field), plus direct admin GET /api/discovery-candidates / POST /api/discovery-candidates/:id/dismiss— (admin only)/admin/ operator dashboard, Pipeline section
Chain analyticsStablecoins cache aggregate circulating buckets, chainCirculating buckets (already aggregated by DefiLlama), report card cache (safety scores for quality sub-factor)worker/src/api/chains.ts (compute on read from stablecoins + report-card D1 caches and emit freshness metadata); worker/src/cron/snapshot-chain-supply.ts writes daily totals to D1Live leaderboard: computed on-the-fly from D1 caches with _meta freshness; history: chain_supply_historyGET /api/chainsuseChains, useChainProfileData, useChainStablecoins/chains/ leaderboard, /chains/[chain]/ profile pages
Alt-peg / non-USD sharesupply_history rows for commodity-pegged and fiat non-USD stablecoinsworker/src/api/non-usd-share.ts computes historical aggregate shares on read from daily supply snapshotssupply_historyGET /api/non-usd-shareuseNonUsdShare/alt-pegs/ market-share chart and non-USD/commodity context
Timeline / Tape eventsDepeg, freeze, safety-score, PSI, DEWS, mint/burn, yield, methodology, cemetery, and lifecycle source tables/static registriesworker/src/cron/project-tape.ts projects source transitions through class-specific tape projectors on the DEWS/PSI DB-only lanetape_eventsGET /api/eventsuseEvents, useLatestEvents, useTimelineFeedData/timeline/ cross-class event feed and homepage timeline modules

The DEX flow has an additive shadow measured-execution subflow. Pinned Uniswap V3 and PancakeSwap V3 QuoterV2/factory RPC reads, plus the Fluid resolver adapter, enter worker/src/cron/measured-execution/ through the isolated sync-cl-exit-depth job. The prior retained-pool target generation is stored in dex_measured_execution_targets; raw proof and validated quote profiles are generation-fenced in dex_measured_execution_quotes. The following sync-dex-liquidity run consumes only a published prior quote generation and exposes proof-free profiles and explicit capability gates through the existing DEX API. All measured deployment cohorts remain score-ineligible while their activation evidence is pending.

The private report-cards:snapshot row is checksum-verified gzip/base64 with bounded decompression; its decoded public V8 JSON is unchanged, and the new reader also accepts legacy plain envelopes during rolling deploys.

The report-card publication flow also runs a candidate-only Safety Score V9 sidecar after the atomic V8 publication commits. It reuses the exact normalized base generation, adds reviewed V9 facts, and writes the latest candidate/diff, one compact summary per UTC day, selected content-addressed replay evidence, and append-only movement reviews. A failed attempt can be retried later on the same day; routine successful runs do not retain a full artifact bundle. GET /api/admin-safety-score-v9 and its review mutation remain the operator surface. The additive GET /api/report-cards/v9 route now exposes a strict, fully identified shadow contract for dark consumer verification. Shadow state still does not feed GET /api/report-cards, the active frontend, yield, Telegram, chain analytics, or V8-compatible public history; those remain V8 until the independent validation, coverage, shadow-window, and consumer-cutover gates are satisfied. See Safety Score V9 Rollout.

Scheduling Backbone

Cron expressions are deployed from worker/wrangler.toml; shared/lib/cron-jobs.ts owns canonical schedule/job metadata and shared/lib/scheduled-runner-registry.ts owns expression-to-runner dispatch. Use Worker Infrastructure: Cron Scheduling for execution details and npm run check:cron-sync / npm run check:cron-connections for the authoritative live inventory and connection-budget report.

Freshness Contract (Frontend)

API hooks that use useApiQuery follow the interval supplied by their caller:

  • staleTime = interval
  • refetchInterval = 2 * interval

Defined centrally in src/hooks/use-api-query.ts. Cron-backed hooks should pass the producer cadence unless a documented route-specific exception applies. Current exceptions include /api/health (1-minute diagnostic polling, not cron-backed) and /api/usds-status (15-minute UI polling over a daily source snapshot).

Notes

  • Core aggregate boundary: shared/data/stablecoins/listing-decisions.json classifies the catalog, while shared/lib/stablecoins/aggregate-registry.ts projects active core-stablecoin and cash-equivalent entries for monetary aggregates. PSI, digest market/supply totals, current homepage market cap, chain totals/history, and non-USD share consume that projection. Depeg, DEWS, price, per-asset history, and digest risk-signal lanes continue monitoring every active listing, including variants and stable-value investments. Client ranking filters use the compact listingClass field in coins.client.generated.json, not the full decision ledger. New PSI and digest snapshots identify the aggregate boundary as core-stablecoins-v1 so consumers can distinguish legacy rows.
  • DEX price bridge: The half-hourly DEX liquidity cron now rebuilds dex_prices.price_sources_json from the final retained priced-pool surface after dedupe, caps, scoring filters, and unit normalization, publishing one aggregate per protocol. The quarter-hourly pricing cron reads these via loadDexPriceSources() and promotes at most one individually-weighted consensus source per protocol: fluid-dex (weight 3), balancer-dex (weight 3), curve-dex (weight 3), uniswap-v3-dex (weight 2), uniswap-v4-dex (weight 2), raydium-dex (weight 2), orca-dex (weight 2), meteora-dex (weight 2), pancakeswap-dex (weight 2), aerodrome-dex (weight 2), velodrome-dex (weight 2). These promoted protocol sources only enter primary consensus when corroborated or when no non-DEX voices exist, and the overlapping dex-promoted aggregate (weight 1) is withheld whenever at least one promoted protocol candidate passes freshness and TVL validation for the same asset, even if that candidate is then excluded for lack of corroboration. The aggregate DEX fallback enters consensus only when no protocol candidate clears those pre-corroboration checks. DEX admission/merge skip reasons are emitted into logs and cron metadata so stale rows, malformed snapshots, TVL filters, missing registry mappings, and duplicate identities can be traced without scraping the raw tables.
  • Abort-aware high-volume publication: DEX liquidity and DEWS persistence pass the cron AbortSignal into chunked D1 batches, retrying D1 operations, and final freshness-sentinel guards. If timeout or lease-loss aborts the run after a partial batch, the run fails before publishing freshness:dex-liquidity, freshness:dews, or the exact DEWS publication pointer. Durable DEWS consumers, canaries, and freshness reporting use the pointer rather than raw MAX(computed_at) rows.
  • Cache passthrough endpoints include freshness metadata via _meta and/or X-Data-Age.
  • Chain profile pages intentionally coordinate two APIs: GET /api/chains for the summary card and GET /api/stablecoins for composition. The detailed sections stay hidden until both snapshots share the same updatedAt, which keeps incomplete or mismatched data from being presented as a full per-chain breakdown.
  • chain_supply_history remains a forward-only internal dataset until the post-2026-04-08 baseline. Earlier rows were written before shared chain-label canonicalization and are not approved for public charting.
  • /api/dex-liquidity is meta-aware on the frontend: the page uses worker freshness metadata (and degraded-run Warning headers) rather than client fetch time to assess staleness.
  • Liquidity history now carries coverageClass / coverageConfidence; trend and durability consumers should treat low-confidence snapshots as informational, not authoritative baselines.
  • dex_liquidity_history is retained for the public 365-day history window; older daily snapshots are pruned during successful sync-dex-liquidity persistence instead of living as an indefinite research archive.
  • Admin/backfill endpoints bypass edge cache via cacheBypass flags in shared/lib/api-endpoints/.
  • The stablecoins cache loader distinguishes ok, degraded, and error states. Operator-facing or published consumers (/status, daily digest, safety snapshot) now fail closed on non-ok cache reads instead of treating broken cache state as an empty valid dataset.
  • consensusSources flows from the price-consensus cron stage through the stablecoins cache → /api/stablecoins and /api/peg-summaryuseStablecoins / usePegSummary hooks → PriceTransparencyCard on the detail page and CoverageBadge source-count enrichment on the coverage page.
  • priceSourceConfidenceProfile flows from DEX-inclusive primary pricing through the stablecoins cache and /api/stablecoins. It is omitted for non-DEX prices and currently remains a data/API transparency field rather than a UI dependency.