@@ -4,21 +4,51 @@ pragma solidity ^0.8.0;
44import "./interface/IPermissions.sol " ;
55import "../lib/TWStrings.sol " ;
66
7+ /**
8+ * @title Permissions
9+ * @dev This contracts provides extending-contracts with role-based access control mechanisms
10+ */
711contract Permissions is IPermissions {
12+ /// @dev Map from keccak256 hash of a role => a map from address => whether address has role.
813 mapping (bytes32 => mapping (address => bool )) private _hasRole;
14+
15+ /// @dev Map from keccak256 hash of a role to role admin. See {getRoleAdmin}.
916 mapping (bytes32 => bytes32 ) private _getRoleAdmin;
1017
18+ /// @dev Default admin role for all roles. Only accounts with this role can grant/revoke other roles.
1119 bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00 ;
1220
21+ /// @dev Modifier that checks if an account has the specified role; reverts otherwise.
1322 modifier onlyRole (bytes32 role ) {
1423 _checkRole (role, msg .sender );
1524 _;
1625 }
1726
27+ /**
28+ * @notice Checks whether an account has a particular role.
29+ * @dev Returns `true` if `account` has been granted `role`.
30+ *
31+ * @param role keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE")
32+ * @param account Address of the account for which the role is being checked.
33+ */
1834 function hasRole (bytes32 role , address account ) public view override returns (bool ) {
1935 return _hasRole[role][account];
2036 }
2137
38+ /**
39+ * @notice Checks whether an account has a particular role;
40+ * role restrictions can be swtiched on and off.
41+ *
42+ * @dev Returns `true` if `account` has been granted `role`.
43+ * Role restrictions can be swtiched on and off:
44+ * - If address(0) has ROLE, then the ROLE restrictions
45+ * don't apply.
46+ * - If address(0) does not have ROLE, then the ROLE
47+ * restrictions will apply.
48+ *
49+ * @param role keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE")
50+ * @param account Address of the account for which the role is being checked.
51+ */
2252 function hasRoleWithSwitch (bytes32 role , address account ) public view returns (bool ) {
2353 if (! _hasRole[role][address (0 )]) {
2454 return _hasRole[role][account];
@@ -27,10 +57,25 @@ contract Permissions is IPermissions {
2757 return true ;
2858 }
2959
60+ /**
61+ * @notice Returns the admin role that controls the specified role.
62+ * @dev See {grantRole} and {revokeRole}.
63+ * To change a role's admin, use {_setRoleAdmin}.
64+ *
65+ * @param role keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE")
66+ */
3067 function getRoleAdmin (bytes32 role ) external view override returns (bytes32 ) {
3168 return _getRoleAdmin[role];
3269 }
3370
71+ /**
72+ * @notice Grants a role to an account, if not previously granted.
73+ * @dev Caller must have admin role for the `role`.
74+ * Emits {RoleGranted Event}.
75+ *
76+ * @param role keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE")
77+ * @param account Address of the account to which the role is being granted.
78+ */
3479 function grantRole (bytes32 role , address account ) public virtual override {
3580 _checkRole (_getRoleAdmin[role], msg .sender );
3681 if (_hasRole[role][account]) {
@@ -39,35 +84,55 @@ contract Permissions is IPermissions {
3984 _setupRole (role, account);
4085 }
4186
87+ /**
88+ * @notice Revokes role from an account.
89+ * @dev Caller must have admin role for the `role`.
90+ * Emits {RoleRevoked Event}.
91+ *
92+ * @param role keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE")
93+ * @param account Address of the account from which the role is being revoked.
94+ */
4295 function revokeRole (bytes32 role , address account ) public virtual override {
4396 _checkRole (_getRoleAdmin[role], msg .sender );
4497 _revokeRole (role, account);
4598 }
4699
100+ /**
101+ * @notice Revokes role from the account.
102+ * @dev Caller must have the `role`, with caller being the same as `account`.
103+ * Emits {RoleRevoked Event}.
104+ *
105+ * @param role keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE")
106+ * @param account Address of the account from which the role is being revoked.
107+ */
47108 function renounceRole (bytes32 role , address account ) public virtual override {
48109 if (msg .sender != account) {
49110 revert ("Can only renounce for self " );
50111 }
51112 _revokeRole (role, account);
52113 }
53114
115+ /// @dev Sets `adminRole` as `role`'s admin role.
54116 function _setRoleAdmin (bytes32 role , bytes32 adminRole ) internal virtual {
55117 bytes32 previousAdminRole = _getRoleAdmin[role];
56118 _getRoleAdmin[role] = adminRole;
57119 emit RoleAdminChanged (role, previousAdminRole, adminRole);
58120 }
59121
122+ /// @dev Sets up `role` for `account`
60123 function _setupRole (bytes32 role , address account ) internal virtual {
61124 _hasRole[role][account] = true ;
62125 emit RoleGranted (role, account, msg .sender );
63126 }
64127
128+ /// @dev Revokes `role` from `account`
65129 function _revokeRole (bytes32 role , address account ) internal virtual {
66130 _checkRole (role, account);
67131 delete _hasRole[role][account];
68132 emit RoleRevoked (role, account, msg .sender );
69133 }
70134
135+ /// @dev Checks `role` for `account`. Reverts with a message including the required role.
71136 function _checkRole (bytes32 role , address account ) internal view virtual {
72137 if (! _hasRole[role][account]) {
73138 revert (
@@ -83,6 +148,7 @@ contract Permissions is IPermissions {
83148 }
84149 }
85150
151+ /// @dev Checks `role` for `account`. Reverts with a message including the required role.
86152 function _checkRoleWithSwitch (bytes32 role , address account ) internal view virtual {
87153 if (! hasRoleWithSwitch (role, account)) {
88154 revert (
0 commit comments