AccessControlEnumerableUpgradeable.sol 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.5.0-rc.0) (access/AccessControlEnumerable.sol)
  3. pragma solidity ^0.8.0;
  4. import "./IAccessControlEnumerableUpgradeable.sol";
  5. import "./AccessControlUpgradeable.sol";
  6. import "../utils/structs/EnumerableSetUpgradeable.sol";
  7. import "../proxy/utils/Initializable.sol";
  8. /**
  9. * @dev Extension of {AccessControl} that allows enumerating the members of each role.
  10. */
  11. abstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {
  12. function __AccessControlEnumerable_init() internal onlyInitializing {
  13. __Context_init_unchained();
  14. __ERC165_init_unchained();
  15. __AccessControl_init_unchained();
  16. __AccessControlEnumerable_init_unchained();
  17. }
  18. function __AccessControlEnumerable_init_unchained() internal onlyInitializing {
  19. }
  20. using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;
  21. mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;
  22. /**
  23. * @dev See {IERC165-supportsInterface}.
  24. */
  25. function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
  26. return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);
  27. }
  28. /**
  29. * @dev Returns one of the accounts that have `role`. `index` must be a
  30. * value between 0 and {getRoleMemberCount}, non-inclusive.
  31. *
  32. * Role bearers are not sorted in any particular way, and their ordering may
  33. * change at any point.
  34. *
  35. * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
  36. * you perform all queries on the same block. See the following
  37. * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
  38. * for more information.
  39. */
  40. function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {
  41. return _roleMembers[role].at(index);
  42. }
  43. /**
  44. * @dev Returns the number of accounts that have `role`. Can be used
  45. * together with {getRoleMember} to enumerate all bearers of a role.
  46. */
  47. function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {
  48. return _roleMembers[role].length();
  49. }
  50. /**
  51. * @dev Overload {_grantRole} to track enumerable memberships
  52. */
  53. function _grantRole(bytes32 role, address account) internal virtual override {
  54. super._grantRole(role, account);
  55. _roleMembers[role].add(account);
  56. }
  57. /**
  58. * @dev Overload {_revokeRole} to track enumerable memberships
  59. */
  60. function _revokeRole(bytes32 role, address account) internal virtual override {
  61. super._revokeRole(role, account);
  62. _roleMembers[role].remove(account);
  63. }
  64. uint256[49] private __gap;
  65. }