@bloxchain/contracts 1.0.0-alpha.15 → 1.0.0-alpha.16

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