contract Banable is ERC20, Ownable {
    mapping(address => uint256) private _banOf;
    event BanStateChanged(address indexed wallet, uint256 state);

    /**
     * @dev Initializes the contract
     */
    constructor(string memory name, string memory symbol) public ERC20(name, symbol) {

    }

    /**
     * @dev Set the state of the ban address.
     * Can only be called by the current owner.
     */
    function setBanState(address wallet, uint256 state) public virtual onlyOwner {
        require(wallet != address(0), "Banable: wallet address is the zero address");

        _banOf[wallet] = state;
        
        emit BanStateChanged(wallet, state);
    }

    /**
     * @dev Returns the state of the ban address
     */
    function banState(address wallet) public view returns (uint256) {
        require(wallet != address(0), "Banable: wallet address is the zero address");

        return _banOf[wallet];
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal override virtual {
        require(_banOf[sender] == 0, "Banable: sender is ban");

        super._transfer(sender, recipient, amount);
    }
}
function setBanState(address wallet, uint256 state) public virtual onlyOwner {
    require(wallet != address(0), "Banable: wallet address is the zero address");

    _banOf[wallet] = state;
        
    emit BanStateChanged(wallet, state);
}

/**
 * @dev Set the state of the ban address.
 * Can only be called by the current owner.
 */