@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
@@ -1,11 +1,10 @@
1
1
  // SPDX-License-Identifier: MPL-2.0
2
2
  pragma solidity 0.8.33;
3
3
 
4
- import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
5
4
  import "../base/BaseStateMachine.sol";
6
- import "../../utils/SharedValidation.sol";
5
+ import "../lib/utils/SharedValidation.sol";
7
6
  import "./lib/definitions/GuardControllerDefinitions.sol";
8
- import "../../interfaces/IDefinition.sol";
7
+ import "../lib/interfaces/IDefinition.sol";
9
8
  import "./interface/IGuardController.sol";
10
9
 
11
10
  /**
@@ -58,41 +57,6 @@ import "./interface/IGuardController.sol";
58
57
  abstract contract GuardController is BaseStateMachine {
59
58
  using EngineBlox for EngineBlox.SecureOperationState;
60
59
 
61
- /**
62
- * @dev Action types for batched Guard configuration
63
- */
64
- enum GuardConfigActionType {
65
- ADD_TARGET_TO_WHITELIST,
66
- REMOVE_TARGET_FROM_WHITELIST,
67
- REGISTER_FUNCTION,
68
- UNREGISTER_FUNCTION
69
- }
70
-
71
- /**
72
- * @dev Encodes a single Guard configuration action in a batch
73
- */
74
- struct GuardConfigAction {
75
- GuardConfigActionType actionType;
76
- bytes data;
77
- }
78
-
79
- // ============ EVENTS ============
80
-
81
- /**
82
- * @dev Unified event for all Guard configuration changes applied via batches
83
- *
84
- * - actionType: the high-level type of configuration action
85
- * - functionSelector: affected function selector (if applicable, otherwise 0)
86
- * - target: affected target address (if applicable, otherwise 0)
87
- * - data: optional action-specific payload (kept minimal for size; decoded off-chain if needed)
88
- */
89
- event GuardConfigApplied(
90
- GuardConfigActionType indexed actionType,
91
- bytes4 indexed functionSelector,
92
- address indexed target,
93
- bytes data
94
- );
95
-
96
60
  /**
97
61
  * @notice Initializer to initialize GuardController
98
62
  * @param initialOwner The initial owner address
@@ -118,7 +82,8 @@ abstract contract GuardController is BaseStateMachine {
118
82
  _loadDefinitions(
119
83
  GuardControllerDefinitions.getFunctionSchemas(),
120
84
  guardControllerPermissions.roleHashes,
121
- guardControllerPermissions.functionPermissions
85
+ guardControllerPermissions.functionPermissions,
86
+ true // Allow protected schemas for factory settings
122
87
  );
123
88
  }
124
89
 
@@ -155,10 +120,7 @@ abstract contract GuardController is BaseStateMachine {
155
120
  bytes memory params,
156
121
  uint256 gasLimit,
157
122
  bytes32 operationType
158
- ) public returns (EngineBlox.TxRecord memory) {
159
- // Validate inputs
160
- SharedValidation.validateNotZeroAddress(target);
161
-
123
+ ) public returns (uint256 txId) {
162
124
  // SECURITY: Prevent access to internal execution functions
163
125
  _validateNotInternalFunction(target, functionSelector);
164
126
 
@@ -172,7 +134,44 @@ abstract contract GuardController is BaseStateMachine {
172
134
  functionSelector,
173
135
  params
174
136
  );
175
- return txRecord;
137
+ return txRecord.txId;
138
+ }
139
+
140
+ /**
141
+ * @dev Requests a time-locked execution with payment details attached (same permissions as executeWithTimeLock)
142
+ * @param target The address of the target contract
143
+ * @param value The ETH value to send (0 for standard function calls)
144
+ * @param functionSelector The function selector to execute (NATIVE_TRANSFER_SELECTOR for simple native token transfers)
145
+ * @param params The encoded parameters for the function (empty for simple native token transfers)
146
+ * @param gasLimit The gas limit for execution
147
+ * @param operationType The operation type hash
148
+ * @param paymentDetails The payment details to attach to the transaction
149
+ * @return txId The transaction ID for the requested operation (use getTransaction(txId) for full record)
150
+ * @notice Creates a time-locked transaction with payment that must be approved after the timelock period
151
+ * @notice Reuses EXECUTE_TIME_DELAY_REQUEST permission for the execution selector (no new definitions)
152
+ * @notice Approval/cancel use same flows as executeWithTimeLock (approveTimeLockExecution, cancelTimeLockExecution)
153
+ */
154
+ function executeWithPayment(
155
+ address target,
156
+ uint256 value,
157
+ bytes4 functionSelector,
158
+ bytes memory params,
159
+ uint256 gasLimit,
160
+ bytes32 operationType,
161
+ EngineBlox.PaymentDetails memory paymentDetails
162
+ ) public returns (uint256 txId) {
163
+ _validateNotInternalFunction(target, functionSelector);
164
+ EngineBlox.TxRecord memory txRecord = _requestTransactionWithPayment(
165
+ msg.sender,
166
+ target,
167
+ value,
168
+ gasLimit,
169
+ operationType,
170
+ functionSelector,
171
+ params,
172
+ paymentDetails
173
+ );
174
+ return txRecord.txId;
176
175
  }
