@bloxchain/contracts 1.0.0-alpha.2 → 1.0.0-alpha.21
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 +798 -753
- package/abi/EngineBlox.abi.json +566 -576
- package/abi/GuardController.abi.json +1546 -2095
- package/abi/GuardControllerDefinitions.abi.json +416 -0
- package/abi/IDefinition.abi.json +57 -47
- package/abi/RuntimeRBAC.abi.json +901 -959
- package/abi/RuntimeRBACDefinitions.abi.json +265 -81
- package/abi/SecureOwnable.abi.json +1522 -2581
- package/abi/SecureOwnableDefinitions.abi.json +174 -164
- package/components/README.md +8 -0
- package/core/access/RuntimeRBAC.sol +253 -270
- package/core/access/interface/IRuntimeRBAC.sol +55 -84
- package/core/access/lib/definitions/RuntimeRBACDefinitions.sol +97 -4
- package/core/base/BaseStateMachine.sol +198 -108
- package/core/base/interface/IBaseStateMachine.sol +153 -153
- package/core/execution/GuardController.sol +156 -131
- package/core/execution/interface/IGuardController.sol +146 -120
- package/core/execution/lib/definitions/GuardControllerDefinitions.sol +207 -45
- package/core/lib/EngineBlox.sol +2636 -2322
- package/{interfaces → core/lib/interfaces}/IDefinition.sol +49 -49
- package/{interfaces → core/lib/interfaces}/IEventForwarder.sol +5 -3
- package/{utils → core/lib/utils}/SharedValidation.sol +69 -22
- package/core/pattern/Account.sol +84 -0
- package/core/security/SecureOwnable.sol +180 -146
- package/core/security/interface/ISecureOwnable.sol +105 -104
- package/core/security/lib/definitions/SecureOwnableDefinitions.sol +818 -786
- 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/abi/SimpleVaultDefinitions.abi.json +0 -269
- 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.35;
|
|
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, isGrantRevocable, 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,56 @@ 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
|
|
631
|
-
* @param
|
|
703
|
+
* @param enforceHandlerRelations Whether to enforce strict handler/schema alignment
|
|
704
|
+
* @param isProtected Whether the function schema is protected from unregister
|
|
705
|
+
* @param isGrantRevocable Whether role grants for this schema may be removed via `removeFunctionFromRole` (any role, including protected roles, when true)
|
|
632
706
|
* @param handlerForSelectors Array of handler selectors
|
|
633
707
|
* @notice This function is virtual to allow extensions to add hook functionality
|
|
634
708
|
*/
|
|
635
|
-
function
|
|
709
|
+
function _registerFunction(
|
|
636
710
|
string memory functionSignature,
|
|
637
711
|
bytes4 functionSelector,
|
|
638
712
|
string memory operationName,
|
|
639
713
|
uint16 supportedActionsBitmap,
|
|
714
|
+
bool enforceHandlerRelations,
|
|
640
715
|
bool isProtected,
|
|
716
|
+
bool isGrantRevocable,
|
|
641
717
|
bytes4[] memory handlerForSelectors
|
|
642
718
|
) internal virtual {
|
|
643
|
-
EngineBlox.
|
|
719
|
+
EngineBlox.registerFunction(
|
|
644
720
|
_getSecureState(),
|
|
645
721
|
functionSignature,
|
|
646
722
|
functionSelector,
|
|
647
723
|
operationName,
|
|
648
724
|
supportedActionsBitmap,
|
|
725
|
+
enforceHandlerRelations,
|
|
649
726
|
isProtected,
|
|
727
|
+
isGrantRevocable,
|
|
650
728
|
handlerForSelectors
|
|
651
729
|
);
|
|
652
730
|
}
|
|
653
731
|
|
|
654
732
|
/**
|
|
655
|
-
* @dev Centralized function to
|
|
656
|
-
* @param functionSelector The function selector to
|
|
733
|
+
* @dev Centralized function to unregister a function schema
|
|
734
|
+
* @param functionSelector The function selector to unregister
|
|
657
735
|
* @param safeRemoval Whether to perform safe removal (check for role references)
|
|
658
736
|
* @notice This function is virtual to allow extensions to add hook functionality
|
|
659
737
|
*/
|
|
660
|
-
function
|
|
661
|
-
EngineBlox.
|
|
738
|
+
function _unregisterFunction(bytes4 functionSelector, bool safeRemoval) internal virtual {
|
|
739
|
+
EngineBlox.unregisterFunction(_getSecureState(), functionSelector, safeRemoval);
|
|
662
740
|
}
|
|
663
741
|
|
|
664
742
|
/**
|
|
@@ -686,6 +764,20 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
686
764
|
|
|
687
765
|
// ============ PERMISSION VALIDATION ============
|
|
688
766
|
|
|
767
|
+
/**
|
|
768
|
+
* @dev Binds signed `MetaTxParams` to this wrapper's entrypoint (`msg.sig`) and verifying contract.
|
|
769
|
+
* Must run in `BaseStateMachine` context, not inside linked `EngineBlox` library code (delegatecall
|
|
770
|
+
* would make `msg.sig` refer to the library function, not the outer wrapper).
|
|
771
|
+
* @param metaTx The meta-transaction whose `params` are validated against `msg.sig` and `address(this)`.
|
|
772
|
+
*/
|
|
773
|
+
function _validateMetaTxHandlerBinding(EngineBlox.MetaTransaction memory metaTx) internal view {
|
|
774
|
+
SharedValidation.validateMetaTxHandlerSelectorBinding(
|
|
775
|
+
metaTx.params.handlerSelector,
|
|
776
|
+
bytes4(msg.sig)
|
|
777
|
+
);
|
|
778
|
+
SharedValidation.validateMetaTxHandlerContractBinding(metaTx.params.handlerContract);
|
|
779
|
+
}
|
|
780
|
+
|
|
689
781
|
/**
|
|
690
782
|
* @dev Centralized function to validate that the caller has any role
|
|
691
783
|
*/
|
|
@@ -721,7 +813,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
721
813
|
/**
|
|
722
814
|
* @dev Adds a function selector to the system macro selectors set.
|
|
723
815
|
* 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
|
|
816
|
+
* @param functionSelector The function selector to add (e.g. NATIVE_TRANSFER_SELECTOR).
|
|
725
817
|
*/
|
|
726
818
|
function _addMacroSelector(bytes4 functionSelector) internal {
|
|
727
819
|
EngineBlox.addMacroSelector(_getSecureState(), functionSelector);
|
|
@@ -763,8 +855,8 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
763
855
|
* @param target The target address to whitelist
|
|
764
856
|
* @notice This function is virtual to allow extensions to add hook functionality
|
|
765
857
|
*/
|
|
766
|
-
function
|
|
767
|
-
_getSecureState().
|
|
858
|
+
function _addTargetToWhitelist(bytes4 functionSelector, address target) internal virtual {
|
|
859
|
+
_getSecureState().addTargetToWhitelist(functionSelector, target);
|
|
768
860
|
}
|
|
769
861
|
|
|
770
862
|
/**
|
|
@@ -773,16 +865,18 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
773
865
|
* @param target The target address to remove
|
|
774
866
|
* @notice This function is virtual to allow extensions to add hook functionality
|
|
775
867
|
*/
|
|
776
|
-
function
|
|
777
|
-
_getSecureState().
|
|
868
|
+
function _removeTargetFromWhitelist(bytes4 functionSelector, address target) internal virtual {
|
|
869
|
+
_getSecureState().removeTargetFromWhitelist(functionSelector, target);
|
|
778
870
|
}
|
|
779
871
|
|
|
780
872
|
/**
|
|
781
|
-
* @dev
|
|
873
|
+
* @dev Gets all whitelisted targets for a function selector
|
|
782
874
|
* @param functionSelector The function selector
|
|
783
875
|
* @return Array of whitelisted target addresses
|
|
876
|
+
* @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
|
|
784
877
|
*/
|
|
785
|
-
function
|
|
878
|
+
function getFunctionWhitelistTargets(bytes4 functionSelector) public view returns (address[] memory) {
|
|
879
|
+
_validateAnyRole();
|
|
786
880
|
return _getSecureState().getFunctionWhitelistTargets(functionSelector);
|
|
787
881
|
}
|
|
788
882
|
|
|
@@ -794,31 +888,31 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
794
888
|
* @param functionSchemas Array of function schema definitions
|
|
795
889
|
* @param roleHashes Array of role hashes
|
|
796
890
|
* @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
|
|
891
|
+
* @param requireProtected When true, all function schemas must be protected; reverts if any is not
|
|
892
|
+
* @notice When requireProtected is true, every function schema must have isProtected == true
|
|
800
893
|
*/
|
|
801
894
|
function _loadDefinitions(
|
|
802
895
|
EngineBlox.FunctionSchema[] memory functionSchemas,
|
|
803
896
|
bytes32[] memory roleHashes,
|
|
804
897
|
EngineBlox.FunctionPermission[] memory functionPermissions,
|
|
805
|
-
bool
|
|
898
|
+
bool requireProtected
|
|
806
899
|
) internal {
|
|
807
900
|
// Load function schemas
|
|
808
901
|
for (uint256 i = 0; i < functionSchemas.length; i++) {
|
|
809
|
-
//
|
|
810
|
-
if (
|
|
811
|
-
revert SharedValidation.
|
|
812
|
-
|
|
902
|
+
// When enforcing, require every schema to be protected
|
|
903
|
+
if (requireProtected && !functionSchemas[i].isProtected) {
|
|
904
|
+
revert SharedValidation.ContractFunctionMustBeProtected(
|
|
905
|
+
functionSchemas[i].functionSelector
|
|
813
906
|
);
|
|
814
907
|
}
|
|
815
|
-
|
|
816
|
-
_getSecureState(),
|
|
908
|
+
_registerFunction(
|
|
817
909
|
functionSchemas[i].functionSignature,
|
|
818
910
|
functionSchemas[i].functionSelector,
|
|
819
911
|
functionSchemas[i].operationName,
|
|
820
912
|
functionSchemas[i].supportedActionsBitmap,
|
|
913
|
+
functionSchemas[i].enforceHandlerRelations,
|
|
821
914
|
functionSchemas[i].isProtected,
|
|
915
|
+
functionSchemas[i].isGrantRevocable,
|
|
822
916
|
functionSchemas[i].handlerForSelectors
|
|
823
917
|
);
|
|
824
918
|
}
|
|
@@ -826,11 +920,7 @@ abstract contract BaseStateMachine is Initializable, ERC165Upgradeable, Reentran
|
|
|
826
920
|
// Load role permissions using parallel arrays
|
|
827
921
|
SharedValidation.validateArrayLengthMatch(roleHashes.length, functionPermissions.length);
|
|
828
922
|
for (uint256 i = 0; i < roleHashes.length; i++) {
|
|
829
|
-
|
|
830
|
-
_getSecureState(),
|
|
831
|
-
roleHashes[i],
|
|
832
|
-
functionPermissions[i]
|
|
833
|
-
);
|
|
923
|
+
_addFunctionToRole(roleHashes[i], functionPermissions[i]);
|
|
834
924
|
}
|
|
835
925
|
}
|
|
836
926
|
|