'Adding Liquidity to Pancakeswap in Testnet

I need help with my code. I want to create a simple Smart Contract with adding Liquidity to Pancakeswap. I tried many different things, but the transaction always fails.

I Deployed the Conract, added BNB to this Contract and then i want to call the addInitialLiquidity function to set the Liquiditypool.

This is my Errorcode:

    Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
Internal JSON-RPC error. { "code": 3, "message": "execution reverted: TransferHelper: TRANSFER_FROM_FAILED", "data": "0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000245472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c454400000000000000000000000000000000000000000000000000000000" }

And this is the Smart Contract

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol";
import "https://github.com/Uniswap/v2-periphery/blob/master/contracts/interfaces/IUniswapV2Router02.sol";
import "https://github.com/Uniswap/v2-core/blob/master/contracts/interfaces/IUniswapV2Factory.sol";

contract CWCoin is ERC20, Ownable{
    using SafeMath for uint256;

    uint8 liquiFee = 1;

    IUniswapV2Router02 public uniswapV2Router;
    address public uniswapV2Pair;
    bool initialLiqDone = false;

    constructor ()
        ERC20("CWCoin", "CWC"){

            IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(
                0xD99D1c33F9fC3444f8101754aBC46c52416550D1
            );

            address _uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
                .createPair(address(this), _uniswapV2Router.WETH());

            uniswapV2Router = _uniswapV2Router;
            uniswapV2Pair = _uniswapV2Pair;

            _mint(msg.sender, 1000000 * 10 ** uint(decimals()) );
            _mint(address(this), 100000 * 10 ** uint(decimals()) );
    }

    receive() external payable{}

     function swapAndLiquify(uint256 tokens) private {
        // split the contract balance into halves
        uint256 half = tokens.div(2);
        uint256 otherHalf = tokens.sub(half);
        uint256 initialBalance = address(this).balance;

        // swap tokens for ETH
        swapTokensForEth(half); // <- this breaks the ETH -> HATE swap when swap+liquify is triggered

        // how much ETH did we just swap into?
        uint256 newBalance = address(this).balance.sub(initialBalance);

        // add liquidity to uniswap
        addLiquidity(otherHalf, newBalance);
    }


    function addInitialLiquidity() public onlyOwner{

        // approve token transfer to cover all possible scenarios
        _approve(address(this), address(uniswapV2Router),  ~uint256(0));
        _approve(address(this), address(uniswapV2Pair),  ~uint256(0));

        // add the liquidity
        uniswapV2Router.addLiquidityETH{value: address(this).balance}(
            address(this),
            balanceOf(address(this)),
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            owner(),
            block.timestamp
        );

        initialLiqDone = true;

    }

    function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
        // approve token transfer to cover all possible scenarios
        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // add the liquidity
        uniswapV2Router.addLiquidityETH{value: ethAmount}(
            address(this),
            tokenAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            address(0),
            block.timestamp
        );
    }

    function swapTokensForEth(uint256 tokenAmount) private {
        // generate the uniswap pair path of token -> weth
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();

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

        // make the swap
        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0, // accept any amount of ETH
            path,
            address(this),
            block.timestamp
        );
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal override{
        require(from != address(0), "From not null address");
        require(to != address(0), "To not null address");

        if(amount == 0){
            super._transfer(from, to, 0);
            return;
        }

        uint256 liqui = amount.mul(liquiFee).div(100);

        swapAndLiquify(liqui);

        super._transfer(from, to, amount.sub(liqui));
    }

}

Smart Contract in Testnet

0xF0e54bA09c3e7E66f414dCE375f5FAE6846041F7

Transaction

0xa80e9acbf7310de437f41afdf19f9554bdd846c37ad004dc8efbec9c29093cb2

I hope anyone can help. Thank you very much

Edit: I tried many different things. Approved the Router, Approved the Pair, Approved my wallet Address

I tried to add Liquidity via bscscan. Nothing worked.



Solution 1:[1]

The exception is originating from IUniswapV2Router02 contract, in safeTransferFrom function of TransferHelper library. This function wants to transfer your tokens to pair contract by calling transferFrom function of your contract. Pancakeswap will assume the transfer succeeded if you return true in the transferFrom function. I checked your contract on bscscan testnet but it's not verified and so I couldn't read what transferFrom function is doing. I'm guessing it's calling _transfer but then not returning true when it's done.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1