@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
@@ -7,8 +7,8 @@ import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/Mes
7
7
  import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
8
8
 
9
9
  // Local imports
10
- import "../../utils/SharedValidation.sol";
11
- import "../../interfaces/IEventForwarder.sol";
10
+ import "./utils/SharedValidation.sol";
11
+ import "./interfaces/IEventForwarder.sol";
12
12
 
13
13
  /**
14
14
  * @title EngineBlox
@@ -190,6 +190,10 @@ library EngineBlox {
190
190
  mapping(bytes4 => EnumerableSet.AddressSet) functionTargetWhitelist;
191
191
  // Per-function target hooks (generic pipeline for hook setup)
192
192
  mapping(bytes4 => EnumerableSet.AddressSet) functionTargetHooks;
193
+
194
+ // ============ SYSTEM MACRO SELECTORS ============
195
+ // Function selectors that are allowed to target address(this) (e.g. native transfer, update payment)
196
+ EnumerableSet.Bytes32Set systemMacroSelectorsSet;
193
197
  }
194
198
 
195
199
  bytes32 constant OWNER_ROLE = keccak256(bytes("OWNER_ROLE"));
@@ -200,10 +204,6 @@ library EngineBlox {
200
204
  bytes4 public constant NATIVE_TRANSFER_SELECTOR = bytes4(keccak256("__bloxchain_native_transfer__()"));
201
205
  bytes32 public constant NATIVE_TRANSFER_OPERATION = keccak256("NATIVE_TRANSFER");
202
206
 
203
- // Payment update selector (reserved signature for payment detail updates)
204
- bytes4 public constant UPDATE_PAYMENT_SELECTOR = bytes4(keccak256("__bloxchain_update_payment__()"));
205
- bytes32 public constant UPDATE_PAYMENT_OPERATION = keccak256("UPDATE_PAYMENT");
206
-
207
207
  // EIP-712 Type Hashes
208
208
  bytes32 private constant TYPE_HASH = keccak256("MetaTransaction(TxRecord txRecord,MetaTxParams params,bytes data)TxRecord(uint256 txId,uint256 releaseTime,uint8 status,TxParams params,bytes32 message,bytes result,PaymentDetails payment)TxParams(address requester,address target,uint256 value,uint256 gasLimit,bytes32 operationType,bytes4 executionSelector,bytes executionParams)MetaTxParams(uint256 chainId,uint256 nonce,address handlerContract,bytes4 handlerSelector,uint8 action,uint256 deadline,uint256 maxGasPrice,address signer)PaymentDetails(address recipient,uint256 nativeTokenAmount,address erc20TokenAddress,uint256 erc20TokenAmount)");
209
209
  bytes32 private constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
@@ -255,6 +255,9 @@ library EngineBlox {
255
255
  assignWallet(self, OWNER_ROLE, _owner);
256
256
  assignWallet(self, BROADCASTER_ROLE, _broadcaster);
257
257
  assignWallet(self, RECOVERY_ROLE, _recovery);
258
+
259
+ // Register default system macro selectors (allowed to target address(this) for system-level operations)
260
+ addMacroSelector(self, NATIVE_TRANSFER_SELECTOR);
258
261
 
259
262
  // Mark as initialized after successful setup
260
263
  self.initialized = true;
@@ -318,20 +321,64 @@ library EngineBlox {
318
321
  gasLimit,
319
322
  operationType,
320
323
  executionSelector,
321
- executionParams
324
+ executionParams,
325
+ _noPayment()
322
326
  );
323
327
  }
324
328
 
325
329
  /**
326
- * @dev Internal helper function to request a transaction without permission checks.
330
+ * @dev Requests a transaction with payment details attached from the start.
327
331
  * @param self The SecureOperationState to modify.
328
332
  * @param requester The address of the requester.
329
333
  * @param target The target contract address for the transaction.
330
334
  * @param value The value to send with the transaction.
331
335
  * @param gasLimit The gas limit for the transaction.
332
336
  * @param operationType The type of operation.
337
+ * @param handlerSelector The function selector of the handler/request function.
333
338
  * @param executionSelector The function selector to execute (NATIVE_TRANSFER_SELECTOR for simple native token transfers).
334
339
  * @param executionParams The encoded parameters for the function (empty for simple native token transfers).
340
+ * @param paymentDetails The payment details to attach to the transaction.
341
+ * @return The created TxRecord with payment set.
342
+ * @notice Validates request permissions (same as txRequest).
343
+ */
344
+ function txRequestWithPayment(
345
+ SecureOperationState storage self,
346
+ address requester,
347
+ address target,
348
+ uint256 value,
349
+ uint256 gasLimit,
350
+ bytes32 operationType,
351
+ bytes4 handlerSelector,
352
+ bytes4 executionSelector,
353
+ bytes memory executionParams,
354
+ PaymentDetails memory paymentDetails
355
+ ) public returns (TxRecord memory) {
356
+ // Validate both execution and handler selector permissions (same as txRequest)
357
+ _validateExecutionAndHandlerPermissions(self, msg.sender, executionSelector, handlerSelector, TxAction.EXECUTE_TIME_DELAY_REQUEST);
358
+
359
+ return _txRequest(
360
+ self,
361
+ requester,
362
+ target,
363
+ value,
364
+ gasLimit,
365
+ operationType,
366
+ executionSelector,
367
+ executionParams,
368
+ paymentDetails
369
+ );
370
+ }
371
+
372
+ /**
373
+ * @dev Internal helper function to request a transaction without permission checks.
374
+ * @param self The SecureOperationState to modify.
375
+ * @param requester The address of the requester.
376
+ * @param target The target contract address for the transaction.
377
+ * @param value The value to send with the transaction.
378
+ * @param gasLimit The gas limit for the transaction.
379
+ * @param operationType The type of operation.
380
+ * @param executionParams The encoded parameters for the function (empty for simple native token transfers).
381
+ * @param paymentDetails The payment details to attach (use empty struct for no payment).
335
382
  * @return The created TxRecord.
336
383
  * @notice This function skips permission validation and should only be called from functions
337
384
  * that have already validated permissions.
@@ -344,7 +391,8 @@ library EngineBlox {
344
391
  uint256 gasLimit,
345
392
  bytes32 operationType,
346
393
  bytes4 executionSelector,
347
- bytes memory executionParams
394
+ bytes memory executionParams,
395
+ PaymentDetails memory paymentDetails
348
396
  ) private returns (TxRecord memory) {
349
397
  SharedValidation.validateNotZeroAddress(target);
350
398
  // enforce that the requested target is whitelisted for this selector.
@@ -358,7 +406,8 @@ library EngineBlox {
358
406
  gasLimit,
359
407
  operationType,
360
408
  executionSelector,
361
- executionParams
409
+ executionParams,
410
+ paymentDetails
362
411
  );
363
412
 
364
413
  self.txRecords[txRequestRecord.txId] = txRequestRecord;
@@ -499,7 +548,8 @@ library EngineBlox {
499
548
  metaTx.txRecord.params.gasLimit,
500
549
  metaTx.txRecord.params.operationType,
501
550
  metaTx.txRecord.params.executionSelector,
502
- metaTx.txRecord.params.executionParams
551
+ metaTx.txRecord.params.executionParams,
552
+ metaTx.txRecord.payment
503
553
  );
504
554
 
505
555
  metaTx.txRecord = txRecord;
@@ -643,6 +693,7 @@ library EngineBlox {
643
693
  * @param operationType The type of operation being performed
644
694
  * @param executionSelector The function selector to execute (NATIVE_TRANSFER_SELECTOR for simple native token transfers)
645
695
  * @param executionParams The encoded parameters for the function (empty for simple native token transfers)
696
+ * @param payment The payment details to attach to the record (use empty struct for no payment)
646
697
  * @return TxRecord A new transaction record with populated fields
647
698
  */
