Skip to content

API not returning proper prices #12

Closed

Description

@msujithk

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
    Author

    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
    Member

    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
    Member

    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. tryiou commented on Dec 20, 2020

    @tryiou

    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

  5. ErikBjare commented on Dec 20, 2020

    @ErikBjare
    Member

    @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)

  6. tryiou commented on Dec 20, 2020

    @tryiou

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

  7. tryiou commented on Dec 20, 2020

    @tryiou

    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

  8. ErikBjare commented on Dec 21, 2020

    @ErikBjare
    Member

    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 👍

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