Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swapExactTokensForETHSupportingFeeOnTransferTokens fails when from == uniswapPair address #117

Open
francestu96 opened this issue Mar 2, 2022 · 3 comments

Comments

@francestu96
Copy link

I want to apply a fee of the 10% every time my token is transferred (except the case the from is the owner).
When i use PancakeSwap I'm able to create a pool, however, when I try to swap the token from the just created pool, I receive the error 'Pancake: TRANSFER_FAILED'

This happen when the from filed is equal to the _uniswapV2Pair address.

Why this happens and how to fix this problem?

The token code below:

modifier lockSwapTokenForETH {
    _inSwapTokenForETH = true;
    _;
    _inSwapTokenForETH = false;

} 

function _transfer(address from, address to, uint256 amount) private {
     // by adding "from != _uniswapV2Pair" it works
    if (!_inSwapTokenForETH && from != _owner){           
        uint feeAmount = amount * 10 / 100;

        _transfer(from, address(this), feeAmount);
        _swapTokensForEth(feeAmount);   

        _transfer(from, to, amount - feeAmount);
        emit Transfer(from, to, amount - feeAmount);
    }
    else{
        _transfer(from, to, amount);
        emit Transfer(from, to, amount);
    }
}

function _swapTokensForEth(uint256 tokenAmount) private lockSwapTokenForETH {
    address[] memory path = new address[](2);
    path[0] = address(this);
    path[1] = _uniswapV2Router.WETH();

    _approve(address(this), address(_uniswapV2Router), tokenAmount);

    _uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(tokenAmount, 0, path, address(this), block.timestamp);
}

receive() external payable {}
@francestu96
Copy link
Author

francestu96 commented May 2, 2022 via email

@italoHonoratoSA
Copy link

Oi Italo, você excluiu seu comentário? Não consigo mais vê-lo no GitHub. Você conseguiu encontrar uma solução para isso?

Yes I made it,

Below is the solution to this famous error. See if it helps you solve your problem:

https://medium.com/@italo.honorato/how-to-resolve-transferhelper-error-transfer-from-failed-fb4c8bf6488c

Basically the error happens because it is not possible to approve a permission for the UNISWAP_V2_ROUTER to spend tokens from the ContractSwapOnUniswap address, why by default the ERC20 approve function will not recognize ContractSwapOnUniswap as msg.sender . That is, the TransferHelper: TRANSFER_FROM_FAILED error occurs because the UNISWAP_V2_ROUTER does not have the necessary permission in the token contract to spend balance of ContractSwapOnUniswap .

It concludes that this is a design error of the ERC20 standard itself applied to contracts that make exchanges from other accounts. If I'm wrong, please correct me.

Does anyone know how to guide me on how to open a discussion on the subject, for possible improvements in this?

@Aminkavoos
Copy link

I want to apply a fee of the 10% every time my token is transferred (except the case the from is the owner).
When i use PancakeSwap I'm able to create a pool, however, when I try to swap the token from the just created pool, I receive the error 'Pancake: TRANSFER_FAILED'

This happen when the from filed is equal to the _uniswapV2Pair address.

Why this happens and how to fix this problem?

The token code below:

modifier lockSwapTokenForETH {
    _inSwapTokenForETH = true;
    _;
    _inSwapTokenForETH = false;

} 

function _transfer(address from, address to, uint256 amount) private {
     // by adding "from != _uniswapV2Pair" it works
    if (!_inSwapTokenForETH && from != _owner){           
        uint feeAmount = amount * 10 / 100;

        _transfer(from, address(this), feeAmount);
        _swapTokensForEth(feeAmount);   

        _transfer(from, to, amount - feeAmount);
        emit Transfer(from, to, amount - feeAmount);
    }
    else{
        _transfer(from, to, amount);
        emit Transfer(from, to, amount);
    }
}

function _swapTokensForEth(uint256 tokenAmount) private lockSwapTokenForETH {
    address[] memory path = new address[](2);
    path[0] = address(this);
    path[1] = _uniswapV2Router.WETH();

    _approve(address(this), address(_uniswapV2Router), tokenAmount);

    _uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(tokenAmount, 0, path, address(this), block.timestamp);
}

receive() external payable {}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants