You are trying to create a contract factory for the contract, which is abstract and can't be deployed

Solidity 0.8.6 compiler forces the contract to be marked as an abstract contract when trying to use the draft-ERC20Permit feature.

TypeError: Contract "EmberX" should be marked as abstract.

However, hardhat throws an error when trying to deploy the compiled contract on a localhost node

NomicLabsHardhatPluginError: You are trying to create a contract factory for the contract Srinjoy, which is abstract and can't be deployed.
If you want to call a contract using Srinjoy as its interface use the "getContractAt" function instead.
    at getContractFactoryByName (/home/eos/Desktop/Substrate/ethops/node_modules/@nomiclabs/hardhat-ethers/src/internal/helpers.ts:112:11)
    at main (/home/eos/Desktop/Substrate/ethops/scripts/deploy.js:4:18)

:1234: Code to reproduce

pragma solidity 0.8.6;

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Snapshot.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

abstract contract Srinjoy is ERC20, ERC20Burnable, ERC20Permit, ERC20Snapshot, AccessControl, Pausable {

    // Create role identifiers for burner, minter, pauser, snapshot
    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
    bytes32 public constant SNAPSHOT_ROLE = keccak256("SNAPSHOT_ROLE");

    constructor() ERC20("Srinjoy", "SJOY") {
        // Premine 1993 tokens    
        _mint(msg.sender, 1993 * 10 ** decimals());
        // contract deployer plays god as default admin role with ability to grant and revoke any roles
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
        // contract deployer has ercdefault burner, minter, pauser, snapshot role
        _setupRole(BURNER_ROLE, msg.sender);
        _setupRole(MINTER_ROLE, msg.sender);
        _setupRole(PAUSER_ROLE, msg.sender);
        _setupRole(SNAPSHOT_ROLE, msg.sender);

    function _beforeTokenTransfer(address from, address to, uint256 amount) internal whenNotPaused override(ERC20, ERC20Snapshot)
        super._beforeTokenTransfer(from, to, amount);

    // Check that the calling account has the burner role
    function burn(address from, uint256 amount) public onlyRole(BURNER_ROLE) {
        _burn(from, amount);

    // Check that the calling account has the minter role
    function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
        _mint(to, amount);

    function pause() public {
        require(hasRole(PAUSER_ROLE, msg.sender));

    function unpause() public {
        require(hasRole(PAUSER_ROLE, msg.sender));

    function snapshot() public {
        require(hasRole(SNAPSHOT_ROLE, msg.sender));

:computer: Environment


module.exports = {
  solidity: "0.8.6",


  "name": "ethops",
  "version": "0.0.1",
  "description": "ethereum deveops",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  "keywords": [
  "author": "srinjoy chakravarty",
  "license": "ISC",
  "devDependencies": {
    "@nomiclabs/hardhat-ethers": "^2.0.2",
    "ethers": "^5.4.0",
    "hardhat": "^2.4.1"
  "dependencies": {
    "@openzeppelin/contracts": "^4.2.0"