'How to get exact value of a token with Web3.py on PancakeSwap? Function getAmountsOut() returns a wrong value
Good day everyone, I'll try to be as clear as possible. I was trying to get the price of s**tcoins using web3.py and, after solving many problems, I'm stuck on the question i asked.
tokenAddres = '0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82' #Cake
tokenAddres = Web3.toChecksumAddress(tokenAddres)
bnbPrice = calcBNBPrice()
print(f'current BNB price: {bnbPrice}')
priceInBnb = calcSell(1, tokenAddres)
print(f'SHIT_TOKEN VALUE IN BNB : {priceInBnb} | Just convert it to USD ')
print(f'SHIT_TOKEN VALUE IN USD: {priceInBnb * bnbPrice}')
The calcsell function should be the one that return the value of the token in BNB
def calcSell(tokenToSell, tokenAddress):
BNBTokenAddress = Web3.toChecksumAddress("0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c") # BNB
amountOut = None
tokenRouter = web3.eth.contract(address=Web3.toChecksumAddress(tokenAddress), abi=tokenAbi)
tokenDecimals = tokenRouter.functions.decimals().call()
tokenToSell = setDecimals(tokenToSell, tokenDecimals) # Set token a correct number of 0s
router = web3.eth.contract(address=Web3.toChecksumAddress(pancakeSwapContract), abi=pancakeSwapAbi)
amountIn = web3.toWei(tokenToSell, 'ether')
amountOut = router.functions.getAmountsOut(amountIn, [tokenAddress, BNBTokenAddress]).call()
amountOut = web3.fromWei(amountOut[1], 'ether')
return amountOut
The value i get is:
SHIT_TOKEN VALUE IN BNB : 974136.205251839691973598 | Just convert it to USD
SHIT_TOKEN VALUE IN USD: 340708627.4489159379891912819
while the correct one is:
SHIT_TOKEN VALUE IN BNB : 0.048846069961106416 | Just convert it to USD
SHIT_TOKEN VALUE IN USD: 16.98585439310707
Any guess? Thank you in advance and, for any question, feel free to ask!
Solution 1:[1]
I wish your question was more specific: you are using specifically PancakeSwap to determine the price. But your question doesn't mention it at all.
Regardless, I know two ways to get a price quote from PancakeSwap using web3.py:
- Using their API.
import requests
def calcSell(tokenAddress):
apiURL = "https://api.pancakeswap.info/api/v2/tokens/"
response = requests.get(url = apiURL + tokenAddress)
price = extractPriceFromRaw(response)
return price
def extractPriceFromRaw(response):
jsonRaw = response.json()
price = jsonRaw['data']['price']
return price
CAKE = '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82'
print(calcSell(KRW))
- Using their smart contract's .getAmountsOut() function directly. What you are trying to do.
from web3 import Web3
def calcSell(tokenAddress):
routerContract = web3.eth.contract(address=routerPCS, abi=pancakeSwapAbi)
oneToken = web3.toWei(1, 'Ether')
price = routerContract.functions.getAmountsOut(oneToken, [tokenAddress, BUSD]).call()
normalizedPrice = web3.fromWei(price[1], 'Ether')
return normalizedPrice
web3 = Web3(Web3.HTTPProvider('https://bsc-dataseed1.binance.org:443'))
routerPCS = '0x10ED43C718714eb63d5aA57B78B54704E256024E'
BUSD = '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56'
CAKE = '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82'
print(calcSell(CAKE))
I did not try to debug your code, but I assume that your problems are because of the way you torture tokenToSell
value, instead of simply making it equal to 1 Ether: tokenToSell = web3.toWei(1, 'Ether')
Solution 2:[2]
I think this line
tokenToSell = setDecimals(tokenToSell, tokenDecimals) # Set token a correct number of 0s
does the exact same thing as this line
amountIn = web3.toWei(tokenToSell, 'ether')
which makes the amountIn
to be 1*(10**18)*(10**18)
Assuming the decimal is 18, get rid of amountIn = web3.toWei(tokenToSell, 'ether')
as tokenToSell is already in it's wei format.
Solution 3:[3]
use this api https://docs.moralis.io/
you can easily get token price with WEB3API
Moralis.initialize("APPID");
Moralis.serverURL = 'https://serverlink'
const options = {
address: "token address",
chain: "bsc",
exchange: "PancakeSwapv2"
};
Moralis.Web3API.token.getTokenPrice(options).then((result: String) => {
const userStr = JSON.stringify(result);
JSON.parse(userStr, (key, value) => {
if ( key === "usdPrice") {
console.log(value)
settokenprice(value)
}
return value;
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | MickeyDickey |
Solution 2 | Isaac Frank |
Solution 3 | Usama Hassan |