@bloxchain/contracts 1.0.0-alpha → 1.0.0-alpha.10

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 (55) hide show
  1. package/README.md +55 -18
  2. package/abi/{ControlBlox.abi.json → AccountBlox.abi.json} +699 -2974
  3. package/abi/BareBlox.abi.json +127 -90
  4. package/abi/BaseStateMachine.abi.json +127 -90
  5. package/abi/EngineBlox.abi.json +11 -31
  6. package/abi/GuardController.abi.json +217 -895
  7. package/abi/GuardControllerDefinitions.abi.json +380 -0
  8. package/abi/IDefinition.abi.json +19 -0
  9. package/abi/RoleBlox.abi.json +818 -2404
  10. package/abi/RuntimeRBAC.abi.json +122 -328
  11. package/abi/RuntimeRBACDefinitions.abi.json +243 -0
  12. package/abi/SecureBlox.abi.json +620 -1952
  13. package/abi/SecureOwnable.abi.json +469 -1801
  14. package/abi/SecureOwnableDefinitions.abi.json +57 -0
  15. package/abi/SimpleRWA20.abi.json +486 -1999
  16. package/abi/SimpleRWA20Definitions.abi.json +19 -0
  17. package/abi/SimpleVault.abi.json +884 -2685
  18. package/abi/SimpleVaultDefinitions.abi.json +19 -0
  19. package/components/README.md +8 -0
  20. package/core/access/RuntimeRBAC.sol +184 -0
  21. package/core/access/interface/IRuntimeRBAC.sol +55 -0
  22. package/{contracts/core → core}/access/lib/definitions/RuntimeRBACDefinitions.sol +121 -1
  23. package/{contracts/core → core}/base/BaseStateMachine.sol +187 -54
  24. package/{contracts/core → core}/base/interface/IBaseStateMachine.sol +7 -0
  25. package/{contracts/core → core}/execution/GuardController.sol +89 -155
  26. package/{contracts/core → core}/execution/interface/IGuardController.sol +52 -12
  27. package/{contracts/core → core}/execution/lib/definitions/GuardControllerDefinitions.sol +91 -2
  28. package/{contracts/core → core}/lib/EngineBlox.sol +167 -64
  29. package/{contracts → core/lib}/interfaces/IDefinition.sol +15 -6
  30. package/{contracts → core/lib}/interfaces/IEventForwarder.sol +1 -1
  31. package/{contracts → core/lib}/utils/SharedValidation.sol +490 -486
  32. package/core/pattern/Account.sol +75 -0
  33. package/core/research/BloxchainWallet.sol +133 -0
  34. package/core/research/FactoryBlox/FactoryBlox.sol +344 -0
  35. package/core/research/FactoryBlox/FactoryBloxDefinitions.sol +144 -0
  36. package/core/research/erc1155-blox/ERC1155Blox.sol +170 -0
  37. package/core/research/erc1155-blox/lib/definitions/ERC1155BloxDefinitions.sol +203 -0
  38. package/core/research/erc20-blox/ERC20Blox.sol +135 -0
  39. package/core/research/erc20-blox/lib/definitions/ERC20BloxDefinitions.sol +185 -0
  40. package/core/research/erc721-blox/ERC721Blox.sol +131 -0
  41. package/core/research/erc721-blox/lib/definitions/ERC721BloxDefinitions.sol +172 -0
  42. package/core/research/lending-blox/.gitkeep +1 -0
  43. package/core/research/p2p-blox/P2PBlox.sol +266 -0
  44. package/core/research/p2p-blox/README.md +85 -0
  45. package/core/research/p2p-blox/lib/definitions/P2PBloxDefinitions.sol +19 -0
  46. package/{contracts/core → core}/security/SecureOwnable.sol +390 -419
  47. package/{contracts/core → core}/security/interface/ISecureOwnable.sol +27 -40
  48. package/{contracts/core → core}/security/lib/definitions/SecureOwnableDefinitions.sol +786 -757
  49. package/package.json +49 -47
  50. package/standards/README.md +12 -0
  51. package/standards/behavior/ICopyable.sol +36 -0
  52. package/standards/hooks/IOnActionHook.sol +21 -0
  53. package/contracts/core/access/RuntimeRBAC.sol +0 -344
  54. package/contracts/core/access/interface/IRuntimeRBAC.sol +0 -108
  55. package/contracts/interfaces/IOnActionHook.sol +0 -79
