GeezerVison is showing github.com — API not returning proper prices · Issue #12 · uniswap-python/uniswap-python
API not returning proper prices #12DescriptionAPI 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. Activitymsujithk commented on Aug 5, 2020 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. ErikBjare commented on Sep 25, 2020 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. ErikBjare commented on Sep 25, 2020 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. tryiou commented on Dec 20, 2020 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 ErikBjare commented on Dec 20, 2020 @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) tryiou commented on Dec 20, 2020 thanks for your answer, i'll study this more in depth 👍 tryiou commented on Dec 20, 2020 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 ErikBjare commented on Dec 21, 2020 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 👍
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|