9

I need to get the exchange rate for every token on Uniswap with Web3 like Uniswap itself which they then display on their web interface on app.uniswap.org like this:

enter image description here

So when I enter to swap the amount of tokens I want to to give (1 ETH in this example) it shows me the estimated amount of tokens I will receive (1691.53 DAI in this example)

What I've tried

I want to get the information directly from the blockchain and don't wanna use an API because I need the prices to be as up to date as possible so I thought of searching for a function in one of Uniswap's smart contracts but only found a function called quote() but I couldn't do anything with that.

-> If someone can help me please provide me with some code examples on how to exactly do that.

Also I need to know if I got the concept of Uniswap... To be able to exchange one token for another there has to be a pool already for this exact pair I want to exchange is this right?

Paulus
  • 410
  • 1
  • 6
  • 21

2 Answers2

6

There is a more simple solution to pull the price straight from Blockchain the steps are as follow:

  1. Using the router contract call getAmountsOut(1.0, [token, WETH])
  2. Using the router contract call getAmountsOut(1.0, [WETH, USDT])
  3. multiply the amounts you got in 1) and 2), note you have to convert them to decimals before doing the step 3
Enrique Ramos
  • 61
  • 1
  • 1
4

You'll first need the address of the contract for the pair whose price(s) you want to access.

Two ways to do this:

  1. Find the addresses of the two tokens separately, and feed them into the UniswapV2Factory contract to get the address of the pair's contract; or...

  2. Go to Uniswap, enter the two tokens into the usual interface, then visit the "View Pair Analytics" page, at the bottom of which will be the address of their contract and a link to Etherscan.

Once you know the pair's contract address, you can access the prices directly via Web3. Inside the pair's contract - of type UniswapV2Pair - there are the following variables:

...
address public factory;
address public token0;
address public token1;

uint112 private reserve0; // uses single storage slot, accessible via getReserves uint112 private reserve1; // uses single storage slot, accessible via getReserves uint32 private blockTimestampLast; // uses single storage slot, accessible via getReserves

uint public price0CumulativeLast; uint public price1CumulativeLast; ...

The final two represent the token prices (sort of... see below). They're public, so getter functions will automagically be available.

However... that's not the end of the story.

The prices in the contracts are cumulative prices, not the last spot price. That means you'll have to do some maths to make those values useful.

The Uniswap Oracles page has some details on how you can calculate a time-weighted average price (TWAP) suitable for your needs.

Richard Horrocks
  • 37,835
  • 13
  • 87
  • 144
  • But I have to somehow set the pair I want to receive to prices of. How do I do that? – Paulus Mar 19 '21 at 19:31
  • Do you have the address of the contract for each of the two tokens? – Richard Horrocks Mar 19 '21 at 23:04
  • Or do you want to do this for all token pairs? – Richard Horrocks Mar 19 '21 at 23:06
  • I want to do it for all pairs... I already have achieved something somehow but don't really know what I have got here (https://ethereum.stackexchange.com/a/92488/68019) – Paulus Mar 19 '21 at 23:21
  • And it also doesn't have something to do with the price0CumulativeLast/price1CumulativeLast variables – Paulus Mar 19 '21 at 23:27
  • https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples/ExampleOracleSimple.sol this helped me out to get the actual prices I wanted... Thanks @Richard Horrocks for your answer it helped me out a lot!! – Paulus Mar 20 '21 at 12:34
  • What does reserve0 and reserve1 exactly represent?? Can I calculate circulatting supply and LP for given token based on reserves? – Mugetsu Jun 06 '21 at 11:58