What are Uniswap V2 oracles?

What are Oracles?

In EVM world, you can interact with other deployed smart contracts fairly easily. However, what if you need access to the data which doesn’t exist on chain? Example: Applications with real-life utilities often depend upon things like live data feeds of real word events like sports, commodity prices etc. That is where oracles help you. Oracles are a bridge between outside data and your on-chain smart contract. Intresting thing is the fact that you can build oracles using Uniswap V2.

But, Isn’t Uniswap an exchange? 

Yes, that’s right! Uniswap is a DEX ( Decentralised Exchange ). It’s meant to function like automated market makers. But that’s not the only utility. Uniswap’s “pair” contract can be used as a source of the exchange rate between the tokens of the respective pair. Now let’s take a look at how Uniswap can be used as an oracle. Before that, we need to understand a few concepts.

Uniswap v2 and Time-weighted average prices ( TWAP )

Yes, that’s what TWAP stands for. Time-weighted average price. How do you calculate TWAP using the Uniswap V2 contract?

Each pair contract has the following two public variables: 

  • price0CumulatveLast
  • price1CumulativeLast

These two variables store the sum of all the time-weighted historic prices for Token0 and Token1 for every second passed after the contract has been deployed. Let’s say that the current time is “t”. Now if you want to calculate TWAP for Token0 for 8 Hours: 

  • Record the value of price0CumulatveLast and respective block timestamp at  ( t – 8 ):  Pt-8 and blocktimestampt-8
  • Record the value of price0CumulatveLast and respective block timestamp at  ( t ):  Pt and blocktimestampt

TWAP for 8 hours = (  Pt Pt-8 ) / ( blocktimestampt blocktimestampt-8 )

That’s it! That is all there is to the mathematics behind time-weighted average price. This diagram directly from Uniswap’s docs perfectly captures this.

Integrating Uniswap V2 Oracles

This is where things get a bit tricky. But, worry not, we will break down this part very systematically, and in a way, it’s very easy to interpret. No jargon, I promise.

As seen in the above example for calculating TWAP, we need two prices and two timestamps. In other words, we need one reference price and timestamp along with the current price and timestamp. However, we cannot fetch the reference price directly from the pair contract. We need a separate “Oracle” contract that handles this logic for us.

The simple contract: Fixed Window Oracle.

I know I said, no jargon. But it’s really simple. Let’s say that you want the 1-hour TWAP for a particular token. You simply write a smart contract that has the logic to store the value of `price0CumulativeLast` ( assuming the token is  token0 in the pair contract ). And you update the value of this variable every hour by exposing an `update` function. Now it’s your responsibility to make sure that this contract is updated every hour so that it can return the average price over the last hour. And of course, you will need a function that returns the calculated average price in the required format to be used further.

Here is the full example of this contract:

https://github.com/ashwinYardi/uniswap-v2-oracles/blob/afbd493530b73fd3fe58ae174e584f5454d5f899/contracts/SimpleFixedWindowOracle.sol

Needless to say, updating a smart contract every fixed hour can be an expensive, tedious job and can take down your other dependencies if not updated properly. Also, since it has a fixed window, it often doesn’t reflect short-term price fluctuations. Also, the historic prices and newer prices are treated equally. Ideally, the latest prices should be given more weight in order to make your oracle sensitive to price fluctuations. 

Sliding Window Oracle

In moving window oracles, there are two variables that you can tune according to the requirement and your preferences: 

  1. Window size i.e. 2 months, 1 hour, 1 day.
  2. Granularity: How many observations are to be recorded within a corresponding window.

The price is always calculated over the latest window. Granularity dictates the accuracy of the price returned by the oracle. More the granularity, the higher the accuracy of the average price. However, you will need more updates in your oracle contract.

Here is the contract for the sliding window oracle: 

https://github.com/ashwinYardi/uniswap-v2-oracles/blob/afbd493530b73fd3fe58ae174e584f5454d5f899/contracts/MovingWindowOracle.sol

This contract is a generic moving window oracle that can be used for multiple uniswap V2 pairs. Just let the contract know the details like which Uniswap factory address to use, what’s windowSize, and what’s granularity, and that’s it! Now you can use this contract for any Uniswap pair created by the factory. 

Even though difficult to manipulate, Uniswap V2 oracles are still prone to manipulations if favorable conditions are there which outweigh oracle manipulation cost. Also, if the chain halts for a significant time, then also oracle-based Dapps can be exploited. I will be writing a separate article on how these decentralized oracles can be manipulated. Stay tuned and follow on social handles to stay in touch! 

%d bloggers like this: