@bloxchain/contracts 1.0.0-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +49 -0
  2. package/abi/BareBlox.abi.json +1341 -0
  3. package/abi/BaseStateMachine.abi.json +1308 -0
  4. package/abi/ControlBlox.abi.json +6210 -0
  5. package/abi/EngineBlox.abi.json +872 -0
  6. package/abi/GuardController.abi.json +3045 -0
  7. package/abi/IDefinition.abi.json +94 -0
  8. package/abi/RoleBlox.abi.json +4569 -0
  9. package/abi/RuntimeRBAC.abi.json +1857 -0
  10. package/abi/RuntimeRBACDefinitions.abi.json +133 -0
  11. package/abi/SecureBlox.abi.json +4085 -0
  12. package/abi/SecureOwnable.abi.json +4085 -0
  13. package/abi/SecureOwnableDefinitions.abi.json +354 -0
  14. package/abi/SimpleRWA20.abi.json +5545 -0
  15. package/abi/SimpleRWA20Definitions.abi.json +172 -0
  16. package/abi/SimpleVault.abi.json +5208 -0
  17. package/abi/SimpleVaultDefinitions.abi.json +250 -0
  18. package/contracts/core/access/RuntimeRBAC.sol +344 -0
  19. package/contracts/core/access/interface/IRuntimeRBAC.sol +108 -0
  20. package/contracts/core/access/lib/definitions/RuntimeRBACDefinitions.sol +168 -0
  21. package/contracts/core/base/BaseStateMachine.sol +834 -0
  22. package/contracts/core/base/interface/IBaseStateMachine.sol +153 -0
  23. package/contracts/core/execution/GuardController.sol +507 -0
  24. package/contracts/core/execution/interface/IGuardController.sol +120 -0
  25. package/contracts/core/execution/lib/definitions/GuardControllerDefinitions.sol +401 -0
  26. package/contracts/core/lib/EngineBlox.sol +2283 -0
  27. package/contracts/core/security/SecureOwnable.sol +419 -0
  28. package/contracts/core/security/interface/ISecureOwnable.sol +118 -0
  29. package/contracts/core/security/lib/definitions/SecureOwnableDefinitions.sol +757 -0
  30. package/contracts/interfaces/IDefinition.sol +40 -0
  31. package/contracts/interfaces/IEventForwarder.sol +33 -0
  32. package/contracts/interfaces/IOnActionHook.sol +79 -0
  33. package/contracts/utils/SharedValidation.sol +486 -0
  34. package/package.json +47 -0
