I am trying to swap weth token to dai token (both ERC20) by uniswap router contract:

I tried following two approaches:

1. use truffle console to manipulate weth/dai/router contract. This method working fine. see detail below:

// Dai.sol
pragma solidity ^0.6.6;

contract Dai {
    function balanceOf(address owner) external view returns(uint) {}
    function totalSupply() external view returns (uint256){}
    function transfer(address recipient, uint256 amount) external returns (bool){}
    function allowance(address owner, address spender) external view returns (uint256){}
    function approve(address spender, uint256 amount) external returns (bool){}
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool){}
// Weth.sol
pragma solidity ^0.6.6;

contract Weth {
    function deposit() public payable {}
    function approve(address spender, uint amount) external {}
    function allowance(address owner, address spender) external view returns(uint) {}
    function balanceOf(address owner) external view returns(uint) {}
    function transfer(address recipient, uint256 amount) external returns (bool){}
// Router.sol

pragma solidity ^0.6.6;

contract Router {
    function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts){}
    function getAmountsOut(uint amountIn, address[] memory path) public view returns (uint[] memory amounts){}
    function getAmountsIn(uint amountOut, address[] memory path)public view virtual returns (uint[] memory amounts) {}

There are the step by step commands line on truffle console:

truffle(kovan)> dai = await Dai.at("0x4f96fe3b7a6cf9725f59d353f723c1bdb64ca6aa")
truffle(kovan)> weth = await Weth.at("0xd0a1e359811322d97991e03f863a0c30c2cf029c")
truffle(kovan)> router =await Router.at("0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D")

truffle(kovan)> amountIn = await router.getAmountsIn(web3.utils.toWei("1"), [weth.address, dai.address])
truffle(kovan)> amountIn = amountIn[0]
truffle(kovan)> amountOut = web3.utils.toWei("1")
truffle(kovan)> weth.approve(router.address, amountIn)
truffle(kovan)> time = Math.floor((Date.now()/1000)) + 60*120
truffle(kovan)> router.swapExactTokensForTokens(amountIn, amountOut, [weth.address, dai.address], accounts[0], time)

In this case, the transaction of swapExactTokensForTokens has been successfully gone through (https://kovan.etherscan.io/tx/0x11e51ad94d90ec9b2182768bcea87ad5a15d5cf83a91a02d52f2990cbaed5c61)

  1. import IUniswapV2Router02.sol from uniswapv2 and manipulate router.swapExactTokensForTokens in my contract.
// SwapToken.sol
pragma solidity ^0.6.6;

import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "@uniswap/v2-core/contracts/interfaces/IERC20.sol";

contract SwapTokens {
    IUniswapV2Router02 public uniRouter = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
    event test (uint timestamp, uint amountIn, uint amountOut, address[] path, uint allowance, address sender);
    function swapper(address token1, address token2) public  {
        address[] memory path = new address[](2);
        path[0] = token1;
        path[1] = token2;
        uint amountOut = 1 ether;
        uint amountIn = uniRouter.getAmountsIn(
        IERC20(token1).approve(address(uniRouter), amountIn);
        uint allowed = IERC20(token1).allowance(msg.sender, address(uniRouter));        
        emit test(now+90, amountIn, amountOut, path, allowed, msg.sender);

            now + 120

Then I run the swapper function as below:

sw = await SwapTokens.deployed()
sw.swapper(weth.address, dai.address)

And the transaction fails with Fail with error 'TransferHelper: TRANSFER_FROM_FAILED' (https://kovan.etherscan.io/tx/0x3324fd65004e001163b665b79583f894e17854bc3371b89f39d472504cb4b46a)

These two approches seem both the same for me. I do not know which part I have done mistakenly.

1 Answer 1


When you call the uniswap contract from inside your contract then msg.sender will always be your contract since you are making the external make sure

  1. your contract either has the token you want to swap or it has the allowance
  2. check if you are on the right network and using the right addresses
  • You are right! Thanks for your pointing out. It saves my day.
    – Eric Lee
    Apr 21, 2021 at 16:09

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.