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?

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

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

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

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

I think unsiwap supports Kovan, Rinkeby

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

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

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

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

Hi @jmarrr,

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