Skip to content

Commit 25d5396

Browse files
committed
refactor: renamed facet to 'AccessControlFacet' and refactored to follow standard compose practices
1 parent b2ac77d commit 25d5396

File tree

3 files changed

+197
-188
lines changed

3 files changed

+197
-188
lines changed

src/AccessControl/AccessControl.sol

Lines changed: 0 additions & 140 deletions
This file was deleted.
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity >=0.8.30;
3+
4+
contract AccessControlFacet {
5+
6+
/// @notice Emitted when the admin role for a role is changed.
7+
/// @param _role The role that was changed.
8+
/// @param _previousAdminRole The previous admin role.
9+
/// @param _newAdminRole The new admin role.
10+
event RoleAdminChanged(bytes32 indexed _role, bytes32 indexed _previousAdminRole, bytes32 indexed _newAdminRole);
11+
12+
/// @notice Emitted when a role is granted to an account.
13+
/// @param _role The role that was granted.
14+
/// @param _account The account that was granted the role.
15+
/// @param _sender The sender that granted the role.
16+
event RoleGranted(bytes32 indexed _role, address indexed _account, address indexed _sender);
17+
18+
/// @notice Emitted when a role is revoked from an account.
19+
/// @param _role The role that was revoked.
20+
/// @param _account The account from which the role was revoked.
21+
/// @param _sender The account that revoked the role.
22+
event RoleRevoked(bytes32 indexed _role, address indexed _account, address indexed _sender);
23+
24+
/// @notice Thrown when the account does not have a specific role.
25+
/// @param _role The role that the account does not have.
26+
/// @param _account The account that does not have the role.
27+
error AccessControlUnauthorizedAccount(address _account, bytes32 _role);
28+
29+
/// @notice Thrown when the sender is not the account to renounce the role from.
30+
/// @param _sender The sender that is not the account to renounce the role from.
31+
/// @param _account The account to renounce the role from.
32+
error AccessControlUnauthorizedSender(address _sender, address _account);
33+
34+
/// @notice Storage slot identifier.
35+
bytes32 constant STORAGE_POSITION = keccak256("compose.accesscontrol");
36+
37+
/// @notice Default admin role.
38+
bytes32 constant DEFAULT_ADMIN_ROLE = 0x00;
39+
40+
/// @notice storage struct for the AccessControl.
41+
struct AccessControlStorage {
42+
mapping(address account => mapping(bytes32 role => bool hasRole)) hasRole;
43+
mapping(bytes32 role => bytes32 adminRole) adminRole;
44+
}
45+
46+
/// @notice Returns the storage for the AccessControl.
47+
/// @return s The storage for the AccessControl.
48+
function getStorage() internal pure returns (AccessControlStorage storage s) {
49+
bytes32 position = STORAGE_POSITION;
50+
assembly {
51+
s.slot := position
52+
}
53+
}
54+
55+
/// @notice Returns if an account has a role.
56+
/// @param _role The role to check.
57+
/// @param _account The account to check the role for.
58+
/// @return True if the account has the role, false otherwise.
59+
function hasRole(bytes32 _role, address _account) external view returns(bool){
60+
AccessControlStorage storage s = getStorage();
61+
return s.hasRole[_account][_role];
62+
}
63+
64+
65+
/// @notice Checks if an account has a required role.
66+
/// @param _role The role to check.
67+
/// @param _account The account to check the role for.
68+
/// @custom:error AccessControlUnauthorizedAccount If the account does not have the role.
69+
function requireRole(bytes32 _role, address _account) external view {
70+
AccessControlStorage storage s = getStorage();
71+
if (!s.hasRole[_account][_role]){
72+
revert AccessControlUnauthorizedAccount(_account, _role);
73+
}
74+
}
75+
76+
/// @notice Returns the admin role for a role.
77+
/// @param _role The role to get the admin for.
78+
/// @return The admin role for the role.
79+
function getRoleAdmin(bytes32 _role) external view returns(bytes32){
80+
AccessControlStorage storage s = getStorage();
81+
return s.adminRole[_role];
82+
}
83+
84+
85+
/// @notice Grants a role to an account.
86+
/// @param _role The role to grant.
87+
/// @param _account The account to grant the role to.
88+
/// @dev Emits a {RoleGranted} event.
89+
/// @custom:error AccessControlUnauthorizedAccount If the caller is not the admin of the role.
90+
function grantRole(bytes32 _role, address _account) external {
91+
AccessControlStorage storage s = getStorage();
92+
bytes32 adminRole = s.adminRole[_role];
93+
94+
// Check if the caller is the admin of the role.
95+
if (!s.hasRole[msg.sender][adminRole]){
96+
revert AccessControlUnauthorizedAccount(msg.sender, adminRole);
97+
}
98+
99+
bool _hasRole = s.hasRole[_account][_role];
100+
if (!_hasRole) {
101+
s.hasRole[_account][_role] = true;
102+
emit RoleGranted(_role, _account, msg.sender);
103+
}
104+
}
105+
106+
/// @notice Revokes a role from an account.
107+
/// @param _role The role to revoke.
108+
/// @param _account The account to revoke the role from.
109+
/// @dev Emits a {RoleRevoked} event.
110+
/// @custom:error AccessControlUnauthorizedAccount If the caller is not the admin of the role.
111+
function revokeRole(bytes32 _role, address _account) external {
112+
AccessControlStorage storage s = getStorage();
113+
bytes32 adminRole = s.adminRole[_role];
114+
115+
// Check if the caller is the admin of the role.
116+
if (!s.hasRole[msg.sender][adminRole]){
117+
revert AccessControlUnauthorizedAccount(msg.sender, adminRole);
118+
}
119+
120+
bool _hasRole = s.hasRole[_account][_role];
121+
if (_hasRole) {
122+
s.hasRole[_account][_role] = false;
123+
emit RoleRevoked(_role, _account, msg.sender);
124+
}
125+
}
126+
127+
128+
/// @notice Renounces a role from the caller.
129+
/// @param _role The role to renounce.
130+
/// @param _account The account to renounce the role from.
131+
/// @dev Emits a {RoleRevoked} event.
132+
/// @custom:error AccessControlUnauthorizedSender If the caller is not the account to renounce the role from.
133+
function renounceRole(bytes32 _role, address _account) external {
134+
AccessControlStorage storage s = getStorage();
135+
136+
// Check If the caller is not the account to renounce the role from.
137+
if(msg.sender != _account){
138+
revert AccessControlUnauthorizedSender(msg.sender, _account);
139+
}
140+
bool _hasRole = s.hasRole[_account][_role];
141+
if (_hasRole) {
142+
s.hasRole[_account][_role] = false;
143+
emit RoleRevoked(_role, _account, msg.sender);
144+
}
145+
}
146+
147+
}

0 commit comments

Comments
 (0)