Data Pipeline
The app is read-only against Postgres. All time-series data is produced by off-chain jobs in scripts/ that read on-chain state (and a few external APIs) and upsert into the onchain_credit schema. Every lending venue is measured with the same convention (see Metric Methodology): the realised ratio of an on-chain compounding index between two blocks, annualised by the actual elapsed time, so /carries compares venues like-for-like.
Refreshers (cron)
| Job | Cadence | Writes | What it reads |
|---|---|---|---|
refreshers/token-yields.ts | 6h | token_yield_apy | Share-to-asset rate per wrapper via archive eth_call (convertToAssets(1e18) for ERC-4626, getStETHByWstETH for wstETH, getRate() for weETH/ezETH, an external rateSource for osETH); stores share_rate, 24h supply_apy, and 30d apy_30d |
refreshers/fluid-ll.ts | 6h | fluid_ll_apy | Fluid Liquidity Layer supply/borrow exchange prices, annualised over the 6h window |
refreshers/fluid-dex.ts | 6h | fluid_dex_apy | Fluid DEX swap fees + smart-col/smart-debt reserves; fee_apy_usd = fee_window_usd × 1460 / (tvl_col + tvl_debt) |
refreshers/aave-v3.ts | 6h | aave_v3_reserve_apy | Aave v3 liquidityIndex / variableBorrowIndex (RAY-scaled), annualised |
refreshers/sparklend.ts | 6h | sparklend_reserve_apy | Same as Aave, against SparkLend's pool (separate table to avoid token-key collisions) |
refreshers/sofr-rates.ts | Daily | sofr_rates | NY Fed SOFR + compounded 30d/90d/180d averages + the compounding index |
refreshers/yield-token-assets.ts | Daily | assets | Rolls up token_yield_apy into the Asset Coverage table rows (current APY, 1M/YTD/1Y returns, market cap) |
refreshers/vault-risk-params.ts | Weekly | vault_risk_params | Per-strategy max-LTV + liquidation threshold on-chain, with a changed_at audit |
refreshers/vault-capacity.ts | Weekly | vault_capacity | Per-strategy borrow-cap / supply-cap headroom (Aave/Spark static caps; Fluid dynamic caps) |
The Fluid LL/DEX series also have daily rollup tables (fluid_ll_apy_daily, fluid_dex_apy_daily) that the carry charts read on the 6M / 1Y / YTD views.
Ad-hoc jobs
sync-fluid-vaults.ts— run on demand (not a cron). Pulls Fluid's vault API, computes supply TVL, classifies each vault, checks coverage, and upsertsfluid_vault_registrywith astatus(see Carry Strategies). Run with--dry-runto preview the active / below-floor / blocked split without writing. Must be re-run after a new yield adapter or DEX-pool snapshot lands for the affected vaults to flip toactive.resolve-oracles.ts— read-only oracle audit / drift guard (see Oracle Transparency).backfill-*.ts— one-off history backfills (e.g.backfill-fluid-core.tsreconstructs deep Fluid history from core-storage reads; per-asset backfills seedtoken_yield_apyfor newly added wrappers). These reuse the same annualisation math as the live refreshers.
On-chain access
src/lib/data/rpc.ts provides the read helpers: eth_call against a public RPC for current state, an archive endpoint for historical-block reads, eth_getStorageAt for packed storage Fluid exposes no clean getter for, and a DefiLlama block-by-timestamp lookup. Prices come from the DefiLlama Coins API.