I am having difficulty understanding getting the price within the contract. So I created 2 different methods (one using SDK and other one using ethers.js)

  • When I try the SDK, I get 3839.62
  • When I try with ethers.js, I get 55561073443426097 so it's not just decimal difference :/
let chainId = ChainId.MAINNET;
const dai = await Fetcher.fetchTokenData(chainId, '0x6B175474E89094C44Da98b954EedeAC495271d0F')
const weth = WETH[chainId]

const pair = await Fetcher.fetchPairData(dai, weth);
const route = new Route([pair], weth)
const trade = new Trade(route, new TokenAmount(weth, '100000000000000000'), TradeType.EXACT_INPUT);

console.log(trade.executionPrice.toSignificant(6)); // 3839.62

const provider = new ethers.providers.getDefaultProvider();
const weth = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
const dai = '0x6B175474E89094C44Da98b954EedeAC495271d0F'

let uniswapRouter = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D';

const routerABI = [
'function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB)',
'function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut)'

let factoryContract = new ethers.Contract(uniswapRouter, routerABI, provider);
let price = await factoryContract.getAmountOut('100000000000000000', weth, dai)
console.log(price.toString()); // 55561073443426097

By integrating the contract, how can I get the price? Is there a method in contracts like: getPrice(tokenAAmount, tokenA, tokenB) returns (tokenBAmount)

Update: I can get the midprice using

let pairAddress = '';

const pairABI = [
'function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast)'

let pairContract = new ethers.Contract(pairAddress, pairABI, provider);
let reserves = await pairContract.getReserves();
let price = Number(reserves._reserve0) / Number(reserves._reserve1)

console.log(price.toPrecision(6)); // mid price

Router (0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D) - getAmountsOut, it takes amount-in and conversion path then will return amount after conversion (so in your case you need to add weth and dai to the array and send as second parameter).

Also it's possible to call (not send) each conversion function (like swapExactTokensForTokens) and in return you'll get amount of each coin in your conversion path. However to run this one you'll have to have enough balance in the account still

  • Thanks. Do you mean like this await routerContract.getAmountsOut('100000000000000000', [dai, weth])? This returned me 100000000000000000,25620998120358 but execution price in SDK is 3879.65. What is the relation between them? Do I need to normalise it somehow?
    – senty
    May 8 at 22:33
  • Ignore what I said, I put them other way around by mistake. It returned 100000000000000000,3852757269603527914787. Very close. However, do you know how should I deal with the comma? Should I just use split() or is there a better way to handle this?
    – senty
    May 8 at 22:48
  • 1
    Very close because probably the UI is usually lagging or adding slippage... for dealing with decimals - JS unfortunately isn't supporting any decimal lib out of the box. You can just treat it as string, in such cases. You'll need to read amount of decimals of the last coin using ERC-20 function var decimals = 18; var decimal_part_start = i.length - decimals; var number = i.substr(0, decimal_part_start)+ "." + i.substring(decimal_part_start);
    – Slawek
    May 8 at 23:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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