contract Token is ERC20Burnable, Blacklistable {

    address public minter;

    event Mint(address indexed minter, address indexed to, uint256 amount);
    event MinterChanged(address indexed newMinter);

    constructor(string memory _name, string memory _symbol)
        ERC20(_name, _symbol)
    {
    }

    /**
     * @dev Throws if called by any account other than a minter
     */
    modifier onlyMinter() {
        require(
            msg.sender == minter,
            "Mint: caller is not the minter"
        );
        _;
    }

    /**
     * @dev Function to mint tokens
     * @param _to The address that will receive the minted tokens.
     * @param _amount The amount of tokens to mint. Must be less than or equal
     * to the minterAllowance of the caller.
     * @return A boolean that indicates if the operation was successful.
     */
    function mint(address _to, uint256 _amount)
        public
        onlyMinter
        notBlacklisted(msg.sender)
        notBlacklisted(_to)
        returns (bool)
    {
        _mint(_to, _amount);
        return true;
    }

    function updateMinter(address _newMinter) external onlyOwner {
        require(
            _newMinter != address(0),
            "Mint: new minter is the zero address"
        );
        minter = _newMinter;
        emit MinterChanged(minter);
    }

    /**
     * @notice Set spender's allowance over the caller's tokens to be a given
     * value.
     * @param spender   Spender's address
     * @param amount     Allowance amount
     * @return True if successful
     */
    function approve(address spender, uint256 amount)
        public virtual override
        notBlacklisted(msg.sender)
        notBlacklisted(spender)
        returns (bool)
    {
        _approve(msg.sender, spender, amount);
        return true;
    }

    /**
     * @notice Transfer tokens by spending allowance
     * @param from  Payer's address
     * @param to    Payee's address
     * @param amount Transfer amount
     * @return True if successful
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    )
        public virtual override
        notBlacklisted(msg.sender)
        notBlacklisted(from)
        notBlacklisted(to)
        returns (bool)
    {
        return ERC20.transferFrom(from, to, amount);
    }

    /**
     * @notice Transfer tokens from the caller
     * @param to    Payee's address
     * @param amount Transfer amount
     * @return True if successful
     */
    function transfer(address to, uint256 amount)
        public virtual override
        notBlacklisted(msg.sender)
        notBlacklisted(to)
        returns (bool)
    {
        return ERC20.transfer(to, amount);
    }

}
function transferFrom(
    address from,
    address to,
    uint256 amount
)
    public virtual override
    notBlacklisted(msg.sender)
    notBlacklisted(from)
    notBlacklisted(to)
    returns (bool)
{
    return ERC20.transferFrom(from, to, amount);
}

/**
 * @notice Transfer tokens by spending allowance
 * @param from  Payer's address
 * @param to    Payee's address
 * @param amount Transfer amount
 * @return True if successful
 */