648
699
  function createNewTxRecord(
@@ -653,8 +704,9 @@ library EngineBlox {
653
704
  uint256 gasLimit,
654
705
  bytes32 operationType,
655
706
  bytes4 executionSelector,
656
- bytes memory executionParams
657
- ) private view returns (TxRecord memory) {
707
+ bytes memory executionParams,
708
+ PaymentDetails memory payment
709
+ ) private view returns (TxRecord memory) {
658
710
  return TxRecord({
659
711
  txId: self.txCounter + 1,
660
712
  releaseTime: block.timestamp + self.timeLockPeriodSec * 1 seconds,
@@ -670,12 +722,7 @@ library EngineBlox {
670
722
  }),
671
723
  message: 0,
672
724
  result: "",
673
- payment: PaymentDetails({
674
- recipient: address(0),
675
- nativeTokenAmount: 0,
676
- erc20TokenAddress: address(0),
677
- erc20TokenAmount: 0
678
- })
725
+ payment: payment
679
726
  });
680
727
  }
681
728
 
@@ -708,42 +755,6 @@ library EngineBlox {
708
755
  }
709
756
  }
710
757
 
711
- // ============ PAYMENT MANAGEMENT FUNCTIONS ============
712
-
713
- /**
714
- * @dev Updates payment details for a pending transaction
715
- * @param self The SecureOperationState to modify
716
- * @param txId The transaction ID to update payment for
717
- * @param paymentDetails The new payment details
718
- * @notice Access control: Requires permission for UPDATE_PAYMENT_SELECTOR and execution selector
719
- * @notice This prevents attackers from redirecting funds after transaction request
720
- * @notice Contracts must register UPDATE_PAYMENT_SELECTOR schema and grant permissions
721
- * @notice Permission check: Both UPDATE_PAYMENT_SELECTOR AND execution selector permissions required
722
- */
723
- function updatePaymentForTransaction(
724
- SecureOperationState storage self,
725
- uint256 txId,
726
- PaymentDetails memory paymentDetails
727
- ) public {
728
- _validateTxStatus(self, txId, TxStatus.PENDING);
729
-
730
- // Permission-based access control using macro selector
731
- // Requires permission for UPDATE_PAYMENT_SELECTOR with EXECUTE_TIME_DELAY_REQUEST action
732
- if (!hasActionPermission(self, msg.sender, UPDATE_PAYMENT_SELECTOR, TxAction.EXECUTE_TIME_DELAY_REQUEST)) {
733
- revert SharedValidation.NoPermission(msg.sender);
734
- }
735
-
736
- // Also verify permission for the transaction's execution selector
737
- // This ensures caller has permission for the underlying transaction (dual permission check)
738
- if (!hasActionPermission(self, msg.sender, self.txRecords[txId].params.executionSelector, TxAction.EXECUTE_TIME_DELAY_REQUEST)) {
739
- revert SharedValidation.NoPermission(msg.sender);
740
- }
741
-
742
- self.txRecords[txId].payment = paymentDetails;
743
-
744
- logTxEvent(self, txId, self.txRecords[txId].params.executionSelector);
745
- }
746
-
747
758
  // ============ ROLE-BASED ACCESS CONTROL FUNCTIONS ============
