> For the complete documentation index, see [llms.txt](https://docs.efficientdex.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.efficientdex.com/how-pools-work/price-feeds-and-oracles.md).

# Price feeds and oracles

How an Efficient pool reads checked USD prices from its price feed, and how a lending market's oracle sits beside it where the pool borrows.

**Every Efficient pool names one price feed contract.** It answers checked USD prices and nothing else. The pool works out its price, the feed price, from two of those USD prices. Every fill and credit check in a pool with a price band uses it.

Each lending market a pool borrows from has its own oracle. The pool can require each market's oracle to agree with its feed before it borrows.

## The price feed

**The price feed reads each listed token's USD price from that token's Chainlink USD feed.** It uses no cross rates. It quotes USD per whole token to 18 decimals and rounds nothing.

One feed contract can serve many pools. Those pools share its listings, staleness limits and peg bands.

A pool's creator names its feed in `createPool`. No call changes it afterwards. Only new pool code can point a pool at another feed, after the factory's delay. [Roles and governance](/run-a-pool/roles-and-governance.md) explains how.

The factory doesn't check that a pool's feed is the standard one. So depositors confirm it with the lens's `identity(pool)`. See [Pool operators](/use-efficient/provide-liquidity/pool-operators.md#before-depositing).

Every price read checks the sequencer first, then the round itself. The read reverts with `InvalidPrice` if the round has any of these:

* a zero round id
* an answer of zero or less
* a timestamp of zero or in the future

## How the pool derives its price

**The feed price is the pool asset's USD price divided by the loan asset's.** The loan asset is the other token in the pool's pair. It's a token the pool can borrow, and it's the first loan asset. Any extra token the pool can borrow is a loan asset too. For loan asset $$i$$:

$$
P\_i = \frac{u\_{\mathrm{pool}}}{u\_i}
$$

Here $$u\_{\mathrm{pool}}$$ and $$u\_i$$ are the two USD prices. The result $$P\_i$$ is units of loan asset $$i$$ per unit of pool asset.

For example, take an Efficient pool that trades cbBTC against USDC. Its pool asset is cbBTC and its loan asset is USDC. If cbBTC is at a hypothetical $100,000 and USDC at $1, its feed price is 100,000 USDC per cbBTC.

**A swap in a pool with a price band uses one checked price read.** That read covers the pool asset and the first loan asset. The swap reverts with the feed's own error if that read fails. Otherwise the hooks receive that price. The pool holds every fill to the price band around it. [Hooks](/how-pools-work/hooks.md) covers the band.

Other loan assets are read without reverting. So if one of their prices fails a check, only a call that values or borrows that asset fails.

The feed price also sets net asset value (see [The pool and its book](/how-pools-work/the-pool-and-its-book.md)). In a pool that borrows, it sets the [credit check](/how-pools-work/credit-and-collateral.md) too.

A pool with no price band reads no feed price on its swaps or flows. Its hooks price each fill without one. At creation, its feed needs to list only its loan asset. Such a pool can't read its net asset value while it holds any loan asset.

## Staleness limits

**Each token on the feed has its own staleness limit.** A read of an older round reverts with `StalePrice`. The limit is the token's `heartbeat` setting. It's above zero and at most 2 days.

The first Everlong vault's limits are 1 hour for cbBTC and 25 hours for USDC. They sit above Chainlink's published heartbeats.

**Loan-to-loan swaps also apply the pool's own age limit, `maxPriceAgeSec`.** No other call reads it. A swap between two loan assets reverts with `StalePair` if either price is older than that limit. The limit is fixed at creation. The first vault's is 15 minutes, though loan-to-loan swaps are off there.

## The sequencer check

**The feed refuses prices while a rollup's sequencer is down and for a grace period after it restarts.** Reads revert with `SequencerDown` during an outage. Inside the grace period they revert with `SequencerGrace`. The grace gives the feeds time to post new rounds.

The uptime feed and the grace period are fixed at deployment. The first vault's grace on Base is 1 hour. A feed deployed without an uptime feed skips the check, as on Katana.

## Peg bands

**A peg band is a breaker on a loan asset.** It stops the flows that can add debt while the asset is off its peg. A token is on its peg while its USD price sits within its band of $1. A band of zero means no check.

Sells revert with `PegBroken` while the first loan asset is off peg and its borrowing is on. Buys continue. When that asset's borrowing is off, a sell skips the check, because it adds no debt and pays out only what the pool holds.

Deposits that borrow an off-peg loan asset revert too. So do loan-to-loan swaps in or out of one.

A pool with a price band admits its pair only when the pool asset has no peg band. So peg bands apply to loan assets alone. The first vault's USDC band is 1%.

## When the feed can't price

**In a pool with a price band, every swap, `poke` and recentre needs two checked prices.** They're the pool asset's and the first loan asset's. The following also need a checked price:

* a deposit that borrows
* net asset value
* a collateral top-up
* each conversion leg on the asset router and the entry market

Every proportional deposit also needs one while a performance or protocol fee rate is on. Proportional deposits use `depositProRata` or `mintProRata`.

A pool with no price band reads no feed on a swap or a recentre. So a feed failure stops neither. Its `poke` has no price to pass on, so it reverts with `NoBand`. The asset router's conversion legs and the entry market still read the feed's pair. So they need both assets listed and a checked price.

A feed failure doesn't stop the pool's proportional exit, `redeemProRata`, because its legs and exit check read no feed price. Its fee skim reads the feed without reverting. It charges no fee while the pool can't be valued.

The lens and the feed's `peekUsd` and `peekPair` return an `ok` flag of false instead of reverting. So monitors keep reading.

## The lending market's oracle

**A lending market liquidates a pool that borrows from it at the market's own oracle price.** The pool's feed price doesn't change that. Each Morpho Blue market names its own oracle. The pool's oracle band can stop borrowing from a market whose oracle strays too far from the feed price.

[Credit and collateral](/how-pools-work/credit-and-collateral.md) covers the band's test, what it gates and the health factor at the market's own price.

## Listing and replacing feeds

**The feed contract has its own Safe.** The Safe lists a token at once, but replaces a token's feed only after a delay. In the first deployment, that Safe is the protocol Safe.

`addToken` lists a token whose Chainlink feed answers a valid, fresh price in the same call. An existing pool prices a newly listed loan asset only once its pool operator adds it, after the pool's governance delay. A new pool can use the token from creation.

A pool with no price band can take one once the feed lists its pool asset. The pool operator or the guardian attaches it with `setMarketBand`, with no delay. The pool reads the feed price from then on.

`scheduleOracle(token, aggregator, heartbeat, pegBandWad)` replaces a token's feed, staleness limit and peg band together. The replacement waits 10 days, or 4 hours if the token's current feed is failing when the Safe schedules it.

Once it's due, anyone can execute it with `executeOracle(token)`. The new feed must answer in that call. A 4-hour replacement lapses instead if the old feed's latest round is valid and either fresh or posted since the schedule. It also lapses once more than a day has passed since it fell due.

The feed contract can't be upgraded. Its Safe is fixed at deployment. [Roles and governance](/run-a-pool/roles-and-governance.md) lists these delays beside the pool's own. [Operate a pool](/run-a-pool/operate-a-pool.md) covers what a keeper watches.
