Uniswap TransferHelper TRANSFER_FROM_FAILED even on approved token

I am trying to swap using WETH from my contract to DAI using swapExactTokensForTokens(amountIn, amountOutMin, getPathForETHtoToken(tokenAddress), address(this), deadline) with uniswap. First I approved large amount on both DAI and WETH address then I deposited 0.01 worth of WETH using:

function wrap() public payable restricted {
    if (msg.value != 0) {
      WETH.deposit{value : msg.value}();
      WETH.transfer(address(this), msg.value);
    }
  }

on my contract and now able to see the balance in WETH
Next on remix I filled out the parameters for my swap function

function Buy(uint amountIn, uint amountOutMin, uint deadline, address tokenAddress) external payable restricted {
    uniswapRouter.swapExactTokensForTokens(amountIn, amountOutMin, getPathForETHtoToken(tokenAddress), address(this), deadline);
}

// amountIn = 10000000000000000, amountOutMin = 4029840000000000000, etc

And when I execute I get this error

Fail with error 'TransferHelper: TRANSFER_FROM_FAILED'

How do I resolve this issue?

1 Like

I think you should decrease the amount of amountOutMin.
BTW, you can swap eth to dai directly by swapExactETHForTokens

1 Like

Ya swapExactETHForTokens works fine with eth, only when trying to swap WETH/DAI have that error even with approve router or the contract address, the amountOutMin are based on uniswap price and tried to adjust still gets the error

1 Like

Ohhh, maybe you should check the route of WETH-DAI, is it directly WETH-DAI, or should be WETH-USDC-DAI?

1 Like

Is there a website where I can check the routing of tokens?

1 Like

I think unsiwap supports Kovan, Rinkeby

1 Like

Ya currently testing on Rinkeby, I see the route of WETH/DAI is just same no 3rd path

1 Like

Anyone? I already approve the token both dai and weth on the router address and contract address still getting the error

1 Like

I think you should decrease the amount of amountOutMin to 1 wei have a try.

1 Like

Here is the source code of my contract that can be tested on remix

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.8;

import "https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/interfaces/IUniswapV2Router02.sol";
import "https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/interfaces/IERC20.sol";

abstract contract WETH9_ 
{
    mapping (address => uint)                       public  balanceOf;
    mapping (address => mapping (address => uint))  public  allowance;
    
    function deposit() virtual external payable;
    function withdraw(uint wad) virtual external;
    function totalSupply() virtual external view returns (uint);
    
    function approve(address guy, uint wad) virtual external returns (bool) ;
    function transfer(address dst, uint wad) virtual external returns (bool) ;
    function transferFrom(address src, address dst, uint wad) virtual external returns (bool);
}

contract Test {
  address payable manager;
  address internal constant UNISWAP_ROUTER_ADDRESS = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; //  Uniswap Router Address
  address internal constant WETH_ADDRESS = 0xbCA556c912754Bc8E7D4Aad20Ad69a1B1444F42d; //  WETH Ropsten Address !! TO CHANGE
  WETH9_ internal WETH;
  IUniswapV2Router02 public uniswapRouter;

  constructor() public {
    uniswapRouter = IUniswapV2Router02(UNISWAP_ROUTER_ADDRESS);
    WETH = WETH9_(WETH_ADDRESS);
    manager = msg.sender;
  }
  modifier restricted() {
      require(msg.sender == manager, "manager allowed only");
      _;
  }
  function kill() external restricted {
    selfdestruct(manager);
  }
  function Buy(uint amountIn, uint amountOutMin, uint deadline, address tokenAddress) external payable restricted {
    uniswapRouter.swapExactTokensForTokens(amountIn, amountOutMin, getPathForETHtoToken(tokenAddress), address(this), deadline);
  }
  function Sell(uint amountIn, uint amountOutMin, uint deadline, address tokenAddress) external payable restricted {
    uniswapRouter.swapExactTokensForTokens(amountIn, amountOutMin, getPathForTokentoETH(tokenAddress), address(this), deadline);
  }
  function getPathForETHtoToken(address tokenAddress) private view returns (address[] memory) {
    address[] memory path = new address[](2);
    path[0] = uniswapRouter.WETH();
    path[1] = tokenAddress;
    
    return path;
  }
  function getPathForTokentoETH(address tokenAddress) private view returns (address[] memory) {
    address[] memory path = new address[](2);
    path[0] = tokenAddress;
    path[1] = uniswapRouter.WETH();
    
    return path;
  }
  function approve(uint tokenAmount, address tokenAddress) external restricted {
    IERC20 token = IERC20(tokenAddress);
    token.approve(address(uniswapRouter), tokenAmount);
  }
  function balanceOf(address tokenAddress) view public returns (uint) {
    return IERC20(tokenAddress).balanceOf(address(this));
  }
  function wrap() public payable restricted {
    if (msg.value != 0) {
      WETH.deposit{value : msg.value}();
      WETH.transfer(address(this), msg.value);
    }
  }
  function unwrap(uint amount) public payable restricted {
    if (amount != 0) {
      WETH.withdraw(amount);
      msg.sender.transfer(address(this).balance);
    }
  }
  // important to receive ETH
  receive() payable external {}
}

DAI ropsten address: 0xaD6D458402F60fD3Bd25163575031ACDce07538D
Error looks like this: https://dashboard.tenderly.co/tx/ropsten/0xe6b92792768b6ef62b30a69d70052cc20e82156834379c1e102c53c683d22884

Anyone can help me figure this out? Thanks

1 Like

Hi @jmarrr,

You may want to try asking this in the Uniswap Discord: https://discord.com/invite/XErMcTq (from: https://uniswap.org/)