3

I have two interfaces:

interface IUniswap {
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable /*DELETE MAYBE*/ returns (uint[] memory amounts);
    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts);   
}

interface IERC20 {
     function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
     function approve(address spender, uint256 amount) external returns (bool);
     function allowance(address owner, address spender) external view returns (uint256);
}

I would like to swap some tokens (that the contract already has) into ETH, using the following function:

function swapTokenForEth(address token, uint amountIn) external returns (bool) {
    

    address[] memory path = new address[](2);
    uint deadline = block.timestamp + 600;

    path[0] = token;
    path[1] = WETH;

    require(IERC20(token).approve(address(uniswap), (amountIn + 10000)), 'Uniswap approval failed');
    uniswap.swapExactTokensForETH(
        amountIn,
        1, //MIN FIXED TO 1 FOR TESTING
        path,
        address(this),
        deadline
    );

    return true;

}

The transaction reverts giving the following error: Fail with error 'TransferHelper: ETH_TRANSFER_FAILED'.

Thanks in advanced for the help.

2
  • Well, does your contract hold amountIn tokens right before you execute its swapTokenForEth function? Dec 11, 2020 at 12:14
  • Yes it does. I am going to concatenate this operation with a swapETHForToken, therefore in the same transaction the contract should:1. Buy tokens, 2. Sell tokens Dec 11, 2020 at 12:41

2 Answers 2

3

The Router02 documentation says that

If the to address is a smart contract, it must have the ability to receive ETH.

This is exactly the case now, so you have to use the payable modifier on your function:

function swapTokenForEth(address token, uint amountIn) external payable returns (bool) {
    

    address[] memory path = new address[](2);
    uint deadline = block.timestamp + 600;

    path[0] = token;
    path[1] = WETH;

    require(IERC20(token).approve(address(uniswap), (amountIn + 10000)), 'Uniswap approval failed');
    uniswap.swapExactTokensForETH(
        amountIn,
        1, //MIN FIXED TO 1 FOR TESTING
        path,
        address(this),
        deadline
    );

    return true;

}

0
1

You Must Include the following in your smart contract

receive() payable external {}

I Hope This Helps

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.