A simple and fully decentralized price oracle based on Uniswap for DeFi

Simone Rigolon
4 min readNov 25, 2020

--

In the previous article I explained why UniswapV2 can and should be used to build a decentralized price oracle for the rest of DeFi on Ethereum. I would suggest you to read it if you haven’t already. In this article I am going to show an actual implementation of such an oracle, and I am going to explain the design choice I made.

Design philosophy

One of the reasons that directly and indirectly made Uniswap the most popular decentralized exchange can be found in its design philosophy, that can be quickly summarized.

  • Full decentralization: on UniswapV2 the only privilege that the admin has is that of turning on the hardcoded fee. That privilege is now in the end of the UNI holders. Apart from this, all other function on the UniswapV2 core contracts require no privilege and thus make it fully decentralized.
  • Minimal governance: as explained in the previous point, the governance has no power over the UniswapV2 core contracts, except for turning on the fee.
  • No maintenance: anyone can add a new pair on Uniswap, thus making it future proof and self-sustainable.
  • Strength and simplicity: these are referred to UniswapV2’s core contracts. It is guaranteed that they will always exists and continue to work as they do now since they are non-upgradable, and they are also kept as simple as possible in order to minimize security risks and avoid functions that are not strictly necessary. Additional functionalities can always be added later in peripheric contracts.

A price oracle based on Uniswap should have these characteristic as well. As pointed in the previous article we would want this price oracle to be used by as many DeFi applications as possible. The fact that the oracle does not need any active governance or maintenance will enable other DeFi developers to trust the fact that such oracle will remain functioning forever, as long as Uniswap V2 will continue to work.

SimpleUniswapOracle implementation

All files can be found in this repository: https://github.com/Impermax-Finance/simple-uniswap-oracle. The implementation of the core contract can be read in the file SimpleUniswapOracle.sol, and is detailed in the following lines.

As explained in the previous article the oracle will always calculate the average price over the last T seconds, where T ≥ MIN_T. In this implementation MIN_T = 3600 seconds. As on Uniswap anyone can add a new pair to the oracle by passing the address of the UniswapV2 pair to the function initialize().

All the data is stored inside the oracle’s smart contract. For each pair, we save the value of Uniswap’s price0CumulativeLast and the block.timestamp during the last update and during the second-last. We’re going to use these values to calculate the average price in future requests. In the actual implementation we are saving last and second-last as A and B and we are exchanging them at each update. This allow us to reduce the number of write in storage and minimize the gas cost.

After the call of initialize(), the price will not be available for MIN_T seconds, after which the price will be always available. The price for an initialized UniswapV2 pair can be requested by passing the address of that pair to the function getResult(). If T ≥ MIN_T seconds has elapsed since the last update, then the price oracle will return T and price, the average of the price during the last T seconds. Otherwise, if not enough time has elapsed since the last update the oracle will use the second-last update to make the calculations. In the first case the protocol will also update the pair, while in the second case the storage will remain unchanged.

Note: as a convention, the price is always calculated as token0 / token1.

Gas costs

The gas costs for the execution of getResult() are quite low: around 20000 gas if the price was updated during the read and 10000 gas otherwise.

Web3 demo

The oracle has been deployed to the Ropsten network and I have created a simple web3 demo so that you can already try and play around with it. You will notice that you can either refresh the price off-chain or update it on-chain. If you chose to update it, you will have to wait 10 minutes to see the fresher price and to update it again. For each pair you will also see when the last update happened and T, the seconds elapsed since the last update. You can find the demo here: https://oracledemo.impermax.finance/

The next steps

If enough people are interested, we can agree on a final version of the smart contract, audit it, and deploy it on mainnet. At that point it will be free for anyone to use, modify or build upon.

--

--

Simone Rigolon
Simone Rigolon

Written by Simone Rigolon

DeFi developer, founder of Impermax Finance

No responses yet