@@ -8,7 +8,7 @@ import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol
8
8
 
9
9
  // Contracts imports
10
10
  import "../lib/EngineBlox.sol";
11
- import "../../utils/SharedValidation.sol";
11
+ import "../lib/utils/SharedValidation.sol";
12
12
  import "./interface/IBaseStateMachine.sol";
13
13
 
14
14
  /**
@@ -42,31 +42,13 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
42
42
 
43
43
  EngineBlox.SecureOperationState internal _secureState;
44
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
- );
45
+ /**
46
+ * @dev Unified component event for SecureOwnable, GuardController, RuntimeRBAC.
47
+ * Indexers filter by functionSelector (msg.sig at emit site) and decode data (abi-encoded payload).
48
+ * @param functionSelector The function selector (msg.sig) at the emit site; used by indexers to filter
49
+ * @param data ABI-encoded payload associated with the event
50
+ */
51
+ event ComponentEvent(bytes4 indexed functionSelector, bytes data);
70
52
 
71
53
  /**
72
54
  * @notice Initializes the base state machine core
@@ -157,7 +139,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
157
139
  bytes4 functionSelector,
158
140
  bytes memory params
159
141
  ) internal virtual returns (EngineBlox.TxRecord memory) {
160
- return EngineBlox.txRequest(
142
+ EngineBlox.TxRecord memory txRecord = EngineBlox.txRequest(
161
143
  _getSecureState(),
162
144
  requester,
163
145
  target,
@@ -168,6 +150,48 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
168
150
  functionSelector,
169
151
  params
170
152
  );
153
+ _postActionHook(txRecord);
154
+ return txRecord;
155
+ }
156
+
157
+ /**
158
+ * @dev Centralized function to request a transaction with payment details attached from the start
159
+ * @param requester The address requesting the transaction
160
+ * @param target The target contract address
161
+ * @param value The ETH value to send (0 for standard function calls)
162
+ * @param gasLimit The gas limit for execution
163
+ * @param operationType The type of operation
164
+ * @param functionSelector The function selector for execution (NATIVE_TRANSFER_SELECTOR for simple native token transfers)
165
+ * @param params The encoded parameters for the function (empty for simple native token transfers)
166
+ * @param paymentDetails The payment details to attach to the transaction
167
+ * @return The created transaction record with payment set
168
+ * @notice Validates request permissions (same as request without payment)
169
+ * @notice This function is virtual to allow extensions to add hook functionality
170
+ */
171
+ function _requestTransactionWithPayment(
172
+ address requester,
173
+ address target,
174
+ uint256 value,
175
+ uint256 gasLimit,
176
+ bytes32 operationType,
177
+ bytes4 functionSelector,
178
+ bytes memory params,
179
+ EngineBlox.PaymentDetails memory paymentDetails
180
+ ) internal virtual returns (EngineBlox.TxRecord memory) {
181
+ EngineBlox.TxRecord memory txRecord = EngineBlox.txRequestWithPayment(
182
+ _getSecureState(),
183
+ requester,
184
+ target,
185
+ value,
186
+ gasLimit,
187
+ operationType,
188
+ bytes4(msg.sig),
189
+ functionSelector,
190
+ params,
191
+ paymentDetails
192
+ );
193
+ _postActionHook(txRecord);
194
+ return txRecord;
171
195
  }
172
196
 
