@bloxchain/contracts 1.0.0-alpha.2 → 1.0.0-alpha.20
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 +7 -7
- package/abi/BaseStateMachine.abi.json +85 -45
- package/abi/EngineBlox.abi.json +73 -90
- package/abi/GuardController.abi.json +252 -806
- package/abi/{SimpleVaultDefinitions.abi.json → GuardControllerDefinitions.abi.json} +170 -28
- package/abi/IDefinition.abi.json +5 -0
- package/abi/RuntimeRBAC.abi.json +155 -218
- package/abi/RuntimeRBACDefinitions.abi.json +179 -0
- package/abi/SecureOwnable.abi.json +524 -1621
- package/abi/SecureOwnableDefinitions.abi.json +5 -0
- package/components/README.md +8 -0
- package/core/access/RuntimeRBAC.sol +255 -270
- package/core/access/interface/IRuntimeRBAC.sol +55 -84
- package/core/access/lib/definitions/RuntimeRBACDefinitions.sol +93 -2
- package/core/base/BaseStateMachine.sol +193 -107
- package/core/base/interface/IBaseStateMachine.sol +153 -153
- package/core/execution/GuardController.sol +155 -131
- package/core/execution/interface/IGuardController.sol +146 -120
- package/core/execution/lib/definitions/GuardControllerDefinitions.sol +193 -43
- package/core/lib/EngineBlox.sol +2683 -2322
- package/{interfaces → core/lib/interfaces}/IDefinition.sol +49 -49
- package/{interfaces → core/lib/interfaces}/IEventForwarder.sol +33 -33
- package/{utils → core/lib/utils}/SharedValidation.sol +61 -8
- package/core/pattern/Account.sol +84 -0
- package/core/security/SecureOwnable.sol +456 -412
- package/core/security/interface/ISecureOwnable.sol +105 -104
- package/core/security/lib/definitions/SecureOwnableDefinitions.sol +22 -6
- package/package.json +5 -5
- package/standards/README.md +12 -0
- package/standards/behavior/ICopyable.sol +34 -0
- package/standards/hooks/IOnActionHook.sol +21 -0
- package/abi/AccountBlox.abi.json +0 -5799
- package/abi/BareBlox.abi.json +0 -1284
- package/abi/RoleBlox.abi.json +0 -4209
- package/abi/SecureBlox.abi.json +0 -3828
- package/abi/SimpleRWA20.abi.json +0 -5288
- package/abi/SimpleRWA20Definitions.abi.json +0 -191
- package/abi/SimpleVault.abi.json +0 -4951
- package/core/research/BloxchainWallet.sol +0 -306
- package/core/research/erc20-blox/ERC20Blox.sol +0 -140
- package/core/research/erc20-blox/lib/definitions/ERC20BloxDefinitions.sol +0 -185
- package/interfaces/IOnActionHook.sol +0 -79
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
-
pragma solidity 0.8.
|
|
2
|
+
pragma solidity 0.8.34;
|
|
3
3
|
|
|
4
4
|
// OpenZeppelin imports
|
|
5
5
|
import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
|
|
6
6
|
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
7
|
-
import "@openzeppelin/contracts
|
|
7
|
+
import "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
|
|
8
8
|
|
|
9
9
|
// Contracts imports
|
|
10
10
|
import "../lib/EngineBlox.sol";
|
|
11
|
-
import "
|
|
11
|
+
import "../lib/utils/SharedValidation.sol";
|
|
12
12
|
import "./interface/IBaseStateMachine.sol";
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -36,7 +36,7 @@ import "./interface/IBaseStateMachine.sol";
|
|
|
36
36
|
* - System configuration queries
|
|
37
37
|
* - Event forwarding for external monitoring
|
|
38
38
|
*/
|
|
39
|
-
abstract contract BaseStateMachine is Initializable, ERC165Upgradeable,
|
|
39
|
+
abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, ReentrancyGuardTransient {
|
|
40
40
|
using EngineBlox for EngineBlox.SecureOperationState;
|
|
41
41
|
using SharedValidation for *;
|
|
42
42
|
|
|
@@ -57,6 +57,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
57
57
|
* @param recovery The recovery address
|
|
58
58
|
* @param timeLockPeriodSec The timelock period in seconds
|
|
59
59
|
* @param eventForwarder The event forwarder address
|
|
60
|
+
* @dev Reentrancy protection inherits OpenZeppelin {ReentrancyGuardTransient} (EIP-1153 transient storage; requires Cancun+ / configured EVM such as Osaka). No initializer is required.
|
|
60
61
|
*/
|
|
61
62
|
function _initializeBaseStateMachine(
|
|
62
63
|
address initialOwner,
|
|
@@ -65,12 +66,14 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
65
66
|
uint256 timeLockPeriodSec,
|
|
66
67
|
address eventForwarder
|
|
67
68
|
) internal onlyInitializing {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
// Skip if already initialized (e.g. when multiple components call from Account.initialize)
|
|
70
|
+
if (!_secureState.initialized) {
|
|
71
|
+
__ERC165_init();
|
|
72
|
+
|
|
73
|
+
_secureState.initialize(initialOwner, broadcaster, recovery, timeLockPeriodSec);
|
|
72
74
|
|
|
73
|
-
|
|
75
|
+
_secureState.setEventForwarder(eventForwarder);
|
|
76
|
+
}
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
// ============ SYSTEM ROLE QUERY FUNCTIONS ============
|
|
@@ -118,7 +121,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
118
121
|
* @dev Centralized function to request a transaction with common validation
|
|
119
122
|
* @param requester The address requesting the transaction
|
|
120
123
|
* @param target The target contract address
|
|
121
|
-
* @param value The ETH value to send (0 for standard function calls)
|
|
124
|
+
* @param value The ETH value to send (typically 0 for standard function calls; non-zero is supported for payable edge-case workflows)
|
|
122
125
|
* @param gasLimit The gas limit for execution
|
|
123
126
|
* @param operationType The type of operation
|
|
124
127
|
* @param functionSelector The function selector for execution (NATIVE_TRANSFER_SELECTOR for simple native token transfers)
|
|
@@ -127,8 +130,9 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
127
130
|
* @notice Validates permissions for the calling function (request function), not the execution selector
|
|
128
131
|
* @notice Execution functions are internal-only and don't need permission definitions
|
|
129
132
|
* @notice This function is virtual to allow extensions to add hook functionality
|
|
130
|
-
* @notice
|
|
131
|
-
* @notice
|
|
133
|
+
* @notice Recommended standard calls: value=0, functionSelector=non-zero, params=encoded data
|
|
134
|
+
* @notice Flexible edge case: non-native selectors may intentionally forward ETH to payable targets
|
|
135
|
+
* @notice Native-only convenience flow: value>0, functionSelector=NATIVE_TRANSFER_SELECTOR, params=""
|
|
132
136
|
*/
|
|
133
137
|
function _requestTransaction(
|
|
134
138
|
address requester,
|
|
@@ -139,7 +143,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
139
143
|
bytes4 functionSelector,
|
|
140
144
|
bytes memory params
|
|
141
145
|
) internal virtual returns (EngineBlox.TxRecord memory) {
|
|
142
|
-
|
|
146
|
+
EngineBlox.TxRecord memory txRecord = EngineBlox.txRequest(
|
|
143
147
|
_getSecureState(),
|
|
144
148
|
requester,
|
|
145
149
|
target,
|
|
@@ -150,6 +154,48 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
150
154
|
functionSelector,
|
|
151
155
|
params
|
|
152
156
|
);
|
|
157
|
+
_postActionHook(txRecord);
|
|
158
|
+
return txRecord;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @dev Centralized function to request a transaction with payment details attached from the start
|
|
163
|
+
* @param requester The address requesting the transaction
|
|
164
|
+
* @param target The target contract address
|
|
165
|
+
* @param value The ETH value to send (typically 0 for standard function calls; non-zero is supported for payable edge-case workflows)
|
|
166
|
+
* @param gasLimit The gas limit for execution
|
|
167
|
+
* @param operationType The type of operation
|
|
168
|
+
* @param functionSelector The function selector for execution (NATIVE_TRANSFER_SELECTOR for simple native token transfers)
|
|
169
|
+
* @param params The encoded parameters for the function (empty for simple native token transfers)
|
|
170
|
+
* @param paymentDetails The payment details to attach to the transaction
|
|
171
|
+
* @return The created transaction record with payment set
|
|
172
|
+
* @notice Validates request permissions (same as request without payment)
|
|
173
|
+
* @notice This function is virtual to allow extensions to add hook functionality
|
|
174
|
+
*/
|
|
175
|
+
function _requestTransactionWithPayment(
|
|
176
|
+
address requester,
|
|
177
|
+
address target,
|
|
178
|
+
uint256 value,
|
|
179
|
+
uint256 gasLimit,
|
|
180
|
+
bytes32 operationType,
|
|
181
|
+
bytes4 functionSelector,
|
|
182
|
+
bytes memory params,
|
|
183
|
+
EngineBlox.PaymentDetails memory paymentDetails
|
|
184
|
+
) internal virtual returns (EngineBlox.TxRecord memory) {
|
|
185
|
+
EngineBlox.TxRecord memory txRecord = EngineBlox.txRequestWithPayment(
|
|
186
|
+
_getSecureState(),
|
|
187
|
+
requester,
|
|
188
|
+
target,
|
|
189
|
+
value,
|
|
190
|
+
gasLimit,
|
|
191
|
+
operationType,
|
|
192
|
+
bytes4(msg.sig),
|
|
193
|
+
functionSelector,
|
|
194
|
+
params,
|
|
195
|
+
paymentDetails
|
|
196
|
+
);
|
|
197
|
+
_postActionHook(txRecord);
|
|
198
|
+
return txRecord;
|
|
153
199
|
}
|
|
154
200
|
|
|
155
201
|
/**
|
|
@@ -159,12 +205,14 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
159
205
|
* @notice Validates permissions for the calling function (approval function selector), not the execution selector
|
|
160
206
|
* @notice Execution functions are internal-only and don't need permission definitions
|
|
161
207
|
* @notice This function is virtual to allow extensions to add hook functionality
|
|
162
|
-
* @notice Protected by
|
|
208
|
+
* @notice Protected by ReentrancyGuardTransient to prevent reentrancy attacks
|
|
163
209
|
*/
|
|
164
210
|
function _approveTransaction(
|
|
165
211
|
uint256 txId
|
|
166
212
|
) internal virtual nonReentrant returns (EngineBlox.TxRecord memory) {
|
|
167
|
-
|
|
213
|
+
EngineBlox.TxRecord memory txRecord = EngineBlox.txDelayedApproval(_getSecureState(), txId, bytes4(msg.sig));
|
|
214
|
+
_postActionHook(txRecord);
|
|
215
|
+
return txRecord;
|
|
168
216
|
}
|
|
169
217
|
|
|
170
218
|
/**
|
|
@@ -174,12 +222,15 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
174
222
|
* @notice Validates permissions for the calling function (msg.sig) and handler selector from metaTx
|
|
175
223
|
* @notice Uses EXECUTE_META_APPROVE action for permission checking
|
|
176
224
|
* @notice This function is virtual to allow extensions to add hook functionality
|
|
177
|
-
* @notice Protected by
|
|
225
|
+
* @notice Protected by ReentrancyGuardTransient to prevent reentrancy attacks
|
|
178
226
|
*/
|
|
179
227
|
function _approveTransactionWithMetaTx(
|
|
180
228
|
EngineBlox.MetaTransaction memory metaTx
|
|
181
229
|
) internal virtual nonReentrant returns (EngineBlox.TxRecord memory) {
|
|
182
|
-
|
|
230
|
+
_validateMetaTxHandlerBinding(metaTx);
|
|
231
|
+
EngineBlox.TxRecord memory txRecord = EngineBlox.txApprovalWithMetaTx(_getSecureState(), metaTx);
|
|
232
|
+
_postActionHook(txRecord);
|
|
233
|
+
return txRecord;
|
|
183
234
|
}
|
|
184
235
|
|
|
185
236
|
/**
|
|
@@ -193,7 +244,9 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
193
244
|
function _cancelTransaction(
|
|
194
245
|
uint256 txId
|
|
195
246
|
) internal virtual returns (EngineBlox.TxRecord memory) {
|
|
196
|
-
|
|
247
|
+
EngineBlox.TxRecord memory txRecord = EngineBlox.txCancellation(_getSecureState(), txId, bytes4(msg.sig));
|
|
248
|
+
_postActionHook(txRecord);
|
|
249
|
+
return txRecord;
|
|
197
250
|
}
|
|
198
251
|
|
|
199
252
|
/**
|
|
@@ -207,7 +260,10 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
207
260
|
function _cancelTransactionWithMetaTx(
|
|
208
261
|
EngineBlox.MetaTransaction memory metaTx
|
|
209
262
|
) internal virtual returns (EngineBlox.TxRecord memory) {
|
|
210
|
-
|
|
263
|
+
_validateMetaTxHandlerBinding(metaTx);
|
|
264
|
+
EngineBlox.TxRecord memory txRecord = EngineBlox.txCancellationWithMetaTx(_getSecureState(), metaTx);
|
|
265
|
+
_postActionHook(txRecord);
|
|
266
|
+
return txRecord;
|
|
211
267
|
}
|
|
212
268
|
|
|
213
269
|
/**
|
|
@@ -217,26 +273,55 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
217
273
|
* @notice Validates permissions for the calling function (msg.sig) and handler selector from metaTx
|
|
218
274
|
* @notice Uses EXECUTE_META_REQUEST_AND_APPROVE action for permission checking
|
|
219
275
|
* @notice This function is virtual to allow extensions to add hook functionality
|
|
220
|
-
* @notice Protected by
|
|
276
|
+
* @notice Protected by ReentrancyGuardTransient to prevent reentrancy attacks
|
|
221
277
|
*/
|
|
222
278
|
function _requestAndApproveTransaction(
|
|
223
279
|
EngineBlox.MetaTransaction memory metaTx
|
|
224
280
|
) internal virtual nonReentrant returns (EngineBlox.TxRecord memory) {
|
|
225
|
-
|
|
281
|
+
_validateMetaTxHandlerBinding(metaTx);
|
|
282
|
+
EngineBlox.TxRecord memory txRecord = EngineBlox.requestAndApprove(_getSecureState(), metaTx);
|
|
283
|
+
_postActionHook(txRecord);
|
|
284
|
+
return txRecord;
|
|
226
285
|
}
|
|
227
286
|
|
|
228
287
|
/**
|
|
229
|
-
* @dev
|
|
230
|
-
*
|
|
231
|
-
* @param
|
|
232
|
-
* @notice This function is virtual to allow extensions to add hook functionality
|
|
288
|
+
* @dev Post-action hook invoked after any transaction operation that produces a TxRecord.
|
|
289
|
+
* Override in derived contracts to add centralized post-tx logic (e.g. notifications, side effects).
|
|
290
|
+
* @param txRecord The transaction record produced by the operation
|
|
233
291
|
*/
|
|
234
|
-
function
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
292
|
+
function _postActionHook(EngineBlox.TxRecord memory txRecord) internal virtual {}
|
|
293
|
+
|
|
294
|
+
// ============ HOOK MANAGEMENT ============
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* @dev Sets the hook contract for a function selector (internal; no access control).
|
|
298
|
+
* Extensions (e.g. HookManager) may expose an external setHook with owner check.
|
|
299
|
+
* @param functionSelector The function selector
|
|
300
|
+
* @param hook The hook contract address (must not be zero)
|
|
301
|
+
*/
|
|
302
|
+
function _setHook(bytes4 functionSelector, address hook) internal {
|
|
303
|
+
EngineBlox.setHook(_getSecureState(), functionSelector, hook);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* @dev Clears the hook contract for a function selector (internal; no access control).
|
|
308
|
+
* Extensions may expose an external clearHook with owner check.
|
|
309
|
+
* @param functionSelector The function selector
|
|
310
|
+
* @param hook The hook contract address to remove (must not be zero)
|
|
311
|
+
*/
|
|
312
|
+
function _clearHook(bytes4 functionSelector, address hook) internal {
|
|
313
|
+
EngineBlox.clearHook(_getSecureState(), functionSelector, hook);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* @dev Returns all configured hooks for a function selector
|
|
318
|
+
* @param functionSelector The function selector
|
|
319
|
+
* @return hooks Array of hook contract addresses
|
|
320
|
+
* @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
|
|
321
|
+
*/
|
|
322
|
+
function getHooks(bytes4 functionSelector) public view returns (address[] memory hooks) {
|
|
323
|
+
_validateAnyRole();
|
|
324
|
+
return EngineBlox.getHooks(_getSecureState(), functionSelector);
|
|
240
325
|
}
|
|
241
326
|
|
|
242
327
|
// ============ META-TRANSACTION UTILITIES ============
|
|
@@ -325,28 +410,29 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
325
410
|
* @param toTxId The ending transaction ID (inclusive)
|
|
326
411
|
* @return The transaction history within the specified range
|
|
327
412
|
* @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
|
|
413
|
+
* @notice Returns an empty array when **`txCounter == 0`** or when the range, after clamping to **1..txCounter**,
|
|
414
|
+
* does not overlap any transaction ids (e.g. `fromTxId` entirely above the current counter).
|
|
328
415
|
*/
|
|
329
416
|
function getTransactionHistory(uint256 fromTxId, uint256 toTxId) public view returns (EngineBlox.TxRecord[] memory) {
|
|
330
417
|
_validateAnyRole();
|
|
331
|
-
|
|
332
|
-
|
|
418
|
+
|
|
419
|
+
uint256 counter = _secureState.txCounter;
|
|
420
|
+
|
|
421
|
+
// Normalize bounds to valid transaction id range [1, counter]
|
|
333
422
|
fromTxId = fromTxId > 0 ? fromTxId : 1;
|
|
334
|
-
toTxId = toTxId >
|
|
335
|
-
|
|
336
|
-
//
|
|
337
|
-
|
|
423
|
+
toTxId = toTxId > counter ? counter : toTxId;
|
|
424
|
+
|
|
425
|
+
// Empty history: invalid / non-overlapping clamped range (includes txCounter == 0 → toTxId == 0).
|
|
426
|
+
uint256 rangeSize = fromTxId > toTxId ? 0 : toTxId - fromTxId + 1;
|
|
427
|
+
|
|
428
|
+
if (rangeSize > 0) {
|
|
429
|
+
SharedValidation.validateRangeSize(rangeSize, 1000);
|
|
430
|
+
}
|
|
338
431
|
|
|
339
|
-
uint256 rangeSize = toTxId - fromTxId + 1;
|
|
340
|
-
|
|
341
|
-
// For larger ranges, use paginated version
|
|
342
|
-
SharedValidation.validateRangeSize(rangeSize, 1000);
|
|
343
|
-
|
|
344
432
|
EngineBlox.TxRecord[] memory history = new EngineBlox.TxRecord[](rangeSize);
|
|
345
|
-
|
|
346
433
|
for (uint256 i = 0; i < rangeSize; i++) {
|
|
347
434
|
history[i] = _secureState.getTxRecord(fromTxId + i);
|
|
348
435
|
}
|
|
349
|
-
|
|
350
436
|
return history;
|
|
351
437
|
}
|
|
352
438
|
|
|
@@ -368,7 +454,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
368
454
|
*/
|
|
369
455
|
function getPendingTransactions() public view returns (uint256[] memory) {
|
|
370
456
|
_validateAnyRole();
|
|
371
|
-
return _secureState.
|
|
457
|
+
return _secureState.getPendingTransactions();
|
|
372
458
|
}
|
|
373
459
|
|
|
374
460
|
// ============ ROLE AND PERMISSION QUERIES ============
|
|
@@ -377,7 +463,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
377
463
|
* @dev Gets the basic role information by its hash
|
|
378
464
|
* @param roleHash The hash of the role to get
|
|
379
465
|
* @return roleName The name of the role
|
|
380
|
-
* @return
|
|
466
|
+
* @return hash The hash of the role
|
|
381
467
|
* @return maxWallets The maximum number of wallets allowed for this role
|
|
382
468
|
* @return walletCount The current number of wallets assigned to this role
|
|
383
469
|
* @return isProtected Whether the role is protected from removal
|
|
@@ -385,7 +471,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
385
471
|
*/
|
|
386
472
|
function getRole(bytes32 roleHash) public view returns (
|
|
387
473
|
string memory roleName,
|
|
388
|
-
bytes32
|
|
474
|
+
bytes32 hash,
|
|
389
475
|
uint256 maxWallets,
|
|
390
476
|
uint256 walletCount,
|
|
391
477
|
bool isProtected
|
|
@@ -429,29 +515,21 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
429
515
|
* @return Array of authorized wallet addresses
|
|
430
516
|
* @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
|
|
431
517
|
*/
|
|
432
|
-
function
|
|
518
|
+
function getAuthorizedWallets(bytes32 roleHash) public view returns (address[] memory) {
|
|
433
519
|
_validateAnyRole();
|
|
434
520
|
_validateRoleExists(roleHash);
|
|
435
521
|
return _getAuthorizedWallets(roleHash);
|
|
436
522
|
}
|
|
437
523
|
|
|
438
524
|
/**
|
|
439
|
-
* @dev
|
|
440
|
-
* @param functionSelector The function selector to
|
|
441
|
-
* @return
|
|
442
|
-
|
|
443
|
-
function functionSchemaExists(bytes4 functionSelector) public view returns (bool) {
|
|
444
|
-
return _secureState.functions[functionSelector].functionSelector == functionSelector;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* @dev Returns if an action is supported by a function
|
|
449
|
-
* @param functionSelector The function selector to check
|
|
450
|
-
* @param action The action to check
|
|
451
|
-
* @return True if the action is supported by the function, false otherwise
|
|
525
|
+
* @dev Gets function schema information
|
|
526
|
+
* @param functionSelector The function selector to get information for
|
|
527
|
+
* @return The full FunctionSchema struct (functionSignature, functionSelector, operationType, operationName, supportedActionsBitmap, enforceHandlerRelations, isProtected, handlerForSelectors)
|
|
528
|
+
* @notice Reverts with ResourceNotFound if the schema does not exist
|
|
452
529
|
*/
|
|
453
|
-
function
|
|
454
|
-
|
|
530
|
+
function getFunctionSchema(bytes4 functionSelector) external view returns (EngineBlox.FunctionSchema memory) {
|
|
531
|
+
_validateAnyRole();
|
|
532
|
+
return _secureState.getFunctionSchema(functionSelector);
|
|
455
533
|
}
|
|
456
534
|
|
|
457
535
|
/**
|
|
@@ -485,7 +563,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
485
563
|
*/
|
|
486
564
|
function getSupportedOperationTypes() public view returns (bytes32[] memory) {
|
|
487
565
|
_validateAnyRole();
|
|
488
|
-
return _secureState.
|
|
566
|
+
return _secureState.getSupportedOperationTypes();
|
|
489
567
|
}
|
|
490
568
|
|
|
491
569
|
/**
|
|
@@ -495,7 +573,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
495
573
|
*/
|
|
496
574
|
function getSupportedRoles() public view returns (bytes32[] memory) {
|
|
497
575
|
_validateAnyRole();
|
|
498
|
-
return _secureState.
|
|
576
|
+
return _secureState.getSupportedRoles();
|
|
499
577
|
}
|
|
500
578
|
|
|
501
579
|
/**
|
|
@@ -505,7 +583,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
505
583
|
*/
|
|
506
584
|
function getSupportedFunctions() public view returns (bytes4[] memory) {
|
|
507
585
|
_validateAnyRole();
|
|
508
|
-
return _secureState.
|
|
586
|
+
return _secureState.getSupportedFunctions();
|
|
509
587
|
}
|
|
510
588
|
|
|
511
589
|
/**
|
|
@@ -542,15 +620,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
542
620
|
* @return Array of authorized wallet addresses
|
|
543
621
|
*/
|
|
544
622
|
function _getAuthorizedWallets(bytes32 roleHash) internal view returns (address[] memory) {
|
|
545
|
-
EngineBlox.
|
|
546
|
-
uint256 walletCount = role.walletCount;
|
|
547
|
-
|
|
548
|
-
address[] memory wallets = new address[](walletCount);
|
|
549
|
-
for (uint256 i = 0; i < walletCount; i++) {
|
|
550
|
-
wallets[i] = _getAuthorizedWalletAt(roleHash, i);
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
return wallets;
|
|
623
|
+
return EngineBlox.getAuthorizedWallets(_getSecureState(), roleHash);
|
|
554
624
|
}
|
|
555
625
|
|
|
556
626
|
/**
|
|
@@ -601,14 +671,14 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
601
671
|
}
|
|
602
672
|
|
|
603
673
|
/**
|
|
604
|
-
* @dev Centralized function to update
|
|
674
|
+
* @dev Centralized function to update wallet for a role (replaces oldWallet with newWallet).
|
|
605
675
|
* @param roleHash The role hash
|
|
606
676
|
* @param newWallet The new wallet address
|
|
607
677
|
* @param oldWallet The old wallet address
|
|
608
678
|
* @notice This function is virtual to allow extensions to add hook functionality or additional validation
|
|
609
679
|
*/
|
|
610
|
-
function
|
|
611
|
-
EngineBlox.
|
|
680
|
+
function _updateWallet(bytes32 roleHash, address newWallet, address oldWallet) internal virtual {
|
|
681
|
+
EngineBlox.updateWallet(_getSecureState(), roleHash, newWallet, oldWallet);
|
|
612
682
|
}
|
|
613
683
|
|
|
614
684
|
/**
|
|
@@ -617,48 +687,53 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
617
687
|
* @notice This function is virtual to allow extensions to add hook functionality
|
|
618
688
|
*/
|
|
619
689
|
function _updateTimeLockPeriod(uint256 newTimeLockPeriodSec) internal virtual {
|
|
690
|
+
uint256 oldPeriod = getTimeLockPeriodSec();
|
|
620
691
|
EngineBlox.updateTimeLockPeriod(_getSecureState(), newTimeLockPeriodSec);
|
|
692
|
+
_logComponentEvent(abi.encode(oldPeriod, newTimeLockPeriodSec));
|
|
621
693
|
}
|
|
622
694
|
|
|
623
695
|
// ============ FUNCTION SCHEMA MANAGEMENT ============
|
|
624
696
|
|
|
625
697
|
/**
|
|
626
|
-
* @dev Centralized function to
|
|
698
|
+
* @dev Centralized function to register a function schema
|
|
627
699
|
* @param functionSignature The function signature
|
|
628
700
|
* @param functionSelector The function selector
|
|
629
701
|
* @param operationName The operation name
|
|
630
702
|
* @param supportedActionsBitmap The bitmap of supported actions
|
|
703
|
+
* @param enforceHandlerRelations Whether to enforce strict handler/schema alignment
|
|
631
704
|
* @param isProtected Whether the function schema is protected
|
|
632
705
|
* @param handlerForSelectors Array of handler selectors
|
|
633
706
|
* @notice This function is virtual to allow extensions to add hook functionality
|
|
634
707
|
*/
|
|
635
|
-
function
|
|
708
|
+
function _registerFunction(
|
|
636
709
|
string memory functionSignature,
|
|
637
710
|
bytes4 functionSelector,
|
|
638
711
|
string memory operationName,
|
|
639
712
|
uint16 supportedActionsBitmap,
|
|
713
|
+
bool enforceHandlerRelations,
|
|
640
714
|
bool isProtected,
|
|
641
715
|
bytes4[] memory handlerForSelectors
|
|
642
716
|
) internal virtual {
|
|
643
|
-
EngineBlox.
|
|
717
|
+
EngineBlox.registerFunction(
|
|
644
718
|
_getSecureState(),
|
|
645
719
|
functionSignature,
|
|
646
720
|
functionSelector,
|
|
647
721
|
operationName,
|
|
648
722
|
supportedActionsBitmap,
|
|
723
|
+
enforceHandlerRelations,
|
|
649
724
|
isProtected,
|
|
650
725
|
handlerForSelectors
|
|
651
726
|
);
|
|
652
727
|
}
|
|
653
728
|
|
|
654
729
|
/**
|
|
655
|
-
* @dev Centralized function to
|
|
656
|
-
* @param functionSelector The function selector to
|
|
730
|
+
* @dev Centralized function to unregister a function schema
|
|
731
|
+
* @param functionSelector The function selector to unregister
|
|
657
732
|
* @param safeRemoval Whether to perform safe removal (check for role references)
|
|
658
733
|
* @notice This function is virtual to allow extensions to add hook functionality
|
|
659
734
|
*/
|
|
660
|
-
function
|
|
661
|
-
EngineBlox.
|
|
735
|
+
function _unregisterFunction(bytes4 functionSelector, bool safeRemoval) internal virtual {
|
|
736
|
+
EngineBlox.unregisterFunction(_getSecureState(), functionSelector, safeRemoval);
|
|
662
737
|
}
|
|
663
738
|
|
|
664
739
|
/**
|
|
@@ -686,6 +761,20 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
686
761
|
|
|
687
762
|
// ============ PERMISSION VALIDATION ============
|
|
688
763
|
|
|
764
|
+
/**
|
|
765
|
+
* @dev Binds signed `MetaTxParams` to this wrapper's entrypoint (`msg.sig`) and verifying contract.
|
|
766
|
+
* Must run in `BaseStateMachine` context, not inside linked `EngineBlox` library code (delegatecall
|
|
767
|
+
* would make `msg.sig` refer to the library function, not the outer wrapper).
|
|
768
|
+
* @param metaTx The meta-transaction whose `params` are validated against `msg.sig` and `address(this)`.
|
|
769
|
+
*/
|
|
770
|
+
function _validateMetaTxHandlerBinding(EngineBlox.MetaTransaction memory metaTx) internal view {
|
|
771
|
+
SharedValidation.validateMetaTxHandlerSelectorBinding(
|
|
772
|
+
metaTx.params.handlerSelector,
|
|
773
|
+
bytes4(msg.sig)
|
|
774
|
+
);
|
|
775
|
+
SharedValidation.validateMetaTxHandlerContractBinding(metaTx.params.handlerContract);
|
|
776
|
+
}
|
|
777
|
+
|
|
689
778
|
/**
|
|
690
779
|
* @dev Centralized function to validate that the caller has any role
|
|
691
780
|
*/
|
|
@@ -721,7 +810,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
721
810
|
/**
|
|
722
811
|
* @dev Adds a function selector to the system macro selectors set.
|
|
723
812
|
* Macro selectors are allowed to target address(this) for system-level operations.
|
|
724
|
-
* @param functionSelector The function selector to add (e.g. NATIVE_TRANSFER_SELECTOR
|
|
813
|
+
* @param functionSelector The function selector to add (e.g. NATIVE_TRANSFER_SELECTOR).
|
|
725
814
|
*/
|
|
726
815
|
function _addMacroSelector(bytes4 functionSelector) internal {
|
|
727
816
|
EngineBlox.addMacroSelector(_getSecureState(), functionSelector);
|
|
@@ -763,8 +852,8 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
763
852
|
* @param target The target address to whitelist
|
|
764
853
|
* @notice This function is virtual to allow extensions to add hook functionality
|
|
765
854
|
*/
|
|
766
|
-
function
|
|
767
|
-
_getSecureState().
|
|
855
|
+
function _addTargetToWhitelist(bytes4 functionSelector, address target) internal virtual {
|
|
856
|
+
_getSecureState().addTargetToWhitelist(functionSelector, target);
|
|
768
857
|
}
|
|
769
858
|
|
|
770
859
|
/**
|
|
@@ -773,16 +862,18 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
773
862
|
* @param target The target address to remove
|
|
774
863
|
* @notice This function is virtual to allow extensions to add hook functionality
|
|
775
864
|
*/
|
|
776
|
-
function
|
|
777
|
-
_getSecureState().
|
|
865
|
+
function _removeTargetFromWhitelist(bytes4 functionSelector, address target) internal virtual {
|
|
866
|
+
_getSecureState().removeTargetFromWhitelist(functionSelector, target);
|
|
778
867
|
}
|
|
779
868
|
|
|
780
869
|
/**
|
|
781
|
-
* @dev
|
|
870
|
+
* @dev Gets all whitelisted targets for a function selector
|
|
782
871
|
* @param functionSelector The function selector
|
|
783
872
|
* @return Array of whitelisted target addresses
|
|
873
|
+
* @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
|
|
784
874
|
*/
|
|
785
|
-
function
|
|
875
|
+
function getFunctionWhitelistTargets(bytes4 functionSelector) public view returns (address[] memory) {
|
|
876
|
+
_validateAnyRole();
|
|
786
877
|
return _getSecureState().getFunctionWhitelistTargets(functionSelector);
|
|
787
878
|
}
|
|
788
879
|
|
|
@@ -794,30 +885,29 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
794
885
|
* @param functionSchemas Array of function schema definitions
|
|
795
886
|
* @param roleHashes Array of role hashes
|
|
796
887
|
* @param functionPermissions Array of function permissions (parallel to roleHashes)
|
|
797
|
-
* @param
|
|
798
|
-
* @notice When
|
|
799
|
-
* @notice This allows custom definitions to be restricted from creating protected schemas
|
|
888
|
+
* @param requireProtected When true, all function schemas must be protected; reverts if any is not
|
|
889
|
+
* @notice When requireProtected is true, every function schema must have isProtected == true
|
|
800
890
|
*/
|
|
801
891
|
function _loadDefinitions(
|
|
802
892
|
EngineBlox.FunctionSchema[] memory functionSchemas,
|
|
803
893
|
bytes32[] memory roleHashes,
|
|
804
894
|
EngineBlox.FunctionPermission[] memory functionPermissions,
|
|
805
|
-
bool
|
|
895
|
+
bool requireProtected
|
|
806
896
|
) internal {
|
|
807
897
|
// Load function schemas
|
|
808
898
|
for (uint256 i = 0; i < functionSchemas.length; i++) {
|
|
809
|
-
//
|
|
810
|
-
if (
|
|
811
|
-
revert SharedValidation.
|
|
812
|
-
|
|
899
|
+
// When enforcing, require every schema to be protected
|
|
900
|
+
if (requireProtected && !functionSchemas[i].isProtected) {
|
|
901
|
+
revert SharedValidation.ContractFunctionMustBeProtected(
|
|
902
|
+
functionSchemas[i].functionSelector
|
|
813
903
|
);
|
|
814
904
|
}
|
|
815
|
-
|
|
816
|
-
_getSecureState(),
|
|
905
|
+
_registerFunction(
|
|
817
906
|
functionSchemas[i].functionSignature,
|
|
818
907
|
functionSchemas[i].functionSelector,
|
|
819
908
|
functionSchemas[i].operationName,
|
|
820
909
|
functionSchemas[i].supportedActionsBitmap,
|
|
910
|
+
functionSchemas[i].enforceHandlerRelations,
|
|
821
911
|
functionSchemas[i].isProtected,
|
|
822
912
|
functionSchemas[i].handlerForSelectors
|
|
823
913
|
);
|
|
@@ -826,11 +916,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
826
916
|
// Load role permissions using parallel arrays
|
|
827
917
|
SharedValidation.validateArrayLengthMatch(roleHashes.length, functionPermissions.length);
|
|
828
918
|
for (uint256 i = 0; i < roleHashes.length; i++) {
|
|
829
|
-
|
|
830
|
-
_getSecureState(),
|
|
831
|
-
roleHashes[i],
|
|
832
|
-
functionPermissions[i]
|
|
833
|
-
);
|
|
919
|
+
_addFunctionToRole(roleHashes[i], functionPermissions[i]);
|
|
834
920
|
}
|
|
835
921
|
}
|
|
836
922
|
|