Uniswap V2 Tutorial – How to Swap Tokens Back to Ether

solidityuniswap

I am trying to do the reverse action of what I did in this question:
Basically sell/swap some arbitrary token and receive ether on Uniswap V2 using IUniswapV2Router02.

Here is what I have done:

 contract SellTokens{
    
       IUniswapV2Router02 usi = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
          
    function sellDai(uint256 daiQty , address cryptoToken) public payable returns(uint256){

//address cryptoToken = 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa;//0x00D811B7d33cECCFcb7435F14cCC274a31CE7F5d//multiDaiKovan;

    uint256 ethAmountDerivable = getEstimatedTokenForETH(daiQty , cryptoToken)[0];
 
  uint deadline = now + 300; // using 'now' for convenience, for mainnet pass deadline from frontend!

    usi.swapExactTokensForETH(daiQty , ethAmountDerivable, getPathForTokenToETH(cryptoToken), address(this), deadline);

   return ethAmountDerivable;

}
    
    function getEstimatedTokenForETH(uint daiQty , address crypto) public view returns (uint[] memory) {
        return usi.getAmountsIn(daiQty, getPathForTokenToETH(crypto));
      }
    
     function getPathForTokenToETH(address crypto) private view returns (address[] memory) {
        address[] memory path = new address[](2);
        path[0] = crypto;
        path[1] = usi.WETH();
        
        return path;
      }
    
    }

When I call sellDai from truffle console using:

c.sellDai(web3.utils.toWei('0.02'),'0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa',{value: 3000000000000000})

I get the following output

The status says:
Fail with error 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'

What could be the issue, please?

EDIT

I changed the getAmountsIn function call to getAmountsOut, and the error changed from INSUFFICIENT_OUTPUT_AMOUNT to TransferHelper: TRANSFER_FROM_FAILED.

EDIT 2

After the admonition to approve the token before transfer, I did this:

function sellDai(uint256 daiQty , address cryptoToken) public payable returns(uint256){

//address cryptoToken = 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa;//0x00D811B7d33cECCFcb7435F14cCC274a31CE7F5d//multiDaiKovan;

  uint256 ethAmountDerivable = getEstimatedTokenForETH(daiQty , cryptoToken)[0];
  ethAmountDerivable = ethAmountDerivable.mul(10).div(11);// divide by 1.1
 
  uint deadline = now + 300; // using 'now' for convenience, for mainnet pass deadline from frontend!

  IERC20 dai = IERC20(cryptoToken);
  dai.approve(address(this), 0);
  dai.approve(address(this), daiQty);

    usi.swapExactTokensForETH(daiQty , ethAmountDerivable, getPathForTokenToETH(cryptoToken), address(this), deadline);

   return ethAmountDerivable;

}

But it still didnt work. Any ideas please. Here is the transaction

Thanks again

Best Answer

I think it's because you are using getAmountsIn instead of getAmountsOut. You are starting with the input amount (Dai) and want to get the output amount, not the reverse. It's therefore returning an amount denominated in Dai, which is a much higher number than the equivalent $ value of Eth, so the trade fails the check for the minimum output (which is way too high) https://github.com/Uniswap/uniswap-v2-periphery/blob/460ffcda51492bef3b191fdaf50092e0d35b66c2/contracts/libraries/UniswapV2Library.sol#L52

Related Topic