GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — API not returning proper prices · Issue #12 · uniswap-python/uniswap-python

API not returning proper prices #12

New issue
Copy link
New issue
Copy link
Closed
Closed
API not returning proper prices#12
Copy link

Description

@msujithk
msujithk
opened on Aug 5, 2020
Issue body actions

API that are used to get token prices are not returning accurate prices. The prices are determined by considering the ether balance and token balance (eth_balance / token_balance) of token exchange contract.
For example :
Dai/Sai Uniswapcontract: 0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14 has 90 eth and 17520 DAI. The price is returned by calculating 90/17520 which is incorrect. Can you please look into this or correct me if i am wrong. Thanks.

Activity

  1. msujithk commented on Aug 5, 2020

    @msujithk
    msujithk
    on Aug 5, 2020
    Author
    More actions

    Looks like Uniswap uses WETH (wraped ETH) instead of ETH, Does it have to do anything with the above issue? WETH amount should be fetched from the token exchange contract instead of ETH for price calculation in get_eth_token_input_price and other related functions. I am not an expert on this like you are, just posting my thoughts here. Thanks.

  2. ErikBjare commented on Sep 25, 2020

    @ErikBjare
    ErikBjare
    on Sep 25, 2020
    Member
    More actions

    This library always assumes the routing token1 -> (w)eth -> token2 for token -> token transactions (on Uniswap v2) and gets the prices directly from the contract (we're not computing prices ourselves here, just asking the contract for the price given a route).

    Edit: I now realize the contract you're referring to is Uniswap v1. It's currently at 63.02 ETH and 12349 SAI, which becomes 0.005103247226496073 ETH/SAI, which seems to be correct when checking Coingecko for reference (0.00509591 ETH/SAI). I don't know how Uniswap v1 treats ETH vs WETH, and I'm not sure exactly what you are asking or how the price is incorrect.

  3. ErikBjare commented on Sep 25, 2020

    @ErikBjare
    ErikBjare
    on Sep 25, 2020
    Member
    More actions

    Just tested uniswap.get_token_eth_input_price(sai, 1*10**18) / 10**18 which returns something similar (0.005087772161388855), so not sure what you think is wrong here. Closing.

  4. ErikBjare
    closed this as completedon Sep 25, 2020
  5. tryiou commented on Dec 20, 2020

    @tryiou
    tryiou
    on Dec 20, 2020
    More actions

    Hey there, thanks for sharing this work with us, bumping this thread as i get similar problem it seems :

    def conversion(rate, usd_rate):
        conversion = ((1 / rate) * (usd_rate / 10 ** 6)) * (10 ** 18)
        return conversion
    
    
    eth = "0x0000000000000000000000000000000000000000"
    bat = "0x0D8775F648430679A709E98d2b0Cb6250d2887EF"
    dai = "0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359"
    ablock = Web3.toChecksumAddress("0xe692c8d72bd4ac7764090d54842a305546dd1de5")
    usdt = Web3.toChecksumAddress("0xdac17f958d2ee523a2206206994597c13d831ec7")
    usdc = Web3.toChecksumAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48")
    wbtc = Web3.toChecksumAddress("0x2260fac5e5542a773aa44fbcfedf7c193bc2c599")
    uni = Web3.toChecksumAddress("0x1f9840a85d5af5bf1d1762f925bdaddc4201f984")
    ablock_rate = uniswap_wrapper.get_eth_token_input_price(ablock, 10 ** 18)
    usdt_rate = uniswap_wrapper.get_eth_token_input_price(usdt, 10 ** 18)
    bat_rate = uniswap_wrapper.get_eth_token_input_price(bat, 10 ** 18)
    usdc_rate = uniswap_wrapper.get_eth_token_input_price(usdc, 10 ** 18)
    wbtc_rate = uniswap_wrapper.get_eth_token_input_price(wbtc, 10 ** 18)
    uni_rate = uniswap_wrapper.get_eth_token_input_price(uni, 10 ** 18)
    dai_rate = uniswap_wrapper.get_eth_token_input_price(dai, 10 ** 18)
    
    print("1 BAT =", conversion(bat_rate, usdt_rate), "USDT")
    print("1 aBLOCK =", conversion(ablock_rate, usdt_rate), "USDT")
    print("1 WETH =", usdt_rate / (10 ** 6), "USDT")
    print("1 USDC =", conversion(usdc_rate, usdt_rate), "USDT")
    print("1 WBTC =", conversion(wbtc_rate, usdt_rate), "USDT")
    print("1 UNI =", conversion(uni_rate, usdt_rate), "USDT")
    print("1 DAI =", conversion(dai_rate, usdt_rate), "USDT")
    

    this give me:
    1 BAT = 0.23610407627217966 USDT
    1 aBLOCK = 18154844558.9239 USDT
    1 WETH = 643.893084 USDT
    1 USDC = 997933195691.8488 USDT
    1 WBTC = 232699612651547.88 USDT
    1 UNI = 3.822174314993634 USDT
    1 DAI = 3.71318337592881 USDT

    BAT, WETH and UNI look correct, aBLOCK,USDC,WBTC look like problem with digits, and DAI seems out, using wrapper with version 2 and infura provider

  6. ErikBjare commented on Dec 20, 2020

    @ErikBjare
    ErikBjare
    on Dec 20, 2020
    Member
    More actions

    @tryiou That's because your conversion function makes an incorrect assumption about the number of decimals. As an example, WBTC has 8, not 18 (https://etherscan.io/token/0x2260fac5e5542a773aa44fbcfedf7c193bc2c599).

    It's a common mistake to make, see for example this issue: #41

    Edit: Your wbtc_rate (and others) is also incorrect. If you want the price of 1 WBTC denominated in ETH, you should use: wbtc_rate = uniswap_wrapper.get_eth_token_input_price(wbtc, 10 ** 8) (8 decimals as defined by the WBTC ERC20 contract)

  7. tryiou commented on Dec 20, 2020

    @tryiou
    tryiou
    on Dec 20, 2020
    More actions

    thanks for your answer, i'll study this more in depth 👍

  8. tryiou commented on Dec 20, 2020

    @tryiou
    tryiou
    on Dec 20, 2020
    More actions

    testing few more

    wbtc = Web3.toChecksumAddress("0x2260fac5e5542a773aa44fbcfedf7c193bc2c599")
    wbtc_rate = uniswap_wrapper.get_eth_token_input_price(wbtc, 10 ** 8)
    print("wbtc_rate =", wbtc_rate)
    
    usdc = Web3.toChecksumAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48")
    usdc_rate = uniswap_wrapper.get_eth_token_input_price(usdc, 10 ** 6)
    print("usdc_rate =", usdc_rate)
    

    correcting the decimal following contract definition,
    this give me:
    wbtc_rate = 0
    usdc_rate = 0
    i tried to increase again the decimal selection and change my conversion func, this seems to give correct result :

    def conversion(rate, usd_rate, decimal):
        conversion = ((1 / rate) * (usd_rate / 10 ** 6)) * decimal
        return conversion
    
    usdt = Web3.toChecksumAddress("0xdac17f958d2ee523a2206206994597c13d831ec7")
    usdt_rate = uniswap_wrapper.get_eth_token_input_price(usdt, 10 ** 18)
    
    wbtc = Web3.toChecksumAddress("0x2260fac5e5542a773aa44fbcfedf7c193bc2c599")
    wbtc_rate = uniswap_wrapper.get_eth_token_input_price(wbtc, 10 ** 18)
    
    print("wbtc_rate =", wbtc_rate)
    print("1 wbtc =", conversion(wbtc_rate, usdt_rate, 10 ** 8), "USDT")
    

    wbtc_rate = 2712959
    1 wbtc = 23918.122868793816 USDT

  9. ErikBjare commented on Dec 21, 2020

    @ErikBjare
    ErikBjare
    on Dec 21, 2020
    Member
    More actions

    Ah, yeah I was wrong about the get_eth_token_input_price argument. It should indeed be 10**18.

    Happy to see you figured it 👍

    Reacted by tryiou
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.