contract MiniToken is ERC20WithSupply, Pausable, MiniMinterAccess {
    // ERC20 'variables'
    string public constant override symbol = "MINI";
    string public constant override name = "MiniToken";
    uint8 public constant override decimals = 18;
    uint public cap;

    event CapUpdated(uint256 cap);
    event TokenSet();

    constructor( address _vault, uint256 _initialSupply, uint256 _cap) {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
        _setupRole(OPERATOR_ROLE, _vault);
        require(_cap == 0 ||  _initialSupply <= _cap, "Cap exceeded");
        cap = _cap;
        _mint(_vault, _initialSupply);
        _pause();
    }

    /**
     * @dev Unlocks token.
     */
    function setToken() external {
        require(
            hasAdminRole(_msgSender()),
            "MINI.setToken: Sender must be admin"
        );
        _unpause();
        emit TokenSet();
    }

    /**
     * @dev Sets the hard cap on token supply. 
     */
    function setCap(uint _cap) external  {
        require(
            hasAdminRole(_msgSender()),
            "MINI.setCap: Sender must be admin"
        );
        require( _cap >= totalSupply, "MINI: Cap less than totalSupply");
        cap = _cap;
        emit CapUpdated(cap);
    }

    function mint(address to, uint256 amount) public {
        require(hasMinterRole(_msgSender()), "MINI: must have minter role to mint");
        require(to != address(0), "MINI: no mint to zero address");
        require(cap >= totalSupply + amount, "MINI: Don't go over MAX");
        _mint(to, amount);
    }
    /**
     * @dev Destroys `amount` tokens from the caller.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }


    /**
     * @dev Requires hasOperatorRole for token transfers before Mini has been set. 
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        if (paused()) {
            require(hasOperatorRole(_msgSender()), "MINI: tokens cannot be transferred until setMini has been executed");
        }
    }

}
/// @title MINI
function _beforeTokenTransfer(
    address from,
    address to,
    uint256 amount
) internal virtual override {
    if (paused()) {
        require(hasOperatorRole(_msgSender()), "MINI: tokens cannot be transferred until setMini has been executed");
    }
}

/**
 * @dev Requires hasOperatorRole for token transfers before Mini has been set. 
 */