Skip to content

Oracles

Stake DAO Lending relies on a custom oracle suite designed to price any Curve StableSwap-NG LP token in a conservative, lending-safe way. The implementation combines Curve's EMA data with Chainlink feeds and strict freshness checks.

This page explains both the high-level behavior for end users and some important mechanics for integrators and reviewers.

For full implementation details, technical docs, and curator guidance, see this link.

Why This Oracle Exists

Lending protocols need prices that are:

  • Market-based: reflect real trading activity
  • Conservative: avoid overvaluing collateral during depegs
  • Composable: work across many pools without custom contracts (see Adapters and Composability below)

Curve's StableSwap pools offer two on-chain primitives that are ideal for this:

  • price_oracle: EMA price between pool assets
  • get_virtual_price: invariant-based LP valuation

The Stake DAO oracle combines those with a hop-based Chainlink conversion path to express the LP price in any quote asset used for lending.

The Core Formula

Price(Base / Quote)=min(price_oracle(i))×get_virtual_price×price(hopi)÷price(Quote / USD)\begin{aligned} \text{Price(Base / Quote)} &= \min(\text{price\_oracle}(i)) \times \text{get\_virtual\_price} \\ &\times \prod \text{price}(\text{hop}_i) \\ &\div \text{price(Quote / USD)} \end{aligned}

The oracle prices an LP token in four conceptual moves:

  1. Conservative LP valuation in coin0: it takes the minimum EMA price across pool assets (never above 1) and multiplies by get_virtual_price(). This avoids overvaluing LPs during depegs.
  2. Convert coin0 to USD: a short, ordered Chainlink hop chain translates the coin0 value into USD.
  3. Convert USD to the loan asset: if the loan asset is not coin0, a quote feed converts USD into the market's loan asset.
  4. Scale to the lending protocol's precision: the final value is scaled to the format expected by the lending protocol.

This design keeps the oracle conservative, composable, and consistent across pools.

Feed Configuration Rules

This section explains how integrators should set up the oracle’s feed paths and configure the necessary safety parameters to ensure accurate and secure pricing.

Quote asset feed

What it is: The Chainlink price feed that expresses the loan asset in USD. It is used to convert the oracle’s USD value into the market’s loan asset when they are different.

If the quote asset equals coin0, set:

  • quoteAssetFeed = address(0)
  • quoteAssetFeedHeartbeat = 0

Otherwise, provide a live Chainlink feed and heartbeat for the quote asset (USD per quote asset).

coin0 to USD hop chain

What it is: An ordered list of Chainlink feeds that converts coin0 into USD step by step.

Each hop consumes the output of the previous hop. Keep it short and use the most reliable feeds available.

Heartbeats and freshness

What it is: Per-feed staleness limits that define how old a price update can be before it is considered unsafe.

Every feed includes a heartbeat (max staleness). The oracle reverts if the price is non-positive or if the updatedAt timestamp is older than the heartbeat window. This prevents stale prices from being used in lending decisions.

Safety Notes and Limitations

Appreciating Token Adjustment

In StableSwap-NG pools, get_virtual_price() already unwraps appreciating tokens (wstETH, sDAI, etc.) via stored rates. That means the LP is priced in the principal token, not the wrapper. When building the hop chain, the first hop must price the principal (e.g., stETH/USD, not wstETH/USD) to avoid double-counting appreciation.

Flash-manipulation caveat

This oracle leverages Curve's battle-tested EMA price oracle which provides protection against flash loan attacks through exponential moving average smoothing. The conservative minimum pricing across all pool assets prevents overvaluation during asset depegs. However, this oracle is intended for high-TVL, curated pools only. Conservative LLTV settings are still recommended for additional safety.

Read-Only Reentrancy Attack

This oracle relies on Curve's get_virtual_price() function which is vulnerable to read-only reentrancy attacks when the pool contains native ETH or ERC-777 tokens. The attack occurs when the token is sent to a malicious contract that reenters get_virtual_price() while the pool state is inconsistent (balances not yet updated but LP supply already decreased).

L2 sequencer downtime

The oracle does not include L2 sequencer uptime checks. If deploying on L2, wrap the oracle with a sequencer guard to halt pricing when the sequencer is offline.

Conservative by design

The min-clamp means the oracle never increases LP value based on an overvalued pool asset. This reduces risk but can slightly undervalue collateral during market stress.

Periphery

V2 - Configurable Denomination

Stake DAO is working on a V2 StableSwap oracle that allows denominating the LP in any pool coin (not just coin0). We will update this page as soon as the new implementation is ready.

Adapters and Composability

Adapters expose non-Chainlink sources through a Chainlink-style interface, so they can be composed in hop chains or consumed by external protocols. Stake DAO ships three adapters:

  • OracleChainlinkAdapter: wraps a Stake DAO oracle and exposes latestRoundData() / decimals() in Chainlink format.
  • CurvePriceFeedChainlinkAdapter: wraps Curve's native price feeds behind the same Chainlink interface.
  • PythChainlinkAdapter: exposes Pyth price feeds as Chainlink-compatible data.

This makes it possible to chain oracles through hop feeds and reuse Stake DAO pricing wherever Chainlink-style feeds are expected.

Summary

Stake DAO's Curve StableSwap oracle combines Curve EMA data, invariant pricing, and strict feed hygiene to deliver conservative LP valuations suitable for lending markets. The design prioritizes safety, composability, and consistency across pools, while keeping deployments simple and auditable.