contract ERC20Token is ERC20, ERC20Burnable, ERC20Pausable {
  using SafeMath for uint256;

  uint256 private _supplyCap;
  address _minter;

  constructor(
    string memory name,
    string memory symbol,
    address minter,
    uint256 supplyCap
  ) ERC20(name, symbol) {
    _supplyCap = supplyCap;
    _minter = minter;
    _mint(minter == address(0) ? msg.sender : minter, _supplyCap);
  }

  /**
   * @dev Returns the cap on the token's total supply.
   */
  function cap() public view returns (uint256) {
    return _supplyCap;
  }

  /**
   * @dev Override mint from ERC20.sol.
   *
   * Requirements:
   * - `value` must not cause the total supply to go over the cap.
   */
  function _mint(address account, uint256 value) internal override {
    require(
      _supplyCap == 0 || totalSupply().add(value) <= _supplyCap,
      "Cap exceeded"
    );

    super._mint(account, value);
  }

  function _beforeTokenTransfer(
    address from,
    address to,
    uint256 amount
  ) internal override(ERC20, ERC20Pausable) {
    super._beforeTokenTransfer(from, to, amount);
  }

  function pause() external {
    require(msg.sender == _minter, "UNAUTHORIZED");
    _pause();
  }

  function unpause() external {
    require(msg.sender == _minter, "UNAUTHORIZED");
    _unpause();
  }
}
function cap() public view returns (uint256) {
  return _supplyCap;
}

/**
 * @dev Returns the cap on the token's total supply.
 */