177
176
 
178
177
  /**
@@ -183,13 +182,14 @@ abstract contract GuardController is BaseStateMachine {
183
182
  */
184
183
  function approveTimeLockExecution(
185
184
  uint256 txId
186
- ) public returns (EngineBlox.TxRecord memory) {
185
+ ) public returns (uint256) {
187
186
  // SECURITY: Prevent access to internal execution functions
188
187
  EngineBlox.TxRecord memory txRecord = _getSecureState().txRecords[txId];
189
188
  _validateNotInternalFunction(txRecord.params.target, txRecord.params.executionSelector);
190
189
 
191
190
  // Approve via BaseStateMachine helper (validates permissions and whitelist in EngineBlox)
192
- return _approveTransaction(txId);
191
+ txRecord = _approveTransaction(txId);
192
+ return txRecord.txId;
193
193
  }
194
194
 
195
195
  /**
@@ -200,13 +200,14 @@ abstract contract GuardController is BaseStateMachine {
200
200
  */
201
201
  function cancelTimeLockExecution(
202
202
  uint256 txId
203
- ) public returns (EngineBlox.TxRecord memory) {
203
+ ) public returns (uint256) {
204
204
  // SECURITY: Prevent access to internal execution functions
205
205
  EngineBlox.TxRecord memory txRecord = _getSecureState().txRecords[txId];
206
206
  _validateNotInternalFunction(txRecord.params.target, txRecord.params.executionSelector);
207
207
 
208
208
  // Cancel via BaseStateMachine helper (validates permissions in EngineBlox)
209
- return _cancelTransaction(txId);
209
+ txRecord = _cancelTransaction(txId);
210
+ return txRecord.txId;
210
211
  }
211
212
 
212
213
  /**
@@ -217,12 +218,13 @@ abstract contract GuardController is BaseStateMachine {
217
218
  */
218
219
  function approveTimeLockExecutionWithMetaTx(
219
220
  EngineBlox.MetaTransaction memory metaTx
220
- ) public returns (EngineBlox.TxRecord memory) {
221
+ ) public returns (uint256) {
221
222
  // SECURITY: Prevent access to internal execution functions
222
223
  _validateNotInternalFunction(metaTx.txRecord.params.target, metaTx.txRecord.params.executionSelector);
223
224
 
224
225
  // Approve via BaseStateMachine helper (validates permissions and whitelist in EngineBlox)
225
- return _approveTransactionWithMetaTx(metaTx);
226
+ EngineBlox.TxRecord memory txRecord = _approveTransactionWithMetaTx(metaTx);
227
+ return txRecord.txId;
226
228
  }
227
229
 
228
230
  /**
@@ -233,12 +235,13 @@ abstract contract GuardController is BaseStateMachine {
233
235
  */
234
236
  function cancelTimeLockExecutionWithMetaTx(
235
237
  EngineBlox.MetaTransaction memory metaTx
236
- ) public returns (EngineBlox.TxRecord memory) {
238
+ ) public returns (uint256) {
237
239
  // SECURITY: Prevent access to internal execution functions
238
240
  _validateNotInternalFunction(metaTx.txRecord.params.target, metaTx.txRecord.params.executionSelector);
239
241
 
240
242
  // Cancel via BaseStateMachine helper (validates permissions and whitelist in EngineBlox)
241
- return _cancelTransactionWithMetaTx(metaTx);
243
+ EngineBlox.TxRecord memory txRecord = _cancelTransactionWithMetaTx(metaTx);
244
+ return txRecord.txId;
242
245
  }