748
759
 
749
760
 
@@ -759,6 +770,18 @@ library EngineBlox {
759
770
  return self.roles[role];
760
771
  }
761
772
 
773
+ /**
774
+ * @dev Gets the function schema by selector.
775
+ * @param self The SecureOperationState to read from.
776
+ * @param functionSelector The function selector to get the schema for.
777
+ * @return The FunctionSchema struct (memory copy).
778
+ * @notice Reverts with ResourceNotFound if the schema does not exist.
779
+ */
780
+ function getFunctionSchema(SecureOperationState storage self, bytes4 functionSelector) public view returns (FunctionSchema memory) {
781
+ _validateFunctionSchemaExists(self, functionSelector);
782
+ return self.functions[functionSelector];
783
+ }
784
+
762
785
  /**
763
786
  * @dev Creates a role with specified function permissions.
764
787
  * @param self The SecureOperationState to check.
@@ -772,6 +795,9 @@ library EngineBlox {
772
795
  uint256 maxWallets,
773
796
  bool isProtected
774
797
  ) public {
798
+ SharedValidation.validateRoleNameNotEmpty(roleName);
799
+ SharedValidation.validateMaxWalletsGreaterThanZero(maxWallets);
800
+
775
801
  bytes32 roleHash = keccak256(bytes(roleName));
776
802
 
777
803
  // Validate role count limit
@@ -1110,7 +1136,7 @@ library EngineBlox {
1110
1136
  // SECURITY: Validate that functions existing in contract bytecode must be protected
1111
1137
  // This checks if the function selector exists in the contract's bytecode
1112
1138
  // If it exists, it must be protected to prevent accidental removal of system-critical functions
1113
- _validateContractFunctionProtection(functionSignature, functionSelector, isProtected);
1139
+ _validateContractFunctionProtection(functionSelector, isProtected);
1114
1140
 
1115
1141
  // Derive operation type from operation name
1116
1142
  bytes32 derivedOperationType = keccak256(bytes(operationName));
@@ -1331,6 +1357,37 @@ library EngineBlox {
1331
1357
  return _convertAddressSetToArray(set);
1332
1358
  }
1333
1359
 
1360
+ // ============ SYSTEM MACRO SELECTORS ============
1361
+
1362
+ /**
1363
+ * @dev Adds a function selector to the system macro selectors set.
1364
+ * Macro selectors are allowed to target address(this) for system-level operations (e.g. native transfer).
1365
+ * @param self The SecureOperationState to modify.
1366
+ * @param functionSelector The function selector to add (e.g. NATIVE_TRANSFER_SELECTOR).
1367
+ */
1368
+ function addMacroSelector(
1369
+ SecureOperationState storage self,
1370
+ bytes4 functionSelector
1371
+ ) public {
1372
+ SharedValidation.validateHandlerSelector(functionSelector);
1373
+ bytes32 sel = bytes32(functionSelector);
1374
+ if (!self.systemMacroSelectorsSet.add(sel)) {
1375
+ revert SharedValidation.ResourceAlreadyExists(sel);
1376
+ }
1377
+ }
1378
+
1379
+ /**
1380
+ * @dev Returns true if the given function selector is in the system macro selectors set.
1381
+ * @param self The SecureOperationState to check.
1382
+ * @param functionSelector The function selector to check.
1383
+ */
1384
+ function isMacroSelector(
1385
+ SecureOperationState storage self,
1386
+ bytes4 functionSelector
1387
+ ) public view returns (bool) {
1388
+ return self.systemMacroSelectorsSet.contains(bytes32(functionSelector));
1389
+ }
1390
+
1334
1391
  // ============ FUNCTION TARGET HOOKS MANAGEMENT ============
