Uniswap TWAP

Overview

The Uniswap TWAP oracle is available for any token which has a pair on Uniswap V2 or V3. It allows you to calculate the average price of the asset over some period of time up to a certain extent.

When to use

Use the Uniswap TWAP oracle if your token is listed on Uniswap V2 or V3 with sufficient trader activity and liquidity. In other words, it is expected that if there is an arbitrage opportunity, a trader should come and take it in order to rebalance the pool. If this is not the case, then it’s possible for an attacker to skew the price and simply wait for the TWAP to update.

Potential risks

You must decide on the time interval to use, which can be tricky. A shorter time interval means that you will see price updates quicker, but also lowers the cost of attack to manipulate the oracle. A longer time interval makes it much harder to manipulate the average price, but also means you won’t be able to react to volatility in the markets.

Example implementation

For Uniswap V2, see GitHub for an implementation of a 24 hour TWAP oracle.

For Uniswap V3, see GitHub for a library which you can integrate into your project.

Curve Virtual Price

Overview

Curve pools provide a function to calculate the price of a single LP token in a flash loan resistant manner.

When to use

If you need to calculate the price of Curve LP shares, then use the get_virtual_price function.

Potential risks

No additional risks besides dependency risk for every token the Curve pool supports.

Example implementation

See Curve’s documentation for more info.

Maker Price Feed

Overview

Maker operates their own network of price feeds which exposes data to whitelisted contracts on-chain. Projects can apply for access to the price data through the Maker governance process.

When to use

Use Maker’s price feeds if you think you can make it through the governance process and you would prefer to offload your oracle risks to the Maker oracle team.

Potential risks

You need to trust the Maker team and the anonymous feeds to behave correctly. However, the risk is low in practice given that Maker itself depends on these oracles. Also, as feed operators need to submit prices on chain manually, prices may be delayed during periods of extremely high chain congestion.

Example implementation

Submit a MIP10c9 subproposal to Maker Governance

Chainlink

Overview

Chainlink supports over 100 price feeds on Ethereum mainnet, mainly for pairs with ETH and pairs with USD. Developers can access this data for free simply by querying the smart contracts when needed.

When to use

Use Chainlink if you need pricing data for an asset that Maker or Uniswap doesn’t support, or if the latency associated with a TWAP oracle is unacceptable to your project.

Potential risks

Similar to Maker, you’ll need to trust the Chainlink team and node operators to behave correctly. Chainlink also requires node operators to push values on chain, so it may also suffer delays during periods of high chain congestion.

Example implementation

Refer to the Chainlink documentation for an example of how to get the price from a Chainlink aggregator smart contract.

FAQ

OK, but why shouldn’t I use spot price in the first place?

Good question. It depends on what you’re using the spot price for, although odds are you probably want to use it to calculate the price of some asset that users are depositing onto your platform. This means that it’s crucial to ensure that the user can’t just lie to you about how much the asset is really worth.

Unfortunately, spot price by definition changes whenever someone buys or sells the asset. This means an attacker can easily make the apparent value much higher or much lower than the true value of the asset. For a protocol which uses the price to calculate the borrowing power of a user, artifically inflating the value of an asset being deposited as collateral means the entire protocol can be (and will be, as numerous hacks have shown) completely drained.

How do I tell if I’m using spot price?

A good question! It turns out it might not be immediately obvious if you’re using spot price or not.

Let’s imagine that you want to find the price of WBTC in ETH. A seemingly obvious solution is to take the Uniswap V2 pair for ETH/WBTC, grab the reserve balance of ETH and WBTC, then divide the two. However, you’ve just calculated the spot price, and an attacker can easily manipulate it by buying or selling into the pool.

That seems fairly straightforward, but what if you actually want to calculate the price of a single ETH/WBTC LP token? It may be tempting to calculate the USD value of ETH and WBTC in order to calculate the total USD value of the pool. However, by doing this you’re actually incorporating the spot price because you’re still dependent on the reserve balances of the pool. This is an extremely subtle detail, and more than one project has been caught by it. You can read more about this footgun in this writeup by @cmichelio.

Wait, I use a different oracle that you haven’t listed here!

This list is incomplete and not meant to be conclusive, but feel free to reach out and I’ll update this page as needed!

Disclaimers

This post is for general information purposes only. It does not constitute investment advice or a recommendation or solicitation to buy or sell any investment and should not be used in the evaluation of the merits of making any investment decision. It should not be relied upon for accounting, legal or tax advice or investment recommendations. This post reflects the current opinions of the authors and is not made on behalf of Paradigm or its affiliates and does not necessarily reflect the opinions of Paradigm, its affiliates or individuals associated with Paradigm. The opinions reflected herein are subject to change without being updated.

Paradigm invests in certain protocols referenced herein. The references herein are not meant ot endorse or recommend these protocols for investment or otherwise.