@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
@@ -246,5 +246,24 @@
246
246
  ],
247
247
  "stateMutability": "pure",
248
248
  "type": "function"
249
+ },
250
+ {
251
+ "inputs": [
252
+ {
253
+ "internalType": "bytes4",
254
+ "name": "interfaceId",
255
+ "type": "bytes4"
256
+ }
257
+ ],
258
+ "name": "supportsInterface",
259
+ "outputs": [
260
+ {
261
+ "internalType": "bool",
262
+ "name": "",
263
+ "type": "bool"
264
+ }
265
+ ],
266
+ "stateMutability": "pure",
267
+ "type": "function"
249
268
  }
250
269
  ]
@@ -0,0 +1,8 @@
1
+ # Bloxchain Components
2
+
3
+ Official **components** built on top of `core/` that form a component library for building applications. These are maintained by the protocol team and sit outside the minimal engine.
4
+
5
+
6
+ ## Structure
7
+
8
+ Subfolders will be added by domain as components are added.
@@ -0,0 +1,184 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ pragma solidity 0.8.33;
3
+
4
+ // Contract imports
5
+ import "../base/BaseStateMachine.sol";
6
+ import "../lib/EngineBlox.sol";
7
+ import "../lib/utils/SharedValidation.sol";
8
+ import "./lib/definitions/RuntimeRBACDefinitions.sol";
9
+ import "../lib/interfaces/IDefinition.sol";
10
+ import "./interface/IRuntimeRBAC.sol";
11
+
12
+ /**
13
+ * @title RuntimeRBAC
14
+ * @dev Minimal Runtime Role-Based Access Control system based on EngineBlox
15
+ *
16
+ * This contract provides essential runtime RBAC functionality:
17
+ * - Creation of non-protected roles
18
+ * - Basic wallet assignment to roles
19
+ * - Function permission management per role
20
+ * - Integration with EngineBlox for secure operations
21
+ *
22
+ * Key Features:
23
+ * - Only non-protected roles can be created dynamically
24
+ * - Protected roles (OWNER, BROADCASTER, RECOVERY) are managed by SecureOwnable
25
+ * - Minimal interface for core RBAC operations
26
+ * - Essential role management functions only
27
+ */
28
+ abstract contract RuntimeRBAC is BaseStateMachine, IRuntimeRBAC {
29
+ using EngineBlox for EngineBlox.SecureOperationState;
30
+ using SharedValidation for *;
31
+
32
+ /**
33
+ * @notice Initializer to initialize RuntimeRBAC
34
+ * @param initialOwner The initial owner address
35
+ * @param broadcaster The broadcaster address
36
+ * @param recovery The recovery address
37
+ * @param timeLockPeriodSec The timelock period in seconds
38
+ * @param eventForwarder The event forwarder address
39
+ */
40
+ function initialize(
41
+ address initialOwner,
42
+ address broadcaster,
43
+ address recovery,
44
+ uint256 timeLockPeriodSec,
45
+ address eventForwarder
46
+ ) public virtual onlyInitializing {
47
+ // Initialize base state machine (only if not already initialized)
48
+ if (!_secureState.initialized) {
49
+ _initializeBaseStateMachine(initialOwner, broadcaster, recovery, timeLockPeriodSec, eventForwarder);
50
+ }
51
+
52
+ // Load RuntimeRBAC-specific definitions
53
+ IDefinition.RolePermission memory permissions = RuntimeRBACDefinitions.getRolePermissions();
54
+ _loadDefinitions(
55
+ RuntimeRBACDefinitions.getFunctionSchemas(),
56
+ permissions.roleHashes,
57
+ permissions.functionPermissions,
58
+ true // Allow protected schemas for factory settings
59
+ );
60
+ }
61
+
62
+ // ============ INTERFACE SUPPORT ============
63
+
64
+ /**
65
+ * @dev See {IERC165-supportsInterface}.
66
+ * @notice Adds IRuntimeRBAC interface ID for component detection
67
+ */
68
+ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
69
+ return interfaceId == type(IRuntimeRBAC).interfaceId || super.supportsInterface(interfaceId);
70
+ }
71
+
72
+ // ============ ROLE CONFIGURATION BATCH INTERFACE ============
73
+
74
+ /**
75
+ * @dev Requests and approves a RBAC configuration batch using a meta-transaction
76
+ * @param metaTx The meta-transaction
77
+ * @return The transaction record
78
+ * @notice OWNER signs, BROADCASTER executes according to RuntimeRBACDefinitions
79
+ */
80
+ function roleConfigBatchRequestAndApprove(
81
+ EngineBlox.MetaTransaction memory metaTx
82
+ ) public returns (uint256) {
83
+ _validateBroadcaster(msg.sender);
84
+ EngineBlox.TxRecord memory txRecord = _requestAndApproveTransaction(metaTx);
85
+ return txRecord.txId;
86
+ }
87
+
88
+ /**
89
+ * @dev External function that can only be called by the contract itself to execute a RBAC configuration batch
90
+ * @param actions Encoded role configuration actions
91
+ */
92
+ function executeRoleConfigBatch(IRuntimeRBAC.RoleConfigAction[] calldata actions) external {
93
+ _validateExecuteBySelf();
94
+ _executeRoleConfigBatch(actions);
95
+ }
96
+
97
+ // ============ HELPER FUNCTIONS ============
98
+
99
+ /**
100
+ * @dev Reverts if the role is protected (prevents editing OWNER, BROADCASTER, RECOVERY via batch).
101
+ * @param roleHash The role hash to check
102
+ */
103
+ function _requireRoleNotProtected(bytes32 roleHash) internal view {
104
+ if (_getSecureState().roles[roleHash].isProtected) {
105
+ revert SharedValidation.CannotModifyProtected(roleHash);
106
+ }
107
+ }
108
+
109
+ /**
110
+ * @dev Internal helper to execute a RBAC configuration batch
111
+ * @param actions Encoded role configuration actions
112
+ */
113
+ function _executeRoleConfigBatch(IRuntimeRBAC.RoleConfigAction[] calldata actions) internal {
114
+ _validateBatchSize(actions.length);
115
+
116
+ for (uint256 i = 0; i < actions.length; i++) {
117
+ IRuntimeRBAC.RoleConfigAction calldata action = actions[i];
118
+
119
+ if (action.actionType == IRuntimeRBAC.RoleConfigActionType.CREATE_ROLE) {
120
+ // Decode CREATE_ROLE action data
121
+ // Format: (string roleName, uint256 maxWallets)
122
+ (
123
+ string memory roleName,
124
+ uint256 maxWallets
125
+ ) = abi.decode(action.data, (string, uint256));
126
+
127
+ // Create the role in the secure state with isProtected = false
128
+ bytes32 roleHash = _createRole(roleName, maxWallets, false);
129
+
130
+ _logComponentEvent(_encodeRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType.CREATE_ROLE, roleHash, bytes4(0)));
131
+ } else if (action.actionType == IRuntimeRBAC.RoleConfigActionType.REMOVE_ROLE) {
132
+ // Decode REMOVE_ROLE action data
133
+ // Format: (bytes32 roleHash)
134
+ (bytes32 roleHash) = abi.decode(action.data, (bytes32));
135
+ _removeRole(roleHash);
136
+
137
+ _logComponentEvent(_encodeRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType.REMOVE_ROLE, roleHash, bytes4(0)));
138
+ } else if (action.actionType == IRuntimeRBAC.RoleConfigActionType.ADD_WALLET) {
139
+ // Decode ADD_WALLET action data
140
+ // Format: (bytes32 roleHash, address wallet)
141
+ (bytes32 roleHash, address wallet) = abi.decode(action.data, (bytes32, address));
142
+ _requireRoleNotProtected(roleHash);
143
+ _assignWallet(roleHash, wallet);
144
+
145
+ _logComponentEvent(_encodeRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType.ADD_WALLET, roleHash, bytes4(0)));
146
+ } else if (action.actionType == IRuntimeRBAC.RoleConfigActionType.REVOKE_WALLET) {
147
+ // Decode REVOKE_WALLET action data
148
+ // Format: (bytes32 roleHash, address wallet)
149
+ (bytes32 roleHash, address wallet) = abi.decode(action.data, (bytes32, address));
150
+ _requireRoleNotProtected(roleHash);
151
+ _revokeWallet(roleHash, wallet);
152
+
153
+ _logComponentEvent(_encodeRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType.REVOKE_WALLET, roleHash, bytes4(0)));
154
+ } else if (action.actionType == IRuntimeRBAC.RoleConfigActionType.ADD_FUNCTION_TO_ROLE) {
155
+ // Decode ADD_FUNCTION_TO_ROLE action data
156
+ // Format: (bytes32 roleHash, FunctionPermission functionPermission)
157
+ (
158
+ bytes32 roleHash,
159
+ EngineBlox.FunctionPermission memory functionPermission
160
+ ) = abi.decode(action.data, (bytes32, EngineBlox.FunctionPermission));
161
+
162
+ _addFunctionToRole(roleHash, functionPermission);
163
+
164
+ _logComponentEvent(_encodeRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType.ADD_FUNCTION_TO_ROLE, roleHash, functionPermission.functionSelector));
165
+ } else if (action.actionType == IRuntimeRBAC.RoleConfigActionType.REMOVE_FUNCTION_FROM_ROLE) {
166
+ // Decode REMOVE_FUNCTION_FROM_ROLE action data
167
+ // Format: (bytes32 roleHash, bytes4 functionSelector)
168
+ (bytes32 roleHash, bytes4 functionSelector) = abi.decode(action.data, (bytes32, bytes4));
169
+ _removeFunctionFromRole(roleHash, functionSelector);
170
+
171
+ _logComponentEvent(_encodeRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType.REMOVE_FUNCTION_FROM_ROLE, roleHash, functionSelector));
172
+ } else {
173
+ revert SharedValidation.NotSupported();
174
+ }
175
+ }
176
+ }
177
+
178
+ /**
179
+ * @dev Encodes RBAC config event payload for ComponentEvent. Decode as (RoleConfigActionType, bytes32 roleHash, bytes4 functionSelector).
180
+ */
181
+ function _encodeRoleConfigEvent(IRuntimeRBAC.RoleConfigActionType action, bytes32 roleHash, bytes4 selector) internal pure returns (bytes memory) {
182
+ return abi.encode(action, roleHash, selector);
183
+ }
184
+ }
@@ -0,0 +1,55 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ pragma solidity 0.8.33;
3
+
4
+ import "../../lib/EngineBlox.sol";
5
+
6
+ /**
7
+ * @title IRuntimeRBAC
8
+ * @dev Interface for Runtime Role-Based Access Control system
9
+ *
10
+ * This interface defines the functions for managing runtime roles through batch operations.
11
+ * All role management operations are performed via the batch interface for atomic execution.
12
+ *
13
+ * Key Features:
14
+ * - Batch-based role configuration (atomic operations)
15
+ * - Runtime function schema registration
16
+ * - Integration with EngineBlox for secure operations
17
+ * - Query functions for role and permission inspection
18
+ *
19
+ * Note: This contract inherits from BaseStateMachine which provides additional query functions
20
+ * such as getRole(), hasRole(), getActiveRolePermissions(), getSupportedRoles(), etc.
21
+ */
22
+ interface IRuntimeRBAC {
23
+ /**
24
+ * @dev Action types for batched RBAC configuration
25
+ */
26
+ enum RoleConfigActionType {
27
+ CREATE_ROLE,
28
+ REMOVE_ROLE,
29
+ ADD_WALLET,
30
+ REVOKE_WALLET,
31
+ ADD_FUNCTION_TO_ROLE,
32
+ REMOVE_FUNCTION_FROM_ROLE
33
+ }
34
+
35
+ /**
36
+ * @dev Encodes a single RBAC configuration action in a batch
37
+ */
38
+ struct RoleConfigAction {
39
+ RoleConfigActionType actionType;
40
+ bytes data;
41
+ }
42
+
43
+ /// @dev RBAC config changes are emitted via BaseStateMachine.ComponentEvent with functionSelector = msg.sig (executeRoleConfigBatch). Decode data as (RoleConfigActionType, bytes32 roleHash, bytes4 functionSelector).
44
+
45
+ // ============ ROLE CONFIGURATION BATCH INTERFACE ============
46
+
47
+ /**
48
+ * @dev Requests and approves a RBAC configuration batch using a meta-transaction
49
+ * @param metaTx The meta-transaction
50
+ * @return The transaction record
51
+ */
52
+ function roleConfigBatchRequestAndApprove(
53
+ EngineBlox.MetaTransaction memory metaTx
54
+ ) external returns (uint256);
55
+ }
@@ -1,8 +1,10 @@
1
1
  // SPDX-License-Identifier: MPL-2.0
