Oracles
This reference guide lists different Oracles you can use when building on Optimism. Oracles (opens in a new tab) provide offchain data onchain. This allows code running on a blockchain to access a wide variety of information. For example, a stablecoin (opens in a new tab) that accepts ETH as collateral needs to know the ETH/USD exchange rate:
- How many stablecoins can we give a user for a given amount of ETH?
- Do we need to liquidate any deposits because they are under collateralized?
Security and Decentralization
Different oracles have different security assumptions and different levels of decentralization. Usually they are either run by the organization that produces the information, or have a mechanism to reward entities that provide accurate information and penalize those that provide incorrect information.
Types of Oracles
There are two types of oracles:
-
Push oracles are updated continuously and always have up to date information available onchain.
-
Pull oracles are only updated when information is requested by a contract. Pull oracles are themselves divided into two types:
- Double-transaction oracles, which require two transactions. The first transaction is the request for information, which usually causes the oracle to emit an event that triggers some offchain mechanism to provide the answer (through its own transaction). The second transaction actually reads onchain the result from the oracle and uses it.
- Single-transaction oracles, which only require one transaction, such as Chainlink's random number generator (opens in a new tab). The way this works is that the transaction that requests the information includes a callback (address and the call data to provide it). When the oracle is updated (which also happens through a transaction, but one that is not sent by the user), the oracle uses the callback to inform a contract of the result.
Gas Oracle
OP Mainnet provides a Gas Price Oracle (opens in a new tab) that provides information about gas prices and related parameters. It can also calculate the total cost of a transaction for you before you send it.
This contract is a predeploy at address 0x420000000000000000000000000000000000000F
:
This is a push Oracle. OP Mainnet (and the testnets) updates the gas price parameters onchain whenever those parameters change. The L1 gas price, which can be volatile, is only pushed once every 5 minutes, and each time can change only by up to 20%.
Chainlink
On OP Mainnet Chainlink (opens in a new tab) provides a number of price feeds (opens in a new tab). Those feeds are available on the production network.
This is a push Oracle. You can always get up to date information (see, for example, here (scroll down to latestAnswer) (opens in a new tab)).
See this guide to learn how to use the Chainlink feeds (opens in a new tab).
Tellor
Tellor (opens in a new tab) is a permissionless, censorship-resistant, and customizable oracle.
The Tellor protocol can secure putting any verifiable data onchain, from spot price feeds, TWAPs, random numbers, to EVM calldata - you can even specify your own "query type" (opens in a new tab) to build a feed to fit your specific needs.
As described in the oracles overview section of this page, we are an oracle protocol that has "a mechanism to reward entities that provide accurate information and penalize those that provide incorrect information." Therefore it is necessary to allow some reasonable amount of time (opens in a new tab) between an oracle update and using that data, to allow for a potential dispute (probabilistic finality).
Tellor is a pull oracle where users fund (tip) a specific feed to get updated data reports and then read the data from our oracle contract, however under certain circumstances it can act similar to a push oracle; if your reading from a feed that is already being updated by others, or if you are running your own data reporter. (opens in a new tab)
To learn more about using tellor please read our docs (opens in a new tab) or get in touch (opens in a new tab).
Tellor contract addresses on OP Mainnet and the testnets can be found here. (opens in a new tab)
Band
Band (opens in a new tab) provides a source of onchain randomness (opens in a new tab). You can learn how to use it here (opens in a new tab). It is a single-transaction pull oracle.
Universal Market Access (UMA)
UMA (opens in a new tab) is a generic oracle. It lets any contract request information (ask a question), and any staked entity can provide an answer. Other external entities can dispute the proposed answer by providing their own answer and putting up their own stake. In the case of dispute the question goes to a vote of token holders. The token holders that vote with the majority are assumed to be truthful and get rewarded. The external entities that proposed the correct answer are rewarded. Those that proposed the wrong answer lose their stake.
See here for the UMA addresses on OP Mainnet (opens in a new tab).
See here for instructions how to use UMA (opens in a new tab).
UMA is a pull Oracle, it does not get information until it is requested by a contract. This means that a decentralized application needs to issue two transactions. First, a transaction that causes a contract on the blockchain to ask for the information. Later (in the case of UMA 48 hours later if there is no dispute, longer if there is), a second transaction need to be triggered to cause the contract to read from the Oracle and see the response to the request.
Uniswap
Technically speaking Uniswap (opens in a new tab) is not an oracle, because the information comes from onchain sources. However, Uniswap pools do provide quotes that give the relative costs of assets (opens in a new tab).
Using onchain asset prices, especially those in low liquidity pools, makes you vulnerable to price manipulation.
To use Uniswap as an Oracle:
-
To find the pool address, look at the Uniswap factory (opens in a new tab). Use getPool with these parameters:
Parameter Meaning One token address Address of the ERC-20 contract for that token on OP Mainnet (chainId 10) (opens in a new tab) Other token address Address of the ERC-20 contract for that token on OP Mainnet (chainId 10) (opens in a new tab) Pool fee The pool fee percentage times ten thousand. For example, for 0.3% enter 3000
-
In your contract, use IUniswapV3PoolState (opens in a new tab) and IUniswapV3PoolDerivedState (opens in a new tab) to get the pool state.