@bloxchain/contracts 1.0.0-alpha.2 → 1.0.0-alpha.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/abi/BaseStateMachine.abi.json +85 -45
- package/abi/EngineBlox.abi.json +73 -90
- package/abi/GuardController.abi.json +252 -806
- package/abi/{SimpleVaultDefinitions.abi.json → GuardControllerDefinitions.abi.json} +170 -28
- package/abi/IDefinition.abi.json +5 -0
- package/abi/RuntimeRBAC.abi.json +155 -218
- package/abi/RuntimeRBACDefinitions.abi.json +179 -0
- package/abi/SecureOwnable.abi.json +524 -1621
- package/abi/SecureOwnableDefinitions.abi.json +5 -0
- package/components/README.md +8 -0
- package/core/access/RuntimeRBAC.sol +255 -270
- package/core/access/interface/IRuntimeRBAC.sol +55 -84
- package/core/access/lib/definitions/RuntimeRBACDefinitions.sol +93 -2
- package/core/base/BaseStateMachine.sol +193 -107
- package/core/base/interface/IBaseStateMachine.sol +153 -153
- package/core/execution/GuardController.sol +155 -131
- package/core/execution/interface/IGuardController.sol +146 -120
- package/core/execution/lib/definitions/GuardControllerDefinitions.sol +193 -43
- package/core/lib/EngineBlox.sol +2683 -2322
- package/{interfaces → core/lib/interfaces}/IDefinition.sol +49 -49
- package/{interfaces → core/lib/interfaces}/IEventForwarder.sol +33 -33
- package/{utils → core/lib/utils}/SharedValidation.sol +61 -8
- package/core/pattern/Account.sol +84 -0
- package/core/security/SecureOwnable.sol +456 -412
- package/core/security/interface/ISecureOwnable.sol +105 -104
- package/core/security/lib/definitions/SecureOwnableDefinitions.sol +22 -6
- package/package.json +5 -5
- package/standards/README.md +12 -0
- package/standards/behavior/ICopyable.sol +34 -0
- package/standards/hooks/IOnActionHook.sol +21 -0
- package/abi/AccountBlox.abi.json +0 -5799
- package/abi/BareBlox.abi.json +0 -1284
- package/abi/RoleBlox.abi.json +0 -4209
- package/abi/SecureBlox.abi.json +0 -3828
- package/abi/SimpleRWA20.abi.json +0 -5288
- package/abi/SimpleRWA20Definitions.abi.json +0 -191
- package/abi/SimpleVault.abi.json +0 -4951
- package/core/research/BloxchainWallet.sol +0 -306
- package/core/research/erc20-blox/ERC20Blox.sol +0 -140
- package/core/research/erc20-blox/lib/definitions/ERC20BloxDefinitions.sol +0 -185
- package/interfaces/IOnActionHook.sol +0 -79
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Bloxchain Components
|
|
2
|
+
|
|
3
|
+
Official **components** built on top of `core/` that form a component library for building applications. These are maintained by the protocol team and sit outside the minimal engine.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Structure
|
|
7
|
+
|
|
8
|
+
Subfolders will be added by domain as components are added.
|
|
@@ -1,270 +1,255 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
-
pragma solidity 0.8.
|
|
3
|
-
|
|
4
|
-
// Contract imports
|
|
5
|
-
import "../base/BaseStateMachine.sol";
|
|
6
|
-
import "../lib/EngineBlox.sol";
|
|
7
|
-
import "
|
|
8
|
-
import "./lib/definitions/RuntimeRBACDefinitions.sol";
|
|
9
|
-
import "
|
|
10
|
-
import "./interface/IRuntimeRBAC.sol";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @title RuntimeRBAC
|
|
14
|
-
* @dev Minimal Runtime Role-Based Access Control system based on EngineBlox
|
|
15
|
-
*
|
|
16
|
-
* This contract provides essential runtime RBAC functionality:
|
|
17
|
-
* - Creation of non-protected roles
|
|
18
|
-
* - Basic wallet assignment to roles
|
|
19
|
-
* - Function permission management per role
|
|
20
|
-
* - Integration with EngineBlox for secure operations
|
|
21
|
-
*
|
|
22
|
-
* Key Features:
|
|
23
|
-
* - Only non-protected roles can be created dynamically
|
|
24
|
-
* - Protected roles (OWNER, BROADCASTER, RECOVERY) are managed by SecureOwnable
|
|
25
|
-
* - Minimal interface for core RBAC operations
|
|
26
|
-
* - Essential role management functions only
|
|
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
|
-
EngineBlox.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
* @
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
* @
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
//
|
|
257
|
-
// CRITICAL: The order matters - _loadDefinitions loads schemas FIRST, then permissions
|
|
258
|
-
// In _createNewRole, we assume schemas are already registered (from initialize)
|
|
259
|
-
// If schemas aren't registered, addFunctionToRole will revert with ResourceNotFound
|
|
260
|
-
for (uint256 i = 0; i < functionPermissions.length; i++) {
|
|
261
|
-
// Add function permission to role
|
|
262
|
-
// addFunctionToRole will check:
|
|
263
|
-
// 1. Role exists in supportedRolesSet (✅ just created)
|
|
264
|
-
// 2. Function selector exists in supportedFunctionsSet (must be registered during initialize)
|
|
265
|
-
// 3. Actions are supported by function schema (via _validateMetaTxPermissions)
|
|
266
|
-
_addFunctionToRole(roleHash, functionPermissions[i]);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
}
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
pragma solidity 0.8.34;
|
|
3
|
+
|
|
4
|
+
// Contract imports
|
|
5
|
+
import "../base/BaseStateMachine.sol";
|
|
6
|
+
import "../lib/EngineBlox.sol";
|
|
7
|
+
import "../lib/utils/SharedValidation.sol";
|
|
8
|
+
import "./lib/definitions/RuntimeRBACDefinitions.sol";
|
|
9
|
+
import "../lib/interfaces/IDefinition.sol";
|
|
10
|
+
import "./interface/IRuntimeRBAC.sol";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @title RuntimeRBAC
|
|
14
|
+
* @dev Minimal Runtime Role-Based Access Control system based on EngineBlox
|
|
15
|
+
*
|
|
16
|
+
* This contract provides essential runtime RBAC functionality:
|
|
17
|
+
* - Creation of non-protected roles
|
|
18
|
+
* - Basic wallet assignment to roles
|
|
19
|
+
* - Function permission management per role
|
|
20
|
+
* - Integration with EngineBlox for secure operations
|
|
21
|
+
*
|
|
22
|
+
* Key Features:
|
|
23
|
+
* - Only non-protected roles can be created dynamically
|
|
24
|
+
* - Protected roles (OWNER, BROADCASTER, RECOVERY) are managed by SecureOwnable
|
|
25
|
+
* - Minimal interface for core RBAC operations
|
|
26
|
+
* - Essential role management functions only
|
|
27
|
+
*
|
|
28
|
+
* @custom:security PROTECTED-ROLE POLICY (defense in layers):
|
|
29
|
+
* - RuntimeRBAC is **unauthorized** to modify protected roles (wallet add/revoke/remove).
|
|
30
|
+
* - For ADD_WALLET and REVOKE_WALLET we call _requireRoleNotProtected so batch ops cannot
|
|
31
|
+
* change who holds system roles. For REMOVE_ROLE we rely on EngineBlox.removeRole, which
|
|
32
|
+
* enforces the same policy at the library layer (cannot remove protected roles).
|
|
33
|
+
* - Function-permission updates on protected roles are intentionally supported for flexibility,
|
|
34
|
+
* but EngineBlox.removeFunctionFromRole still blocks removal of protected function schemas
|
|
35
|
+
* (isProtected == true). This prevents bricking core protected operations like ownership flow
|
|
36
|
+
* selectors while still allowing policy updates for non-protected selectors.
|
|
37
|
+
* - The **only** place to modify system wallets (protected roles) is the SecureOwnable
|
|
38
|
+
* security component (e.g. transferOwnershipRequest, broadcaster/recovery changes).
|
|
39
|
+
* - This layering is intentional: RBAC cannot touch protected roles; SecureOwnable is the
|
|
40
|
+
* single source of truth for system wallet changes.
|
|
41
|
+
*/
|
|
42
|
+
abstract contract RuntimeRBAC is BaseStateMachine, IRuntimeRBAC {
|
|
43
|
+
using EngineBlox for EngineBlox.SecureOperationState;
|
|
44
|
+
using SharedValidation for *;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @notice Initializer to initialize RuntimeRBAC
|
|
48
|
+
* @param initialOwner The initial owner address
|
|
49
|
+
* @param broadcaster The broadcaster address
|
|
50
|
+
* @param recovery The recovery address
|
|
51
|
+
* @param timeLockPeriodSec The timelock period in seconds
|
|
52
|
+
* @param eventForwarder The event forwarder address
|
|
53
|
+
*/
|
|
54
|
+
function initialize(
|
|
55
|
+
address initialOwner,
|
|
56
|
+
address broadcaster,
|
|
57
|
+
address recovery,
|
|
58
|
+
uint256 timeLockPeriodSec,
|
|
59
|
+
address eventForwarder
|
|
60
|
+
) public virtual onlyInitializing {
|
|
61
|
+
_initializeBaseStateMachine(initialOwner, broadcaster, recovery, timeLockPeriodSec, eventForwarder);
|
|
62
|
+
|
|
63
|
+
// Load RuntimeRBAC-specific definitions
|
|
64
|
+
IDefinition.RolePermission memory permissions = RuntimeRBACDefinitions.getRolePermissions();
|
|
65
|
+
_loadDefinitions(
|
|
66
|
+
RuntimeRBACDefinitions.getFunctionSchemas(),
|
|
67
|
+
permissions.roleHashes,
|
|
68
|
+
permissions.functionPermissions,
|
|
69
|
+
true // Enforce all function schemas are protected
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ============ INTERFACE SUPPORT ============
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @dev See {IERC165-supportsInterface}.
|
|
77
|
+
* @notice Adds IRuntimeRBAC interface ID for component detection
|
|
78
|
+
*/
|
|
79
|
+
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
|
|
80
|
+
return interfaceId == type(IRuntimeRBAC).interfaceId || super.supportsInterface(interfaceId);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ============ ROLE CONFIGURATION BATCH INTERFACE ============
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @dev Requests and approves a RBAC configuration batch using a meta-transaction
|
|
87
|
+
* @param metaTx The meta-transaction
|
|
88
|
+
* @return The transaction ID of the applied batch
|
|
89
|
+
* @notice OWNER signs, BROADCASTER executes according to RuntimeRBACDefinitions
|
|
90
|
+
*/
|
|
91
|
+
function roleConfigBatchRequestAndApprove(
|
|
92
|
+
EngineBlox.MetaTransaction memory metaTx
|
|
93
|
+
) public returns (uint256) {
|
|
94
|
+
_validateBroadcaster(msg.sender);
|
|
95
|
+
SharedValidation.validateEmptyPayment(
|
|
96
|
+
metaTx.txRecord.payment.recipient,
|
|
97
|
+
metaTx.txRecord.payment.nativeTokenAmount,
|
|
98
|
+
metaTx.txRecord.payment.erc20TokenAddress,
|
|
99
|
+
metaTx.txRecord.payment.erc20TokenAmount
|
|
100
|
+
);
|
|
101
|
+
EngineBlox.TxRecord memory txRecord = _requestAndApproveTransaction(metaTx);
|
|
102
|
+
return txRecord.txId;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @dev External function that can only be called by the contract itself to execute a RBAC configuration batch
|
|
107
|
+
* @param actions Encoded role configuration actions
|
|
108
|
+
*
|
|
109
|
+
* ## Role config batch ordering (required to avoid revert and gas waste)
|
|
110
|
+
*
|
|
111
|
+
* Actions must be ordered so that dependencies are satisfied:
|
|
112
|
+
* - **CREATE_ROLE** must appear before **ADD_WALLET** or **ADD_FUNCTION_TO_ROLE** for the same role; otherwise the role does not exist and the add will revert.
|
|
113
|
+
* - **REMOVE_ROLE** should be used only for an existing role; use **REVOKE_WALLET** first if the role has assigned wallets (optional but recommended for clarity).
|
|
114
|
+
* - For a given role, typical order: CREATE_ROLE → ADD_WALLET / ADD_FUNCTION_TO_ROLE as needed; to remove: REVOKE_WALLET (and REMOVE_FUNCTION_FROM_ROLE) as needed → REMOVE_ROLE.
|
|
115
|
+
*/
|
|
116
|
+
function executeRoleConfigBatch(IRuntimeRBAC.RoleConfigAction[] calldata actions) external {
|
|
117
|
+
_validateExecuteBySelf();
|
|
118
|
+
_executeRoleConfigBatch(actions);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ============ HELPER FUNCTIONS ============
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* @dev Reverts if the role is protected (prevents editing OWNER, BROADCASTER, RECOVERY via batch).
|
|
125
|
+
* Used for ADD_WALLET and REVOKE_WALLET so RuntimeRBAC cannot change who holds system roles.
|
|
126
|
+
* REMOVE_ROLE is not checked here; EngineBlox.removeRole enforces protected-role policy at
|
|
127
|
+
* the library layer. See contract-level @custom:security PROTECTED-ROLE POLICY.
|
|
128
|
+
* @param roleHash The role hash to check
|
|
129
|
+
*/
|
|
130
|
+
function _requireRoleNotProtected(bytes32 roleHash) internal view {
|
|
131
|
+
if (_getSecureState().roles[roleHash].isProtected) {
|
|
132
|
+
revert SharedValidation.CannotModifyProtected(roleHash);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @dev Internal helper to execute a RBAC configuration batch
|
|
138
|
+
* @param actions Encoded role configuration actions
|
|
139
|
+
*
|
|
140
|
+
* @custom:order Required ordering to avoid revert and gas waste:
|
|
141
|
+
* 1. CREATE_ROLE before any ADD_WALLET or ADD_FUNCTION_TO_ROLE for that role.
|
|
142
|
+
* 2. REMOVE_ROLE only for a role that exists; prefer REVOKE_WALLET (and REMOVE_FUNCTION_FROM_ROLE) before REMOVE_ROLE when the role has members.
|
|
143
|
+
*/
|
|
144
|
+
function _executeRoleConfigBatch(IRuntimeRBAC.RoleConfigAction[] calldata actions) internal {
|
|
145
|
+
_validateBatchSize(actions.length);
|
|
146
|
+
|
|
147
|
+
for (uint256 i = 0; i < actions.length; ++i) {
|
|
148
|
+
IRuntimeRBAC.RoleConfigAction calldata action = actions[i];
|
|
149
|
+
|
|
150
|
+
if (action.actionType == IRuntimeRBAC.RoleConfigActionType.CREATE_ROLE) {
|
|
151
|
+
_executeCreateRole(action.data);
|
|
152
|
+
} else if (action.actionType == IRuntimeRBAC.RoleConfigActionType.REMOVE_ROLE) {
|
|
153
|
+
_executeRemoveRole(action.data);
|
|
154
|
+
} else if (action.actionType == IRuntimeRBAC.RoleConfigActionType.ADD_WALLET) {
|
|
155
|
+
_executeAddWallet(action.data);
|
|
156
|
+
} else if (action.actionType == IRuntimeRBAC.RoleConfigActionType.REVOKE_WALLET) {
|
|
157
|
+
_executeRevokeWallet(action.data);
|
|
158
|
+
} else if (action.actionType == IRuntimeRBAC.RoleConfigActionType.ADD_FUNCTION_TO_ROLE) {
|
|
159
|
+
_executeAddFunctionToRole(action.data);
|
|
160
|
+
} else if (action.actionType == IRuntimeRBAC.RoleConfigActionType.REMOVE_FUNCTION_FROM_ROLE) {
|
|
161
|
+
_executeRemoveFunctionFromRole(action.data);
|
|
162
|
+
} else {
|
|
163
|
+
revert SharedValidation.NotSupported();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @dev Executes CREATE_ROLE: creates a new non-protected role
|
|
170
|
+
* @param data ABI-encoded (string roleName, uint256 maxWallets)
|
|
171
|
+
*/
|
|
172
|
+
function _executeCreateRole(bytes calldata data) internal {
|
|
173
|
+
(string memory roleName, uint256 maxWallets) = abi.decode(data, (string, uint256));
|
|
174
|
+
bytes32 roleHash = _createRole(roleName, maxWallets, false);
|
|
175
|
+
_logRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType.CREATE_ROLE, roleHash, bytes4(0), address(0));
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @dev Executes REMOVE_ROLE: removes a role by hash.
|
|
180
|
+
* Protected-role check is enforced in EngineBlox.removeRole (library layer); RuntimeRBAC
|
|
181
|
+
* does not duplicate it here. SecureOwnable is the only component authorized to change
|
|
182
|
+
* system wallets; RBAC is unauthorized to modify protected roles. See @custom:security
|
|
183
|
+
* PROTECTED-ROLE POLICY on the contract.
|
|
184
|
+
* @param data ABI-encoded (bytes32 roleHash)
|
|
185
|
+
*/
|
|
186
|
+
function _executeRemoveRole(bytes calldata data) internal {
|
|
187
|
+
(bytes32 roleHash) = abi.decode(data, (bytes32));
|
|
188
|
+
_removeRole(roleHash);
|
|
189
|
+
_logRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType.REMOVE_ROLE, roleHash, bytes4(0), address(0));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* @dev Executes ADD_WALLET: assigns a wallet to a role (role must not be protected)
|
|
194
|
+
* @param data ABI-encoded (bytes32 roleHash, address wallet)
|
|
195
|
+
*/
|
|
196
|
+
function _executeAddWallet(bytes calldata data) internal {
|
|
197
|
+
(bytes32 roleHash, address wallet) = abi.decode(data, (bytes32, address));
|
|
198
|
+
_requireRoleNotProtected(roleHash);
|
|
199
|
+
_assignWallet(roleHash, wallet);
|
|
200
|
+
_logRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType.ADD_WALLET, roleHash, bytes4(0), wallet);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @dev Executes REVOKE_WALLET: revokes a wallet from a role (role must not be protected)
|
|
205
|
+
* @param data ABI-encoded (bytes32 roleHash, address wallet)
|
|
206
|
+
*/
|
|
207
|
+
function _executeRevokeWallet(bytes calldata data) internal {
|
|
208
|
+
(bytes32 roleHash, address wallet) = abi.decode(data, (bytes32, address));
|
|
209
|
+
_requireRoleNotProtected(roleHash);
|
|
210
|
+
_revokeWallet(roleHash, wallet);
|
|
211
|
+
_logRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType.REVOKE_WALLET, roleHash, bytes4(0), wallet);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @dev Executes ADD_FUNCTION_TO_ROLE: adds a function permission to a role.
|
|
216
|
+
* @param data ABI-encoded (bytes32 roleHash, FunctionPermission functionPermission)
|
|
217
|
+
* @custom:security By design we allow adding function permissions to protected roles (OWNER, BROADCASTER, RECOVERY)
|
|
218
|
+
* to retain flexibility to grant new function permissions to system roles; only wallet add/revoke
|
|
219
|
+
* are restricted on protected roles.
|
|
220
|
+
*/
|
|
221
|
+
function _executeAddFunctionToRole(bytes calldata data) internal {
|
|
222
|
+
(
|
|
223
|
+
bytes32 roleHash,
|
|
224
|
+
EngineBlox.FunctionPermission memory functionPermission
|
|
225
|
+
) = abi.decode(data, (bytes32, EngineBlox.FunctionPermission));
|
|
226
|
+
_addFunctionToRole(roleHash, functionPermission);
|
|
227
|
+
_logRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType.ADD_FUNCTION_TO_ROLE, roleHash, functionPermission.functionSelector, address(0));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @dev Executes REMOVE_FUNCTION_FROM_ROLE: removes a function permission from a role.
|
|
232
|
+
* @param data ABI-encoded (bytes32 roleHash, bytes4 functionSelector)
|
|
233
|
+
* @custom:security By design we allow removing function permissions from protected roles (OWNER, BROADCASTER, RECOVERY)
|
|
234
|
+
* to retain flexibility to adjust which functions system roles can call; only wallet add/revoke
|
|
235
|
+
* are restricted on protected roles. EngineBlox.removeFunctionFromRole still blocks
|
|
236
|
+
* removing protected function schemas (isProtected == true), so critical protected
|
|
237
|
+
* selectors cannot be stripped from roles.
|
|
238
|
+
*/
|
|
239
|
+
function _executeRemoveFunctionFromRole(bytes calldata data) internal {
|
|
240
|
+
(bytes32 roleHash, bytes4 functionSelector) = abi.decode(data, (bytes32, bytes4));
|
|
241
|
+
_removeFunctionFromRole(roleHash, functionSelector);
|
|
242
|
+
_logRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType.REMOVE_FUNCTION_FROM_ROLE, roleHash, functionSelector, address(0));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* @dev Encodes and logs a role config event via ComponentEvent. Payload decodes as (RoleConfigActionType, bytes32 roleHash, bytes4 functionSelector, address wallet).
|
|
247
|
+
* @param action The role config action type
|
|
248
|
+
* @param roleHash The role hash
|
|
249
|
+
* @param selector The function selector (or zero for N/A)
|
|
250
|
+
* @param wallet The wallet address (or zero for actions that do not apply to a wallet)
|
|
251
|
+
*/
|
|
252
|
+
function _logRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType action, bytes32 roleHash, bytes4 selector, address wallet) internal {
|
|
253
|
+
_logComponentEvent(abi.encode(action, roleHash, selector, wallet));
|
|
254
|
+
}
|
|
255
|
+
}
|