Hi I created a smart contract but when I am swaping 1 Million DAI with WBTC tokens I am getting only ~3379786784 WEI (~34 WBTC) but when I am checking its value on UNISWAP website it is showing 43 WBTC.

I am using ganache-cli with mainnet fork. Using truffle to test the smart contract.


const BN = require("bn.js");
const IERC20 = artifacts.require("IERC20");
const TestUniswap = artifacts.require("TestUniswap");

contract("TestUniswap", (accounts) =>{
    const DAI = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
    const DAI_WHALE = "0xF977814e90dA44bFA03b6295A0616a897441aceC";
    const WBTC = "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599";

    const WHALE = DAI_WHALE;
    const AMOUNT_IN = new BN(10).pow(new BN(18)).mul(new BN(1000000));
    const AMOUNT_OUT_MIN = 1;
    const TOKEN_IN = DAI;
    const TOKEN_OUT = WBTC;
    const TO = accounts[0];

    it("should swap", async ()=>{
        const tokenIn = await IERC20.at(TOKEN_IN);
        const tokenOut = await IERC20.at(TOKEN_OUT);
        const testUniswap = await TestUniswap.new();
        console.log(`outbefore ${await tokenOut.balanceOf(TO)}`);

        await tokenIn.approve(testUniswap.address, AMOUNT_IN, {from: WHALE});

        await testUniswap.swap(

        console.log(`out ${await tokenOut.balanceOf(TO)}`);


// SPDX-License-Identifier: MIT
pragma solidity ^0.8;

import "./interfaces/IERC20.sol";
import "./interfaces/Uniswap.sol";

contract TestUniswap{
    address private constant UNISWAP_V2_ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    address private constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

    function swap(
        address _tokenIn, //Token trading in for
        address _tokenOut, //Token that we want
        uint256 _amountIn,
        uint256 _amountOutMin,
        address _to
    ) external{
        //Transferring the token to this contract that we want to swap
        IERC20(_tokenIn).transferFrom(msg.sender, address(this), _amountIn);
        IERC20(_tokenIn).approve(UNISWAP_V2_ROUTER, _amountIn);

        address[] memory path;
        path = new address[](3);
        path[0] = _tokenIn;
        path[1] = WETH;
        path[2] = _tokenOut;


Whole project


  • It's possible that website is using a different path? Example DAI-WETH-WBTC.
    – 0xSanson
    Aug 9, 2022 at 11:03
  • @RiccardoS I have passed the path param to swapExactTokensForTokens method. And its DAI-WETH-WBTC I am assuming its because of the version as uniswap uses v3 now and I am using v2. Aug 10, 2022 at 5:08

1 Answer 1


script is just using the Uniswap v2 router and routing directly from DAI -> WBTC within the DAI <> WBTC pool, which only has enough depth to get you ~34 WBTC with 1m DAI

The Uniswap site will use Uniswap v3, and it will also route between multiple routes using multiple pools. Here's the route that the Uniswap site is currently giving me:

enter image description here

This is why it's getting a such a better rate, it's routing through various USDC and ETH pools, with differing fees, to get the rate you see

  • So there is nothing wrong with my code, its just because of the version? Aug 10, 2022 at 5:07
  • 1
    Your code gets the proper rate on the UniswapV2 WBTC <> DAI pool that you would expect, yes. I would suggest using Uniswap's smart order router library to get the optimal path using v3, github.com/Uniswap/smart-order-router
    – natewelch_
    Aug 10, 2022 at 12:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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