Openzeppelin offers RBAC whereby an address may be granted a specific set of responsibilities. I would like to know which might be considered a better practice - using Access Control Or using an EnumerableSet and maintaining a list of addresses.

For example, in case of whitelisting in presales, it's a common pattern to maintain a mapping of sorts which is checked when an addresses tries to mint during presale. That addresses has to be included beforehand in the said mapping. Using an EnumerableSetof type AddressSet may be an obvious upgrade to that but would using Access Control be even better?

Instead of adding an array of addresses to an EnumerableSet if I were to grant them a MINTER_ROLE and maintain a Counter for tracking number of minters - checking if the invoker of the mint() has been granted the minter role with has_role() or the onlyRole() modifier as opposed to using the add(), length and contains() for EnumerableSet for the same.

Which one would be considered a better practice and what would be the Gas considerations in each case?

1 Answer 1


There's also AccessControlEnumerable. The biggest factor will be whether you are launching on ethereum mainnet. Because here gas matters and you would want to minimize storage writes as much as possible.

Consider an array for example (a relaxation to enumerable sets). You now have to store the addresses in that array and how much each can mint. Using enumerable sets works similar (you are storing the indexes that correspond to the addresses).

There shouldn't be a reason for you to require this enumerable set on-chain though. A more efficient solution would be to store a mapping(address => uint256) whitelistMintAllowance. You would require a check mintAmount <= whitelistMintAllowance[minter] in the whitelist mint function and decrease the allowance right afterward: whitelistMintAllowance[minter] -= mintAmount.

Again, if this is ethereum, you might want to consider using signatures that can be validated on-chain, since these will save you the gas costs of adding all those addresses to the contract.

  • Between mapping(address => uint256), EnumerableSet.AddressSet and Access Control methodology, which one would be more efficient do you think (considering all accounts whitelisted can only mint equal amounts specified at first which may be queries with .balanceOf()? Commented Mar 11, 2022 at 14:05
  • EnumerableSet internally is a mapping + an array, so it would be more costly. Like I said, if it's not ethereum, you shouldn't be worrying about these things. If it is, you might even want to go with signatures. Using balanceOf is not safe, because people can simply transfer the nfts after they have minted.
    – phaze
    Commented Mar 11, 2022 at 15:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.