Euler Price Oracles is a library of modular oracle adapters and components that implement IPriceOracle
, a quote-based interface compatible with ERC-7726.
To read more about the design and motivation behind IPriceOracle
and the oracles in this repo, check out the whitepaper and ERC-7726.
To understand how Price Oracles fit into the Euler Vault Kit, check out the price oracles section of the EVK whitepaper.
To use or develop with Euler Price Oracles, check out the Usage section.
To find out ways to contribute to Euler Price Oracles, check out the Contributing section.
To observe 200+ live deployments of these oracle adapters check out the dedicated Oracle Dashboard.
Euler Price Oracles has been audited by Spearbit, OpenZeppelin, ChainSecurity, Omniscia, yAudit, and Cantina.
IPriceOracle
All contracts in this library implement the IPriceOracle
interface.
/// @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.
Euler Price Oracles are unique in that they expose a flexible quoting interface instead of reporting a static price.
[!NOTE] Imagine a Chainlink price feed which reports the value
1 EUL/ETH
, the unit price ofEUL
. Now consider anIPriceOracle
adapter for the feed. It will fetch the unit price, multiply it byinAmount
, and return the quantityinAmount EUL/ETH
. We call this a quote as it functionally resembles a swap on a decentralized exchange.
The quoting interface offers several benefits to consumers:
getQuote
does exactly that.inAmount
is one whole unit of base
.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.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:
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.
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.
Adapters are fully immutable without governance or upgradeability.
An adapter connects to one pricing system and queries a single price feed in that system.
An adapter works in both directions. If it supports quoting X/Y
it must also support Y/X
.
An adapter's parameters and acceptance logic are easily observed on-chain.
Adapter | Type | Method | Supported Pairs | Parameters |
---|---|---|---|---|
ChainlinkOracle | External | Push | Provider feeds | feed, max staleness |
ChronicleOracle | External | Push | Provider feeds | feed, max staleness |
PythOracle | External | Pull | Provider feeds | feed, max staleness, max confidence interval |
RedstoneCoreOracle | External | Pull | Provider feeds | feed, max staleness, cache ttl |
LidoOracle | Onchain | Rate | wstETH/stETH | - |
LidoFundamentalOracle | Onchain | Rate | wstETH/ETH | - |
UniswapV3Oracle | Onchain | TWAP | UniV3 pools | fee, twap window |
PendleOracle | Onchain | TWAP | Pendle markets | pendle market, twap window |
RateProviderOracle | Onchain | Rate | Balancer rate providers | rate provider |
FixedRateOracle | Onchain | Rate | Any | rate |
To install Price Oracles in a Foundry project:
forge install euler-xyz/euler-price-oracle
Clone the repo:
git clone https://github.com/euler-xyz/euler-price-oracle.git && cd euler-price-oracle
Install forge dependencies:
forge install
[Optional] Install Node.js dependencies:
npm install
Compile the contracts:
forge build
The repo contains 4 types of tests: unit, property, bounds, fork, identified by their filename suffix.
To run fork tests set the ETHEREUM_RPC_URL
variable in your environment:
# File: .env
ETHEREUM_RPC_URL=...
Alternatively, to exclude fork tests:
forge test --no-match-contract Fork
[!IMPORTANT]
Tests inRedstoneCoreOracle.fork.t.sol
use theffi
cheatcode to invoke a script that retrieves Redstone update data. FFI mode is not enabled by default for safety reasons. To run the Redstone Fork tests setffi = true
infoundry.toml
.
Euler Price Oracles is a free and open-source public good. We encourage you to engage and contribute.
Feel free to open a GitHub issue discussing your ideas.
[!TIP] Submit testing- and documentation-related PRs to
development
and changes undersrc/
toexperiments
.
Here are a few ideas how you can improve Euler Price Oracles:
getQuotes
returns bid/ask prices, however we are not aware of any oracle providers that currently support them. Write an IPriceOracle
wrapper that applies a price spread around a mid-point price. The spread could be dynamic based on proxy metrics such as liquidity, volume, (implied) volatility, correlation. We are highly interested in research towards this direction.IPriceOracle
wrapper that implements a trustless circuit-breaker mechanism that detects failure conditions. Upon detection it could switch to another oracle or redeploy the adapter with different parameters.EulerRouter
that supports more flexible configuration.AggregatorV3Interface
either directly or through a facade contract. Are they safe to use through ChainlinkOracle
in this library?EulerRouter
can price ERC4626 shares to assets by calling convertToAssets
. Which of the currently live vaults have a manipulation-resistant pricing function?maxStaleness
on Ethereum considering network delays and possible censorship? Are there ways maxStaleness
can be safely reduced?This software is experimental and is provided "as is" and "as available".
No warranties are provided and no liability will be accepted for any loss incurred through the use of this codebase.
Always include thorough tests when using Euler Price Oracles to ensure it interacts correctly with your code.
(c) 2024 Euler Labs Ltd.
The Euler Price Oracles code is licensed under the GPL-2.0-or-later license.