4

I'm trying to get the implied price of ETH/USDC using the reserves of WETH and USDC on Uniswap. My code looks like this:

const UNISWAP_FACTORY_ADDR = "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f";
const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
const WETH = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";

async function main(){
  var factory = new web3.eth.Contract(factoryABI.abi, UNISWAP_FACTORY_ADDR);
  var pairAddress = await factory.methods.getPair(WETH, USDC).call();
  var pair = new web3.eth.Contract(pairABI.abi, pairAddress);
  var reserves = await pair.methods.getReserves().call();
  console.log(pairAddress);
  console.log(reserves);
  console.log(reserves[1] / reserves[0]);
}

My output though looks like this:

0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc
Result {
  '0': '108170733532523',
  '1': '24147939422729143528620',
  '2': '1636133844',
  reserve0: '108170733532523',
  reserve1: '24147939422729143528620',
  blockTimestampLast: '1636133844'
}
223239120.54704463

Why am I getting a price value of 223239120? The current price of ETH is ~$4500, so it doesnt look like my issue is just a decimal problem. What am I doing wrong here? Thanks!

2 Answers 2

7

The price in the USDC / WETH pool is confusing because of two factors:

  1. The number of decimals in the tokens is different: 6 decimals for USDC, 18 decimals for WETH, leading to one "unit" of USDC being worth much more than one unit (wei) of WETH.

  2. The contract address of the USDC token is lower than the contract address of WETH9 on the ETH mainnet. Uniswap pairs are always in the same order, based on token addresses. This means that the price is expressed for USDC in terms of WETH.

To get the real price of ETH in terms of USDC, adjust for the decimals, and then invert the result (the inverted value of x is 1/x). The result is 4479.50.

In Python code:

price = 223239120
adjusted_price = price / (10 ** (18 - 6))
inverted_price = 1 / adjusted_price
print(inverted_price)
1
  • Awesome yes that did the trick! thanks for the clarification.
    – tsuigeo
    Commented Nov 5, 2021 at 19:10
0

Here is a ready made Python library example for calculating prices for Uniswap v2-likes.

# Estimate how much ETH we will receive for 500 USDC.
# In this case the pool ETH price is $1700 so this should be below ~1/4 of ETH
amount_eth = estimate_buy_price(
    uniswap_v2,
    weth,
    usdc,
    1*10**18,  # estimate price for 1 ETH
)
assert amount_eth / 1e18 == pytest.approx(0.28488156127668085)

Note that any theoretical midprice might not be relevant for your use case. Because any price really depends on how much token is being bought/sold.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.