Pretty simple ERC20 contract

Hello all,
Please take a look at the contract and see if it has vulnerbility.

  • solc version: 0.8.2
  • @openzeppelin/contracts version: 4.4.1
  • truffle version: 5.4.25
pragma solidity ^0.8.2;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/access/AccessControlEnumerable.sol";

contract MyToken is AccessControlEnumerable, ERC20Burnable {

    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    constructor(string memory name, string memory symbol, uint256 amount) ERC20(name, symbol) {

        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
        _setupRole(MINTER_ROLE, _msgSender());
        _mint(_msgSender(), amount);

    function mint(address to, uint256 amount) public virtual {
        require(hasRole(MINTER_ROLE, _msgSender()), "MyToken: you don't have minter role");
        _mint(to, amount);

I just deployed and verified on testnet, it works fine but I want to know If it have any possible vulnerbility or not.
Thank you.

Are you using GSN? the reason you use _msgSener is because of GSN ?
How do you check hasRole ?

I think that _msgSender() is a replacement for msg.sender. For regular transactions it returns just msg.sender and for meta transacions it returns the end user(not a relayer).

And when I deploy this contract, constructor sets MINTER_ROLE to _msgSender() by _seupRole(). So I can check who has the minter role by hasRole.

I think you'll also need to call _setRoleAdmin to set up the admin role for MINTER_ROLE, otherwise, it is not possible to grant new wallets as MINTER_ROLE.

I think the account which owes DEFAULT_ADMIN_ROLE is possible to grant new account as MINTER_ROLE.

hmm, the grantRole function is the one to grant a role to a certain account. The modifier suggests only the admin role can grant this role. If you don't set up the admin role for MINTER_ROLE, not sure if this function can pass the modifier.

It may, and if this is the case, let me know. Thanks.

    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);

I think It can't pass getRoleAdmin(role),

function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;

If I don't setup the admin for MINTER_ROLE, getRoleAdmin returns '0x00..'.

1 Like