173
197
  /**
@@ -182,7 +206,9 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
182
206
  function _approveTransaction(
183
207
  uint256 txId
184
208
  ) internal virtual nonReentrant returns (EngineBlox.TxRecord memory) {
185
- return EngineBlox.txDelayedApproval(_getSecureState(), txId, bytes4(msg.sig));
209
+ EngineBlox.TxRecord memory txRecord = EngineBlox.txDelayedApproval(_getSecureState(), txId, bytes4(msg.sig));
210
+ _postActionHook(txRecord);
211
+ return txRecord;
186
212
  }
187
213
 
188
214
  /**
@@ -197,7 +223,9 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
197
223
  function _approveTransactionWithMetaTx(
198
224
  EngineBlox.MetaTransaction memory metaTx
199
225
  ) internal virtual nonReentrant returns (EngineBlox.TxRecord memory) {
200
- return EngineBlox.txApprovalWithMetaTx(_getSecureState(), metaTx);
226
+ EngineBlox.TxRecord memory txRecord = EngineBlox.txApprovalWithMetaTx(_getSecureState(), metaTx);
227
+ _postActionHook(txRecord);
228
+ return txRecord;
201
229
  }
202
230
 
203
231
  /**
@@ -211,7 +239,9 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
211
239
  function _cancelTransaction(
212
240
  uint256 txId
213
241
  ) internal virtual returns (EngineBlox.TxRecord memory) {
214
- return EngineBlox.txCancellation(_getSecureState(), txId, bytes4(msg.sig));
242
+ EngineBlox.TxRecord memory txRecord = EngineBlox.txCancellation(_getSecureState(), txId, bytes4(msg.sig));
243
+ _postActionHook(txRecord);
244
+ return txRecord;
215
245
  }
216
246
 
217
247
  /**
@@ -225,7 +255,9 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
225
255
  function _cancelTransactionWithMetaTx(
226
256
  EngineBlox.MetaTransaction memory metaTx
227
257
  ) internal virtual returns (EngineBlox.TxRecord memory) {
228
- return EngineBlox.txCancellationWithMetaTx(_getSecureState(), metaTx);
258
+ EngineBlox.TxRecord memory txRecord = EngineBlox.txCancellationWithMetaTx(_getSecureState(), metaTx);
259
+ _postActionHook(txRecord);
260
+ return txRecord;
229
261
  }
230
262
 
231
263
  /**
@@ -240,21 +272,51 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
240
272
  function _requestAndApproveTransaction(
241
273
  EngineBlox.MetaTransaction memory metaTx
242
274
  ) internal virtual nonReentrant returns (EngineBlox.TxRecord memory) {
243
- return EngineBlox.requestAndApprove(_getSecureState(), metaTx);
275
+ EngineBlox.TxRecord memory txRecord = EngineBlox.requestAndApprove(_getSecureState(), metaTx);
276
+ _postActionHook(txRecord);
277
+ return txRecord;
244
278
  }
245
279
 
246
280
  /**
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
281
+ * @dev Post-action hook invoked after any transaction operation that produces a TxRecord.
282
+ * Override in derived contracts to add centralized post-tx logic (e.g. notifications, side effects).
283
+ * @param txRecord The transaction record produced by the operation
251
284
  */
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);
285
+ function _postActionHook(EngineBlox.TxRecord memory txRecord) internal virtual {}
286
+
287
+ // ============ HOOK MANAGEMENT ============
288
+
289
+ /**
290
+ * @dev Sets the hook contract for a function selector (internal; no access control).
291
+ * Extensions (e.g. HookManager) may expose an external setHook with owner check.
292
+ * @param functionSelector The function selector
293
+ * @param hook The hook contract address (must not be zero)
294
+ */
295
+ function _setHook(bytes4 functionSelector, address hook) internal {
296
+ EngineBlox.addTargetToFunctionHooks(_getSecureState(), functionSelector, hook);
297
+ _logComponentEvent(abi.encode(functionSelector, hook));
298
+ }
299
+
300
+ /**
301
+ * @dev Clears the hook contract for a function selector (internal; no access control).
302
+ * Extensions may expose an external clearHook with owner check.
303
+ * @param functionSelector The function selector
304
+ * @param hook The hook contract address to remove (must not be zero)
305
+ */
306
+ function _clearHook(bytes4 functionSelector, address hook) internal {
307
+ EngineBlox.removeTargetFromFunctionHooks(_getSecureState(), functionSelector, hook);
308
+ _logComponentEvent(abi.encode(functionSelector, hook));
309
+ }
310
+
311
+ /**
312
+ * @dev Returns all configured hooks for a function selector
313
+ * @param functionSelector The function selector
314
+ * @return hooks Array of hook contract addresses
315
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
316
+ */
317
+ function getHooks(bytes4 functionSelector) public view returns (address[] memory hooks) {
318
+ _validateAnyRole();
319
+ return EngineBlox.getFunctionHookTargets(_getSecureState(), functionSelector);
258
320
  }
