Blog

Engineering

Why we built our in-house onchain price feed

We price 300,000+ tokens from raw onchain data. Our price feed is the backbone of every dollar-denominated metric institutions use.

Token Terminal

Why we built our in-house onchain price feed

Most of the metrics Token Terminal serves need a USD price somewhere in the calculation, such as total value locked, active loans, and fees. Across 100+ blockchains and 1,200+ protocols, every dollar-denominated metric depends on the same thing: a reliable answer to what each token is worth.

Measuring value accrual onchain requires understanding the unit in which that value accrues. A lending protocol earns interest in the borrowed asset. A DEX collects fees in whatever tokens pass through its pools. Liquid staking adds another layer: a derivative token that compounds against its underlying asset. Yield protocols go further, splitting a single token into principal and yield instruments priced independently.

Crypto's open design space means value can accrue in increasingly complex and unconventional forms. Anyone assessing financial performance through onchain data needs two things:

  • Price feeds that cover all relevant tokens.
  • Confidence that those feeds are reliable enough to underpin top-level metrics.

Manually curating which tokens to price doesn't scale. The long tail is too large and changes too fast. But including every token without filtering is equally dangerous: illiquid tokens are cheap to manipulate, and a single bad price can distort the metrics for a protocol or an entire ecosystem. Coverage and reliability pull in opposite directions. We solve this with layered heuristics that filter out tokens without meaningful economic activity.

Our in-house price feed covers over 300,000 tokens and powers every onchain financial metric we serve to institutions on a daily basis. This post explains how we built it.

From stablecoins to the long tail

We establish prices in layers, where each layer depends only on the one above it.

Tier 1: Stablecoins. We use over 20 stablecoins as the foundation. USDC, USDT, DAI, and others are pegged at $1.00. We cross-reference them against onchain oracle feeds to confirm the peg holds. These form the ground truth that everything else prices against.

Tier 2: Spot tokens. We start from wrapped native tokens: WETH on Ethereum, WBNB on BSC, WAVAX on Avalanche, and equivalents on every other supported chain. These get priced first from DEX pools where they trade against stablecoins. From there, we iterate: any token that trades against an already-priced token in a pool with sufficient liquidity gets a price in the next pass. Each pass widens coverage. A few iterations take us from around 50 wrapped tokens to over 300,000. We use a liquidity-weighted average across pools, where deeper pools carry more influence. Pools must hold at least $5,000 on each side to qualify as a price source.

Tier 3: Derivative and liquidity provider (LP) tokens. These tokens don't trade directly in DEX pools. They derive their value from other tokens through protocol-specific logic. Pricing them requires the tiers above, which is why the hierarchy matters.

Tier 1
Stablecoins
Tier 2
Spot tokens
Tier 3
Derivative and LP tokens

Each tier derives its prices from the tier above. Coverage widens at each level.

How each token type gets a price

The tokens we price fall into three categories, each requiring different logic.

Spot tokens trade directly in DEX pools. Every pool family computes prices differently.

Uniswap v2 pools maintain a constant product of their two reserves. The price is the ratio between them: when one side is bought, the other grows proportionally. This works for any token pair, but the price moves with every trade regardless of size.

Curve pools take a different approach for assets that should trade near parity. An amplification parameter flattens the bonding curve around the 1:1 price, so large reserve changes barely move the price. When reserves skew too far from equilibrium, the curve steepens and begins to behave like a constant product pool. Curve pools can also hold more than two tokens. We decompose each N-token pool into all possible pairs, generating synthetic two-sided pools so the rest of the pipeline can treat them uniformly.

Uniswap v2 constant product vs Curve StableSwap
Uniswap v2 uses the constant product invariant (xy=k). Curve StableSwap flattens the curve near parity so large reserve changes barely move the price. At the extremes, it steepens and converges toward constant product.
Curve invariant (StableSwap)Uniswap invariant (xy=k)Constant price (x+y=D)

