@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.
- package/README.md +55 -18
- package/abi/{ControlBlox.abi.json → AccountBlox.abi.json} +699 -2974
- package/abi/BareBlox.abi.json +127 -90
- package/abi/BaseStateMachine.abi.json +127 -90
- package/abi/EngineBlox.abi.json +11 -31
- package/abi/GuardController.abi.json +217 -895
- package/abi/GuardControllerDefinitions.abi.json +380 -0
- package/abi/IDefinition.abi.json +19 -0
- package/abi/RoleBlox.abi.json +818 -2404
- package/abi/RuntimeRBAC.abi.json +122 -328
- package/abi/RuntimeRBACDefinitions.abi.json +243 -0
- package/abi/SecureBlox.abi.json +620 -1952
- package/abi/SecureOwnable.abi.json +469 -1801
- package/abi/SecureOwnableDefinitions.abi.json +57 -0
- package/abi/SimpleRWA20.abi.json +486 -1999
- package/abi/SimpleRWA20Definitions.abi.json +19 -0
- package/abi/SimpleVault.abi.json +884 -2685
- package/abi/SimpleVaultDefinitions.abi.json +19 -0
- package/components/README.md +8 -0
- package/core/access/RuntimeRBAC.sol +184 -0
- package/core/access/interface/IRuntimeRBAC.sol +55 -0
- package/{contracts/core → core}/access/lib/definitions/RuntimeRBACDefinitions.sol +121 -1
- package/{contracts/core → core}/base/BaseStateMachine.sol +187 -54
- package/{contracts/core → core}/base/interface/IBaseStateMachine.sol +7 -0
- package/{contracts/core → core}/execution/GuardController.sol +89 -155
- package/{contracts/core → core}/execution/interface/IGuardController.sol +52 -12
- package/{contracts/core → core}/execution/lib/definitions/GuardControllerDefinitions.sol +91 -2
- package/{contracts/core → core}/lib/EngineBlox.sol +167 -64
- package/{contracts → core/lib}/interfaces/IDefinition.sol +15 -6
- package/{contracts → core/lib}/interfaces/IEventForwarder.sol +1 -1
- package/{contracts → core/lib}/utils/SharedValidation.sol +490 -486
- package/core/pattern/Account.sol +75 -0
- package/core/research/BloxchainWallet.sol +133 -0
- package/core/research/FactoryBlox/FactoryBlox.sol +344 -0
- package/core/research/FactoryBlox/FactoryBloxDefinitions.sol +144 -0
- package/core/research/erc1155-blox/ERC1155Blox.sol +170 -0
- package/core/research/erc1155-blox/lib/definitions/ERC1155BloxDefinitions.sol +203 -0
- package/core/research/erc20-blox/ERC20Blox.sol +135 -0
- package/core/research/erc20-blox/lib/definitions/ERC20BloxDefinitions.sol +185 -0
- package/core/research/erc721-blox/ERC721Blox.sol +131 -0
- package/core/research/erc721-blox/lib/definitions/ERC721BloxDefinitions.sol +172 -0
- package/core/research/lending-blox/.gitkeep +1 -0
- package/core/research/p2p-blox/P2PBlox.sol +266 -0
- package/core/research/p2p-blox/README.md +85 -0
- package/core/research/p2p-blox/lib/definitions/P2PBloxDefinitions.sol +19 -0
- package/{contracts/core → core}/security/SecureOwnable.sol +390 -419
- package/{contracts/core → core}/security/interface/ISecureOwnable.sol +27 -40
- package/{contracts/core → core}/security/lib/definitions/SecureOwnableDefinitions.sol +786 -757
- package/package.json +49 -47
- package/standards/README.md +12 -0
- package/standards/behavior/ICopyable.sol +36 -0
- package/standards/hooks/IOnActionHook.sol +21 -0
- package/contracts/core/access/RuntimeRBAC.sol +0 -344
- package/contracts/core/access/interface/IRuntimeRBAC.sol +0 -108
- 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 "
|
|
11
|
-
import "
|
|
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
|
|
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
|
-
|
|
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:
|
|
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(
|
|
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
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
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 "
|
|
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
|
}
|