259
321
 
260
322
  // ============ META-TRANSACTION UTILITIES ============
@@ -441,6 +503,18 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
441
503
  return EngineBlox.getWalletRoles(_getSecureState(), wallet);
442
504
  }
443
505
 
506
+ /**
507
+ * @dev Gets all authorized wallets for a role
508
+ * @param roleHash The role hash to get wallets for
509
+ * @return Array of authorized wallet addresses
510
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
511
+ */
512
+ function getWalletsInRole(bytes32 roleHash) public view returns (address[] memory) {
513
+ _validateAnyRole();
514
+ _validateRoleExists(roleHash);
515
+ return _getAuthorizedWallets(roleHash);
516
+ }
517
+
444
518
  /**
445
519
  * @dev Checks if a function schema exists
446
520
  * @param functionSelector The function selector to check
@@ -460,6 +534,16 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
460
534
  return _secureState.isActionSupportedByFunction(functionSelector, action);
461
535
  }
462
536
 
537
+ /**
538
+ * @dev Gets function schema information
539
+ * @param functionSelector The function selector to get information for
540
+ * @return The full FunctionSchema struct (functionSignature, functionSelector, operationType, operationName, supportedActionsBitmap, isProtected, handlerForSelectors)
541
+ */
542
+ function getFunctionSchema(bytes4 functionSelector) external view returns (EngineBlox.FunctionSchema memory) {
543
+ _validateAnyRole();
544
+ return _secureState.getFunctionSchema(functionSelector);
545
+ }
546
+
463
547
  /**
464
548
  * @dev Gets the function permissions for a specific role
465
549
  * @param roleHash The hash of the role to get permissions for
@@ -548,15 +632,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
548
632
  * @return Array of authorized wallet addresses
549
633
  */
550
634
  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;
635
+ return EngineBlox._getAuthorizedWallets(_getSecureState(), roleHash);
560
636
  }
561
637
 
562
638
  /**
@@ -623,7 +699,9 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
623
699
  * @notice This function is virtual to allow extensions to add hook functionality
624
700
  */
625
701
  function _updateTimeLockPeriod(uint256 newTimeLockPeriodSec) internal virtual {
702
+ uint256 oldPeriod = getTimeLockPeriodSec();
626
703
  EngineBlox.updateTimeLockPeriod(_getSecureState(), newTimeLockPeriodSec);
704
+ _logComponentEvent(abi.encode(oldPeriod, newTimeLockPeriodSec));
627
705
  }
628
706
 
629
707
  // ============ FUNCTION SCHEMA MANAGEMENT ============
@@ -707,6 +785,40 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
707
785
  EngineBlox._validateRoleExists(_getSecureState(), roleHash);
708
786
  }
709
787
 
788
+ /**
789
+ * @dev Centralized function to validate that the caller is the contract itself (for execution-only entry points).
790
+ */
791
+ function _validateExecuteBySelf() internal view {
792
+ SharedValidation.validateInternalCall(address(this));
793
+ }
794
+
795
+ /**
796
+ * @dev Centralized function to validate batch size against EngineBlox.MAX_BATCH_SIZE.
797
+ * @param length The batch length to validate
798
+ */
799
+ function _validateBatchSize(uint256 length) internal pure {
800
+ SharedValidation.validateBatchSize(length, EngineBlox.MAX_BATCH_SIZE);
801
+ }
802
+
803
+ // ============ MACRO SELECTORS ============
804
+
805
+ /**
806
+ * @dev Adds a function selector to the system macro selectors set.
807
+ * Macro selectors are allowed to target address(this) for system-level operations.
808
+ * @param functionSelector The function selector to add (e.g. NATIVE_TRANSFER_SELECTOR).
809
+ */
810
+ function _addMacroSelector(bytes4 functionSelector) internal {
811
+ EngineBlox.addMacroSelector(_getSecureState(), functionSelector);
812
+ }
813
+
814
+ /**
815
+ * @dev Returns true if the given function selector is in the system macro selectors set.
816
+ * @param functionSelector The function selector to check.
817
+ */
818
+ function _isMacroSelector(bytes4 functionSelector) internal view returns (bool) {
819
+ return EngineBlox.isMacroSelector(_getSecureState(), functionSelector);
820
+ }
821
+
710
822
  // ============ UTILITY FUNCTIONS ============
