Skip to main content

Overview

Inside a vault, each collateral is configured as the address of another vault, not the underlying asset (unless the asset is specially constructed to also function as a collateral vault). This means that the value of a user's collateral is in fact the value of the vault's shares. A vault share is not necessarily equal to a unit of the underlying asset because of the exchange rate.

Because converting quantities of shares to underlying asset amounts is itself a pricing operation, this responsibility is delegated to the price oracle. In some cross-chain designs, the price oracle may also be responsible for determining the exchange rate of a corresponding vault on a separate chain.

The Euler Price Oracle system is a composable on-chain pricing system. It is built around an interface called IPriceOracle, which is an abstraction for querying a diverse range of external pricing oracles and normalising their answers.

For full technical details, see the EPO Whitepaper.

IPriceOracle

Each vault has the address of a price oracle installed. This address is immutable and cannot be changed, even by the vault governor. If updates to pricing sources are desired, this address should be a governed EulerRouter pricing component. All oracles must implement the IPriceOracle interface below:

interface IPriceOracle {
/// @return General description of this oracle implementation.
function name() external view returns (string memory);

/// @return outAmount The amount of `quote` that is equivalent to `inAmount` of `base`.
function getQuote(
uint256 inAmount,
address base,
address quote
) external view returns (uint256 outAmount);

/// @return bidOutAmount The amount of `quote` you would get for selling `inAmount` of `base`.
/// @return askOutAmount The amount of `quote` you would spend for buying `inAmount` of `base`.
function getQuotes(
uint256 inAmount,
address base,
address quote
) external view returns (uint256 bidOutAmount, uint256 askOutAmount);
}

This interface shapes oracle interactions in an important way: it forces the consumer to think in amounts rather than prices.

A subset of this interface (getQuote) has been standardized in ERC-7726.

Oracle Adapters

An adapter is a minimal, fully immutable contract that queries an external price feed. It is the atomic building block of the Euler Price Oracles library.

Design Principles

The IPriceOracle interface is permissive in that it does not prescribe a particular way to implement it. However the adapters in this library adhere to a strict set of rules that we believe are necessary to enable safe, open, and self-governed markets to flourish.

Immutable

Adapters are fully immutable without governance or upgradeability.

Minimally Responsible

An adapter connects to one pricing system and queries a single price feed in that system.

Bidirectional

An adapter works in both directions. If it supports quoting X/Y it must also support Y/X.

Observable

An adapter's parameters and acceptance logic are easily observed on-chain.

Summary of Adapters

AdapterTypeMethodSupported PairsParameters
ChainlinkOracleExternalPushProvider feedsfeed, max staleness
ChronicleOracleExternalPushProvider feedsfeed, max staleness
PythOracleExternalPullProvider feedsfeed, max staleness, max confidence interval
RedstoneCoreOracleExternalPullProvider feedsfeed, max staleness, cache ttl
LidoOracleOnchainRatewstETH/stETH-
LidoFundamentalOracleOnchainRatewstETH/ETH-
UniswapV3OracleOnchainTWAPUniV3 poolsfee, twap window
PendleOracleOnchainTWAPPendle marketspendle market, twap window
RateProviderOracleOnchainRateBalancer rate providersrate provider
FixedRateOracleOnchainRateAnyrate

Quotes

Price fractions are never directly returned by the interface. Instead, the oracle acts as though it is quoting swap amounts. This avoids certain catastrophic losses of precisions, especially with low-decimal tokens (see an example with SHIB/USDC).

The quoting interface offers several benefits to consumers:

  • More intuitive queries: Oracles are commonly used in DeFi to determine the value of assets. getQuote does exactly that.
  • More expressive interface: The unit price is a special case of a quote where inAmount is one whole unit of base.
  • Safe and flexible integrations: Under IPriceOracle adapters are internally responsible for converting decimals. This allows consumers to decouple themselves from a particular provider as they can remain agnostic to its implementation details.

Bid/Ask Pricing

Euler Price Oracles additionally expose getQuotes which returns two prices: the selling price (bid) and the buying price (ask).

Bid/ask prices are inherently safer to use in lending markets as they can accurately reflect instantaneous price spreads. While few oracles support bid/ask prices currently, we anticipate their wider adoption in DeFi as on-chain liquidity matures.

Importantly getQuotes allows for custom pricing strategies to be built under the IPriceOracle interface:

Querying two oracles and returning the lower and higher prices. Reporting two prices from a single source e.g. a TWAP and a median. Applying a synthetic spread or a volatility-dependent confidence interval around a mid-price.