Uniswap v3 introduced concentrated liquidity within a defined price range. Instead of spreading liquidity across all possible prices, providers choose a range. Prices come from tick math: each tick represents a discrete price point, and liquidity only exists between the boundaries a provider sets. v4 added a hook system for custom pool logic, but the core pricing curve is unchanged.

Uniswap v3/v4: liquidity is concentrated in tick ranges. Each tick has its own price.
The active tick determines which liquidity is used for the next trade. Taller bars mean deeper liquidity at that price.
$0.3M
$0.5M
$0.8M
$1.4M
$2.8M
$4.2M
$6.1M
$7.8M
active
$7.2M
$5.6M
$4.1M
$2.9M
$1.8M
$1M
$0.6M
$0.3M
$1,700
$1,900
$2,080
$2,200
$2,450
1 WETH = $2,080 USDCEach bar = one tick range
Token A sideToken B sideActive tick

Derivative tokens wrap or transform an underlying asset. Each protocol defines its own redemption logic, which means each one accrues value differently.

Compound cTokens represent a deposit in a lending pool. When you deposit USDC, you receive cUSDC. The number of cTokens in your wallet stays fixed, but each one is worth progressively more USDC over time as the lending pool earns interest. Pricing a cToken means tracking that exchange rate.

Aave aTokens work in the opposite direction. When you deposit USDC, you receive aUSDC. The exchange rate stays at 1:1, but your wallet balance increases as interest accrues. The quantity changes, not the rate.

Lido stETH represents staked ETH. The balance in your wallet grows as staking rewards accumulate, but the price of each stETH stays close to 1 ETH. Pricing means tracking the balance rebase, not an exchange rate.

Pendle splits a yield-bearing token into two separate instruments. The principal token (PT) trades at a discount and converges to face value at maturity. The yield token (YT) captures all rewards until maturity, then becomes worthless. Pricing requires modeling both time-to-maturity and expected yield. For some protocols like Pendle, this involves reading offchain state alongside onchain data.

We resolve each wrapper back to its underlying asset using protocol-specific logic.

Each protocol accrues value differently. Quantity and rate move independently.
Drag to scrub through time. Watch which component changes and which stays constant.
Time0mo
Compound cToken
quantity × rate
100
Quantity
$1.000
Rate
Total$100.00
Aave aToken
quantity × rate
100.0
Quantity
$1.00
Rate
Total$100.00
Lido stETH
balance × price
1.000
Balance
≈1 ETH
Price
Effective1.000 ETH
Pendle PT/YT
PT + YT = underlying
$0.950
PT
$0.050
YT
Maturity12mo
BaseYieldFixed

LP tokens represent shares of a liquidity pool. The price of an LP token is the total USD value of the pool's reserves divided by the outstanding LP token supply.

The formula is straightforward: sum up each reserve multiplied by its token price, then divide by the number of LP tokens in circulation. The inputs are the same spot prices from the tiers above. The challenge is the denominator: tracking LP supply requires indexing every mint and burn event across the pool's lifetime, because the supply changes with every deposit and withdrawal.

In a Uniswap v2 pool, reserves rebalance along the constant product curve as prices move. In a Curve pool, the amplification parameter keeps reserves closer to equilibrium, so LP token prices for correlated pairs are more stable. Both use the same formula. The difference is how the reserves shift.

WETH-UNI Uniswap v2 LP token price
Drag to change ETH price. Reserves rebalance along the constant product curve, and the LP token price updates.
ETH price$2,080
Pool reserves2,404 WETH × $2,080$5.00M666,667 UNI × $7.50$5.00MTotal pool value$10.00MLP supply10,000 tokensLP token price$1000.00
Formula: (reserve₀ × price₀ + reserve₁ × price₁) / supply

Keeping bad data out

Onchain DEX data is adversarial. Scam tokens, manipulated pools, and anomalous trades are constant. We filter them in three layers.

Denylists. We maintain explicit denylists for both pools and tokens. A pool might be hacked, like a compromised Curve pool where an attacker drained one side. A token might be an outright scam, created to extract value from unsuspecting traders. Each denylist entry is annotated with why it was added. These are manually curated and reviewed, not automated. When we remove a price source, the reason is recorded alongside it.