711
823
 
712
824
  /**
@@ -750,11 +862,13 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
750
862
  }
751
863
 
752
864
  /**
753
- * @dev Centralized function to get all whitelisted targets for a function selector
865
+ * @dev Gets all whitelisted targets for a function selector
754
866
  * @param functionSelector The function selector
755
867
  * @return Array of whitelisted target addresses
868
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
756
869
  */
757
- function _getFunctionWhitelistTargets(bytes4 functionSelector) internal view returns (address[] memory) {
870
+ function getFunctionWhitelistTargets(bytes4 functionSelector) public view returns (address[] memory) {
871
+ _validateAnyRole();
758
872
  return _getSecureState().getFunctionWhitelistTargets(functionSelector);
759
873
  }
760
874
 
@@ -766,14 +880,24 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
766
880
  * @param functionSchemas Array of function schema definitions
767
881
  * @param roleHashes Array of role hashes
768
882
  * @param functionPermissions Array of function permissions (parallel to roleHashes)
883
+ * @param allowProtectedSchemas Whether to allow protected function schemas (default: true for factory settings)
884
+ * @notice When allowProtectedSchemas is false, reverts if any function schema is protected
885
+ * @notice This allows custom definitions to be restricted from creating protected schemas
769
886
  */
770
887
  function _loadDefinitions(
771
888
  EngineBlox.FunctionSchema[] memory functionSchemas,
772
889
  bytes32[] memory roleHashes,
773
- EngineBlox.FunctionPermission[] memory functionPermissions
890
+ EngineBlox.FunctionPermission[] memory functionPermissions,
891
+ bool allowProtectedSchemas
774
892
  ) internal {
775
893
  // Load function schemas
776
894
  for (uint256 i = 0; i < functionSchemas.length; i++) {
895
+ // Validate protected schemas if not allowed (for custom definitions)
896
+ if (!allowProtectedSchemas && functionSchemas[i].isProtected) {
897
+ revert SharedValidation.CannotModifyProtected(
898
+ bytes32(functionSchemas[i].functionSelector)
899
+ );
900
+ }
777
901
  EngineBlox.createFunctionSchema(
778
902
  _getSecureState(),
779
903
  functionSchemas[i].functionSignature,
@@ -831,4 +955,13 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
831
955
  }
832
956
  }
833
957
 
958
+ /**
959
+ * @dev Centralized component event logging for SecureOwnable, GuardController, RuntimeRBAC.
960
+ * Uses msg.sig as the event index so callers only pass encoded data.
961
+ * @param data abi.encode of event parameters
962
+ */
963
+ function _logComponentEvent(bytes memory data) internal {
964
+ emit ComponentEvent(msg.sig, data);
965
+ }
966
+
834
967
  }
@@ -105,6 +105,13 @@ interface IBaseStateMachine {
105
105
  */
106
106
  function isActionSupportedByFunction(bytes4 functionSelector, EngineBlox.TxAction action) external view returns (bool);
107
107
 
108
+ /**
109
+ * @dev Gets function schema information
110
+ * @param functionSelector The function selector to get information for
111
+ * @return The full FunctionSchema struct
112
+ */
113
+ function getFunctionSchema(bytes4 functionSelector) external view returns (EngineBlox.FunctionSchema memory);
114
+
108
115
  /**
109
116
  * @dev Gets the function permissions for a specific role
110
117
  * @param roleHash The hash of the role to get permissions for