123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- // SPDX-License-Identifier: MIT
- pragma solidity ^0.8.0;
- import "./AccessControl.sol";
- import "../utils/structs/EnumerableSet.sol";
- /**
- * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
- */
- interface IAccessControlEnumerable {
- function getRoleMember(bytes32 role, uint256 index) external view returns (address);
- function getRoleMemberCount(bytes32 role) external view returns (uint256);
- }
- /**
- * @dev Extension of {AccessControl} that allows enumerating the members of each role.
- */
- abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
- using EnumerableSet for EnumerableSet.AddressSet;
- mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;
- /**
- * @dev See {IERC165-supportsInterface}.
- */
- function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
- return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);
- }
- /**
- * @dev Returns one of the accounts that have `role`. `index` must be a
- * value between 0 and {getRoleMemberCount}, non-inclusive.
- *
- * Role bearers are not sorted in any particular way, and their ordering may
- * change at any point.
- *
- * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
- * you perform all queries on the same block. See the following
- * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
- * for more information.
- */
- function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {
- return _roleMembers[role].at(index);
- }
- /**
- * @dev Returns the number of accounts that have `role`. Can be used
- * together with {getRoleMember} to enumerate all bearers of a role.
- */
- function getRoleMemberCount(bytes32 role) public view override returns (uint256) {
- return _roleMembers[role].length();
- }
- /**
- * @dev Overload {grantRole} to track enumerable memberships
- */
- function grantRole(bytes32 role, address account) public virtual override {
- super.grantRole(role, account);
- _roleMembers[role].add(account);
- }
- /**
- * @dev Overload {revokeRole} to track enumerable memberships
- */
- function revokeRole(bytes32 role, address account) public virtual override {
- super.revokeRole(role, account);
- _roleMembers[role].remove(account);
- }
- /**
- * @dev Overload {renounceRole} to track enumerable memberships
- */
- function renounceRole(bytes32 role, address account) public virtual override {
- super.renounceRole(role, account);
- _roleMembers[role].remove(account);
- }
- /**
- * @dev Overload {_setupRole} to track enumerable memberships
- */
- function _setupRole(bytes32 role, address account) internal virtual override {
- super._setupRole(role, account);
- _roleMembers[role].add(account);
- }
- }
|