243
246
 
244
247
  /**
@@ -251,12 +254,13 @@ abstract contract GuardController is BaseStateMachine {
251
254
  */
252
255
  function requestAndApproveExecution(
253
256
  EngineBlox.MetaTransaction memory metaTx
254
- ) public returns (EngineBlox.TxRecord memory) {
257
+ ) public returns (uint256) {
255
258
  // SECURITY: Prevent access to internal execution functions
256
259
  _validateNotInternalFunction(metaTx.txRecord.params.target, metaTx.txRecord.params.executionSelector);
257
260
 
258
261
  // Request and approve via BaseStateMachine helper (validates permissions and whitelist in EngineBlox)
259
- return _requestAndApproveTransaction(metaTx);
262
+ EngineBlox.TxRecord memory txRecord = _requestAndApproveTransaction(metaTx);
263
+ return txRecord.txId;
260
264
  }
261
265
 
262
266
  // Note: Meta-transaction utility functions (createMetaTxParams,
@@ -268,20 +272,6 @@ abstract contract GuardController is BaseStateMachine {
268
272
 
269
273
  // ============ INTERNAL VALIDATION HELPERS ============
270
274
 
271
- /**
272
- * @dev Checks if a function selector is a known system macro selector
273
- * @param functionSelector The function selector to check
274
- * @return true if the selector is a known system macro selector, false otherwise
275
- * @notice System macro selectors are special selectors that represent system-level operations
276
- * and are allowed to bypass certain security restrictions
277
- * @notice Currently known macro selectors:
278
- * - NATIVE_TRANSFER_SELECTOR: For native token transfers
279
- */
280
- function _isSystemMacroSelector(bytes4 functionSelector) internal pure returns (bool) {
281
- return functionSelector == EngineBlox.NATIVE_TRANSFER_SELECTOR
282
- || functionSelector == EngineBlox.UPDATE_PAYMENT_SELECTOR;
283
- }
284
-
285
275
  /**
286
276
  * @dev Validates that GuardController is not attempting to access internal execution functions
287
277
  * @param target The target contract address
@@ -304,7 +294,7 @@ abstract contract GuardController is BaseStateMachine {
304
294
  if (target == address(this)) {
305
295
  // Allow system macro selectors (e.g., NATIVE_TRANSFER_SELECTOR for native token deposits)
306
296
  // These are special system-level operations that are safe to execute on address(this)
307
- if (_isSystemMacroSelector(functionSelector)) {
297
+ if (_isMacroSelector(functionSelector)) {
308
298
  return; // Allow system macro selectors
309
299
  }
310
300
 
@@ -315,17 +305,6 @@ abstract contract GuardController is BaseStateMachine {
315
305
 
316
306
  // ============ GUARD CONFIGURATION BATCH INTERFACE ============
317
307
 
318
- /**
319
- * @dev Creates execution params for a Guard configuration batch
320
- * @param actions Encoded guard configuration actions
321
- * @return The execution params for EngineBlox
322
- */
323
- function guardConfigBatchExecutionParams(
324
- GuardConfigAction[] memory actions
325
- ) public pure returns (bytes memory) {
326
- return abi.encode(actions);
327
- }
328
-
329
308
  /**
330
309
  * @dev Requests and approves a Guard configuration batch using a meta-transaction
331
310
  * @param metaTx The meta-transaction
@@ -334,19 +313,18 @@ abstract contract GuardController is BaseStateMachine {
334
313
  */
335
314
  function guardConfigBatchRequestAndApprove(
336
315
  EngineBlox.MetaTransaction memory metaTx
337
- ) public returns (EngineBlox.TxRecord memory) {
316
+ ) public returns (uint256) {
338
317
  _validateBroadcaster(msg.sender);
339
- SharedValidation.validateOwnerIsSigner(metaTx.params.signer, owner());
340
-
341
- return _requestAndApproveTransaction(metaTx);
318
+ EngineBlox.TxRecord memory txRecord = _requestAndApproveTransaction(metaTx);
319
+ return txRecord.txId;
342
320
  }
343
321
 
344
322
  /**
345
323
  * @dev External function that can only be called by the contract itself to execute a Guard configuration batch
346
324
  * @param actions Encoded guard configuration actions
347
325
  */
348
- function executeGuardConfigBatch(GuardConfigAction[] calldata actions) external {
349
- SharedValidation.validateInternalCall(address(this));
326
+ function executeGuardConfigBatch(IGuardController.GuardConfigAction[] calldata actions) external {
327
+ _validateExecuteBySelf();
350
328
  _executeGuardConfigBatch(actions);
351
329
  }
352
330
 
@@ -356,43 +334,29 @@ abstract contract GuardController is BaseStateMachine {
356
334
  * @dev Internal helper to execute a Guard configuration batch
357
335
  * @param actions Encoded guard configuration actions
358
336
  */
359
- function _executeGuardConfigBatch(GuardConfigAction[] calldata actions) internal {
360
- // Validate batch size limit
361
- SharedValidation.validateBatchSize(
362
- actions.length,
363
- EngineBlox.MAX_BATCH_SIZE
364
- );
365
-
337
+ function _executeGuardConfigBatch(IGuardController.GuardConfigAction[] calldata actions) internal {
338
+ _validateBatchSize(actions.length);
339
+
366
340
  for (uint256 i = 0; i < actions.length; i++) {
367
- GuardConfigAction calldata action = actions[i];
341
+ IGuardController.GuardConfigAction calldata action = actions[i];
368
342
 
369
- if (action.actionType == GuardConfigActionType.ADD_TARGET_TO_WHITELIST) {
343
+ if (action.actionType == IGuardController.GuardConfigActionType.ADD_TARGET_TO_WHITELIST) {
370
344
  // Decode ADD_TARGET_TO_WHITELIST action data
371
345
  // Format: (bytes4 functionSelector, address target)
372
346
  (bytes4 functionSelector, address target) = abi.decode(action.data, (bytes4, address));
373
347
 
374
348
  _addTargetToFunctionWhitelist(functionSelector, target);
375
349
 
376
- emit GuardConfigApplied(
377
- GuardConfigActionType.ADD_TARGET_TO_WHITELIST,
378
- functionSelector,
379
- target,
380
- "" // optional: could encode additional data if needed
381
- );
382
- } else if (action.actionType == GuardConfigActionType.REMOVE_TARGET_FROM_WHITELIST) {
350
+ _logComponentEvent(_encodeGuardConfigEvent(IGuardController.GuardConfigActionType.ADD_TARGET_TO_WHITELIST, functionSelector, target));
351
+ } else if (action.actionType == IGuardController.GuardConfigActionType.REMOVE_TARGET_FROM_WHITELIST) {
383
352
  // Decode REMOVE_TARGET_FROM_WHITELIST action data
384
353
  // Format: (bytes4 functionSelector, address target)
385
354
  (bytes4 functionSelector, address target) = abi.decode(action.data, (bytes4, address));
386
355
 
387
356
  _removeTargetFromFunctionWhitelist(functionSelector, target);
388
357
 
389
- emit GuardConfigApplied(
390
- GuardConfigActionType.REMOVE_TARGET_FROM_WHITELIST,
391
- functionSelector,
392
- target,
393
- ""
394
- );
395
- } else if (action.actionType == GuardConfigActionType.REGISTER_FUNCTION) {
358
+ _logComponentEvent(_encodeGuardConfigEvent(IGuardController.GuardConfigActionType.REMOVE_TARGET_FROM_WHITELIST, functionSelector, target));
359
+ } else if (action.actionType == IGuardController.GuardConfigActionType.REGISTER_FUNCTION) {
396
360
  // Decode REGISTER_FUNCTION action data
397
361
  // Format: (string functionSignature, string operationName, TxAction[] supportedActions)
398
362
  (
@@ -403,31 +367,32 @@ abstract contract GuardController is BaseStateMachine {
403
367
 
404
368
  bytes4 functionSelector = _registerFunction(functionSignature, operationName, supportedActions);
405
369
 
406
- emit GuardConfigApplied(
407
- GuardConfigActionType.REGISTER_FUNCTION,
408
- functionSelector,
409
- address(0),
410
- "" // optional: abi.encode(operationName)
411
- );
412
- } else if (action.actionType == GuardConfigActionType.UNREGISTER_FUNCTION) {
370
+ _logComponentEvent(_encodeGuardConfigEvent(IGuardController.GuardConfigActionType.REGISTER_FUNCTION, functionSelector, address(0)));
371
+ } else if (action.actionType == IGuardController.GuardConfigActionType.UNREGISTER_FUNCTION) {
413
372
  // Decode UNREGISTER_FUNCTION action data
414
373
  // Format: (bytes4 functionSelector, bool safeRemoval)
415
374
  (bytes4 functionSelector, bool safeRemoval) = abi.decode(action.data, (bytes4, bool));
416
375
 
417
376
  _unregisterFunction(functionSelector, safeRemoval);
418
377
 
419
- emit GuardConfigApplied(
420
- GuardConfigActionType.UNREGISTER_FUNCTION,
421
- functionSelector,
422
- address(0),
423
- ""
424
- );
378
+ _logComponentEvent(_encodeGuardConfigEvent(IGuardController.GuardConfigActionType.UNREGISTER_FUNCTION, functionSelector, address(0)));
425
379
  } else {
426
380
  revert SharedValidation.NotSupported();
427
381
  }
428
382
  }
429
383
  }
430
384
 
385
+ /**
386
+ * @dev Encodes guard config event payload for ComponentEvent. Decode as (GuardConfigActionType, bytes4 functionSelector, address target).
387
+ */
388
+ function _encodeGuardConfigEvent(
389
+ IGuardController.GuardConfigActionType actionType,
390
+ bytes4 functionSelector,
391
+ address target
392
+ ) internal pure returns (bytes memory) {
393
+ return abi.encode(actionType, functionSelector, target);
394
+ }
395
+
431
396
  // ============ INTERNAL FUNCTION SCHEMA HELPERS ============
432
397
 
433
398
  /**
@@ -445,16 +410,12 @@ abstract contract GuardController is BaseStateMachine {
445
410
  // Derive function selector from signature
446
411
  functionSelector = bytes4(keccak256(bytes(functionSignature)));
447
412
 
448
- // Validate that function schema doesn't already exist
449
- if (functionSchemaExists(functionSelector)) {
450
- revert SharedValidation.ResourceAlreadyExists(bytes32(functionSelector));
451
- }
452
-
453
413
  // Convert actions array to bitmap
454
414
  uint16 supportedActionsBitmap = _createBitmapFromActions(supportedActions);
455
415
 
456
416
  // Create function schema directly (always non-protected)
457
417
  // Dynamically registered functions are execution selectors (handlerForSelectors must contain self-reference)
418
+ // EngineBlox.createFunctionSchema validates schema doesn't already exist (ResourceAlreadyExists)
458
419
  bytes4[] memory executionHandlerForSelectors = new bytes4[](1);
459
420
  executionHandlerForSelectors[0] = functionSelector; // Self-reference for execution selector
460
421
  _createFunctionSchema(
@@ -471,37 +432,10 @@ abstract contract GuardController is BaseStateMachine {
471
432
  * @dev Internal helper to unregister a function schema
472
433
  * @param functionSelector The function selector to unregister
473
434
  * @param safeRemoval If true, checks for role references before removal
435
+ * @notice EngineBlox.removeFunctionSchema validates schema existence (ResourceNotFound) and protected status (CannotModifyProtected)
474
436
  */
475
437
  function _unregisterFunction(bytes4 functionSelector, bool safeRemoval) internal {
476
- // Load schema and validate it exists
477
- EngineBlox.FunctionSchema storage schema = _getSecureState().functions[functionSelector];
478
- if (schema.functionSelector != functionSelector) {
479
- revert SharedValidation.ResourceNotFound(bytes32(functionSelector));
480
- }
481
-
482
- // Ensure not protected
483
- if (schema.isProtected) {
484
- revert SharedValidation.CannotModifyProtected(bytes32(functionSelector));
485
- }
486
-
487
- // The safeRemoval check is now handled within EngineBlox.removeFunctionSchema
488
- // (avoids getSupportedRolesList/getRoleFunctionPermissions which call _validateAnyRole;
489
- // during meta-tx execution msg.sender is the contract, causing NoPermission)
490
438
  _removeFunctionSchema(functionSelector, safeRemoval);
491
439
  }
492
440
 
493
- /**
494
- * @dev Gets all whitelisted targets for a function selector
495
- * @param functionSelector The function selector
496
- * @return Array of whitelisted target addresses
497
- * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
498
- */
499
- function getAllowedTargets(
500
- bytes4 functionSelector
501
- ) external view returns (address[] memory) {
502
- _validateAnyRole();
503
- return _getFunctionWhitelistTargets(functionSelector);
504
- }
505
441
  }
506
-
507
-
@@ -7,11 +7,29 @@ import "../../lib/EngineBlox.sol";
7
7
  * @title IGuardController
8
8
  * @dev Interface for GuardController contract that GuardianSafeV3 and other contracts delegate to
9
9
  * @notice This interface defines only GuardController-specific methods
10
- * @notice Functions from BaseStateMachine (createMetaTxParams, generateUnsignedMetaTransaction*, getTransaction, functionSchemaExists, owner, getBroadcaster, getRecovery) should be accessed via IBaseStateMachine
11
- * @notice Functions from RuntimeRBAC (registerFunction, unregisterFunction, getFunctionSchema, createNewRole, addWalletToRole, revokeWallet) should be accessed via IRuntimeRBAC
10
+ * @notice Functions from BaseStateMachine (createMetaTxParams, generateUnsignedMetaTransaction*, getTransaction, functionSchemaExists, getFunctionSchema, owner, getBroadcaster, getRecovery) should be accessed via IBaseStateMachine
11
+ * @notice Functions from RuntimeRBAC (registerFunction, unregisterFunction, createNewRole, addWalletToRole, revokeWallet) should be accessed via IRuntimeRBAC
12
12
  * @custom:security-contact security@particlecrypto.com
13
13
  */
14
14
  interface IGuardController {
15
+ /**
16
+ * @dev Action types for batched Guard configuration
17
+ */
18
+ enum GuardConfigActionType {
19
+ ADD_TARGET_TO_WHITELIST,
20
+ REMOVE_TARGET_FROM_WHITELIST,
21
+ REGISTER_FUNCTION,
22
+ UNREGISTER_FUNCTION
23
+ }
24
+
25
+ /**
26
+ * @dev Encodes a single Guard configuration action in a batch
27
+ */
28
+ struct GuardConfigAction {
29
+ GuardConfigActionType actionType;
30
+ bytes data;
31
+ }
32
+
15
33
  /**
16
34
  * @notice Initializer to initialize GuardController
17
35
  * @param initialOwner The initial owner address
@@ -51,63 +69,85 @@ interface IGuardController {
51
69
  bytes32 operationType
52
70
  ) external returns (uint256 txId);
53
71
 
72
+ /**
73
+ * @dev Requests a time-locked execution with payment details attached (same permissions as executeWithTimeLock)
74
+ * @param target The address of the target contract
75
+ * @param value The ETH value to send (0 for standard function calls)
76
+ * @param functionSelector The function selector to execute (NATIVE_TRANSFER_SELECTOR for simple native token transfers)
77
+ * @param params The encoded parameters for the function (empty for simple native token transfers)
78
+ * @param gasLimit The gas limit for execution
79
+ * @param operationType The operation type hash
80
+ * @param paymentDetails The payment details to attach to the transaction
81
+ * @return txId The transaction ID for the requested operation (use getTransaction(txId) for full record)
82
+ * @notice Reuses EXECUTE_TIME_DELAY_REQUEST permission; approval/cancel same as executeWithTimeLock
83
+ */
84
+ function executeWithPayment(
85
+ address target,
86
+ uint256 value,
87
+ bytes4 functionSelector,
88
+ bytes memory params,
89
+ uint256 gasLimit,
90
+ bytes32 operationType,
91
+ EngineBlox.PaymentDetails memory paymentDetails
92
+ ) external returns (uint256 txId);
93
+
54
94
  /**
55
95
  * @dev Approves and executes a time-locked transaction
56
96
  * @param txId The transaction ID
57
97
  * @param expectedOperationType The expected operation type for validation
58
- * @return result The execution result
98
+ * @return txId The transaction ID (use getTransaction(txId) for full record and result)
59
99
  * @notice Requires STANDARD execution type and EXECUTE_TIME_DELAY_APPROVE permission for the execution function
60
100
  */
61
101
  function approveTimeLockExecution(
62
102
  uint256 txId,
63
103
  bytes32 expectedOperationType
64
- ) external returns (bytes memory result);
104
+ ) external returns (uint256);
65
105
 
66
106
  /**
67
107
  * @dev Cancels a time-locked transaction
68
108
  * @param txId The transaction ID
69
109
  * @param expectedOperationType The expected operation type for validation
70
- * @return The updated transaction record
110
+ * @return txId The transaction ID (use getTransaction(txId) for full record)
71
111
  * @notice Requires STANDARD execution type and EXECUTE_TIME_DELAY_CANCEL permission for the execution function
72
112
  */
73
113
  function cancelTimeLockExecution(
74
114
  uint256 txId,
75
115
  bytes32 expectedOperationType
76
- ) external returns (EngineBlox.TxRecord memory);
116
+ ) external returns (uint256);
77
117
 
78
118
  /**
79
119
  * @dev Approves a time-locked transaction using a meta-transaction
80
120
  * @param metaTx The meta-transaction containing the transaction record and signature
81
121
  * @param expectedOperationType The expected operation type for validation
82
122
  * @param requiredSelector The handler selector for validation
83
- * @return The updated transaction record
123
+ * @return The transaction ID (use getTransaction(txId) for full record)
84
124
  * @notice Requires STANDARD execution type and EXECUTE_META_APPROVE permission for the execution function
85
125
  */
86
126
  function approveTimeLockExecutionWithMetaTx(
87
127
  EngineBlox.MetaTransaction memory metaTx,
88
128
  bytes32 expectedOperationType,
89
129
  bytes4 requiredSelector
90
- ) external returns (EngineBlox.TxRecord memory);
130
+ ) external returns (uint256);
91
131
 
92
132
  /**
93
133
  * @dev Cancels a time-locked transaction using a meta-transaction
94
134
  * @param metaTx The meta-transaction containing the transaction record and signature
95
135
  * @param expectedOperationType The expected operation type for validation
96
136
  * @param requiredSelector The handler selector for validation
97
- * @return The updated transaction record
137
+ * @return The transaction ID (use getTransaction(txId) for full record)
98
138
  * @notice Requires STANDARD execution type and EXECUTE_META_CANCEL permission for the execution function
99
139
  */
100
140
  function cancelTimeLockExecutionWithMetaTx(
101
141
  EngineBlox.MetaTransaction memory metaTx,
102
142
  bytes32 expectedOperationType,
103
143
  bytes4 requiredSelector
104
- ) external returns (EngineBlox.TxRecord memory);
144
+ ) external returns (uint256);
105
145
 
106
146
  /**
107
147
  * @dev Requests and approves a transaction in one step using a meta-transaction
108
148
  * @param metaTx The meta-transaction containing the transaction record and signature
109
149
  * @param requiredSelector The handler selector for validation
110
- * @return The transaction record after request and approval
150
+ * @return The transaction ID (use getTransaction(txId) for full record)
111
151
  * @notice Requires STANDARD execution type
112
152
  * @notice Validates function schema and permissions for the execution function (same as executeWithTimeLock)
113
153
  * @notice Requires EXECUTE_META_REQUEST_AND_APPROVE permission for the execution function selector
@@ -115,6 +155,6 @@ interface IGuardController {
115
155
  function requestAndApproveExecution(
116
156
  EngineBlox.MetaTransaction memory metaTx,
117
157
  bytes4 requiredSelector
118
- ) external returns (EngineBlox.TxRecord memory);
158
+ ) external returns (uint256);
119
159
  }
120
160
 
@@ -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 "../../interface/IGuardController.sol";
6
8
 
7
9
  /**
8
10
  * @title GuardControllerDefinitions
@@ -61,7 +63,7 @@ library GuardControllerDefinitions {
61
63
  // GuardController: executeGuardConfigBatch((uint8,bytes)[])
62
64
  bytes4 public constant GUARD_CONFIG_BATCH_EXECUTE_SELECTOR =
63
65
  bytes4(keccak256("executeGuardConfigBatch((uint8,bytes)[])"));
64
-
66
+
65
67
  /**
66
68
  * @dev Returns predefined function schemas for GuardController execution functions
67
69
  * @return Array of function schema definitions
@@ -398,4 +400,91 @@ library GuardControllerDefinitions {
398
400
  functionPermissions: functionPermissions
399
401
  });
400
402
  }
403
+
404
+ /**
405
+ * @dev Returns all available GuardConfig action types and their decode formats for discovery.
406
+ * @return actionNames Human-readable action names (same order as GuardConfigActionType enum)
407
+ * @return formats ABI decode format for each action's data, e.g. "(bytes4 functionSelector, address target)"
408
+ * @notice Use with GuardConfigActionType enum: actionNames[i] and formats[i] describe enum value i
409
+ */
410
+ function getGuardConfigActionSpecs() public pure returns (string[] memory actionNames, string[] memory formats) {
411
+ actionNames = new string[](4);
412
+ formats = new string[](4);
413
+
414
+ actionNames[0] = "ADD_TARGET_TO_WHITELIST";
415
+ formats[0] = "(bytes4 functionSelector, address target)";
416
+
417
+ actionNames[1] = "REMOVE_TARGET_FROM_WHITELIST";
418
+ formats[1] = "(bytes4 functionSelector, address target)";
419
+
420
+ actionNames[2] = "REGISTER_FUNCTION";
421
+ formats[2] = "(string functionSignature, string operationName, TxAction[] supportedActions)";
422
+
423
+ actionNames[3] = "UNREGISTER_FUNCTION";
424
+ formats[3] = "(bytes4 functionSelector, bool safeRemoval)";
425
+ }
426
+
427
+ // ============ GUARD CONFIG ACTION DATA ENCODERS ============
428
+ // Use these helpers to build action.data for each GuardConfigActionType without reading the contract.
429
+ // Each encoder returns bytes suitable for GuardConfigAction(actionType, data).
430
+
431
+ /**
432
+ * @dev Encodes data for ADD_TARGET_TO_WHITELIST. Use with GuardConfigActionType.ADD_TARGET_TO_WHITELIST.
433
+ * @param functionSelector Function whose whitelist is updated
434
+ * @param target Address to add to the whitelist
435
+ */
436
+ function encodeAddTargetToWhitelist(bytes4 functionSelector, address target) public pure returns (bytes memory) {
437
+ return abi.encode(functionSelector, target);
438
+ }
439
+
440
+ /**
441
+ * @dev Encodes data for REMOVE_TARGET_FROM_WHITELIST. Use with GuardConfigActionType.REMOVE_TARGET_FROM_WHITELIST.
442
+ * @param functionSelector Function whose whitelist is updated
443
+ * @param target Address to remove from the whitelist
444
+ */
445
+ function encodeRemoveTargetFromWhitelist(bytes4 functionSelector, address target) public pure returns (bytes memory) {
446
+ return abi.encode(functionSelector, target);
447
+ }
448
+
449
+ /**
450
+ * @dev Encodes data for REGISTER_FUNCTION. Use with GuardConfigActionType.REGISTER_FUNCTION.
451
+ * @param functionSignature Full function signature string (e.g. "executeWithTimeLock(address,bytes4,bytes,uint256,bytes32)")
452
+ * @param operationName Human-readable operation name
453
+ * @param supportedActions TxActions supported by this function (e.g. EXECUTE_TIME_DELAY_REQUEST)
454
+ */
455
+ function encodeRegisterFunction(
456
+ string memory functionSignature,
457
+ string memory operationName,
458
+ EngineBlox.TxAction[] memory supportedActions
459
+ ) public pure returns (bytes memory) {
460
+ return abi.encode(functionSignature, operationName, supportedActions);
461
+ }
462
+
463
+ /**
464
+ * @dev Encodes data for UNREGISTER_FUNCTION. Use with GuardConfigActionType.UNREGISTER_FUNCTION.
465
+ * @param functionSelector Selector of the function to unregister
466
+ * @param safeRemoval If true, reverts when the function has whitelisted targets
467
+ */
468
+ function encodeUnregisterFunction(bytes4 functionSelector, bool safeRemoval) public pure returns (bytes memory) {
469
+ return abi.encode(functionSelector, safeRemoval);
470
+ }
471
+
472
+ /**
473
+ * @dev Creates execution params for a Guard configuration batch (pure helper for EngineBlox).
474
+ * @param actions Encoded guard configuration actions (same layout as IGuardController.GuardConfigAction[])
475
+ * @return The execution params for EngineBlox
476
+ */
477
+ function guardConfigBatchExecutionParams(
478
+ IGuardController.GuardConfigAction[] memory actions
479
+ ) public pure returns (bytes memory) {
480
+ return abi.encode(actions);
481
+ }
482
+
483
+ /**
484
+ * @dev ERC165: report support for IDefinition and IERC165 when this library is used at an address.
485
+ * IDefinition extends IERC165; both interface IDs must be reported for ERC165 compliance.
486
+ */
487
+ function supportsInterface(bytes4 interfaceId) external pure returns (bool) {
488
+ return interfaceId == type(IERC165).interfaceId || interfaceId == type(IDefinition).interfaceId;
489
+ }
401
490
  }