2
2
  pragma solidity 0.8.33;
3
3
 
4
+ import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
4
5
  import "../../../lib/EngineBlox.sol";
5
- import "../../../../interfaces/IDefinition.sol";
6
+ import "../../../lib/interfaces/IDefinition.sol";
7
+ import "../../../access/interface/IRuntimeRBAC.sol";
6
8
 
7
9
  /**
8
10
  * @title RuntimeRBACDefinitions
@@ -165,4 +167,122 @@ library RuntimeRBACDefinitions {
165
167
  functionPermissions: functionPermissions
166
168
  });
167
169
  }
170
+
171
+ /**
172
+ * @dev Returns all available RoleConfig action types and their decode formats for discovery.
173
+ * @return actionNames Human-readable action names (same order as RoleConfigActionType enum)
174
+ * @return formats ABI decode format for each action's data, e.g. "(string roleName, uint256 maxWallets)"
175
+ * @notice Use with RoleConfigActionType enum: actionNames[i] and formats[i] describe enum value i
176
+ */
177
+ function getRoleConfigActionSpecs() public pure returns (string[] memory actionNames, string[] memory formats) {
178
+ actionNames = new string[](6);
179
+ formats = new string[](6);
180
+
181
+ actionNames[0] = "CREATE_ROLE";
182
+ formats[0] = "(string roleName, uint256 maxWallets)";
183
+
184
+ actionNames[1] = "REMOVE_ROLE";
185
+ formats[1] = "(bytes32 roleHash)";
186
+
187
+ actionNames[2] = "ADD_WALLET";
188
+ formats[2] = "(bytes32 roleHash, address wallet)";
189
+
190
+ actionNames[3] = "REVOKE_WALLET";
191
+ formats[3] = "(bytes32 roleHash, address wallet)";
192
+
193
+ actionNames[4] = "ADD_FUNCTION_TO_ROLE";
194
+ formats[4] = "(bytes32 roleHash, FunctionPermission functionPermission)";
195
+
196
+ actionNames[5] = "REMOVE_FUNCTION_FROM_ROLE";
197
+ formats[5] = "(bytes32 roleHash, bytes4 functionSelector)";
198
+ }
199
+
200
+ // ============ ROLE CONFIG ACTION DATA ENCODERS ============
201
+ // Use these helpers to build action.data for each RoleConfigActionType without reading the contract.
202
+ // Each encoder returns bytes suitable for RoleConfigAction(actionType, data).
203
+
204
+ /**
205
+ * @dev Encodes data for CREATE_ROLE. Use with RoleConfigActionType.CREATE_ROLE.
206
+ * @param roleName Name of the role to create
207
+ * @param maxWallets Maximum number of wallets that can be assigned to this role
208
+ */
209
+ function encodeCreateRole(string memory roleName, uint256 maxWallets) public pure returns (bytes memory) {
210
+ return abi.encode(roleName, maxWallets);
211
+ }
212
+
213
+ /**
214
+ * @dev Encodes data for REMOVE_ROLE. Use with RoleConfigActionType.REMOVE_ROLE.
215
+ * @param roleHash keccak256 hash of the role name
216
+ */
217
+ function encodeRemoveRole(bytes32 roleHash) public pure returns (bytes memory) {
218
+ return abi.encode(roleHash);
219
+ }
220
+
221
+ /**
222
+ * @dev Encodes data for ADD_WALLET. Use with RoleConfigActionType.ADD_WALLET.
223
+ * @param roleHash Role to add the wallet to
224
+ * @param wallet Address to assign to the role
225
+ */
226
+ function encodeAddWallet(bytes32 roleHash, address wallet) public pure returns (bytes memory) {
227
+ return abi.encode(roleHash, wallet);
228
+ }
229
+
230
+ /**
231
+ * @dev Encodes data for REVOKE_WALLET. Use with RoleConfigActionType.REVOKE_WALLET.
232
+ * @param roleHash Role to revoke the wallet from
233
+ * @param wallet Address to revoke
234
+ */
235
+ function encodeRevokeWallet(bytes32 roleHash, address wallet) public pure returns (bytes memory) {
236
+ return abi.encode(roleHash, wallet);
237
+ }
238
+
239
+ /**
240
+ * @dev Encodes data for ADD_FUNCTION_TO_ROLE. Use with RoleConfigActionType.ADD_FUNCTION_TO_ROLE.
241
+ * @param roleHash Role to grant the function permission to
242
+ * @param functionPermission FunctionPermission (functionSelector, grantedActionsBitmap, handlerForSelectors)
243
+ */
244
+ function encodeAddFunctionToRole(
245
+ bytes32 roleHash,
246
+ EngineBlox.FunctionPermission memory functionPermission
247
+ ) public pure returns (bytes memory) {
248
+ return abi.encode(roleHash, functionPermission);
249
+ }
250
+
251
+ /**
252
+ * @dev Encodes data for REMOVE_FUNCTION_FROM_ROLE. Use with RoleConfigActionType.REMOVE_FUNCTION_FROM_ROLE.
253
+ * @param roleHash Role to remove the function from
254
+ * @param functionSelector Selector of the function to remove
255
+ */
256
+ function encodeRemoveFunctionFromRole(bytes32 roleHash, bytes4 functionSelector) public pure returns (bytes memory) {
257
+ return abi.encode(roleHash, functionSelector);
258
+ }
259
+
260
+ /**
261
+ * @dev Creates execution params for a RBAC configuration batch (pure helper for EngineBlox).
262
+ * @param actions Encoded role configuration actions (IRuntimeRBAC.RoleConfigAction[] layout)
263
+ * @return The execution params for EngineBlox
264
+ */
265
+ function roleConfigBatchExecutionParams(
266
+ IRuntimeRBAC.RoleConfigAction[] memory actions
267
+ ) public pure returns (bytes memory) {
268
+ return abi.encode(actions);
269
+ }
270
+
271
+ /**
272
+ * @dev Creates execution params from pre-encoded actions (e.g. abi.encode(RuntimeRBAC.RoleConfigAction[])).
273
+ * Use when callers have RuntimeRBAC.RoleConfigAction[] and same encoding applies.
274
+ * @param preEncoded ABI-encoded role config actions array
275
+ * @return The execution params for EngineBlox
276
+ */
277
+ function roleConfigBatchExecutionParams(bytes memory preEncoded) public pure returns (bytes memory) {
278
+ return preEncoded;
279
+ }
280
+
281
+ /**
282
+ * @dev ERC165: report support for IDefinition and IERC165 when this library is used at an address.
283
+ * IDefinition extends IERC165; both interface IDs must be reported for ERC165 compliance.
284
+ */
285
+ function supportsInterface(bytes4 interfaceId) external pure returns (bool) {
286
+ return interfaceId == type(IERC165).interfaceId || interfaceId == type(IDefinition).interfaceId;
287
+ }
168
288
  }