@bloxchain/contracts 1.0.0-alpha

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.
Files changed (34) hide show
  1. package/README.md +49 -0
  2. package/abi/BareBlox.abi.json +1341 -0
  3. package/abi/BaseStateMachine.abi.json +1308 -0
  4. package/abi/ControlBlox.abi.json +6210 -0
  5. package/abi/EngineBlox.abi.json +872 -0
  6. package/abi/GuardController.abi.json +3045 -0
  7. package/abi/IDefinition.abi.json +94 -0
  8. package/abi/RoleBlox.abi.json +4569 -0
  9. package/abi/RuntimeRBAC.abi.json +1857 -0
  10. package/abi/RuntimeRBACDefinitions.abi.json +133 -0
  11. package/abi/SecureBlox.abi.json +4085 -0
  12. package/abi/SecureOwnable.abi.json +4085 -0
  13. package/abi/SecureOwnableDefinitions.abi.json +354 -0
  14. package/abi/SimpleRWA20.abi.json +5545 -0
  15. package/abi/SimpleRWA20Definitions.abi.json +172 -0
  16. package/abi/SimpleVault.abi.json +5208 -0
  17. package/abi/SimpleVaultDefinitions.abi.json +250 -0
  18. package/contracts/core/access/RuntimeRBAC.sol +344 -0
  19. package/contracts/core/access/interface/IRuntimeRBAC.sol +108 -0
  20. package/contracts/core/access/lib/definitions/RuntimeRBACDefinitions.sol +168 -0
  21. package/contracts/core/base/BaseStateMachine.sol +834 -0
  22. package/contracts/core/base/interface/IBaseStateMachine.sol +153 -0
  23. package/contracts/core/execution/GuardController.sol +507 -0
  24. package/contracts/core/execution/interface/IGuardController.sol +120 -0
  25. package/contracts/core/execution/lib/definitions/GuardControllerDefinitions.sol +401 -0
  26. package/contracts/core/lib/EngineBlox.sol +2283 -0
  27. package/contracts/core/security/SecureOwnable.sol +419 -0
  28. package/contracts/core/security/interface/ISecureOwnable.sol +118 -0
  29. package/contracts/core/security/lib/definitions/SecureOwnableDefinitions.sol +757 -0
  30. package/contracts/interfaces/IDefinition.sol +40 -0
  31. package/contracts/interfaces/IEventForwarder.sol +33 -0
  32. package/contracts/interfaces/IOnActionHook.sol +79 -0
  33. package/contracts/utils/SharedValidation.sol +486 -0
  34. package/package.json +47 -0
