contract CsfERC20 is Context, AccessControl, Ownable, ERC20Burnable, ERC20Pausable {
    using SafeMath for uint256;
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    /**
     * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE`, `PAUSER_ROLE` to the
     * account that deploys the contract.
     *
     * See {ERC20-constructor}.
     */

    constructor(string memory contractName, string memory contractSymbol, uint256 initialAmount, uint8 decimals) ERC20(contractName, contractSymbol) {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
        _setupRole(MINTER_ROLE, _msgSender());
        _setupRole(PAUSER_ROLE, _msgSender());
        _setupDecimals(decimals);
        //Mint amount to the sender
        _mint(_msgSender(), initialAmount * (10 ** uint256(decimals)));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     * force setup DEFAULT_ADMIN_ROLE to owner, in case him has renounced DEFAULT_ADMIN_ROLE
     * beacuse he need to have almost DEFAULT_ADMIN_ROLE role to grant all role to the newOwner
     * Revoke all roles to the previous owner
     * Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE`, `PAUSER_ROLE` to the new owner
     */
    function transferOwnership(address newOwner) public override onlyOwner {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
        grantRole(DEFAULT_ADMIN_ROLE, newOwner);
        grantRole(MINTER_ROLE, newOwner);
        grantRole(PAUSER_ROLE, newOwner);
        revokeRole(MINTER_ROLE, _msgSender());
        revokeRole(PAUSER_ROLE, _msgSender());
        revokeRole(DEFAULT_ADMIN_ROLE, _msgSender());
        super.transferOwnership(newOwner);
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public pure override {
        revert("CsfERC20: renounceOwnership function was disabled; please use transferOwnership");
    }
    
    /**
     * @dev Throws if called by any account without `MINTER_ROLE`.
     */
    modifier onlyMinter() {
        require(hasRole(MINTER_ROLE, _msgSender()), "CsfERC20: MINTER role required");
        _;
    }

    /**
     * @dev Creates `amount` new tokens for `to`.
     *
     * See {ERC20-_mint}.
     *
     * Requirements:
     *
     * - the caller must have the `MINTER_ROLE`.
     */
    function mint(address to, uint256 amount) public virtual onlyMinter {
        _mint(to, amount);
    }
    
    /**
     * @dev Throws if called by any account without `PAUSER_ROLE`.
     */
    modifier onlyPauser() {
        require(hasRole(PAUSER_ROLE, _msgSender()), "CsfERC20: PAUSER role required");
        _;
    }

    /**
     * @dev Pauses all token transfers.
     *
     * See {ERC20Pausable} and {Pausable-_pause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
     function pause() public virtual onlyPauser {
        _pause();
    }

    /**
     * @dev Unpauses all token transfers.
     *
     * See {ERC20Pausable} and {Pausable-_unpause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
    function unpause() public virtual onlyPauser {
        _unpause();
    }

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

}
/**
 * @dev {ERC20} token, including:
 *
 *  - ability for holders to burn (destroy) their tokens
 *  - a minter role that allows for token minting (creation)
 *  - a pauser role that allows to stop all token transfers
 *
 * This contract uses {AccessControl} to lock permissioned functions using the
 * different roles - head to its documentation for details.
 *
 * The account that deploys the contract will be granted the minter and pauser
 * roles, as well as the default admin role, which will let it grant both minter
 * and pauser roles to other accounts.
 */
function pause() public virtual onlyPauser {
   _pause();


/**
 * @dev Pauses all token transfers.
 *
 * See {ERC20Pausable} and {Pausable-_pause}.
 *
 * Requirements:
 *
 * - the caller must have the `PAUSER_ROLE`.
 */