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)
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));
_pause();
}
function unpause() public {
require(hasRole(PAUSER_ROLE, msg.sender));
_unpause();
}
function snapshot() public {
require(hasRole(SNAPSHOT_ROLE, msg.sender));
_snapshot();
}
}
Environment
hardhat.config.js
require('@nomiclabs/hardhat-ethers');
module.exports = {
solidity: "0.8.6",
};
package.json
{
"name": "ethops",
"version": "0.0.1",
"description": "ethereum deveops",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"ethops"
],
"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"
}
}