-
Notifications
You must be signed in to change notification settings - Fork 706
Expand file tree
/
Copy pathMultiRolesAuthority.sol
More file actions
123 lines (91 loc) · 4.68 KB
/
MultiRolesAuthority.sol
File metadata and controls
123 lines (91 loc) · 4.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Auth, Authority} from "../Auth.sol";
/// @notice Flexible and target agnostic role based Authority that supports up to 256 roles.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/authorities/MultiRolesAuthority.sol)
contract MultiRolesAuthority is Auth, Authority {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event UserRoleUpdated(address indexed user, uint8 indexed role, bool enabled);
event PublicCapabilityUpdated(bytes4 indexed functionSig, bool enabled);
event RoleCapabilityUpdated(uint8 indexed role, bytes4 indexed functionSig, bool enabled);
event TargetCustomAuthorityUpdated(address indexed target, Authority indexed authority);
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address _owner, Authority _authority) Auth(_owner, _authority) {}
/*//////////////////////////////////////////////////////////////
CUSTOM TARGET AUTHORITY STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => Authority) public getTargetCustomAuthority;
/*//////////////////////////////////////////////////////////////
ROLE/USER STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => bytes32) public getUserRoles;
mapping(bytes4 => bool) public isCapabilityPublic;
mapping(bytes4 => bytes32) public getRolesWithCapability;
function doesUserHaveRole(address user, uint8 role) public view virtual returns (bool) {
return (uint256(getUserRoles[user]) >> role) & 1 != 0;
}
function doesRoleHaveCapability(uint8 role, bytes4 functionSig) public view virtual returns (bool) {
return (uint256(getRolesWithCapability[functionSig]) >> role) & 1 != 0;
}
/*//////////////////////////////////////////////////////////////
AUTHORIZATION LOGIC
//////////////////////////////////////////////////////////////*/
function canCall(
address user,
address target,
bytes4 functionSig
) public view virtual override returns (bool) {
Authority customAuthority = getTargetCustomAuthority[target];
if (address(customAuthority) != address(0)) return customAuthority.canCall(user, target, functionSig);
return
isCapabilityPublic[functionSig] || bytes32(0) != getUserRoles[user] & getRolesWithCapability[functionSig];
}
/*///////////////////////////////////////////////////////////////
CUSTOM TARGET AUTHORITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setTargetCustomAuthority(address target, Authority customAuthority) public virtual requiresAuth {
getTargetCustomAuthority[target] = customAuthority;
emit TargetCustomAuthorityUpdated(target, customAuthority);
}
/*//////////////////////////////////////////////////////////////
PUBLIC CAPABILITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setPublicCapability(bytes4 functionSig, bool enabled) public virtual requiresAuth {
isCapabilityPublic[functionSig] = enabled;
emit PublicCapabilityUpdated(functionSig, enabled);
}
/*//////////////////////////////////////////////////////////////
USER ROLE ASSIGNMENT LOGIC
//////////////////////////////////////////////////////////////*/
function setUserRole(
address user,
uint8 role,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getUserRoles[user] |= bytes32(1 << role);
} else {
getUserRoles[user] &= ~bytes32(1 << role);
}
emit UserRoleUpdated(user, role, enabled);
}
/*//////////////////////////////////////////////////////////////
ROLE CAPABILITY CONFIGURATION LOGIC
//////////////////////////////////////////////////////////////*/
function setRoleCapability(
uint8 role,
bytes4 functionSig,
bool enabled
) public virtual requiresAuth {
if (enabled) {
getRolesWithCapability[functionSig] |= bytes32(1 << role);
} else {
getRolesWithCapability[functionSig] &= ~bytes32(1 << role);
}
emit RoleCapabilityUpdated(role, functionSig, enabled);
}
}