@@ -0,0 +1,40 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ pragma solidity 0.8.33;
3
+
4
+ import "../core/lib/EngineBlox.sol";
5
+
6
+ /**
7
+ * @dev Interface for definition contracts that provide operation types, function schemas, and role permissions
8
+ *
9
+ * This interface allows contracts to dynamically load their configuration from external
10
+ * definition contracts, enabling modular and extensible contract initialization.
11
+ *
12
+ * Definition contracts should implement this interface to provide:
13
+ * - Operation type definitions (what operations are supported)
14
+ * - Function schema definitions (how functions are structured)
15
+ * - Role permission definitions (who can do what)
16
+ */
17
+ interface IDefinition {
18
+ /**
19
+ * @dev Struct to hold role permission data
20
+ * @param roleHashes Array of role hashes
21
+ * @param functionPermissions Array of function permissions (parallel to roleHashes)
22
+ */
23
+ struct RolePermission {
24
+ bytes32[] roleHashes;
25
+ EngineBlox.FunctionPermission[] functionPermissions;
26
+ }
27
+
28
+ /**
29
+ * @dev Returns all function schema definitions
30
+ * @return Array of function schema definitions
31
+ */
32
+ function getFunctionSchemas() external pure returns (EngineBlox.FunctionSchema[] memory);
33
+
34
+ /**
35
+ * @dev Returns all role hashes and their corresponding function permissions
36
+ * @return RolePermission struct containing roleHashes and functionPermissions arrays
37
+ */
38
+ function getRolePermissions() external pure returns (RolePermission memory);
39
+
40
+ }
@@ -0,0 +1,33 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ pragma solidity 0.8.33;
3
+
4
+ // Import TxRecord struct from EngineBlox
5
+ import "../core/lib/EngineBlox.sol";
6
+
7
+ /**
8
+ * @title IEventForwarder
9
+ * @dev Interface for the event forwarder contract
10
+ *
11
+ * This interface defines the contract for forwarding events from deployed instances
12
+ * to a centralized event monitoring system. It uses function selectors for efficient
13
+ * event identification and categorization.
14
+ */
15
+ interface IEventForwarder {
16
+ /**
17
+ * @dev Forward a transaction event from a deployed instance
18
+ * @param txId The transaction ID
19
+ * @param functionSelector The function selector for the event (bytes4)
20
+ * @param status The transaction status
21
+ * @param requester The address of the requester
22
+ * @param target The target contract address
23
+ * @param operationType The type of operation
24
+ */
25
+ function forwardTxEvent(
26
+ uint256 txId,
27
+ bytes4 functionSelector,
28
+ EngineBlox.TxStatus status,
29
+ address requester,
30
+ address target,
31
+ bytes32 operationType
32
+ ) external;
33
+ }
@@ -0,0 +1,79 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ pragma solidity 0.8.33;
3
+
4
+ import "../core/lib/EngineBlox.sol";
5
+
6
+ /**
7
+ * @title IOnActionHook
8
+ * @dev Minimal interface for external hook contracts attached to state machine actions
9
+ *
10
+ * @notice This interface is intentionally small to keep overall contract size low.
11
+ * @notice Implementations can choose which functions to support; unneeded ones can revert.
12
+ */
13
+ interface IOnActionHook {
14
+ /**
15
+ * @dev Called after a transaction request is created
16
+ * @param txRecord The created transaction record
17
+ * @param caller The address that initiated the request
18
+ */
19
+ function onRequest(
20
+ EngineBlox.TxRecord memory txRecord,
21
+ address caller
22
+ ) external;
23
+
24
+ /**
25
+ * @dev Called after a pending transaction is approved (time-lock flow)
26
+ * @param txRecord The updated transaction record
27
+ * @param caller The address that approved the transaction
28
+ */
29
+ function onApprove(
30
+ EngineBlox.TxRecord memory txRecord,
31
+ address caller
32
+ ) external;
33
+
34
+ /**
35
+ * @dev Called after a pending transaction is cancelled
36
+ * @param txRecord The updated transaction record
37
+ * @param caller The address that cancelled the transaction
38
+ */
39
+ function onCancel(
40
+ EngineBlox.TxRecord memory txRecord,
41
+ address caller
42
+ ) external;
43
+
44
+ /**
45
+ * @dev Called after a transaction is approved via meta-transaction
46
+ * @param txRecord The updated transaction record
47
+ * @param metaTx The meta-transaction used for approval
48
+ * @param caller The address executing the meta-transaction
49
+ */
50
+ function onMetaApprove(
51
+ EngineBlox.TxRecord memory txRecord,
52
+ EngineBlox.MetaTransaction memory metaTx,
53
+ address caller
54
+ ) external;
55
+
56
+ /**
57
+ * @dev Called after a transaction is cancelled via meta-transaction
58
+ * @param txRecord The updated transaction record
59
+ * @param metaTx The meta-transaction used for cancellation
60
+ * @param caller The address executing the meta-transaction
61
+ */
62
+ function onMetaCancel(
63
+ EngineBlox.TxRecord memory txRecord,
64
+ EngineBlox.MetaTransaction memory metaTx,
65
+ address caller
66
+ ) external;
67
+
68
+ /**
69
+ * @dev Called after a transaction is requested and approved in one step via meta-transaction
70
+ * @param txRecord The created + approved transaction record
71
+ * @param metaTx The meta-transaction used for the operation
72
+ * @param caller The address executing the meta-transaction
73
+ */
74
+ function onRequestAndApprove(
75
+ EngineBlox.TxRecord memory txRecord,
76
+ EngineBlox.MetaTransaction memory metaTx,
77
+ address caller
78
+ ) external;
79
+ }
@@ -0,0 +1,486 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ pragma solidity 0.8.33;
3
+
4
+ /**
5
+ * @title SharedValidation
6
+ * @dev Optimized shared library containing common validation functions using enhanced custom errors
7
+ *
8
+ * This library is designed to reduce contract size by centralizing common validation logic
9
+ * and using gas-efficient custom errors instead of string constants. This approach provides
10
+ * significant gas savings and contract size reduction while maintaining clear error context.
11
+ *
12
+ * Features:
13
+ * - Enhanced custom errors with contextual parameters
14
+ * - Address validation functions
15
+ * - Time and deadline validation
16
+ * - Signature validation utilities
17
+ * - Permission and authorization checks
18
+ * - Operation type validation
19
+ * - Gas and transaction validation
20
+ *
21
+ * This library follows the security rules defined in .cursorrules and implements
22
+ * the Checks-Effects-Interactions pattern where applicable.
23
+ *
24
+ * Gas Optimization Benefits:
25
+ * - ~50% gas reduction compared to string-based errors
26
+ * - Significant contract size reduction
27
+ * - Enhanced error context with parameters
28
+ * - Modern Solidity best practices (0.8.4+)
29
+ */
30
+ library SharedValidation {
31
+
32
+ // ============ ENHANCED CUSTOM ERRORS ============
33
+
34
+ // Address validation errors with context
35
+ error InvalidAddress(address provided);
36
+ error NotNewAddress(address newAddress, address currentAddress);
37
+
38
+ // Time and deadline errors with context
39
+ error InvalidTimeLockPeriod(uint256 provided);
40
+ error TimeLockPeriodZero(uint256 provided);
41
+ error DeadlineInPast(uint256 deadline, uint256 currentTime);
42
+ error MetaTxExpired(uint256 deadline, uint256 currentTime);
43
+ error BeforeReleaseTime(uint256 releaseTime, uint256 currentTime);
44
+ error NewTimelockSame(uint256 newPeriod, uint256 currentPeriod);
45
+
46
+ // Permission and authorization errors with context
47
+ error NoPermission(address caller);
48
+ error NoPermissionForFunction(address caller, bytes4 functionSelector);
49
+ error RestrictedOwner(address caller, address owner);
50
+ error RestrictedOwnerRecovery(address caller, address owner, address recovery);
51
+ error RestrictedRecovery(address caller, address recovery);
52
+ error RestrictedBroadcaster(address caller, address broadcaster);
53
+ error SignerNotAuthorized(address signer);
54
+ error OnlyCallableByContract(address caller, address contractAddress);
55
+
56
+ // Transaction and operation errors with context
57
+ error NotSupported();
58
+ error InvalidOperationType(bytes32 actualType, bytes32 expectedType);
59
+ error ZeroOperationTypeNotAllowed();
60
+ error TransactionStatusMismatch(uint8 expectedStatus, uint8 currentStatus);
61
+ error AlreadyInitialized();
62
+ error TransactionIdMismatch(uint256 expectedTxId, uint256 providedTxId);
63
+
64
+ // Signature and meta-transaction errors with context
65
+ error InvalidSignatureLength(uint256 providedLength, uint256 expectedLength);
66
+ error InvalidSignature(bytes signature);
67
+ error InvalidNonce(uint256 providedNonce, uint256 expectedNonce);
68
+ error ChainIdMismatch(uint256 providedChainId, uint256 expectedChainId);
69
+ error InvalidHandlerSelector(bytes4 selector);
70
+ error InvalidSValue(bytes32 s);
71
+ error InvalidVValue(uint8 v);
72
+ error ECDSAInvalidSignature(address recoveredSigner);
73
+ error GasPriceExceedsMax(uint256 currentGasPrice, uint256 maxGasPrice);
74
+
75
+ // Consolidated resource errors
76
+ error ResourceNotFound(bytes32 resourceId);
77
+ error ResourceAlreadyExists(bytes32 resourceId);
78
+ error CannotModifyProtected(bytes32 resourceId);
79
+
80
+ // Consolidated item errors (for addresses: wallets, policies, etc.)
81
+ error ItemAlreadyExists(address item);
82
+ error ItemNotFound(address item);
83
+ error InvalidOperation(address item);
84
+
85
+ // Role and function errors with context
86
+ error RoleWalletLimitReached(uint256 currentCount, uint256 maxWallets);
87
+ error MaxWalletsZero(uint256 provided);
88
+ error ConflictingMetaTxPermissions(bytes4 functionSelector);
89
+ error InternalFunctionNotAccessible(bytes4 functionSelector);
90
+ error ContractFunctionMustBeProtected(bytes4 functionSelector, string functionSignature);
91
+ error TargetNotWhitelisted(address target, bytes4 functionSelector);
92
+ error FunctionSelectorMismatch(bytes4 providedSelector, bytes4 derivedSelector);
93
+ error HandlerForSelectorMismatch(bytes4 schemaHandlerForSelector, bytes4 permissionHandlerForSelector);
94
+ error InvalidRange(uint256 from, uint256 to);
95
+ error OperationFailed();
96
+
97
+ // Payment and balance errors with context
98
+ error InsufficientBalance(uint256 currentBalance, uint256 requiredAmount);
99
+ error PaymentFailed(address recipient, uint256 amount, bytes reason);
100
+
101
+ // Array validation errors with context
102
+ error ArrayLengthMismatch(uint256 array1Length, uint256 array2Length);
103
+ error IndexOutOfBounds(uint256 index, uint256 arrayLength);
104
+
105
+ // System limit errors
106
+ error BatchSizeExceeded(uint256 currentSize, uint256 maxSize);
107
+ error MaxRolesExceeded(uint256 currentCount, uint256 maxRoles);
108
+ error MaxHooksExceeded(uint256 currentCount, uint256 maxHooks);
109
+ error MaxFunctionsExceeded(uint256 currentCount, uint256 maxFunctions);
110
+ error RangeSizeExceeded(uint256 rangeSize, uint256 maxRangeSize);
111
+
112
+ // ============ ADDRESS VALIDATION FUNCTIONS ============
113
+
114
+ /**
115
+ * @dev Validates that an address is not the zero address
116
+ * @param addr The address to validate
117
+ */
118
+ function validateNotZeroAddress(address addr) internal pure {
119
+ if (addr == address(0)) revert InvalidAddress(addr);
120
+ }
121
+
122
+
123
+ /**
124
+ * @dev Validates that a new address is different from the current address
125
+ * @param newAddress The proposed new address
126
+ * @param currentAddress The current address to compare against
127
+ */
128
+ function validateNewAddress(address newAddress, address currentAddress) internal pure {
129
+ if (newAddress == currentAddress) revert NotNewAddress(newAddress, currentAddress);
130
+ }
131
+
132
+ /**
133
+ * @dev Validates that an address is not the zero address and is different from current
134
+ * @param newAddress The proposed new address
135
+ * @param currentAddress The current address to compare against
136
+ */
137
+ function validateAddressUpdate(
138
+ address newAddress,
139
+ address currentAddress
140
+ ) internal pure {
141
+ validateNotZeroAddress(newAddress);
142
+ validateNewAddress(newAddress, currentAddress);
143
+ }
144
+
145
+ /**
146
+ * @dev Validates that a target address is not zero
147
+ * @param target The target address to validate
148
+ */
149
+ function validateTargetAddress(address target) internal pure {
150
+ if (target == address(0)) revert InvalidAddress(target);
151
+ }
152
+
153
+ /**
154
+ * @dev Validates that a handler contract address is not zero
155
+ * @param handler The handler contract address to validate
156
+ */
157
+ function validateHandlerContract(address handler) internal pure {
158
+ if (handler == address(0)) revert InvalidAddress(handler);
159
+ }
160
+
161
+ // ============ TIME AND DEADLINE VALIDATION FUNCTIONS ============
162
+
163
+ /**
164
+ * @dev Validates that a time lock period is greater than zero
165
+ * @param timeLockPeriod The time lock period to validate
166
+ */
167
+ function validateTimeLockPeriod(uint256 timeLockPeriod) internal pure {
168
+ if (timeLockPeriod == 0) revert TimeLockPeriodZero(timeLockPeriod);
169
+ }
170
+
171
+ /**
172
+ * @dev Validates that a deadline is in the future
173
+ * @param deadline The deadline timestamp to validate
174
+ */
175
+ function validateDeadline(uint256 deadline) internal view {
176
+ if (deadline <= block.timestamp) revert DeadlineInPast(deadline, block.timestamp);
177
+ }
178
+
179
+ /**
180
+ * @dev Validates that a new time lock period is different from the current one
181
+ * @param newPeriod The new time lock period
182
+ * @param currentPeriod The current time lock period
183
+ */
184
+ function validateTimeLockUpdate(uint256 newPeriod, uint256 currentPeriod) internal pure {
185
+ validateTimeLockPeriod(newPeriod);
186
+ if (newPeriod == currentPeriod) revert NewTimelockSame(newPeriod, currentPeriod);
187
+ }
188
+
189
+ /**
190
+ * @dev Validates that the current time is after the release time
191
+ * @param releaseTime The release time to check against
192
+ */
193
+ function validateReleaseTime(uint256 releaseTime) internal view {
194
+ if (block.timestamp < releaseTime) revert BeforeReleaseTime(releaseTime, block.timestamp);
195
+ }
196
+
197
+ /**
198
+ * @dev Validates that a meta-transaction has not expired
199
+ * @param deadline The deadline of the meta-transaction
200
+ */
201
+ function validateMetaTxDeadline(uint256 deadline) internal view {
202
+ if (block.timestamp > deadline) revert MetaTxExpired(deadline, block.timestamp);
203
+ }
204
+
205
+ // ============ SIGNATURE VALIDATION FUNCTIONS ============
206
+
207
+ /**
208
+ * @dev Validates that a signature has the correct length (65 bytes)
209
+ * @param signature The signature to validate
210
+ */
211
+ function validateSignatureLength(bytes memory signature) internal pure {
212
+ if (signature.length != 65) revert InvalidSignatureLength(signature.length, 65);
213
+ }
214
+
215
+ /**
216
+ * @dev Validates ECDSA signature parameters
217
+ * @param s The s parameter of the signature
218
+ * @param v The v parameter of the signature
219
+ */
220
+ function validateSignatureParams(bytes32 s, uint8 v) internal pure {
221
+ if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
222
+ revert InvalidSValue(s);
223
+ }
224
+ if (v != 27 && v != 28) revert InvalidVValue(v);
225
+ }
226
+
227
+ /**
228
+ * @dev Validates that a recovered signer is not the zero address
229
+ * @param signer The recovered signer address
230
+ */
231
+ function validateRecoveredSigner(address signer) internal pure {
232
+ if (signer == address(0)) revert ECDSAInvalidSignature(signer);
233
+ }
234
+
235
+ // ============ PERMISSION AND AUTHORIZATION FUNCTIONS ============
236
+
237
+ /**
238
+ * @dev Validates that the caller is the owner
239
+ * @param owner The current owner address
240
+ */
241
+ function validateOwner(address owner) internal view {
242
+ if (owner != msg.sender) revert RestrictedOwner(msg.sender, owner);
243
+ }
244
+
245
+ /**
246
+ * @dev Validates that the caller is either the owner or recovery
247
+ * @param owner The current owner address
248
+ * @param recovery The current recovery address
249
+ */
250
+ function validateOwnerOrRecovery(address owner, address recovery) internal view {
251
+ if (msg.sender != owner && msg.sender != recovery) {
252
+ revert RestrictedOwnerRecovery(msg.sender, owner, recovery);
253
+ }
254
+ }
255
+
256
+ /**
257
+ * @dev Validates that the caller is the recovery address
258
+ * @param recovery The current recovery address
259
+ */
260
+ function validateRecovery(address recovery) internal view {
261
+ if (msg.sender != recovery) revert RestrictedRecovery(msg.sender, recovery);
262
+ }
263
+
264
+ /**
265
+ * @dev Validates that the caller is the broadcaster
266
+ * @param broadcaster The current broadcaster address
267
+ */
268
+ function validateBroadcaster(address broadcaster) internal view {
269
+ if (msg.sender != broadcaster) revert RestrictedBroadcaster(msg.sender, broadcaster);
270
+ }
271
+
272
+ /**
273
+ * @dev Validates that the signer of a meta-transaction is the owner
274
+ * @param signer The signer address from the meta-transaction
275
+ * @param owner The current owner address
276
+ */
277
+ function validateOwnerIsSigner(address signer, address owner) internal pure {
278
+ if (signer != owner) revert NoPermission(signer);
279
+ }
280
+
281
+ /**
282
+ * @dev Validates that the function is being called internally by the contract itself
283
+ * @param contractAddress The address of the contract
284
+ */
285
+ function validateInternalCall(address contractAddress) internal view {
286
+ if (msg.sender != contractAddress) revert OnlyCallableByContract(msg.sender, contractAddress);
287
+ }
288
+
289
+ // ============ TRANSACTION AND OPERATION VALIDATION FUNCTIONS ============
290
+
291
+ /**
292
+ * @dev Validates that an operation type is not zero
293
+ * @param operationType The operation type to validate
294
+ */
295
+ function validateOperationTypeNotZero(bytes32 operationType) internal pure {
296
+ if (operationType == bytes32(0)) revert ZeroOperationTypeNotAllowed();
297
+ }
298
+
299
+ /**
300
+ * @dev Validates that an operation type matches the expected type
301
+ * @param actualType The actual operation type
302
+ * @param expectedType The expected operation type
303
+ */
304
+ function validateOperationType(bytes32 actualType, bytes32 expectedType) internal pure {
305
+ if (actualType != expectedType) revert InvalidOperationType(actualType, expectedType);
306
+ }
307
+
308
+ /**
309
+ * @dev Validates that a transaction exists (has non-zero ID)
310
+ * @param txId The transaction ID to validate
311
+ */
312
+ function validateTransactionExists(uint256 txId) internal pure {
313
+ if (txId == 0) revert ResourceNotFound(bytes32(uint256(txId)));
314
+ }
315
+
316
+ /**
317
+ * @dev Validates that a transaction ID matches the expected value
318
+ * @param txId The transaction ID to validate
319
+ * @param expectedTxId The expected transaction ID
320
+ */
321
+ function validateTransactionId(uint256 txId, uint256 expectedTxId) internal pure {
322
+ if (txId != expectedTxId) revert TransactionIdMismatch(expectedTxId, txId);
323
+ }
324
+
325
+ // ============ META-TRANSACTION VALIDATION FUNCTIONS ============
326
+
327
+ /**
328
+ * @dev Validates chain ID matches the current chain
329
+ * @param chainId The chain ID to validate
330
+ */
331
+ function validateChainId(uint256 chainId) internal view {
332
+ if (chainId != block.chainid) revert ChainIdMismatch(chainId, block.chainid);
333
+ }
334
+
335
+ /**
336
+ * @dev Validates that a handler selector is not zero
337
+ * @param selector The handler selector to validate
338
+ */
339
+ function validateHandlerSelector(bytes4 selector) internal pure {
340
+ if (selector == bytes4(0)) revert InvalidHandlerSelector(selector);
341
+ }
342
+
343
+ /**
344
+ * @dev Validates that a handler selector matches the expected selector
345
+ * @param actualSelector The actual handler selector from the meta transaction
346
+ * @param expectedSelector The expected handler selector to validate against
347
+ */
348
+ function validateHandlerSelectorMatch(bytes4 actualSelector, bytes4 expectedSelector) internal pure {
349
+ if (actualSelector != expectedSelector) revert InvalidHandlerSelector(actualSelector);
350
+ }
351
+
352
+ /**
353
+ * @dev Validates that a nonce matches the expected value
354
+ * @param nonce The nonce to validate
355
+ * @param expectedNonce The expected nonce value
356
+ */
357
+ function validateNonce(uint256 nonce, uint256 expectedNonce) internal pure {
358
+ if (nonce != expectedNonce) revert InvalidNonce(nonce, expectedNonce);
359
+ }
360
+
361
+ /**
362
+ * @dev Validates that the current transaction's gas price is within limits
363
+ * @param maxGasPrice The maximum allowed gas price (in wei)
364
+ */
365
+ function validateGasPrice(uint256 maxGasPrice) internal view {
366
+ if (maxGasPrice == 0) return; // No limit set
367
+
368
+ uint256 currentGasPrice = tx.gasprice;
369
+ if (currentGasPrice > maxGasPrice) {
370
+ revert GasPriceExceedsMax(currentGasPrice, maxGasPrice);
371
+ }
372
+ }
373
+
374
+ // ============ ROLE AND FUNCTION VALIDATION FUNCTIONS ============
375
+
376
+ /**
377
+ * @dev Validates that a role hasn't reached its wallet limit
378
+ * @param currentCount The current number of wallets in the role
379
+ * @param maxWallets The maximum number of wallets allowed
380
+ */
381
+ function validateWalletLimit(uint256 currentCount, uint256 maxWallets) internal pure {
382
+ if (currentCount >= maxWallets) revert RoleWalletLimitReached(currentCount, maxWallets);
383
+ }
384
+
385
+ /**
386
+ * @dev Validates that max wallets is greater than zero
387
+ * @param maxWallets The maximum number of wallets
388
+ */
389
+ function validateMaxWalletsGreaterThanZero(uint256 maxWallets) internal pure {
390
+ if (maxWallets == 0) revert MaxWalletsZero(maxWallets);
391
+ }
392
+
393
+ /**
394
+ * @dev Validates that a role name is not empty
395
+ * @param roleName The role name to validate
396
+ */
397
+ function validateRoleNameNotEmpty(string memory roleName) internal pure {
398
+ if (bytes(roleName).length == 0) revert ResourceNotFound(keccak256(bytes(roleName)));
399
+ }
400
+
401
+ // ============ UTILITY FUNCTIONS ============
402
+
403
+ /**
404
+ * @dev Validates that the first value is less than the second value
405
+ * @param from The first value (should be less than 'to')
406
+ * @param to The second value (should be greater than 'from')
407
+ */
408
+ function validateLessThan(uint256 from, uint256 to) internal pure {
409
+ if (from >= to) revert InvalidRange(from, to);
410
+ }
411
+
412
+ /**
413
+ * @dev Validates that two arrays have the same length
414
+ * @param array1Length The length of the first array
415
+ * @param array2Length The length of the second array
416
+ */
417
+ function validateArrayLengthMatch(uint256 array1Length, uint256 array2Length) internal pure {
418
+ if (array1Length != array2Length) revert ArrayLengthMismatch(array1Length, array2Length);
419
+ }
420
+
421
+ // ============ SYSTEM LIMIT VALIDATION FUNCTIONS ============
422
+
423
+ /**
424
+ * @dev Validates that batch size doesn't exceed limit
425
+ * @param batchSize The current batch size
426
+ * @param maxBatchSize The maximum allowed batch size (0 = unlimited)
427
+ */
428
+ function validateBatchSize(uint256 batchSize, uint256 maxBatchSize) internal pure {
429
+ if (maxBatchSize > 0 && batchSize > maxBatchSize) {
430
+ revert BatchSizeExceeded(batchSize, maxBatchSize);
431
+ }
432
+ }
433
+
434
+ /**
435
+ * @dev Validates that role count doesn't exceed limit
436
+ * @param currentCount The current role count
437
+ * @param maxRoles The maximum allowed roles (0 = unlimited)
438
+ */
439
+ function validateRoleCount(uint256 currentCount, uint256 maxRoles) internal pure {
440
+ if (maxRoles > 0 && currentCount >= maxRoles) {
441
+ revert MaxRolesExceeded(currentCount, maxRoles);
442
+ }
443
+ }
444
+
445
+ /**
446
+ * @dev Validates that hook count doesn't exceed limit
447
+ * @param currentCount The current hook count
448
+ * @param maxHooks The maximum allowed hooks (0 = unlimited)
449
+ */
450
+ function validateHookCount(uint256 currentCount, uint256 maxHooks) internal pure {
451
+ if (maxHooks > 0 && currentCount >= maxHooks) {
452
+ revert MaxHooksExceeded(currentCount, maxHooks);
453
+ }
454
+ }
455
+
456
+ /**
457
+ * @dev Validates that function count doesn't exceed limit
458
+ * @param currentCount The current function count
459
+ * @param maxFunctions The maximum allowed functions (0 = unlimited)
460
+ */
461
+ function validateFunctionCount(uint256 currentCount, uint256 maxFunctions) internal pure {
462
+ if (maxFunctions > 0 && currentCount >= maxFunctions) {
463
+ revert MaxFunctionsExceeded(currentCount, maxFunctions);
464
+ }
465
+ }
466
+
467
+ /**
468
+ * @dev Validates that range size doesn't exceed limit
469
+ * @param rangeSize The range size
470
+ * @param maxRangeSize The maximum allowed range size (0 = unlimited)
471
+ */
472
+ function validateRangeSize(uint256 rangeSize, uint256 maxRangeSize) internal pure {
473
+ if (maxRangeSize > 0 && rangeSize > maxRangeSize) {
474
+ revert RangeSizeExceeded(rangeSize, maxRangeSize);
475
+ }
476
+ }
477
+
478
+ /**
479
+ * @dev Validates that an index is within bounds of an array
480
+ * @param index The index to validate
481
+ * @param arrayLength The length of the array
482
+ */
483
+ function validateIndexInBounds(uint256 index, uint256 arrayLength) internal pure {
484
+ if (index >= arrayLength) revert IndexOutOfBounds(index, arrayLength);
485
+ }
486
+ }
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@bloxchain/contracts",
3
+ "version": "1.0.0-alpha",
4
+ "description": "Library engine for building enterprise grade decentralized permissioned applications",
5
+ "files": [
6
+ "contracts",
7
+ "abi",
8
+ "README.md"
9
+ ],
10
+ "scripts": {
11
+ "prepublishOnly": "node scripts/prepublish-contracts.cjs",
12
+ "postpublish": "node scripts/postpublish-contracts.cjs"
13
+ },
14
+ "keywords": [
15
+ "bloxchain",
16
+ "solidity",
17
+ "ethereum",
18
+ "smart-contracts",
19
+ "state-abstraction",
20
+ "security",
21
+ "multi-signature",
22
+ "rbac",
23
+ "secure-ownership"
24
+ ],
25
+ "author": "Particle Crypto Security",
26
+ "license": "MPL-2.0",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/PracticalParticle/Bloxchain-Protocol.git",
30
+ "directory": "package"
31
+ },
32
+ "homepage": "https://bloxchain.app/",
33
+ "bugs": {
34
+ "url": "https://github.com/PracticalParticle/Bloxchain-Protocol/issues",
35
+ "email": "security@particlecs.com"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "dependencies": {
41
+ "@openzeppelin/contracts": "^5.4.0",
42
+ "@openzeppelin/contracts-upgradeable": "^5.4.0"
43
+ },
44
+ "engines": {
45
+ "node": ">=18.0.0"
46
+ }
47
+ }