@@ -0,0 +1,757 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ pragma solidity 0.8.33;
3
+
4
+ import "../../../lib/EngineBlox.sol";
5
+ import "../../../../interfaces/IDefinition.sol";
6
+
7
+ /**
8
+ * @title SecureOwnableDefinitions
9
+ * @dev Library containing predefined definitions for SecureOwnable initialization
10
+ * This library holds static data that can be used to initialize SecureOwnable contracts
11
+ * without increasing the main contract size
12
+ *
13
+ * This library implements the IDefinition interface from EngineBlox
14
+ * and provides a direct initialization function for SecureOwnable contracts
15
+ *
16
+ * Permission Model:
17
+ * - Handler Functions (triggering functions): Permissions checked via msg.sig in BaseStateMachine
18
+ * - Time-delay handler functions: Checked with EXECUTE_TIME_DELAY_* actions
19
+ * - Meta-transaction handler functions: Checked with EXECUTE_META_* actions
20
+ * - Execution Functions (target functions): Permissions checked in EngineBlox library
21
+ * - For time-delay: EXECUTE_TIME_DELAY_APPROVE/CANCEL actions
22
+ * - For meta-transactions: EXECUTE_META_* and SIGN_META_* actions (both handler and execution)
23
+ */
24
+ library SecureOwnableDefinitions {
25
+
26
+ // Operation Type Constants
27
+ bytes32 public constant OWNERSHIP_TRANSFER = keccak256("OWNERSHIP_TRANSFER");
28
+ bytes32 public constant BROADCASTER_UPDATE = keccak256("BROADCASTER_UPDATE");
29
+ bytes32 public constant RECOVERY_UPDATE = keccak256("RECOVERY_UPDATE");
30
+ bytes32 public constant TIMELOCK_UPDATE = keccak256("TIMELOCK_UPDATE");
31
+
32
+ // Function Selector Constants
33
+ bytes4 public constant TRANSFER_OWNERSHIP_SELECTOR = bytes4(keccak256("executeTransferOwnership(address)"));
34
+ bytes4 public constant UPDATE_BROADCASTER_SELECTOR = bytes4(keccak256("executeBroadcasterUpdate(address)"));
35
+ bytes4 public constant UPDATE_RECOVERY_SELECTOR = bytes4(keccak256("executeRecoveryUpdate(address)"));
36
+ bytes4 public constant UPDATE_TIMELOCK_SELECTOR = bytes4(keccak256("executeTimeLockUpdate(uint256)"));
37
+
38
+ // Time Delay Function Selectors (Handler Functions - checked via msg.sig)
39
+ bytes4 public constant TRANSFER_OWNERSHIP_REQUEST_SELECTOR = bytes4(keccak256("transferOwnershipRequest()"));
40
+ bytes4 public constant TRANSFER_OWNERSHIP_DELAYED_APPROVAL_SELECTOR = bytes4(keccak256("transferOwnershipDelayedApproval(uint256)"));
41
+ bytes4 public constant TRANSFER_OWNERSHIP_CANCELLATION_SELECTOR = bytes4(keccak256("transferOwnershipCancellation(uint256)"));
42
+ bytes4 public constant UPDATE_BROADCASTER_REQUEST_SELECTOR = bytes4(keccak256("updateBroadcasterRequest(address)"));
43
+ bytes4 public constant UPDATE_BROADCASTER_DELAYED_APPROVAL_SELECTOR = bytes4(keccak256("updateBroadcasterDelayedApproval(uint256)"));
44
+ bytes4 public constant UPDATE_BROADCASTER_CANCELLATION_SELECTOR = bytes4(keccak256("updateBroadcasterCancellation(uint256)"));
45
+
46
+ // Meta-transaction Function Selectors (Handler Functions - checked via msg.sig)
47
+ // Note: Solidity function selector calculation for struct parameters uses 2 opening parentheses: ((tuple))
48
+ // Verified: This format produces selector 0x458102e4 which matches the actual function selector
49
+ bytes4 public constant TRANSFER_OWNERSHIP_APPROVE_META_SELECTOR = bytes4(keccak256("transferOwnershipApprovalWithMetaTx(((uint256,uint256,uint8,(address,address,uint256,uint256,bytes32,bytes4,bytes),bytes32,bytes,(address,uint256,address,uint256)),(uint256,uint256,address,bytes4,uint8,uint256,uint256,address),bytes32,bytes,bytes))"));
50
+ bytes4 public constant TRANSFER_OWNERSHIP_CANCEL_META_SELECTOR = bytes4(keccak256("transferOwnershipCancellationWithMetaTx(((uint256,uint256,uint8,(address,address,uint256,uint256,bytes32,bytes4,bytes),bytes32,bytes,(address,uint256,address,uint256)),(uint256,uint256,address,bytes4,uint8,uint256,uint256,address),bytes32,bytes,bytes))"));
51
+ bytes4 public constant UPDATE_BROADCASTER_APPROVE_META_SELECTOR = bytes4(keccak256("updateBroadcasterApprovalWithMetaTx(((uint256,uint256,uint8,(address,address,uint256,uint256,bytes32,bytes4,bytes),bytes32,bytes,(address,uint256,address,uint256)),(uint256,uint256,address,bytes4,uint8,uint256,uint256,address),bytes32,bytes,bytes))"));
52
+ bytes4 public constant UPDATE_BROADCASTER_CANCEL_META_SELECTOR = bytes4(keccak256("updateBroadcasterCancellationWithMetaTx(((uint256,uint256,uint8,(address,address,uint256,uint256,bytes32,bytes4,bytes),bytes32,bytes,(address,uint256,address,uint256)),(uint256,uint256,address,bytes4,uint8,uint256,uint256,address),bytes32,bytes,bytes))"));
53
+ bytes4 public constant UPDATE_RECOVERY_META_SELECTOR = bytes4(keccak256("updateRecoveryRequestAndApprove(((uint256,uint256,uint8,(address,address,uint256,uint256,bytes32,bytes4,bytes),bytes32,bytes,(address,uint256,address,uint256)),(uint256,uint256,address,bytes4,uint8,uint256,uint256,address),bytes32,bytes,bytes))"));
54
+ bytes4 public constant UPDATE_TIMELOCK_META_SELECTOR = bytes4(keccak256("updateTimeLockRequestAndApprove(((uint256,uint256,uint8,(address,address,uint256,uint256,bytes32,bytes4,bytes),bytes32,bytes,(address,uint256,address,uint256)),(uint256,uint256,address,bytes4,uint8,uint256,uint256,address),bytes32,bytes,bytes))"));
55
+
56
+ /**
57
+ * @dev Returns predefined function schemas
58
+ * @return Array of function schema definitions
59
+ */
60
+ function getFunctionSchemas() public pure returns (EngineBlox.FunctionSchema[] memory) {
61
+ EngineBlox.FunctionSchema[] memory schemas = new EngineBlox.FunctionSchema[](16);
62
+
63
+ // Meta-transaction function schemas
64
+ EngineBlox.TxAction[] memory metaApproveActions = new EngineBlox.TxAction[](2);
65
+ metaApproveActions[0] = EngineBlox.TxAction.EXECUTE_META_APPROVE;
66
+ metaApproveActions[1] = EngineBlox.TxAction.SIGN_META_APPROVE;
67
+
68
+ EngineBlox.TxAction[] memory metaCancelActions = new EngineBlox.TxAction[](2);
69
+ metaCancelActions[0] = EngineBlox.TxAction.EXECUTE_META_CANCEL;
70
+ metaCancelActions[1] = EngineBlox.TxAction.SIGN_META_CANCEL;
71
+
72
+ EngineBlox.TxAction[] memory metaRequestApproveActions = new EngineBlox.TxAction[](2);
73
+ metaRequestApproveActions[0] = EngineBlox.TxAction.SIGN_META_REQUEST_AND_APPROVE;
74
+ metaRequestApproveActions[1] = EngineBlox.TxAction.EXECUTE_META_REQUEST_AND_APPROVE;
75
+
76
+ // Time-delayed functions
77
+ EngineBlox.TxAction[] memory timeDelayRequestActions = new EngineBlox.TxAction[](1);
78
+ timeDelayRequestActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_REQUEST;
79
+
80
+ EngineBlox.TxAction[] memory timeDelayApproveActions = new EngineBlox.TxAction[](1);
81
+ timeDelayApproveActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_APPROVE;
82
+
83
+ EngineBlox.TxAction[] memory timeDelayCancelActions = new EngineBlox.TxAction[](1);
84
+ timeDelayCancelActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_CANCEL;
85
+
86
+ // Execution selector actions (for meta-transactions and time-delay)
87
+ // These execution selectors support both approve and cancel actions for both meta-tx and time-delay
88
+ // Also support request action for time-delay (needed for txRequest permission check)
89
+ EngineBlox.TxAction[] memory executionApproveCancelActions = new EngineBlox.TxAction[](7);
90
+ executionApproveCancelActions[0] = EngineBlox.TxAction.EXECUTE_META_APPROVE;
91
+ executionApproveCancelActions[1] = EngineBlox.TxAction.SIGN_META_APPROVE;
92
+ executionApproveCancelActions[2] = EngineBlox.TxAction.EXECUTE_META_CANCEL;
93
+ executionApproveCancelActions[3] = EngineBlox.TxAction.SIGN_META_CANCEL;
94
+ executionApproveCancelActions[4] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_REQUEST;
95
+ executionApproveCancelActions[5] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_APPROVE;
96
+ executionApproveCancelActions[6] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_CANCEL;
97
+
98
+ EngineBlox.TxAction[] memory executionMetaRequestApproveActions = new EngineBlox.TxAction[](2);
99
+ executionMetaRequestApproveActions[0] = EngineBlox.TxAction.SIGN_META_REQUEST_AND_APPROVE;
100
+ executionMetaRequestApproveActions[1] = EngineBlox.TxAction.EXECUTE_META_REQUEST_AND_APPROVE;
101
+
102
+ // Prepare handlerForSelectors arrays
103
+ // Execution selectors must have self-reference (at least one element pointing to themselves)
104
+ bytes4[] memory transferOwnershipExecutionHandlerForSelectors = new bytes4[](1);
105
+ transferOwnershipExecutionHandlerForSelectors[0] = TRANSFER_OWNERSHIP_SELECTOR;
106
+ bytes4[] memory broadcasterExecutionHandlerForSelectors = new bytes4[](1);
107
+ broadcasterExecutionHandlerForSelectors[0] = UPDATE_BROADCASTER_SELECTOR;
108
+ bytes4[] memory recoveryExecutionHandlerForSelectors = new bytes4[](1);
109
+ recoveryExecutionHandlerForSelectors[0] = UPDATE_RECOVERY_SELECTOR;
110
+ bytes4[] memory timelockExecutionHandlerForSelectors = new bytes4[](1);
111
+ timelockExecutionHandlerForSelectors[0] = UPDATE_TIMELOCK_SELECTOR;
112
+
113
+ // Handler selectors point to execution selectors
114
+ bytes4[] memory transferOwnershipHandlerForSelectors = new bytes4[](1);
115
+ transferOwnershipHandlerForSelectors[0] = TRANSFER_OWNERSHIP_SELECTOR;
116
+ bytes4[] memory broadcasterHandlerForSelectors = new bytes4[](1);
117
+ broadcasterHandlerForSelectors[0] = UPDATE_BROADCASTER_SELECTOR;
118
+ bytes4[] memory recoveryHandlerForSelectors = new bytes4[](1);
119
+ recoveryHandlerForSelectors[0] = UPDATE_RECOVERY_SELECTOR;
120
+ bytes4[] memory timelockHandlerForSelectors = new bytes4[](1);
121
+ timelockHandlerForSelectors[0] = UPDATE_TIMELOCK_SELECTOR;
122
+
123
+ // Meta-transaction functions
124
+ schemas[0] = EngineBlox.FunctionSchema({
125
+ functionSignature: "transferOwnershipApprovalWithMetaTx(((uint256,uint256,uint8,(address,address,uint256,uint256,bytes32,bytes4,bytes),bytes32,bytes,(address,uint256,address,uint256)),(uint256,uint256,address,bytes4,uint8,uint256,uint256,address),bytes32,bytes,bytes))",
126
+ functionSelector: TRANSFER_OWNERSHIP_APPROVE_META_SELECTOR,
127
+ operationType: OWNERSHIP_TRANSFER,
128
+ operationName: "OWNERSHIP_TRANSFER",
129
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(metaApproveActions),
130
+ isProtected: true,
131
+ handlerForSelectors: transferOwnershipHandlerForSelectors
132
+ });
133
+
134
+ schemas[1] = EngineBlox.FunctionSchema({
135
+ functionSignature: "transferOwnershipCancellationWithMetaTx(((uint256,uint256,uint8,(address,address,uint256,uint256,bytes32,bytes4,bytes),bytes32,bytes,(address,uint256,address,uint256)),(uint256,uint256,address,bytes4,uint8,uint256,uint256,address),bytes32,bytes,bytes))",
136
+ functionSelector: TRANSFER_OWNERSHIP_CANCEL_META_SELECTOR,
137
+ operationType: OWNERSHIP_TRANSFER,
138
+ operationName: "OWNERSHIP_TRANSFER",
139
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(metaCancelActions),
140
+ isProtected: true,
141
+ handlerForSelectors: transferOwnershipHandlerForSelectors
142
+ });
143
+
144
+ schemas[2] = EngineBlox.FunctionSchema({
145
+ functionSignature: "updateBroadcasterApprovalWithMetaTx(((uint256,uint256,uint8,(address,address,uint256,uint256,bytes32,bytes4,bytes),bytes32,bytes,(address,uint256,address,uint256)),(uint256,uint256,address,bytes4,uint8,uint256,uint256,address),bytes32,bytes,bytes))",
146
+ functionSelector: UPDATE_BROADCASTER_APPROVE_META_SELECTOR,
147
+ operationType: BROADCASTER_UPDATE,
148
+ operationName: "BROADCASTER_UPDATE",
149
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(metaApproveActions),
150
+ isProtected: true,
151
+ handlerForSelectors: broadcasterHandlerForSelectors
152
+ });
153
+
154
+ schemas[3] = EngineBlox.FunctionSchema({
155
+ functionSignature: "updateBroadcasterCancellationWithMetaTx(((uint256,uint256,uint8,(address,address,uint256,uint256,bytes32,bytes4,bytes),bytes32,bytes,(address,uint256,address,uint256)),(uint256,uint256,address,bytes4,uint8,uint256,uint256,address),bytes32,bytes,bytes))",
156
+ functionSelector: UPDATE_BROADCASTER_CANCEL_META_SELECTOR,
157
+ operationType: BROADCASTER_UPDATE,
158
+ operationName: "BROADCASTER_UPDATE",
159
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(metaCancelActions),
160
+ isProtected: true,
161
+ handlerForSelectors: broadcasterHandlerForSelectors
162
+ });
163
+
164
+ schemas[4] = EngineBlox.FunctionSchema({
165
+ functionSignature: "updateRecoveryRequestAndApprove(((uint256,uint256,uint8,(address,address,uint256,uint256,bytes32,bytes4,bytes),bytes32,bytes,(address,uint256,address,uint256)),(uint256,uint256,address,bytes4,uint8,uint256,uint256,address),bytes32,bytes,bytes))",
166
+ functionSelector: UPDATE_RECOVERY_META_SELECTOR,
167
+ operationType: RECOVERY_UPDATE,
168
+ operationName: "RECOVERY_UPDATE",
169
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(metaRequestApproveActions),
170
+ isProtected: true,
171
+ handlerForSelectors: recoveryHandlerForSelectors
172
+ });
173
+
174
+ schemas[5] = EngineBlox.FunctionSchema({
175
+ functionSignature: "updateTimeLockRequestAndApprove(((uint256,uint256,uint8,(address,address,uint256,uint256,bytes32,bytes4,bytes),bytes32,bytes,(address,uint256,address,uint256)),(uint256,uint256,address,bytes4,uint8,uint256,uint256,address),bytes32,bytes,bytes))",
176
+ functionSelector: UPDATE_TIMELOCK_META_SELECTOR,
177
+ operationType: TIMELOCK_UPDATE,
178
+ operationName: "TIMELOCK_UPDATE",
179
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(metaRequestApproveActions),
180
+ isProtected: true,
181
+ handlerForSelectors: timelockHandlerForSelectors
182
+ });
183
+
184
+ // Time-delayed functions
185
+ schemas[6] = EngineBlox.FunctionSchema({
186
+ functionSignature: "transferOwnershipRequest()",
187
+ functionSelector: TRANSFER_OWNERSHIP_REQUEST_SELECTOR,
188
+ operationType: OWNERSHIP_TRANSFER,
189
+ operationName: "OWNERSHIP_TRANSFER",
190
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(timeDelayRequestActions),
191
+ isProtected: true,
192
+ handlerForSelectors: transferOwnershipHandlerForSelectors
193
+ });
194
+
195
+ schemas[7] = EngineBlox.FunctionSchema({
196
+ functionSignature: "transferOwnershipDelayedApproval(uint256)",
197
+ functionSelector: TRANSFER_OWNERSHIP_DELAYED_APPROVAL_SELECTOR,
198
+ operationType: OWNERSHIP_TRANSFER,
199
+ operationName: "OWNERSHIP_TRANSFER",
200
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(timeDelayApproveActions),
201
+ isProtected: true,
202
+ handlerForSelectors: transferOwnershipHandlerForSelectors
203
+ });
204
+
205
+ schemas[8] = EngineBlox.FunctionSchema({
206
+ functionSignature: "transferOwnershipCancellation(uint256)",
207
+ functionSelector: TRANSFER_OWNERSHIP_CANCELLATION_SELECTOR,
208
+ operationType: OWNERSHIP_TRANSFER,
209
+ operationName: "OWNERSHIP_TRANSFER",
210
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(timeDelayCancelActions),
211
+ isProtected: true,
212
+ handlerForSelectors: transferOwnershipHandlerForSelectors
213
+ });
214
+
215
+ schemas[9] = EngineBlox.FunctionSchema({
216
+ functionSignature: "updateBroadcasterRequest(address)",
217
+ functionSelector: UPDATE_BROADCASTER_REQUEST_SELECTOR,
218
+ operationType: BROADCASTER_UPDATE,
219
+ operationName: "BROADCASTER_UPDATE",
220
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(timeDelayRequestActions),
221
+ isProtected: true,
222
+ handlerForSelectors: broadcasterHandlerForSelectors
223
+ });
224
+
225
+ schemas[10] = EngineBlox.FunctionSchema({
226
+ functionSignature: "updateBroadcasterDelayedApproval(uint256)",
227
+ functionSelector: UPDATE_BROADCASTER_DELAYED_APPROVAL_SELECTOR,
228
+ operationType: BROADCASTER_UPDATE,
229
+ operationName: "BROADCASTER_UPDATE",
230
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(timeDelayApproveActions),
231
+ isProtected: true,
232
+ handlerForSelectors: broadcasterHandlerForSelectors
233
+ });
234
+
235
+ schemas[11] = EngineBlox.FunctionSchema({
236
+ functionSignature: "updateBroadcasterCancellation(uint256)",
237
+ functionSelector: UPDATE_BROADCASTER_CANCELLATION_SELECTOR,
238
+ operationType: BROADCASTER_UPDATE,
239
+ operationName: "BROADCASTER_UPDATE",
240
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(timeDelayCancelActions),
241
+ isProtected: true,
242
+ handlerForSelectors: broadcasterHandlerForSelectors
243
+ });
244
+
245
+ // Execution selector schemas (required for meta-transaction dual-permission model)
246
+ // Execution selectors must have self-reference in handlerForSelectors array
247
+ schemas[12] = EngineBlox.FunctionSchema({
248
+ functionSignature: "executeTransferOwnership(address)",
249
+ functionSelector: TRANSFER_OWNERSHIP_SELECTOR,
250
+ operationType: OWNERSHIP_TRANSFER,
251
+ operationName: "OWNERSHIP_TRANSFER",
252
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(executionApproveCancelActions),
253
+ isProtected: true,
254
+ handlerForSelectors: transferOwnershipExecutionHandlerForSelectors
255
+ });
256
+
257
+ schemas[13] = EngineBlox.FunctionSchema({
258
+ functionSignature: "executeBroadcasterUpdate(address)",
259
+ functionSelector: UPDATE_BROADCASTER_SELECTOR,
260
+ operationType: BROADCASTER_UPDATE,
261
+ operationName: "BROADCASTER_UPDATE",
262
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(executionApproveCancelActions),
263
+ isProtected: true,
264
+ handlerForSelectors: broadcasterExecutionHandlerForSelectors
265
+ });
266
+
267
+ schemas[14] = EngineBlox.FunctionSchema({
268
+ functionSignature: "executeRecoveryUpdate(address)",
269
+ functionSelector: UPDATE_RECOVERY_SELECTOR,
270
+ operationType: RECOVERY_UPDATE,
271
+ operationName: "RECOVERY_UPDATE",
272
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(executionMetaRequestApproveActions),
273
+ isProtected: true,
274
+ handlerForSelectors: recoveryExecutionHandlerForSelectors
275
+ });
276
+
277
+ schemas[15] = EngineBlox.FunctionSchema({
278
+ functionSignature: "executeTimeLockUpdate(uint256)",
279
+ functionSelector: UPDATE_TIMELOCK_SELECTOR,
280
+ operationType: TIMELOCK_UPDATE,
281
+ operationName: "TIMELOCK_UPDATE",
282
+ supportedActionsBitmap: EngineBlox.createBitmapFromActions(executionMetaRequestApproveActions),
283
+ isProtected: true,
284
+ handlerForSelectors: timelockExecutionHandlerForSelectors
285
+ });
286
+
287
+ return schemas;
288
+ }
289
+
290
+ /**
291
+ * @dev Returns predefined role hashes and their corresponding function permissions
292
+ * @return RolePermission struct containing roleHashes and functionPermissions arrays
293
+ */
294
+ function getRolePermissions() public pure returns (IDefinition.RolePermission memory) {
295
+ // Calculate total permissions needed
296
+ // Broadcaster: 6 handler (meta-tx) + 4 execution = 10
297
+ // Owner: 4 handler (time-delay) + 6 handler (meta-tx) + 4 execution = 14
298
+ // Recovery: 3 handler (time-delay) + 1 execution = 4
299
+ // Total: 28 permissions
300
+ bytes32[] memory roleHashes = new bytes32[](28);
301
+ EngineBlox.FunctionPermission[] memory functionPermissions = new EngineBlox.FunctionPermission[](28);
302
+
303
+ uint256 index = 0;
304
+
305
+ // ============ BROADCASTER ROLE PERMISSIONS ============
306
+ index = _addBroadcasterPermissions(roleHashes, functionPermissions, index);
307
+
308
+ // ============ OWNER ROLE PERMISSIONS ============
309
+ index = _addOwnerPermissions(roleHashes, functionPermissions, index);
310
+
311
+ // ============ RECOVERY ROLE PERMISSIONS ============
312
+ index = _addRecoveryPermissions(roleHashes, functionPermissions, index);
313
+
314
+ return IDefinition.RolePermission({
315
+ roleHashes: roleHashes,
316
+ functionPermissions: functionPermissions
317
+ });
318
+ }
319
+
320
+ // ============ INTERNAL HELPER FUNCTIONS ============
321
+
322
+ /**
323
+ * @dev Adds broadcaster role permissions
324
+ * @param roleHashes Array to populate with role hashes
325
+ * @param functionPermissions Array to populate with function permissions
326
+ * @param startIndex Starting index in arrays
327
+ * @return Next available index after adding permissions
328
+ */
329
+ function _addBroadcasterPermissions(
330
+ bytes32[] memory roleHashes,
331
+ EngineBlox.FunctionPermission[] memory functionPermissions,
332
+ uint256 startIndex
333
+ ) internal pure returns (uint256) {
334
+ uint256 index = startIndex;
335
+
336
+ // Action arrays for broadcaster
337
+ EngineBlox.TxAction[] memory broadcasterMetaApproveActions = new EngineBlox.TxAction[](1);
338
+ broadcasterMetaApproveActions[0] = EngineBlox.TxAction.EXECUTE_META_APPROVE;
339
+
340
+ EngineBlox.TxAction[] memory broadcasterMetaCancelActions = new EngineBlox.TxAction[](1);
341
+ broadcasterMetaCancelActions[0] = EngineBlox.TxAction.EXECUTE_META_CANCEL;
342
+
343
+ EngineBlox.TxAction[] memory broadcasterMetaRequestApproveActions = new EngineBlox.TxAction[](1);
344
+ broadcasterMetaRequestApproveActions[0] = EngineBlox.TxAction.EXECUTE_META_REQUEST_AND_APPROVE;
345
+
346
+ EngineBlox.TxAction[] memory broadcasterExecutionApproveCancelActions = new EngineBlox.TxAction[](2);
347
+ broadcasterExecutionApproveCancelActions[0] = EngineBlox.TxAction.EXECUTE_META_APPROVE;
348
+ broadcasterExecutionApproveCancelActions[1] = EngineBlox.TxAction.EXECUTE_META_CANCEL;
349
+
350
+ EngineBlox.TxAction[] memory broadcasterExecutionRequestApproveActions = new EngineBlox.TxAction[](1);
351
+ broadcasterExecutionRequestApproveActions[0] = EngineBlox.TxAction.EXECUTE_META_REQUEST_AND_APPROVE;
352
+
353
+ // ============ BROADCASTER: HANDLER FUNCTION PERMISSIONS (Meta-transactions) ============
354
+ // These are checked via msg.sig in BaseStateMachine._validateCallingFunctionPermission
355
+
356
+ // Create reusable handlerForSelectors arrays
357
+ bytes4[] memory transferOwnershipHandlers = new bytes4[](1);
358
+ transferOwnershipHandlers[0] = TRANSFER_OWNERSHIP_SELECTOR;
359
+ bytes4[] memory updateBroadcasterHandlers = new bytes4[](1);
360
+ updateBroadcasterHandlers[0] = UPDATE_BROADCASTER_SELECTOR;
361
+ bytes4[] memory updateRecoveryHandlers = new bytes4[](1);
362
+ updateRecoveryHandlers[0] = UPDATE_RECOVERY_SELECTOR;
363
+ bytes4[] memory updateTimelockHandlers = new bytes4[](1);
364
+ updateTimelockHandlers[0] = UPDATE_TIMELOCK_SELECTOR;
365
+
366
+ // Transfer Ownership Approve Meta (handler function)
367
+ roleHashes[index] = EngineBlox.BROADCASTER_ROLE;
368
+ functionPermissions[index] = EngineBlox.FunctionPermission({
369
+ functionSelector: TRANSFER_OWNERSHIP_APPROVE_META_SELECTOR,
370
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(broadcasterMetaApproveActions),
371
+ handlerForSelectors: transferOwnershipHandlers
372
+ });
373
+ index++;
374
+
375
+ // Transfer Ownership Cancel Meta (handler function)
376
+ roleHashes[index] = EngineBlox.BROADCASTER_ROLE;
377
+ functionPermissions[index] = EngineBlox.FunctionPermission({
378
+ functionSelector: TRANSFER_OWNERSHIP_CANCEL_META_SELECTOR,
379
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(broadcasterMetaCancelActions),
380
+ handlerForSelectors: transferOwnershipHandlers
381
+ });
382
+ index++;
383
+
384
+ // Update Broadcaster Approve Meta (handler function)
385
+ roleHashes[index] = EngineBlox.BROADCASTER_ROLE;
386
+ functionPermissions[index] = EngineBlox.FunctionPermission({
387
+ functionSelector: UPDATE_BROADCASTER_APPROVE_META_SELECTOR,
388
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(broadcasterMetaApproveActions),
389
+ handlerForSelectors: updateBroadcasterHandlers
390
+ });
391
+ index++;
392
+
393
+ // Update Broadcaster Cancel Meta (handler function)
394
+ roleHashes[index] = EngineBlox.BROADCASTER_ROLE;
395
+ functionPermissions[index] = EngineBlox.FunctionPermission({
396
+ functionSelector: UPDATE_BROADCASTER_CANCEL_META_SELECTOR,
397
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(broadcasterMetaCancelActions),
398
+ handlerForSelectors: updateBroadcasterHandlers
399
+ });
400
+ index++;
401
+
402
+ // Update Recovery Meta (handler function)
403
+ roleHashes[index] = EngineBlox.BROADCASTER_ROLE;
404
+ functionPermissions[index] = EngineBlox.FunctionPermission({
405
+ functionSelector: UPDATE_RECOVERY_META_SELECTOR,
406
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(broadcasterMetaRequestApproveActions),
407
+ handlerForSelectors: updateRecoveryHandlers
408
+ });
409
+ index++;
410
+
411
+ // Update Timelock Meta (handler function)
412
+ roleHashes[index] = EngineBlox.BROADCASTER_ROLE;
413
+ functionPermissions[index] = EngineBlox.FunctionPermission({
414
+ functionSelector: UPDATE_TIMELOCK_META_SELECTOR,
415
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(broadcasterMetaRequestApproveActions),
416
+ handlerForSelectors: updateTimelockHandlers
417
+ });
418
+ index++;
419
+
420
+ // ============ BROADCASTER: EXECUTION FUNCTION PERMISSIONS ============
421
+ // These are checked in EngineBlox library functions
422
+
423
+ // Transfer Ownership Execution (for approve/cancel meta-tx)
424
+ roleHashes[index] = EngineBlox.BROADCASTER_ROLE;
425
+ functionPermissions[index] = EngineBlox.FunctionPermission({
426
+ functionSelector: TRANSFER_OWNERSHIP_SELECTOR,
427
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(broadcasterExecutionApproveCancelActions),
428
+ handlerForSelectors: transferOwnershipHandlers // Self-reference indicates execution selector
429
+ });
430
+ index++;
431
+
432
+ // Update Broadcaster Execution (for approve/cancel meta-tx)
433
+ roleHashes[index] = EngineBlox.BROADCASTER_ROLE;
434
+ functionPermissions[index] = EngineBlox.FunctionPermission({
435
+ functionSelector: UPDATE_BROADCASTER_SELECTOR,
436
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(broadcasterExecutionApproveCancelActions),
437
+ handlerForSelectors: updateBroadcasterHandlers // Self-reference indicates execution selector
438
+ });
439
+ index++;
440
+
441
+ // Update Recovery Execution (for request and approve meta-tx)
442
+ roleHashes[index] = EngineBlox.BROADCASTER_ROLE;
443
+ functionPermissions[index] = EngineBlox.FunctionPermission({
444
+ functionSelector: UPDATE_RECOVERY_SELECTOR,
445
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(broadcasterExecutionRequestApproveActions),
446
+ handlerForSelectors: updateRecoveryHandlers // Self-reference indicates execution selector
447
+ });
448
+ index++;
449
+
450
+ // Update Timelock Execution (for request and approve meta-tx)
451
+ roleHashes[index] = EngineBlox.BROADCASTER_ROLE;
452
+ functionPermissions[index] = EngineBlox.FunctionPermission({
453
+ functionSelector: UPDATE_TIMELOCK_SELECTOR,
454
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(broadcasterExecutionRequestApproveActions),
455
+ handlerForSelectors: updateTimelockHandlers // Self-reference indicates execution selector
456
+ });
457
+ index++;
458
+
459
+ return index;
460
+ }
461
+
462
+ /**
463
+ * @dev Adds owner role permissions
464
+ * @param roleHashes Array to populate with role hashes
465
+ * @param functionPermissions Array to populate with function permissions
466
+ * @param startIndex Starting index in arrays
467
+ * @return Next available index after adding permissions
468
+ */
469
+ function _addOwnerPermissions(
470
+ bytes32[] memory roleHashes,
471
+ EngineBlox.FunctionPermission[] memory functionPermissions,
472
+ uint256 startIndex
473
+ ) internal pure returns (uint256) {
474
+ uint256 index = startIndex;
475
+
476
+ // Action arrays for owner
477
+ EngineBlox.TxAction[] memory ownerTimeDelayRequestActions = new EngineBlox.TxAction[](1);
478
+ ownerTimeDelayRequestActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_REQUEST;
479
+
480
+ EngineBlox.TxAction[] memory ownerTimeDelayApproveActions = new EngineBlox.TxAction[](1);
481
+ ownerTimeDelayApproveActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_APPROVE;
482
+
483
+ EngineBlox.TxAction[] memory ownerTimeDelayCancelActions = new EngineBlox.TxAction[](1);
484
+ ownerTimeDelayCancelActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_CANCEL;
485
+
486
+ EngineBlox.TxAction[] memory ownerMetaApproveActions = new EngineBlox.TxAction[](1);
487
+ ownerMetaApproveActions[0] = EngineBlox.TxAction.SIGN_META_APPROVE;
488
+
489
+ EngineBlox.TxAction[] memory ownerMetaCancelActions = new EngineBlox.TxAction[](1);
490
+ ownerMetaCancelActions[0] = EngineBlox.TxAction.SIGN_META_CANCEL;
491
+
492
+ EngineBlox.TxAction[] memory ownerMetaRequestApproveActions = new EngineBlox.TxAction[](1);
493
+ ownerMetaRequestApproveActions[0] = EngineBlox.TxAction.SIGN_META_REQUEST_AND_APPROVE;
494
+
495
+ EngineBlox.TxAction[] memory ownerExecutionApproveCancelActions = new EngineBlox.TxAction[](2);
496
+ ownerExecutionApproveCancelActions[0] = EngineBlox.TxAction.SIGN_META_APPROVE;
497
+ ownerExecutionApproveCancelActions[1] = EngineBlox.TxAction.SIGN_META_CANCEL;
498
+
499
+ EngineBlox.TxAction[] memory ownerExecutionRequestApproveActions = new EngineBlox.TxAction[](1);
500
+ ownerExecutionRequestApproveActions[0] = EngineBlox.TxAction.SIGN_META_REQUEST_AND_APPROVE;
501
+
502
+ EngineBlox.TxAction[] memory ownerExecutionTimeDelayRequestActions = new EngineBlox.TxAction[](1);
503
+ ownerExecutionTimeDelayRequestActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_REQUEST;
504
+
505
+ EngineBlox.TxAction[] memory ownerExecutionTimeDelayApproveActions = new EngineBlox.TxAction[](1);
506
+ ownerExecutionTimeDelayApproveActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_APPROVE;
507
+
508
+ // Create reusable handlerForSelectors arrays for owner permissions
509
+ bytes4[] memory ownerTransferOwnershipHandlers = new bytes4[](1);
510
+ ownerTransferOwnershipHandlers[0] = TRANSFER_OWNERSHIP_SELECTOR;
511
+ bytes4[] memory ownerUpdateBroadcasterHandlers = new bytes4[](1);
512
+ ownerUpdateBroadcasterHandlers[0] = UPDATE_BROADCASTER_SELECTOR;
513
+ bytes4[] memory ownerUpdateRecoveryHandlers = new bytes4[](1);
514
+ ownerUpdateRecoveryHandlers[0] = UPDATE_RECOVERY_SELECTOR;
515
+ bytes4[] memory ownerUpdateTimelockHandlers = new bytes4[](1);
516
+ ownerUpdateTimelockHandlers[0] = UPDATE_TIMELOCK_SELECTOR;
517
+
518
+ // ============ OWNER: HANDLER FUNCTION PERMISSIONS (Time-delay) ============
519
+ // These are checked via msg.sig in BaseStateMachine._validateCallingFunctionPermission
520
+
521
+ // Transfer Ownership Delayed Approval (handler function)
522
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
523
+ functionPermissions[index] = EngineBlox.FunctionPermission({
524
+ functionSelector: TRANSFER_OWNERSHIP_DELAYED_APPROVAL_SELECTOR,
525
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerTimeDelayApproveActions),
526
+ handlerForSelectors: ownerTransferOwnershipHandlers
527
+ });
528
+ index++;
529
+
530
+ // Update Broadcaster Request (handler function)
531
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
532
+ functionPermissions[index] = EngineBlox.FunctionPermission({
533
+ functionSelector: UPDATE_BROADCASTER_REQUEST_SELECTOR,
534
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerTimeDelayRequestActions),
535
+ handlerForSelectors: ownerUpdateBroadcasterHandlers
536
+ });
537
+ index++;
538
+
539
+ // Update Broadcaster Delayed Approval (handler function)
540
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
541
+ functionPermissions[index] = EngineBlox.FunctionPermission({
542
+ functionSelector: UPDATE_BROADCASTER_DELAYED_APPROVAL_SELECTOR,
543
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerTimeDelayApproveActions),
544
+ handlerForSelectors: ownerUpdateBroadcasterHandlers
545
+ });
546
+ index++;
547
+
548
+ // Update Broadcaster Cancellation (handler function)
549
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
550
+ functionPermissions[index] = EngineBlox.FunctionPermission({
551
+ functionSelector: UPDATE_BROADCASTER_CANCELLATION_SELECTOR,
552
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerTimeDelayCancelActions),
553
+ handlerForSelectors: ownerUpdateBroadcasterHandlers
554
+ });
555
+ index++;
556
+
557
+ // ============ OWNER: HANDLER FUNCTION PERMISSIONS (Meta-transactions) ============
558
+ // These are checked via msg.sig in BaseStateMachine._validateCallingFunctionPermission
559
+ // Note: Owner signs meta-transactions, but doesn't execute them (broadcaster executes)
560
+
561
+ // Transfer Ownership Approve Meta (handler function - for signing)
562
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
563
+ functionPermissions[index] = EngineBlox.FunctionPermission({
564
+ functionSelector: TRANSFER_OWNERSHIP_APPROVE_META_SELECTOR,
565
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerMetaApproveActions),
566
+ handlerForSelectors: ownerTransferOwnershipHandlers
567
+ });
568
+ index++;
569
+
570
+ // Transfer Ownership Cancel Meta (handler function - for signing)
571
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
572
+ functionPermissions[index] = EngineBlox.FunctionPermission({
573
+ functionSelector: TRANSFER_OWNERSHIP_CANCEL_META_SELECTOR,
574
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerMetaCancelActions),
575
+ handlerForSelectors: ownerTransferOwnershipHandlers
576
+ });
577
+ index++;
578
+
579
+ // Update Broadcaster Approve Meta (handler function - for signing)
580
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
581
+ functionPermissions[index] = EngineBlox.FunctionPermission({
582
+ functionSelector: UPDATE_BROADCASTER_APPROVE_META_SELECTOR,
583
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerMetaApproveActions),
584
+ handlerForSelectors: ownerUpdateBroadcasterHandlers
585
+ });
586
+ index++;
587
+
588
+ // Update Broadcaster Cancel Meta (handler function - for signing)
589
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
590
+ functionPermissions[index] = EngineBlox.FunctionPermission({
591
+ functionSelector: UPDATE_BROADCASTER_CANCEL_META_SELECTOR,
592
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerMetaCancelActions),
593
+ handlerForSelectors: ownerUpdateBroadcasterHandlers
594
+ });
595
+ index++;
596
+
597
+ // Update Recovery Meta (handler function - for signing)
598
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
599
+ functionPermissions[index] = EngineBlox.FunctionPermission({
600
+ functionSelector: UPDATE_RECOVERY_META_SELECTOR,
601
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerMetaRequestApproveActions),
602
+ handlerForSelectors: ownerUpdateRecoveryHandlers
603
+ });
604
+ index++;
605
+
606
+ // Update Timelock Meta (handler function - for signing)
607
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
608
+ functionPermissions[index] = EngineBlox.FunctionPermission({
609
+ functionSelector: UPDATE_TIMELOCK_META_SELECTOR,
610
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerMetaRequestApproveActions),
611
+ handlerForSelectors: ownerUpdateTimelockHandlers
612
+ });
613
+ index++;
614
+
615
+ // ============ OWNER: EXECUTION FUNCTION PERMISSIONS ============
616
+ // These are checked in EngineBlox library functions
617
+
618
+ // Transfer Ownership Execution (for approve/cancel meta-tx - owner signs)
619
+ // Also supports time-delay approve (for transferOwnershipDelayedApproval)
620
+ EngineBlox.TxAction[] memory ownerTransferOwnershipAllActions = new EngineBlox.TxAction[](3);
621
+ ownerTransferOwnershipAllActions[0] = EngineBlox.TxAction.SIGN_META_APPROVE;
622
+ ownerTransferOwnershipAllActions[1] = EngineBlox.TxAction.SIGN_META_CANCEL;
623
+ ownerTransferOwnershipAllActions[2] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_APPROVE;
624
+
625
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
626
+ functionPermissions[index] = EngineBlox.FunctionPermission({
627
+ functionSelector: TRANSFER_OWNERSHIP_SELECTOR,
628
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerTransferOwnershipAllActions),
629
+ handlerForSelectors: ownerTransferOwnershipHandlers // Self-reference indicates execution selector
630
+ });
631
+ index++;
632
+
633
+ // Update Broadcaster Execution (for approve/cancel meta-tx and time-delay request/approve/cancel - owner signs)
634
+ // Supports:
635
+ // - SIGN_META_APPROVE, SIGN_META_CANCEL: for meta-transactions
636
+ // - EXECUTE_TIME_DELAY_REQUEST: for updateBroadcasterRequest (checked in txRequest)
637
+ // - EXECUTE_TIME_DELAY_APPROVE: for updateBroadcasterDelayedApproval (checked in txDelayedApproval)
638
+ // - EXECUTE_TIME_DELAY_CANCEL: for updateBroadcasterCancellation (checked in txCancellation)
639
+ EngineBlox.TxAction[] memory ownerBroadcasterExecutionAllActions = new EngineBlox.TxAction[](5);
640
+ ownerBroadcasterExecutionAllActions[0] = EngineBlox.TxAction.SIGN_META_APPROVE;
641
+ ownerBroadcasterExecutionAllActions[1] = EngineBlox.TxAction.SIGN_META_CANCEL;
642
+ ownerBroadcasterExecutionAllActions[2] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_REQUEST;
643
+ ownerBroadcasterExecutionAllActions[3] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_APPROVE;
644
+ ownerBroadcasterExecutionAllActions[4] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_CANCEL;
645
+
646
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
647
+ functionPermissions[index] = EngineBlox.FunctionPermission({
648
+ functionSelector: UPDATE_BROADCASTER_SELECTOR,
649
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerBroadcasterExecutionAllActions),
650
+ handlerForSelectors: ownerUpdateBroadcasterHandlers // Self-reference indicates execution selector
651
+ });
652
+ index++;
653
+
654
+ // Update Recovery Execution (for request and approve meta-tx - owner signs)
655
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
656
+ functionPermissions[index] = EngineBlox.FunctionPermission({
657
+ functionSelector: UPDATE_RECOVERY_SELECTOR,
658
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerExecutionRequestApproveActions),
659
+ handlerForSelectors: ownerUpdateRecoveryHandlers // Self-reference indicates execution selector
660
+ });
661
+ index++;
662
+
663
+ // Update Timelock Execution (for request and approve meta-tx - owner signs)
664
+ roleHashes[index] = EngineBlox.OWNER_ROLE;
665
+ functionPermissions[index] = EngineBlox.FunctionPermission({
666
+ functionSelector: UPDATE_TIMELOCK_SELECTOR,
667
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(ownerExecutionRequestApproveActions),
668
+ handlerForSelectors: ownerUpdateTimelockHandlers // Self-reference indicates execution selector
669
+ });
670
+ index++;
671
+
672
+ return index;
673
+ }
674
+
675
+ /**
676
+ * @dev Adds recovery role permissions
677
+ * @param roleHashes Array to populate with role hashes
678
+ * @param functionPermissions Array to populate with function permissions
679
+ * @param startIndex Starting index in arrays
680
+ * @return Next available index after adding permissions
681
+ */
682
+ function _addRecoveryPermissions(
683
+ bytes32[] memory roleHashes,
684
+ EngineBlox.FunctionPermission[] memory functionPermissions,
685
+ uint256 startIndex
686
+ ) internal pure returns (uint256) {
687
+ uint256 index = startIndex;
688
+
689
+ // Action arrays for recovery
690
+ EngineBlox.TxAction[] memory recoveryTimeDelayRequestActions = new EngineBlox.TxAction[](1);
691
+ recoveryTimeDelayRequestActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_REQUEST;
692
+
693
+ EngineBlox.TxAction[] memory recoveryTimeDelayApproveActions = new EngineBlox.TxAction[](1);
694
+ recoveryTimeDelayApproveActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_APPROVE;
695
+
696
+ EngineBlox.TxAction[] memory recoveryTimeDelayCancelActions = new EngineBlox.TxAction[](1);
697
+ recoveryTimeDelayCancelActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_CANCEL;
698
+
699
+ // Create reusable handlerForSelectors array for recovery permissions
700
+ bytes4[] memory recoveryTransferOwnershipHandlers = new bytes4[](1);
701
+ recoveryTransferOwnershipHandlers[0] = TRANSFER_OWNERSHIP_SELECTOR;
702
+
703
+ // ============ RECOVERY: HANDLER FUNCTION PERMISSIONS (Time-delay) ============
704
+ // These are checked via msg.sig in BaseStateMachine._validateCallingFunctionPermission
705
+
706
+ // Transfer Ownership Request (handler function)
707
+ roleHashes[index] = EngineBlox.RECOVERY_ROLE;
708
+ functionPermissions[index] = EngineBlox.FunctionPermission({
709
+ functionSelector: TRANSFER_OWNERSHIP_REQUEST_SELECTOR,
710
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(recoveryTimeDelayRequestActions),
711
+ handlerForSelectors: recoveryTransferOwnershipHandlers
712
+ });
713
+ index++;
714
+
715
+ // Transfer Ownership Delayed Approval (handler function)
716
+ roleHashes[index] = EngineBlox.RECOVERY_ROLE;
717
+ functionPermissions[index] = EngineBlox.FunctionPermission({
718
+ functionSelector: TRANSFER_OWNERSHIP_DELAYED_APPROVAL_SELECTOR,
719
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(recoveryTimeDelayApproveActions),
720
+ handlerForSelectors: recoveryTransferOwnershipHandlers
721
+ });
722
+ index++;
723
+
724
+ // Transfer Ownership Cancellation (handler function)
725
+ roleHashes[index] = EngineBlox.RECOVERY_ROLE;
726
+ functionPermissions[index] = EngineBlox.FunctionPermission({
727
+ functionSelector: TRANSFER_OWNERSHIP_CANCELLATION_SELECTOR,
728
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(recoveryTimeDelayCancelActions),
729
+ handlerForSelectors: recoveryTransferOwnershipHandlers
730
+ });
731
+ index++;
732
+
733
+ // ============ RECOVERY: EXECUTION FUNCTION PERMISSIONS ============
734
+ // These are checked in EngineBlox library functions
735
+
736
+ // Transfer Ownership Execution (for time-delay request/approve/cancel)
737
+ // Recovery needs this for:
738
+ // - EXECUTE_TIME_DELAY_REQUEST: when calling transferOwnershipRequest (checked in txRequest)
739
+ // - EXECUTE_TIME_DELAY_APPROVE: when calling transferOwnershipDelayedApproval
740
+ // - EXECUTE_TIME_DELAY_CANCEL: when calling transferOwnershipCancellation
741
+ EngineBlox.TxAction[] memory recoveryExecutionAllActions = new EngineBlox.TxAction[](3);
742
+ recoveryExecutionAllActions[0] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_REQUEST;
743
+ recoveryExecutionAllActions[1] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_APPROVE;
744
+ recoveryExecutionAllActions[2] = EngineBlox.TxAction.EXECUTE_TIME_DELAY_CANCEL;
745
+
746
+ roleHashes[index] = EngineBlox.RECOVERY_ROLE;
747
+ functionPermissions[index] = EngineBlox.FunctionPermission({
748
+ functionSelector: TRANSFER_OWNERSHIP_SELECTOR,
749
+ grantedActionsBitmap: EngineBlox.createBitmapFromActions(recoveryExecutionAllActions),
750
+ handlerForSelectors: recoveryTransferOwnershipHandlers // Self-reference indicates execution selector
751
+ });
752
+ index++;
753
+
754
+ return index;
755
+ }
756
+
757
+ }