Recipe logo

Uniswap as an Oracle Price Feed

 

Introduction

One of the underappreciated features of Unsiwap is its utility as a Price Oracle. In this recipe, we will use the Sync log event to calculate a Price Feed. This recipe is broken down into three steps:

  1. Find the topic hash for a Sync event.
  2. Use the Covalent API to fetch the event logs.
  3. Calculate the Price feed using data from step 1 and 2 above.

Prerequisites

Endpoints Summary

The key Covalent API endpoints covered here are:

  • v1/{chainId}/events/topics/{topic}/
    • Return a paginated list of decoded log events with one or more topic hashes separated by a comma.

 

Extracting an exchange contract Sync event

For illustrative purposes, we will pick the USDC-ETH uniswap pool at the address 0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc.

 

1) Find the topic hash for Sync events

On Etherscan, we see the events emitted from this contract:

Etherscan Events

We see that the topic hash for the Sync event is 0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1.

Another way to calculate the topic hash is to use the Covalent Topic Hash Calculator.

Sync Topic Calculator

 

2) Use the Covalent API v1/{chainId}/events/topics/{topic}/ endpoint to fetch the event logs

The Covalent API GET log events by topic hash endpoint lets you fetch fully decoded events logs. You can call it with the following parameters:

Parameter Value
chainId 1
topic 0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1
starting-block 11995619
ending-block latest
sender-address 0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc

Also note that the sender-address is our USDC-ETH pool contract address.

Our response from the Covalent API looks something like this (only 1 record shown):

{
  "data": {
    "updated_at": "2021-03-08T06:36:13.987447062Z",
    "items": [
      {
        "block_signed_at": "2021-03-08T04:12:30Z",
        "block_height": 11995619,
        "tx_offset": 130,
        "log_offset": 213,
        "tx_hash": "0x26337bdeec5badee6f52c571a4785ee1fac956df2e2c29b313ffae0477045f53",
        "_raw_log_topics_bytes": null,
        "raw_log_topics": [
          "0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"
        ],
        "sender_address": "0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc",
        "sender_address_label": null,
        "raw_log_data": "0x000000000000000000000000000000000000000000000000000074e25ab853df000000000000000000000000000000000000000000000fd828ec5f992412fd40",
        "decoded": {
          "name": "Sync",
          "signature": "Sync(uint112 reserve0, uint112 reserve1)",
          "params": [
            {
              "name": "reserve0",
              "type": "uint112",
              "indexed": false,
              "decoded": true,
              "value": "128515533460447"
            },
            {
              "name": "reserve1",
              "type": "uint112",
              "indexed": false,
              "decoded": true,
              "value": "74822942799933302046016"
            }
          ]
        }
      },
      ...
    ]
  }
}

The values under decoded.params are the values of the two liquidity reserves of the USDT and ETH tokens in the pool.

 

3) Calculate the price

Before you can calculate the price from the Sync event - you first need to understand how to format these reserves. The reserves are recorded using the contract decimals for the two tokens. In this case:

Token Name Decimals Recorded value Scaled value
USDC USD Coin 6 128515533460447 128,515,533.460447
ETH Ether 18 74822942799933302046016 74,822.942799933302046

Therefore, the price of ETH in the units of USDC is

 

Next steps

Congratulations :tada: :sparkles: You have made a delicacy!

You can use this method to calculate token prices for any pool contract across any Uniswap-like AMM. For example, the same method works on PancakeSwap (Binance Smart Chain), QuickSwap (Matic), RamenSwap (Binance Smart Chain) and so on.

Just be aware that different tokens have different contract decimals and will need to be scaled accordingly.

Last modified: October 27, 2022: october-changelog-2022 (#243) (b6121bb)