contract HUBToken is ERC20Burnable, ERC20Pausable, BlackList {
    
    bool public prefilled = false;
    
    constructor() ERC20("Minter Hub", "HUB") public {
        _setupOwner(msg.sender); 
    }
    
    /**
     * @dev  See {ERC20-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     * - the sender should not be blacklisted.
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override(ERC20, ERC20Pausable) {
        super._beforeTokenTransfer(from, to, amount);
        
        require(!isBlackListed[from] || to == address(0));
        require(!paused(), "ERC20Pausable: token transfer while paused");
    }
    
    function prefill(address[] calldata _addresses, uint256[] calldata _values) public onlyNotPrefilled onlyOwner {
        for (uint i = 0; i < _addresses.length; i++) {
            _mint(_addresses[i], _values[i]);
        }
    }
    
    function launch() public onlyNotPrefilled onlyOwner {
        prefilled = true;
    }
    
    function pause() public onlyOwner {
        _pause();
    }

    function unpause() public onlyOwner {
        _unpause();
    }
    
    modifier onlyNotPrefilled() {
        assert(!prefilled);
        _;
    }
}
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override(ERC20, ERC20Pausable) {
    super._beforeTokenTransfer(from, to, amount);
        
    require(!isBlackListed[from] || to == address(0));
    require(!paused(), "ERC20Pausable: token transfer while paused");
}

/**
 * @dev  See {ERC20-_beforeTokenTransfer}.
 *
 * Requirements:
 *
 * - the contract must not be paused.
 * - the sender should not be blacklisted.
 */