1335
1392
 
1336
1393
  /**
@@ -1495,6 +1552,28 @@ library EngineBlox {
1495
1552
  return role.authorizedWallets.at(index);
1496
1553
  }
1497
1554
 
1555
+ /**
1556
+ * @dev Gets all authorized wallets for a role
1557
+ * @param self The SecureOperationState to check
1558
+ * @param roleHash The role hash
1559
+ * @return Array of authorized wallet addresses
1560
+ * @notice Access control should be enforced by the calling contract.
1561
+ */
1562
+ function _getAuthorizedWallets(
1563
+ SecureOperationState storage self,
1564
+ bytes32 roleHash
1565
+ ) public view returns (address[] memory) {
1566
+ Role storage role = self.roles[roleHash];
1567
+ uint256 walletCount = role.walletCount;
1568
+
1569
+ address[] memory wallets = new address[](walletCount);
1570
+ for (uint256 i = 0; i < walletCount; i++) {
1571
+ wallets[i] = getAuthorizedWalletAt(self, roleHash, i);
1572
+ }
1573
+
1574
+ return wallets;
1575
+ }
1576
+
1498
1577
  /**
1499
1578
  * @dev Gets all function permissions for a role as an array for backward compatibility
1500
1579
  * @param self The SecureOperationState to check
@@ -1700,7 +1779,8 @@ library EngineBlox {
1700
1779
  txParams.gasLimit,
1701
1780
  txParams.operationType,
1702
1781
  txParams.executionSelector,
1703
- txParams.executionParams
1782
+ txParams.executionParams,
1783
+ _noPayment()
1704
1784
  );
1705
1785
 
1706
1786
  return generateMetaTransaction(self, txRecord, metaTxParams);
@@ -2005,6 +2085,17 @@ library EngineBlox {
2005
2085
  }
2006
2086
  }
2007
2087
 
2088
+ /**
2089
+ * @dev Validates that a function schema exists for the given selector.
2090
+ * @param self The SecureOperationState to check.
2091
+ * @param functionSelector The function selector to validate.
2092
+ */
2093
+ function _validateFunctionSchemaExists(SecureOperationState storage self, bytes4 functionSelector) internal view {
2094
+ if (!self.supportedFunctionsSet.contains(bytes32(functionSelector))) {
2095
+ revert SharedValidation.ResourceNotFound(bytes32(functionSelector));
2096
+ }
2097
+ }
2098
+
2008
2099
  /**
2009
2100
  * @dev Validates that a transaction is in the expected status
2010
2101
  * @param self The SecureOperationState to check
@@ -2213,7 +2304,6 @@ library EngineBlox {
2213
2304
 
2214
2305
  /**
2215
2306
  * @dev Validates that if a function exists in contract bytecode, it must be protected
2216
- * @param functionSignature The function signature to check
2217
2307
  * @param functionSelector The function selector
2218
2308
  * @param isProtected Whether the function is marked as protected
2219
2309
  * @notice Checks if the function selector exists in the contract's bytecode function selector table
@@ -2222,15 +2312,15 @@ library EngineBlox {
2222
2312
  * @notice Since we're called via delegatecall, address(this) refers to the calling contract
2223
2313
  */
