contract Zescoin is AccessControlEnumerable, ERC20Pausable {
    uint256 private initialSupply;
    string private _name = "ZesCoin";
    string private _symbol = "ZESC";
    uint8 private _decimals;
    
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");

    constructor() ERC20(_name, _symbol)  {
        _decimals = 4;
        initialSupply = 5114477611 * 10**uint(_decimals);
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
        _mint(msg.sender, initialSupply);
    }
    function decimals() public view override virtual returns (uint8) {
        return 4;
    }
    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     * - the caller must have the `BURNER_ROLE`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        require(hasRole(BURNER_ROLE, _msgSender()), "ERC20: must have burner role to mint");
        uint256 currentAllowance = allowance(account, _msgSender());
        require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
        _approve(account, _msgSender(), currentAllowance - amount);
        _burn(account, amount);
    }    
    /**
     * @dev Creates `amount` new tokens for `to`.
     *
     * Requirements:
     *
     * - the caller must have the `MINTER_ROLE`.
     */
    function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
        _mint(to, amount);
    }   
    /**
    * @dev Pauses all token transfers.
    *
    * Requirements:
    *
    * - the caller must have the `PAUSER_ROLE`.
    */
    function pause() public virtual {
        require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20Pausable: must have pauser role to pause");
        _pause();
    }
    /**
    * @dev Unpauses all token transfers.
    *
    * Requirements:
    *
    * - the caller must have the `PAUSER_ROLE`.
    */    
    function unpause() public virtual {
        require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20Pausable: must have pauser role to unpause");
        _unpause();
    }
    
}
// ----------------------------------------------------------------------------
// ZesCoin contract by SecLab LLC
//
// Symbol      : ZESC
// Name        : ZesCoin
// Total supply: 5,114,477,611
// Decimals    : 4
// Access Control : Role Based Access Control
// 
// Copyright (c) 2021 zOS Global Limited, The MIT License
// ----------------------------------------------------------------------------
function burnFrom(address account, uint256 amount) public virtual {
    require(hasRole(BURNER_ROLE, _msgSender()), "ERC20: must have burner role to mint");
    uint256 currentAllowance = allowance(account, _msgSender());
    require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
    _approve(account, _msgSender(), currentAllowance - amount);
    _burn(account, amount);
}    

/**
 * @dev Destroys `amount` tokens from `account`, deducting from the caller's
 * allowance.
 *
 * Requirements:
 *
 * - the caller must have allowance for ``accounts``'s tokens of at least
 * `amount`.
 * - the caller must have the `BURNER_ROLE`.
 */