@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,834 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ pragma solidity 0.8.33;
3
+
4
+ // OpenZeppelin imports
5
+ import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
6
+ import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
7
+ import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
8
+
9
+ // Contracts imports
10
+ import "../lib/EngineBlox.sol";
11
+ import "../../utils/SharedValidation.sol";
12
+ import "./interface/IBaseStateMachine.sol";
13
+
14
+ /**
15
+ * @title BaseStateMachine
16
+ * @dev Core state machine functionality for secure multi-phase operations
17
+ *
18
+ * This contract provides the foundational state machine capabilities that can be extended
19
+ * by security-specific contracts. It handles:
20
+ * - State initialization and management
21
+ * - Meta-transaction utilities and parameter creation
22
+ * - State queries and transaction history
23
+ * - Role-based access control queries
24
+ * - System state information
25
+ *
26
+ * The contract is designed to be inherited by security-specific contracts that implement
27
+ * their own operation types and business logic while leveraging the core state machine.
28
+ * All access to EngineBlox library functions is centralized through BaseStateMachine
29
+ * wrapper functions to ensure consistency and maintainability.
30
+ *
31
+ * Key Features:
32
+ * - State initialization with role and permission setup
33
+ * - Meta-transaction parameter creation and generation
34
+ * - Comprehensive state queries and transaction history
35
+ * - Role and permission validation utilities
36
+ * - System configuration queries
37
+ * - Event forwarding for external monitoring
38
+ */
39
+ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, ReentrancyGuardUpgradeable {
40
+ using EngineBlox for EngineBlox.SecureOperationState;
41
+ using SharedValidation for *;
42
+
43
+ EngineBlox.SecureOperationState internal _secureState;
44
+
45
+ // Events for core state machine operations
46
+ event TransactionRequested(
47
+ uint256 indexed txId,
48
+ address indexed requester,
49
+ bytes32 indexed operationType,
50
+ uint256 releaseTime
51
+ );
52
+
53
+ event TransactionApproved(
54
+ uint256 indexed txId,
55
+ bytes32 indexed operationType,
56
+ address indexed approver
57
+ );
58
+
59
+ event TransactionCancelled(
60
+ uint256 indexed txId,
61
+ bytes32 indexed operationType,
62
+ address indexed canceller
63
+ );
64
+
65
+ event TransactionExecuted(
66
+ uint256 indexed txId,
67
+ bytes32 indexed operationType,
68
+ bool success
69
+ );
70
+
71
+ /**
72
+ * @notice Initializes the base state machine core
73
+ * @param initialOwner The initial owner address
74
+ * @param broadcaster The broadcaster address
75
+ * @param recovery The recovery address
76
+ * @param timeLockPeriodSec The timelock period in seconds
77
+ * @param eventForwarder The event forwarder address
78
+ */
79
+ function _initializeBaseStateMachine(
80
+ address initialOwner,
81
+ address broadcaster,
82
+ address recovery,
83
+ uint256 timeLockPeriodSec,
84
+ address eventForwarder
85
+ ) internal onlyInitializing {
86
+ __ERC165_init();
87
+ __ReentrancyGuard_init();
88
+
89
+ _secureState.initialize(initialOwner, broadcaster, recovery, timeLockPeriodSec);
90
+
91
+ _secureState.setEventForwarder(eventForwarder);
92
+ }
93
+
94
+ // ============ SYSTEM ROLE QUERY FUNCTIONS ============
95
+
96
+ /**
97
+ * @dev Returns the owner of the contract
98
+ * @return The owner of the contract
99
+ */
100
+ function owner() public view returns (address) {
101
+ return _getAuthorizedWalletAt(EngineBlox.OWNER_ROLE, 0);
102
+ }
103
+
104
+ /**
105
+ * @dev Returns all broadcaster addresses for the BROADCASTER_ROLE
106
+ * @return Array of broadcaster addresses
107
+ */
108
+ function getBroadcasters() public view returns (address[] memory) {
109
+ return _getAuthorizedWallets(EngineBlox.BROADCASTER_ROLE);
110
+ }
111
+
112
+ /**
113
+ * @dev Returns the recovery address
114
+ * @return The recovery address
115
+ */
116
+ function getRecovery() public view returns (address) {
117
+ return _getAuthorizedWalletAt(EngineBlox.RECOVERY_ROLE, 0);
118
+ }
119
+
120
+ // ============ INTERFACE SUPPORT ============
121
+
122
+ /**
123
+ * @dev See {IERC165-supportsInterface}.
124
+ * @notice Base implementation for ERC165 interface detection
125
+ * @notice Registers IBaseStateMachine interface ID for proper interface detection
126
+ * @notice Component contracts (SecureOwnable, RuntimeRBAC, GuardController) should override
127
+ * to add their respective interface IDs for component detection
128
+ */
129
+ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
130
+ return interfaceId == type(IBaseStateMachine).interfaceId || super.supportsInterface(interfaceId);
131
+ }
132
+
133
+ // ============ TRANSACTION MANAGEMENT ============
134
+
135
+ /**
136
+ * @dev Centralized function to request a transaction with common validation
137
+ * @param requester The address requesting the transaction
138
+ * @param target The target contract address
139
+ * @param value The ETH value to send (0 for standard function calls)
140
+ * @param gasLimit The gas limit for execution
141
+ * @param operationType The type of operation
142
+ * @param functionSelector The function selector for execution (NATIVE_TRANSFER_SELECTOR for simple native token transfers)
143
+ * @param params The encoded parameters for the function (empty for simple native token transfers)
144
+ * @return The created transaction record
145
+ * @notice Validates permissions for the calling function (request function), not the execution selector
146
+ * @notice Execution functions are internal-only and don't need permission definitions
147
+ * @notice This function is virtual to allow extensions to add hook functionality
148
+ * @notice For standard function calls: value=0, functionSelector=non-zero, params=encoded data
149
+ * @notice For simple native token transfers: value>0, functionSelector=NATIVE_TRANSFER_SELECTOR, params=""
150
+ */
151
+ function _requestTransaction(
152
+ address requester,
153
+ address target,
154
+ uint256 value,
155
+ uint256 gasLimit,
156
+ bytes32 operationType,
157
+ bytes4 functionSelector,
158
+ bytes memory params
159
+ ) internal virtual returns (EngineBlox.TxRecord memory) {
160
+ return EngineBlox.txRequest(
161
+ _getSecureState(),
162
+ requester,
163
+ target,
164
+ value,
165
+ gasLimit,
166
+ operationType,
167
+ bytes4(msg.sig),
168
+ functionSelector,
169
+ params
170
+ );
171
+ }
172
+
173
+ /**
174
+ * @dev Centralized function to approve a pending transaction after release time
175
+ * @param txId The transaction ID
176
+ * @return The updated transaction record
177
+ * @notice Validates permissions for the calling function (approval function selector), not the execution selector
178
+ * @notice Execution functions are internal-only and don't need permission definitions
179
+ * @notice This function is virtual to allow extensions to add hook functionality
180
+ * @notice Protected by ReentrancyGuard to prevent reentrancy attacks
181
+ */
182
+ function _approveTransaction(
183
+ uint256 txId
184
+ ) internal virtual nonReentrant returns (EngineBlox.TxRecord memory) {
185
+ return EngineBlox.txDelayedApproval(_getSecureState(), txId, bytes4(msg.sig));
186
+ }
187
+
188
+ /**
189
+ * @dev Centralized function to approve a transaction using meta-transaction
190
+ * @param metaTx The meta-transaction
191
+ * @return The updated transaction record
192
+ * @notice Validates permissions for the calling function (msg.sig) and handler selector from metaTx
193
+ * @notice Uses EXECUTE_META_APPROVE action for permission checking
194
+ * @notice This function is virtual to allow extensions to add hook functionality
195
+ * @notice Protected by ReentrancyGuard to prevent reentrancy attacks
196
+ */
197
+ function _approveTransactionWithMetaTx(
198
+ EngineBlox.MetaTransaction memory metaTx
199
+ ) internal virtual nonReentrant returns (EngineBlox.TxRecord memory) {
200
+ return EngineBlox.txApprovalWithMetaTx(_getSecureState(), metaTx);
201
+ }
202
+
203
+ /**
204
+ * @dev Centralized function to cancel a pending transaction
205
+ * @param txId The transaction ID
206
+ * @return The updated transaction record
207
+ * @notice Validates permissions for the calling function (cancellation function selector), not the execution selector
208
+ * @notice Execution functions are internal-only and don't need permission definitions
209
+ * @notice This function is virtual to allow extensions to add hook functionality
210
+ */
211
+ function _cancelTransaction(
212
+ uint256 txId
213
+ ) internal virtual returns (EngineBlox.TxRecord memory) {
214
+ return EngineBlox.txCancellation(_getSecureState(), txId, bytes4(msg.sig));
215
+ }
216
+
217
+ /**
218
+ * @dev Centralized function to cancel a transaction using meta-transaction
219
+ * @param metaTx The meta-transaction
220
+ * @return The updated transaction record
221
+ * @notice Validates permissions for the calling function (msg.sig) and handler selector from metaTx
222
+ * @notice Uses EXECUTE_META_CANCEL action for permission checking
223
+ * @notice This function is virtual to allow extensions to add hook functionality
224
+ */
225
+ function _cancelTransactionWithMetaTx(
226
+ EngineBlox.MetaTransaction memory metaTx
227
+ ) internal virtual returns (EngineBlox.TxRecord memory) {
228
+ return EngineBlox.txCancellationWithMetaTx(_getSecureState(), metaTx);
229
+ }
230
+
231
+ /**
232
+ * @dev Centralized function to request and approve a transaction using meta-transaction
233
+ * @param metaTx The meta-transaction
234
+ * @return The transaction record
235
+ * @notice Validates permissions for the calling function (msg.sig) and handler selector from metaTx
236
+ * @notice Uses EXECUTE_META_REQUEST_AND_APPROVE action for permission checking
237
+ * @notice This function is virtual to allow extensions to add hook functionality
238
+ * @notice Protected by ReentrancyGuard to prevent reentrancy attacks
239
+ */
240
+ function _requestAndApproveTransaction(
241
+ EngineBlox.MetaTransaction memory metaTx
242
+ ) internal virtual nonReentrant returns (EngineBlox.TxRecord memory) {
243
+ return EngineBlox.requestAndApprove(_getSecureState(), metaTx);
244
+ }
245
+
246
+ /**
247
+ * @dev Centralized function to update payment details for a pending transaction
248
+ * @param txId The transaction ID to update payment for
249
+ * @param paymentDetails The new payment details
250
+ * @notice This function is virtual to allow extensions to add hook functionality
251
+ */
252
+ function _updatePaymentForTransaction(
253
+ uint256 txId,
254
+ EngineBlox.PaymentDetails memory paymentDetails
255
+ ) internal virtual returns (EngineBlox.TxRecord memory) {
256
+ EngineBlox.updatePaymentForTransaction(_getSecureState(), txId, paymentDetails);
257
+ return _secureState.getTxRecord(txId);
258
+ }
259
+
260
+ // ============ META-TRANSACTION UTILITIES ============
261
+
262
+ /**
263
+ * @dev Creates meta-transaction parameters with specified values
264
+ * @param handlerContract The contract that will handle the meta-transaction
265
+ * @param handlerSelector The function selector for the handler
266
+ * @param action The transaction action type
267
+ * @param deadline The timestamp after which the meta-transaction expires
268
+ * @param maxGasPrice The maximum gas price allowed for execution
269
+ * @param signer The address that will sign the meta-transaction
270
+ * @return The formatted meta-transaction parameters
271
+ */
272
+ function createMetaTxParams(
273
+ address handlerContract,
274
+ bytes4 handlerSelector,
275
+ EngineBlox.TxAction action,
276
+ uint256 deadline,
277
+ uint256 maxGasPrice,
278
+ address signer
279
+ ) public view returns (EngineBlox.MetaTxParams memory) {
280
+ return EngineBlox.createMetaTxParams(
281
+ handlerContract,
282
+ handlerSelector,
283
+ action,
284
+ deadline,
285
+ maxGasPrice,
286
+ signer
287
+ );
288
+ }
289
+
290
+ /**
291
+ * @dev Generates an unsigned meta-transaction for a new operation
292
+ * @param requester The address requesting the operation
293
+ * @param target The target contract address
294
+ * @param value The ETH value to send
295
+ * @param gasLimit The gas limit for execution
296
+ * @param operationType The type of operation
297
+ * @param executionSelector The function selector to execute (NATIVE_TRANSFER_SELECTOR for simple native token transfers)
298
+ * @param executionParams The encoded parameters for the function (empty for simple native token transfers)
299
+ * @param metaTxParams The meta-transaction parameters
300
+ * @return The unsigned meta-transaction
301
+ */
302
+ function generateUnsignedMetaTransactionForNew(
303
+ address requester,
304
+ address target,
305
+ uint256 value,
306
+ uint256 gasLimit,
307
+ bytes32 operationType,
308
+ bytes4 executionSelector,
309
+ bytes memory executionParams,
310
+ EngineBlox.MetaTxParams memory metaTxParams
311
+ ) public view returns (EngineBlox.MetaTransaction memory) {
312
+ EngineBlox.TxParams memory txParams = EngineBlox.TxParams({
313
+ requester: requester,
314
+ target: target,
315
+ value: value,
316
+ gasLimit: gasLimit,
317
+ operationType: operationType,
318
+ executionSelector: executionSelector,
319
+ executionParams: executionParams
320
+ });
321
+
322
+ return _secureState.generateUnsignedForNewMetaTx(txParams, metaTxParams);
323
+ }
324
+
325
+ /**
326
+ * @dev Generates an unsigned meta-transaction for an existing transaction
327
+ * @param txId The ID of the existing transaction
328
+ * @param metaTxParams The meta-transaction parameters
329
+ * @return The unsigned meta-transaction
330
+ */
331
+ function generateUnsignedMetaTransactionForExisting(
332
+ uint256 txId,
333
+ EngineBlox.MetaTxParams memory metaTxParams
334
+ ) public view returns (EngineBlox.MetaTransaction memory) {
335
+ return _secureState.generateUnsignedForExistingMetaTx(txId, metaTxParams);
336
+ }
337
+
338
+ // ============ STATE QUERIES ============
339
+
340
+ /**
341
+ * @dev Gets transaction history within a specified range
342
+ * @param fromTxId The starting transaction ID (inclusive)
343
+ * @param toTxId The ending transaction ID (inclusive)
344
+ * @return The transaction history within the specified range
345
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
346
+ */
347
+ function getTransactionHistory(uint256 fromTxId, uint256 toTxId) public view returns (EngineBlox.TxRecord[] memory) {
348
+ _validateAnyRole();
349
+
350
+ // Validate the range
351
+ fromTxId = fromTxId > 0 ? fromTxId : 1;
352
+ toTxId = toTxId > _secureState.txCounter ? _secureState.txCounter : toTxId;
353
+
354
+ // Validate that fromTxId is less than toTxId
355
+ SharedValidation.validateLessThan(fromTxId, toTxId);
356
+
357
+ uint256 rangeSize = toTxId - fromTxId + 1;
358
+
359
+ // For larger ranges, use paginated version
360
+ SharedValidation.validateRangeSize(rangeSize, 1000);
361
+
362
+ EngineBlox.TxRecord[] memory history = new EngineBlox.TxRecord[](rangeSize);
363
+
364
+ for (uint256 i = 0; i < rangeSize; i++) {
365
+ history[i] = _secureState.getTxRecord(fromTxId + i);
366
+ }
367
+
368
+ return history;
369
+ }
370
+
371
+ /**
372
+ * @dev Gets a transaction by ID
373
+ * @param txId The transaction ID
374
+ * @return The transaction record
375
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
376
+ */
377
+ function getTransaction(uint256 txId) public view returns (EngineBlox.TxRecord memory) {
378
+ _validateAnyRole();
379
+ return _secureState.getTxRecord(txId);
380
+ }
381
+
382
+ /**
383
+ * @dev Gets all pending transaction IDs
384
+ * @return Array of pending transaction IDs
385
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
386
+ */
387
+ function getPendingTransactions() public view returns (uint256[] memory) {
388
+ _validateAnyRole();
389
+ return _secureState.getPendingTransactionsList();
390
+ }
391
+
392
+ // ============ ROLE AND PERMISSION QUERIES ============
393
+
394
+ /**
395
+ * @dev Gets the basic role information by its hash
396
+ * @param roleHash The hash of the role to get
397
+ * @return roleName The name of the role
398
+ * @return roleHashReturn The hash of the role
399
+ * @return maxWallets The maximum number of wallets allowed for this role
400
+ * @return walletCount The current number of wallets assigned to this role
401
+ * @return isProtected Whether the role is protected from removal
402
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
403
+ */
404
+ function getRole(bytes32 roleHash) public view returns (
405
+ string memory roleName,
406
+ bytes32 roleHashReturn,
407
+ uint256 maxWallets,
408
+ uint256 walletCount,
409
+ bool isProtected
410
+ ) {
411
+ _validateAnyRole();
412
+ EngineBlox.Role storage role = _secureState.getRole(roleHash);
413
+ return (
414
+ role.roleName,
415
+ role.roleHash,
416
+ role.maxWallets,
417
+ role.walletCount,
418
+ role.isProtected
419
+ );
420
+ }
421
+
422
+ /**
423
+ * @dev Returns if a wallet is authorized for a role
424
+ * @param roleHash The hash of the role to check
425
+ * @param wallet The wallet address to check
426
+ * @return True if the wallet is authorized for the role, false otherwise
427
+ */
428
+ function hasRole(bytes32 roleHash, address wallet) public view returns (bool) {
429
+ return _secureState.hasRole(roleHash, wallet);
430
+ }
431
+
432
+ /**
433
+ * @dev Gets all roles assigned to a wallet
434
+ * @param wallet The wallet address to get roles for
435
+ * @return Array of role hashes assigned to the wallet
436
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
437
+ * @notice This function uses the reverse index for efficient lookup
438
+ */
439
+ function getWalletRoles(address wallet) public view returns (bytes32[] memory) {
440
+ _validateAnyRole();
441
+ return EngineBlox.getWalletRoles(_getSecureState(), wallet);
442
+ }
443
+
444
+ /**
445
+ * @dev Checks if a function schema exists
446
+ * @param functionSelector The function selector to check
447
+ * @return True if the function schema exists, false otherwise
448
+ */
449
+ function functionSchemaExists(bytes4 functionSelector) public view returns (bool) {
450
+ return _secureState.functions[functionSelector].functionSelector == functionSelector;
451
+ }
452
+
453
+ /**
454
+ * @dev Returns if an action is supported by a function
455
+ * @param functionSelector The function selector to check
456
+ * @param action The action to check
457
+ * @return True if the action is supported by the function, false otherwise
458
+ */
459
+ function isActionSupportedByFunction(bytes4 functionSelector, EngineBlox.TxAction action) public view returns (bool) {
460
+ return _secureState.isActionSupportedByFunction(functionSelector, action);
461
+ }
462
+
463
+ /**
464
+ * @dev Gets the function permissions for a specific role
465
+ * @param roleHash The hash of the role to get permissions for
466
+ * @return The function permissions array for the role
467
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
468
+ */
469
+ function getActiveRolePermissions(bytes32 roleHash) public view returns (EngineBlox.FunctionPermission[] memory) {
470
+ _validateAnyRole();
471
+ return _secureState.getRoleFunctionPermissions(roleHash);
472
+ }
473
+
474
+ /**
475
+ * @dev Gets the current nonce for a specific signer
476
+ * @param signer The address of the signer
477
+ * @return The current nonce for the signer
478
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
479
+ */
480
+ function getSignerNonce(address signer) public view returns (uint256) {
481
+ _validateAnyRole();
482
+ return _secureState.getSignerNonce(signer);
483
+ }
484
+
485
+ // ============ SYSTEM STATE QUERIES ============
486
+
487
+ /**
488
+ * @dev Returns the supported operation types
489
+ * @return The supported operation types
490
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
491
+ */
492
+ function getSupportedOperationTypes() public view returns (bytes32[] memory) {
493
+ _validateAnyRole();
494
+ return _secureState.getSupportedOperationTypesList();
495
+ }
496
+
497
+ /**
498
+ * @dev Returns the supported roles list
499
+ * @return The supported roles list
500
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
501
+ */
502
+ function getSupportedRoles() public view returns (bytes32[] memory) {
503
+ _validateAnyRole();
504
+ return _secureState.getSupportedRolesList();
505
+ }
506
+
507
+ /**
508
+ * @dev Returns the supported functions list
509
+ * @return The supported functions list
510
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
511
+ */
512
+ function getSupportedFunctions() public view returns (bytes4[] memory) {
513
+ _validateAnyRole();
514
+ return _secureState.getSupportedFunctionsList();
515
+ }
516
+
517
+ /**
518
+ * @dev Returns the time lock period
519
+ * @return The time lock period in seconds
520
+ */
521
+ function getTimeLockPeriodSec() public view returns (uint256) {
522
+ return _secureState.timeLockPeriodSec;
523
+ }
524
+
525
+ /**
526
+ * @dev Returns whether the contract is initialized
527
+ * @return bool True if the contract is initialized, false otherwise
528
+ */
529
+ function initialized() public view returns (bool) {
530
+ return _getInitializedVersion() != type(uint8).max && _secureState.initialized;
531
+ }
532
+
533
+ // ============ ROLE MANAGEMENT ============
534
+
535
+ /**
536
+ * @dev Centralized function to get authorized wallet at specific index
537
+ * @param roleHash The role hash
538
+ * @param index The wallet index
539
+ * @return The authorized wallet address
540
+ */
541
+ function _getAuthorizedWalletAt(bytes32 roleHash, uint256 index) internal view returns (address) {
542
+ return EngineBlox.getAuthorizedWalletAt(_getSecureState(), roleHash, index);
543
+ }
544
+
545
+ /**
546
+ * @dev Centralized function to get all authorized wallets for a role
547
+ * @param roleHash The role hash
548
+ * @return Array of authorized wallet addresses
549
+ */
550
+ function _getAuthorizedWallets(bytes32 roleHash) internal view returns (address[] memory) {
551
+ EngineBlox.Role storage role = _secureState.roles[roleHash];
552
+ uint256 walletCount = role.walletCount;
553
+
554
+ address[] memory wallets = new address[](walletCount);
555
+ for (uint256 i = 0; i < walletCount; i++) {
556
+ wallets[i] = _getAuthorizedWalletAt(roleHash, i);
557
+ }
558
+
559
+ return wallets;
560
+ }
561
+
562
+ /**
563
+ * @dev Centralized function to create a new role
564
+ * @param roleName The name of the role
565
+ * @param maxWallets The maximum number of wallets allowed for this role
566
+ * @param isProtected Whether the role is protected from removal
567
+ * @return roleHash The hash of the created role
568
+ * @notice This function is virtual to allow extensions to add hook functionality
569
+ */
570
+ function _createRole(
571
+ string memory roleName,
572
+ uint256 maxWallets,
573
+ bool isProtected
574
+ ) internal virtual returns (bytes32) {
575
+ bytes32 roleHash = keccak256(bytes(roleName));
576
+ EngineBlox.createRole(_getSecureState(), roleName, maxWallets, isProtected);
577
+ return roleHash;
578
+ }
579
+
580
+ /**
581
+ * @dev Centralized function to remove a role
582
+ * @param roleHash The hash of the role to remove
583
+ * @notice This function is virtual to allow extensions to add hook functionality
584
+ */
585
+ function _removeRole(bytes32 roleHash) internal virtual {
586
+ EngineBlox.removeRole(_getSecureState(), roleHash);
587
+ }
588
+
589
+ /**
590
+ * @dev Centralized function to assign a wallet to a role
591
+ * @param roleHash The role hash
592
+ * @param wallet The wallet address to assign
593
+ * @notice This function is virtual to allow extensions to add hook functionality
594
+ */
595
+ function _assignWallet(bytes32 roleHash, address wallet) internal virtual {
596
+ EngineBlox.assignWallet(_getSecureState(), roleHash, wallet);
597
+ }
598
+
599
+ /**
600
+ * @dev Centralized function to revoke a wallet from a role
601
+ * @param roleHash The role hash
602
+ * @param wallet The wallet address to revoke
603
+ * @notice This function is virtual to allow extensions to add hook functionality
604
+ */
605
+ function _revokeWallet(bytes32 roleHash, address wallet) internal virtual {
606
+ EngineBlox.revokeWallet(_getSecureState(), roleHash, wallet);
607
+ }
608
+
609
+ /**
610
+ * @dev Centralized function to update assigned wallet for a role
611
+ * @param roleHash The role hash
612
+ * @param newWallet The new wallet address
613
+ * @param oldWallet The old wallet address
614
+ * @notice This function is virtual to allow extensions to add hook functionality or additional validation
615
+ */
616
+ function _updateAssignedWallet(bytes32 roleHash, address newWallet, address oldWallet) internal virtual {
617
+ EngineBlox.updateAssignedWallet(_getSecureState(), roleHash, newWallet, oldWallet);
618
+ }
619
+
620
+ /**
621
+ * @dev Centralized function to update the time lock period
622
+ * @param newTimeLockPeriodSec The new time lock period in seconds
623
+ * @notice This function is virtual to allow extensions to add hook functionality
624
+ */
625
+ function _updateTimeLockPeriod(uint256 newTimeLockPeriodSec) internal virtual {
626
+ EngineBlox.updateTimeLockPeriod(_getSecureState(), newTimeLockPeriodSec);
627
+ }
628
+
629
+ // ============ FUNCTION SCHEMA MANAGEMENT ============
630
+
631
+ /**
632
+ * @dev Centralized function to create a function schema
633
+ * @param functionSignature The function signature
634
+ * @param functionSelector The function selector
635
+ * @param operationName The operation name
636
+ * @param supportedActionsBitmap The bitmap of supported actions
637
+ * @param isProtected Whether the function schema is protected
638
+ * @param handlerForSelectors Array of handler selectors
639
+ * @notice This function is virtual to allow extensions to add hook functionality
640
+ */
641
+ function _createFunctionSchema(
642
+ string memory functionSignature,
643
+ bytes4 functionSelector,
644
+ string memory operationName,
645
+ uint16 supportedActionsBitmap,
646
+ bool isProtected,
647
+ bytes4[] memory handlerForSelectors
648
+ ) internal virtual {
649
+ EngineBlox.createFunctionSchema(
650
+ _getSecureState(),
651
+ functionSignature,
652
+ functionSelector,
653
+ operationName,
654
+ supportedActionsBitmap,
655
+ isProtected,
656
+ handlerForSelectors
657
+ );
658
+ }
659
+
660
+ /**
661
+ * @dev Centralized function to remove a function schema
662
+ * @param functionSelector The function selector to remove
663
+ * @param safeRemoval Whether to perform safe removal (check for role references)
664
+ * @notice This function is virtual to allow extensions to add hook functionality
665
+ */
666
+ function _removeFunctionSchema(bytes4 functionSelector, bool safeRemoval) internal virtual {
667
+ EngineBlox.removeFunctionSchema(_getSecureState(), functionSelector, safeRemoval);
668
+ }
669
+
670
+ /**
671
+ * @dev Centralized function to add a function permission to a role
672
+ * @param roleHash The role hash
673
+ * @param functionPermission The function permission to add
674
+ * @notice This function is virtual to allow extensions to add hook functionality
675
+ */
676
+ function _addFunctionToRole(
677
+ bytes32 roleHash,
678
+ EngineBlox.FunctionPermission memory functionPermission
679
+ ) internal virtual {
680
+ EngineBlox.addFunctionToRole(_getSecureState(), roleHash, functionPermission);
681
+ }
682
+
683
+ /**
684
+ * @dev Centralized function to remove a function permission from a role
685
+ * @param roleHash The role hash
686
+ * @param functionSelector The function selector to remove
687
+ * @notice This function is virtual to allow extensions to add hook functionality
688
+ */
689
+ function _removeFunctionFromRole(bytes32 roleHash, bytes4 functionSelector) internal virtual {
690
+ EngineBlox.removeFunctionFromRole(_getSecureState(), roleHash, functionSelector);
691
+ }
692
+
693
+ // ============ PERMISSION VALIDATION ============
694
+
695
+ /**
696
+ * @dev Centralized function to validate that the caller has any role
697
+ */
698
+ function _validateAnyRole() internal view {
699
+ EngineBlox._validateAnyRole(_getSecureState());
700
+ }
701
+
702
+ /**
703
+ * @dev Centralized function to validate that a role exists
704
+ * @param roleHash The role hash to validate
705
+ */
706
+ function _validateRoleExists(bytes32 roleHash) internal view {
707
+ EngineBlox._validateRoleExists(_getSecureState(), roleHash);
708
+ }
709
+
710
+ // ============ UTILITY FUNCTIONS ============
711
+
712
+ /**
713
+ * @dev Centralized function to convert a bitmap to an array of actions
714
+ * @param bitmap The bitmap to convert
715
+ * @return Array of TxAction values
716
+ */
717
+ function _convertBitmapToActions(uint16 bitmap) internal pure returns (EngineBlox.TxAction[] memory) {
718
+ return EngineBlox.convertBitmapToActions(bitmap);
719
+ }
720
+
721
+ /**
722
+ * @dev Centralized function to create a bitmap from an array of actions
723
+ * @param actions Array of TxAction values
724
+ * @return The bitmap representation
725
+ */
726
+ function _createBitmapFromActions(EngineBlox.TxAction[] memory actions) internal pure returns (uint16) {
727
+ return EngineBlox.createBitmapFromActions(actions);
728
+ }
729
+
730
+ // ============ TARGET WHITELIST MANAGEMENT ============
731
+
732
+ /**
733
+ * @dev Centralized function to add a target address to the whitelist for a function selector
734
+ * @param functionSelector The function selector
735
+ * @param target The target address to whitelist
736
+ * @notice This function is virtual to allow extensions to add hook functionality
737
+ */
738
+ function _addTargetToFunctionWhitelist(bytes4 functionSelector, address target) internal virtual {
739
+ _getSecureState().addTargetToFunctionWhitelist(functionSelector, target);
740
+ }
741
+
742
+ /**
743
+ * @dev Centralized function to remove a target address from the whitelist for a function selector
744
+ * @param functionSelector The function selector
745
+ * @param target The target address to remove
746
+ * @notice This function is virtual to allow extensions to add hook functionality
747
+ */
748
+ function _removeTargetFromFunctionWhitelist(bytes4 functionSelector, address target) internal virtual {
749
+ _getSecureState().removeTargetFromFunctionWhitelist(functionSelector, target);
750
+ }
751
+
752
+ /**
753
+ * @dev Centralized function to get all whitelisted targets for a function selector
754
+ * @param functionSelector The function selector
755
+ * @return Array of whitelisted target addresses
756
+ */
757
+ function _getFunctionWhitelistTargets(bytes4 functionSelector) internal view returns (address[] memory) {
758
+ return _getSecureState().getFunctionWhitelistTargets(functionSelector);
759
+ }
760
+
761
+ // ============ DEFINITION LOADING ============
762
+
763
+ /**
764
+ * @dev Loads definitions directly into the secure state
765
+ * This function initializes the secure state with all predefined definitions
766
+ * @param functionSchemas Array of function schema definitions
767
+ * @param roleHashes Array of role hashes
768
+ * @param functionPermissions Array of function permissions (parallel to roleHashes)
769
+ */
770
+ function _loadDefinitions(
771
+ EngineBlox.FunctionSchema[] memory functionSchemas,
772
+ bytes32[] memory roleHashes,
773
+ EngineBlox.FunctionPermission[] memory functionPermissions
774
+ ) internal {
775
+ // Load function schemas
776
+ for (uint256 i = 0; i < functionSchemas.length; i++) {
777
+ EngineBlox.createFunctionSchema(
778
+ _getSecureState(),
779
+ functionSchemas[i].functionSignature,
780
+ functionSchemas[i].functionSelector,
781
+ functionSchemas[i].operationName,
782
+ functionSchemas[i].supportedActionsBitmap,
783
+ functionSchemas[i].isProtected,
784
+ functionSchemas[i].handlerForSelectors
785
+ );
786
+ }
787
+
788
+ // Load role permissions using parallel arrays
789
+ SharedValidation.validateArrayLengthMatch(roleHashes.length, functionPermissions.length);
790
+ for (uint256 i = 0; i < roleHashes.length; i++) {
791
+ EngineBlox.addFunctionToRole(
792
+ _getSecureState(),
793
+ roleHashes[i],
794
+ functionPermissions[i]
795
+ );
796
+ }
797
+ }
798
+
799
+ // ============ INTERNAL UTILITIES ============
800
+
801
+ /**
802
+ * @dev Internal function to get the secure state
803
+ * @return secureState The secure state
804
+ */
805
+ function _getSecureState() internal view returns (EngineBlox.SecureOperationState storage) {
806
+ return _secureState;
807
+ }
808
+
809
+ /**
810
+ * @dev Internal function to check if an address has action permission
811
+ * @param caller The address to check
812
+ * @param functionSelector The function selector
813
+ * @param action The action to check
814
+ * @return True if the caller has permission, false otherwise
815
+ */
816
+ function _hasActionPermission(
817
+ address caller,
818
+ bytes4 functionSelector,
819
+ EngineBlox.TxAction action
820
+ ) internal view returns (bool) {
821
+ return _secureState.hasActionPermission(caller, functionSelector, action);
822
+ }
823
+
824
+ /**
825
+ * @dev Internal helper to validate that a caller has the BROADCASTER_ROLE
826
+ * @param caller The address to validate
827
+ */
828
+ function _validateBroadcaster(address caller) internal view {
829
+ if (!hasRole(EngineBlox.BROADCASTER_ROLE, caller)) {
830
+ revert SharedValidation.NoPermission(caller);
831
+ }
832
+ }
833
+
834
+ }