2224
2314
  function _validateContractFunctionProtection(
2225
- string memory functionSignature,
2226
2315
  bytes4 functionSelector,
2227
2316
  bool isProtected
2228
2317
  ) private view {
2229
- // Check if the function selector exists in the contract's bytecode
2230
- // Since we're called via delegatecall, address(this) refers to the calling contract
2231
- if (selectorExistsInContract(address(this), functionSelector)) {
2232
- if (!isProtected) {
2233
- revert SharedValidation.ContractFunctionMustBeProtected(functionSelector, functionSignature);
2318
+ // Check cheaper condition first: skip expensive bytecode check when already protected
2319
+ if (!isProtected) {
2320
+ // Check if the function selector exists in the contract's bytecode
2321
+ // Since we're called via delegatecall, address(this) refers to the calling contract
2322
+ if (selectorExistsInContract(address(this), functionSelector)) {
2323
+ revert SharedValidation.ContractFunctionMustBeProtected(functionSelector);
2234
2324
  }
2235
2325
  }
2236
2326
  }
@@ -2280,4 +2370,17 @@ library EngineBlox {
2280
2370
  return false;
2281
2371
  }
2282
2372
 
2373
+ /**
2374
+ * @dev Returns an empty PaymentDetails struct for use when no payment is attached.
2375
+ * @return payment Empty payment details (recipient and amounts zero).
2376
+ */
2377
+ function _noPayment() internal pure returns (PaymentDetails memory payment) {
2378
+ return PaymentDetails({
2379
+ recipient: address(0),
2380
+ nativeTokenAmount: 0,
2381
+ erc20TokenAddress: address(0),
2382
+ erc20TokenAmount: 0
2383
+ });
2384
+ }
2385
+
2283
2386
  }
@@ -1,20 +1,25 @@
1
1
  // SPDX-License-Identifier: MPL-2.0
2
2
  pragma solidity 0.8.33;
3
3
 
4
- import "../core/lib/EngineBlox.sol";
4
+ import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
5
+ import "../EngineBlox.sol";
5
6
 
6
7
  /**
7
8
  * @dev Interface for definition contracts that provide operation types, function schemas, and role permissions
8
- *
9
+ *
9
10
  * This interface allows contracts to dynamically load their configuration from external
10
11
  * definition contracts, enabling modular and extensible contract initialization.
11
- *
12
+ *
13
+ * Definition contracts (or deployed definition libraries) used by address should implement
14
+ * ERC165 and return true for type(IDefinition).interfaceId so consumers can validate
15
+ * before calling getFunctionSchemas() / getRolePermissions().
16
+ *
12
17
  * Definition contracts should implement this interface to provide:
13
18
  * - Operation type definitions (what operations are supported)
14
19
  * - Function schema definitions (how functions are structured)
15
20
  * - Role permission definitions (who can do what)
16
21
  */
17
- interface IDefinition {
22
+ interface IDefinition is IERC165 {
18
23
  /**
19
24
  * @dev Struct to hold role permission data
20
25
  * @param roleHashes Array of role hashes
@@ -30,11 +35,15 @@ interface IDefinition {
30
35
  * @return Array of function schema definitions
31
36
  */
32
37
  function getFunctionSchemas() external pure returns (EngineBlox.FunctionSchema[] memory);
33
-
38
+
34
39
  /**
35
40
  * @dev Returns all role hashes and their corresponding function permissions
36
41
  * @return RolePermission struct containing roleHashes and functionPermissions arrays
37
42
  */
38
43
  function getRolePermissions() external pure returns (RolePermission memory);
39
-
44
+
45
+ /**
46
+ * @dev ERC165: return true for type(IDefinition).interfaceId
47
+ */
48
+ function supportsInterface(bytes4 interfaceId) external view returns (bool);
40
49
  }
@@ -2,7 +2,7 @@
2
2
  pragma solidity 0.8.33;
3
3
 
4
4
  // Import TxRecord struct from EngineBlox
5
- import "../core/lib/EngineBlox.sol";
5
+ import "../EngineBlox.sol";
6
6
 
7
7
  /**
8
8
  * @title IEventForwarder