Every excluded pool is annotated with why it was removed.
The full denylist is version-controlled and auditable.
ChainDEXReason
ethereumCurveHacked pool, attacker drained one side
ethereumUniswap v3High total liquidity but low active liquidity
bscApeswapCauses a reserve spike in aggregation
arbitrumSushiSwapCauses a reserve spike in aggregation

Anomaly detection. We flag pools where one side holds orders-of-magnitude more reserves than the other. A skewed pool reports prices that are no longer trustworthy. We also reject any hourly price that moves more than 10x from the previous hour, unless the following hour confirms the new level. This distinguishes a real market event from a flash manipulation: a legitimate crash will sustain, a manipulated spike will revert.

A price that jumps more than 10x from the previous hour is rejected unless the next hour confirms it.
The spike at hour 8 reverts immediately, so it is flagged as manipulation and removed from the feed.
10x threshold$1$14.50 · rejectedh0h6h12h18h23
Cleaned priceRejected spike

Trading filters. Tokens below a minimum unique sender count are treated as likely spam. A token can have deep liquidity in a pool but only a handful of wallets behind it. We also flag swaps with outlier token quantities in a single transaction. Some tokens require exceptions: PEPE has legitimate supply in the hundreds of billions, so we allowlisted it past the large-trade filter. These exceptions are explicit and auditable.

Tokens below the sender threshold are filtered as likely spam, regardless of pool liquidity.
PEPE is allowlisted past the large-trade filter despite extreme token quantities per swap.
min sendersUNIAAVECRVLINKWBTCPEPEUnique sendersVolume
PassesFilteredAllowlisted exception

A token might pass one layer but fail another. A pool could have balanced reserves and active trading, but contain a denylisted token. A token could clear the denylist with enough senders, but its price spikes 10x in one hour and reverts the next. A token could show deep liquidity and stable pricing, but only three wallets ever traded it. This is why the layers work together.

Prices we can defend

Running our own price feed means we can trace any metric back to the specific DEX pools and reserve levels that produced the underlying prices. When a user questions a TVL number, we don't point to an external API. We point to pool reserves at a specific block height.

Institutions, data providers, and analysts depend on these numbers. When someone builds a model on our TVL or revenue data, they need to know the prices underneath are traceable and verifiable. Operating our own price feed is what makes that possible.

Pricing is one layer of our end-to-end data pipeline. Every metric we serve passes through decoding, standardization, and aggregation before it reaches a user. We built this layer in-house because every number we publish needs to be defensible down to the pool level.

If your team needs access to the same price feed we use internally, reach out at sales@tokenterminal.xyz.

The authors of this content, or members, affiliates, or stakeholders of Token Terminal may be participating or are invested in protocols or tokens mentioned herein. The foregoing statement acts as a disclosure of potential conflicts of interest and is not a recommendation to purchase or invest in any token or participate in any protocol. Token Terminal does not recommend any particular course of action in relation to any token or protocol. The content herein is meant purely for educational and informational purposes only, and should not be relied upon as financial, investment, legal, tax or any other professional or other advice. None of the content and information herein is presented to induce or to attempt to induce any reader or other person to buy, sell or hold any token or participate in any protocol or enter into, or offer to enter into, any agreement for or with a view to buying or selling any token or participating in any protocol. Statements made herein (including statements of opinion, if any) are wholly generic and not tailored to take into account the personal needs and unique circumstances of any reader or any other person. Readers are strongly urged to exercise caution and have regard to their own personal needs and circumstances before making any decision to buy or sell any token or participate in any protocol. Observations and views expressed herein may be changed by Token Terminal at any time without notice. Token Terminal accepts no liability whatsoever for any losses or liabilities arising from the use of or reliance on any of this content.

Stay in the loop

Join our mailing list to get the latest insights!

Subscribe to our weekly newsletter
Actionable insights you can’t get elsewhere.
© 2026 Token Terminal