@bloxchain/contracts 1.0.0-alpha.13 → 1.0.0-alpha.15
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 +1 -1
- package/abi/BaseStateMachine.abi.json +2 -45
- package/abi/GuardController.abi.json +20 -63
- package/abi/RuntimeRBAC.abi.json +20 -63
- package/abi/SecureOwnable.abi.json +20 -63
- package/core/base/BaseStateMachine.sol +943 -967
- package/core/base/interface/IBaseStateMachine.sol +0 -8
- package/core/execution/GuardController.sol +447 -458
- package/core/execution/interface/IGuardController.sol +5 -19
- package/core/execution/lib/definitions/GuardControllerDefinitions.sol +22 -9
- package/core/lib/EngineBlox.sol +92 -89
- package/core/security/SecureOwnable.sol +394 -394
- package/package.json +1 -1
- package/abi/AccountBlox.abi.json +0 -3946
- package/abi/BareBlox.abi.json +0 -1378
- package/abi/RoleBlox.abi.json +0 -2994
- package/abi/SecureBlox.abi.json +0 -2753
- package/abi/SimpleRWA20.abi.json +0 -4032
- package/abi/SimpleRWA20Definitions.abi.json +0 -191
- package/abi/SimpleVault.abi.json +0 -3407
- package/abi/SimpleVaultDefinitions.abi.json +0 -269
|
@@ -1,458 +1,447 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
-
pragma solidity 0.8.34;
|
|
3
|
-
|
|
4
|
-
import "../base/BaseStateMachine.sol";
|
|
5
|
-
import "../lib/utils/SharedValidation.sol";
|
|
6
|
-
import "./lib/definitions/GuardControllerDefinitions.sol";
|
|
7
|
-
import "../lib/interfaces/IDefinition.sol";
|
|
8
|
-
import "./interface/IGuardController.sol";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @title GuardController
|
|
12
|
-
* @dev Lightweight controller for generic contract delegation with full EngineBlox workflows
|
|
13
|
-
*
|
|
14
|
-
* This contract provides a complete solution for delegating control to external addresses.
|
|
15
|
-
* It extends BaseStateMachine for core state machine functionality and supports all EngineBlox
|
|
16
|
-
* execution patterns including time-locked transactions, meta-transactions, and payment management.
|
|
17
|
-
*
|
|
18
|
-
* Key Features:
|
|
19
|
-
* - Core state machine functionality from BaseStateMachine
|
|
20
|
-
* -
|
|
21
|
-
* -
|
|
22
|
-
* -
|
|
23
|
-
|
|
24
|
-
* -
|
|
25
|
-
|
|
26
|
-
*
|
|
27
|
-
|
|
28
|
-
* -
|
|
29
|
-
* -
|
|
30
|
-
|
|
31
|
-
* -
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* -
|
|
46
|
-
* -
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* -
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* @notice
|
|
54
|
-
* @
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
* @
|
|
62
|
-
* @param
|
|
63
|
-
* @param
|
|
64
|
-
* @param
|
|
65
|
-
* @param
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
address
|
|
70
|
-
address
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
guardControllerPermissions.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
* @
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
* @
|
|
101
|
-
* @param
|
|
102
|
-
* @param
|
|
103
|
-
* @param
|
|
104
|
-
* @param
|
|
105
|
-
* @param
|
|
106
|
-
* @
|
|
107
|
-
* @
|
|
108
|
-
* @notice
|
|
109
|
-
* @notice
|
|
110
|
-
* @notice For
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
* @
|
|
139
|
-
* @param
|
|
140
|
-
* @param
|
|
141
|
-
* @param
|
|
142
|
-
* @param
|
|
143
|
-
* @param
|
|
144
|
-
* @param
|
|
145
|
-
* @
|
|
146
|
-
* @
|
|
147
|
-
* @notice
|
|
148
|
-
* @notice
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
* @
|
|
176
|
-
* @
|
|
177
|
-
* @
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
txRecord
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
* @
|
|
194
|
-
* @
|
|
195
|
-
* @
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
txRecord
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
* @
|
|
212
|
-
* @
|
|
213
|
-
* @
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
* @
|
|
229
|
-
* @
|
|
230
|
-
* @
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
* @
|
|
246
|
-
* @
|
|
247
|
-
* @
|
|
248
|
-
* @notice
|
|
249
|
-
* @notice
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
//
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
//
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
* @
|
|
274
|
-
* @param
|
|
275
|
-
* @
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
* @notice
|
|
279
|
-
*
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
//
|
|
287
|
-
//
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
//
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
* @
|
|
307
|
-
* @
|
|
308
|
-
* @
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
* @
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
* @
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
* @
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
(
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
* @
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
(
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
* @
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
string memory
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
* @
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
(
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
* @
|
|
401
|
-
* @param
|
|
402
|
-
* @param
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
* @
|
|
417
|
-
* @param
|
|
418
|
-
* @param
|
|
419
|
-
* @
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
string memory
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
//
|
|
434
|
-
//
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
/**
|
|
449
|
-
* @dev Internal helper to unregister a function schema
|
|
450
|
-
* @param functionSelector The function selector to unregister
|
|
451
|
-
* @param safeRemoval If true, checks for role references before removal
|
|
452
|
-
* @notice EngineBlox.removeFunctionSchema validates schema existence (ResourceNotFound) and protected status (CannotModifyProtected)
|
|
453
|
-
*/
|
|
454
|
-
function _unregisterFunction(bytes4 functionSelector, bool safeRemoval) internal {
|
|
455
|
-
_removeFunctionSchema(functionSelector, safeRemoval);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
}
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
pragma solidity 0.8.34;
|
|
3
|
+
|
|
4
|
+
import "../base/BaseStateMachine.sol";
|
|
5
|
+
import "../lib/utils/SharedValidation.sol";
|
|
6
|
+
import "./lib/definitions/GuardControllerDefinitions.sol";
|
|
7
|
+
import "../lib/interfaces/IDefinition.sol";
|
|
8
|
+
import "./interface/IGuardController.sol";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @title GuardController
|
|
12
|
+
* @dev Lightweight controller for generic contract delegation with full EngineBlox workflows
|
|
13
|
+
*
|
|
14
|
+
* This contract provides a complete solution for delegating control to external addresses.
|
|
15
|
+
* It extends BaseStateMachine for core state machine functionality and supports all EngineBlox
|
|
16
|
+
* execution patterns including time-locked transactions, meta-transactions, and payment management.
|
|
17
|
+
*
|
|
18
|
+
* Key Features:
|
|
19
|
+
* - Core state machine functionality from BaseStateMachine
|
|
20
|
+
* - STANDARD execution type only (function selector + params)
|
|
21
|
+
* - Meta-transaction support for delegated approvals and cancellations
|
|
22
|
+
* - Payment management for native tokens and ERC20 tokens
|
|
23
|
+
* - Role-based access control with action-level permissions
|
|
24
|
+
* - Target address whitelist per function selector (defense-in-depth security layer)
|
|
25
|
+
*
|
|
26
|
+
* Security Features:
|
|
27
|
+
* - Target whitelist: Strict security - restricts which contract addresses can be called per function selector
|
|
28
|
+
* - Prevents exploitation of global function selector permissions by limiting valid target contracts
|
|
29
|
+
* - Strict enforcement: Target MUST be explicitly whitelisted for the function selector
|
|
30
|
+
* - If whitelist is empty (no entries), no targets are allowed - explicit deny for security
|
|
31
|
+
* - Target whitelist is ALWAYS checked - no backward compatibility fallback
|
|
32
|
+
*
|
|
33
|
+
* Usage Flow:
|
|
34
|
+
* 1. Deploy GuardController (or combine with RuntimeRBAC/SecureOwnable for role management)
|
|
35
|
+
* 2. Function schemas should be registered via definitions or RuntimeRBAC if combined
|
|
36
|
+
* 3. Create roles and assign function permissions with action bitmaps (via RuntimeRBAC if combined)
|
|
37
|
+
* 4. Assign wallets to roles (via RuntimeRBAC if combined)
|
|
38
|
+
* 5. Configure target whitelists per function selector (REQUIRED for execution)
|
|
39
|
+
* 6. Execute operations via time-lock workflows based on action permissions
|
|
40
|
+
* 7. Target whitelist is ALWAYS validated before execution - target must be in whitelist
|
|
41
|
+
* 8. Target contract validates access (ownership/role-based)
|
|
42
|
+
*
|
|
43
|
+
* Workflows Available:
|
|
44
|
+
* - Standard execution: function selector + params
|
|
45
|
+
* - Time-locked approval: request + approve workflow
|
|
46
|
+
* - Meta-transaction workflows: signed approvals/cancellations
|
|
47
|
+
*
|
|
48
|
+
* Whitelist Management:
|
|
49
|
+
* - executeGuardConfigBatch: Batch execution for adding/removing targets from whitelist (OWNER_ROLE only)
|
|
50
|
+
* - getAllowedTargets: Query whitelisted targets for a function selector
|
|
51
|
+
*
|
|
52
|
+
* @notice This contract is modular and can be combined with RuntimeRBAC and SecureOwnable
|
|
53
|
+
* @notice Target whitelist is a GuardController-specific security feature, not part of EngineBlox library
|
|
54
|
+
* @custom:security-contact security@particlecrypto.com
|
|
55
|
+
*/
|
|
56
|
+
abstract contract GuardController is BaseStateMachine {
|
|
57
|
+
using EngineBlox for EngineBlox.SecureOperationState;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @notice Initializer to initialize GuardController
|
|
61
|
+
* @param initialOwner The initial owner address
|
|
62
|
+
* @param broadcaster The broadcaster address
|
|
63
|
+
* @param recovery The recovery address
|
|
64
|
+
* @param timeLockPeriodSec The timelock period in seconds
|
|
65
|
+
* @param eventForwarder The event forwarder address
|
|
66
|
+
*/
|
|
67
|
+
function initialize(
|
|
68
|
+
address initialOwner,
|
|
69
|
+
address broadcaster,
|
|
70
|
+
address recovery,
|
|
71
|
+
uint256 timeLockPeriodSec,
|
|
72
|
+
address eventForwarder
|
|
73
|
+
) public virtual onlyInitializing {
|
|
74
|
+
_initializeBaseStateMachine(initialOwner, broadcaster, recovery, timeLockPeriodSec, eventForwarder);
|
|
75
|
+
|
|
76
|
+
// Load GuardController-specific definitions
|
|
77
|
+
IDefinition.RolePermission memory guardControllerPermissions = GuardControllerDefinitions.getRolePermissions();
|
|
78
|
+
_loadDefinitions(
|
|
79
|
+
GuardControllerDefinitions.getFunctionSchemas(),
|
|
80
|
+
guardControllerPermissions.roleHashes,
|
|
81
|
+
guardControllerPermissions.functionPermissions,
|
|
82
|
+
true // Enforce all function schemas are protected
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ============ INTERFACE SUPPORT ============
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @dev See {IERC165-supportsInterface}.
|
|
90
|
+
* @notice Adds IGuardController interface ID for component detection
|
|
91
|
+
*/
|
|
92
|
+
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
|
|
93
|
+
return interfaceId == type(IGuardController).interfaceId || super.supportsInterface(interfaceId);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ============ EXECUTION FUNCTIONS ============
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @dev Requests a time-locked execution via EngineBlox workflow
|
|
100
|
+
* @param target The address of the target contract
|
|
101
|
+
* @param value The ETH value to send (0 for standard function calls)
|
|
102
|
+
* @param functionSelector The function selector to execute (NATIVE_TRANSFER_SELECTOR for simple native token transfers)
|
|
103
|
+
* @param params The encoded parameters for the function (empty for simple native token transfers)
|
|
104
|
+
* @param gasLimit The gas limit for execution
|
|
105
|
+
* @param operationType The operation type hash
|
|
106
|
+
* @return txId The transaction ID for the requested operation
|
|
107
|
+
* @notice Creates a time-locked transaction that must be approved after the timelock period
|
|
108
|
+
* @notice Requires EXECUTE_TIME_DELAY_REQUEST permission for the function selector
|
|
109
|
+
* @notice For standard function calls: value=0, functionSelector=non-zero, params=encoded data
|
|
110
|
+
* @notice For simple native token transfers: value>0, functionSelector=NATIVE_TRANSFER_SELECTOR, params=""
|
|
111
|
+
*/
|
|
112
|
+
function executeWithTimeLock(
|
|
113
|
+
address target,
|
|
114
|
+
uint256 value,
|
|
115
|
+
bytes4 functionSelector,
|
|
116
|
+
bytes memory params,
|
|
117
|
+
uint256 gasLimit,
|
|
118
|
+
bytes32 operationType
|
|
119
|
+
) public returns (uint256 txId) {
|
|
120
|
+
// SECURITY: Prevent access to internal execution functions
|
|
121
|
+
_validateNotInternalFunction(target, functionSelector);
|
|
122
|
+
|
|
123
|
+
// Request via BaseStateMachine helper (validates permissions and whitelist in EngineBlox)
|
|
124
|
+
EngineBlox.TxRecord memory txRecord = _requestTransaction(
|
|
125
|
+
msg.sender,
|
|
126
|
+
target,
|
|
127
|
+
value,
|
|
128
|
+
gasLimit,
|
|
129
|
+
operationType,
|
|
130
|
+
functionSelector,
|
|
131
|
+
params
|
|
132
|
+
);
|
|
133
|
+
return txRecord.txId;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @dev Requests a time-locked execution with payment details attached (same permissions as executeWithTimeLock)
|
|
138
|
+
* @param target The address of the target contract
|
|
139
|
+
* @param value The ETH value to send (0 for standard function calls)
|
|
140
|
+
* @param functionSelector The function selector to execute (NATIVE_TRANSFER_SELECTOR for simple native token transfers)
|
|
141
|
+
* @param params The encoded parameters for the function (empty for simple native token transfers)
|
|
142
|
+
* @param gasLimit The gas limit for execution
|
|
143
|
+
* @param operationType The operation type hash
|
|
144
|
+
* @param paymentDetails The payment details to attach to the transaction
|
|
145
|
+
* @return txId The transaction ID for the requested operation (use getTransaction(txId) for full record)
|
|
146
|
+
* @notice Creates a time-locked transaction with payment that must be approved after the timelock period
|
|
147
|
+
* @notice Reuses EXECUTE_TIME_DELAY_REQUEST permission for the execution selector (no new definitions)
|
|
148
|
+
* @notice Approval/cancel use same flows as executeWithTimeLock (approveTimeLockExecution, cancelTimeLockExecution)
|
|
149
|
+
*/
|
|
150
|
+
function executeWithPayment(
|
|
151
|
+
address target,
|
|
152
|
+
uint256 value,
|
|
153
|
+
bytes4 functionSelector,
|
|
154
|
+
bytes memory params,
|
|
155
|
+
uint256 gasLimit,
|
|
156
|
+
bytes32 operationType,
|
|
157
|
+
EngineBlox.PaymentDetails memory paymentDetails
|
|
158
|
+
) public returns (uint256 txId) {
|
|
159
|
+
_validateNotInternalFunction(target, functionSelector);
|
|
160
|
+
EngineBlox.TxRecord memory txRecord = _requestTransactionWithPayment(
|
|
161
|
+
msg.sender,
|
|
162
|
+
target,
|
|
163
|
+
value,
|
|
164
|
+
gasLimit,
|
|
165
|
+
operationType,
|
|
166
|
+
functionSelector,
|
|
167
|
+
params,
|
|
168
|
+
paymentDetails
|
|
169
|
+
);
|
|
170
|
+
return txRecord.txId;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* @dev Approves and executes a time-locked transaction
|
|
175
|
+
* @param txId The transaction ID
|
|
176
|
+
* @return result The execution result
|
|
177
|
+
* @notice Requires STANDARD execution type and EXECUTE_TIME_DELAY_APPROVE permission for the execution function
|
|
178
|
+
*/
|
|
179
|
+
function approveTimeLockExecution(
|
|
180
|
+
uint256 txId
|
|
181
|
+
) public returns (uint256) {
|
|
182
|
+
// SECURITY: Prevent access to internal execution functions
|
|
183
|
+
EngineBlox.TxRecord memory txRecord = _getSecureState().txRecords[txId];
|
|
184
|
+
_validateNotInternalFunction(txRecord.params.target, txRecord.params.executionSelector);
|
|
185
|
+
|
|
186
|
+
// Approve via BaseStateMachine helper (validates permissions and whitelist in EngineBlox)
|
|
187
|
+
txRecord = _approveTransaction(txId);
|
|
188
|
+
return txRecord.txId;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* @dev Cancels a time-locked transaction
|
|
193
|
+
* @param txId The transaction ID
|
|
194
|
+
* @return The updated transaction record
|
|
195
|
+
* @notice Requires STANDARD execution type and EXECUTE_TIME_DELAY_CANCEL permission for the execution function
|
|
196
|
+
*/
|
|
197
|
+
function cancelTimeLockExecution(
|
|
198
|
+
uint256 txId
|
|
199
|
+
) public returns (uint256) {
|
|
200
|
+
// SECURITY: Prevent access to internal execution functions
|
|
201
|
+
EngineBlox.TxRecord memory txRecord = _getSecureState().txRecords[txId];
|
|
202
|
+
_validateNotInternalFunction(txRecord.params.target, txRecord.params.executionSelector);
|
|
203
|
+
|
|
204
|
+
// Cancel via BaseStateMachine helper (validates permissions in EngineBlox)
|
|
205
|
+
txRecord = _cancelTransaction(txId);
|
|
206
|
+
return txRecord.txId;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @dev Approves a time-locked transaction using a meta-transaction
|
|
211
|
+
* @param metaTx The meta-transaction containing the transaction record and signature
|
|
212
|
+
* @return The updated transaction record
|
|
213
|
+
* @notice Requires STANDARD execution type and EXECUTE_META_APPROVE permission for the execution function
|
|
214
|
+
*/
|
|
215
|
+
function approveTimeLockExecutionWithMetaTx(
|
|
216
|
+
EngineBlox.MetaTransaction memory metaTx
|
|
217
|
+
) public returns (uint256) {
|
|
218
|
+
// SECURITY: Prevent access to internal execution functions
|
|
219
|
+
_validateNotInternalFunction(metaTx.txRecord.params.target, metaTx.txRecord.params.executionSelector);
|
|
220
|
+
|
|
221
|
+
// Approve via BaseStateMachine helper (validates permissions and whitelist in EngineBlox)
|
|
222
|
+
EngineBlox.TxRecord memory txRecord = _approveTransactionWithMetaTx(metaTx);
|
|
223
|
+
return txRecord.txId;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* @dev Cancels a time-locked transaction using a meta-transaction
|
|
228
|
+
* @param metaTx The meta-transaction containing the transaction record and signature
|
|
229
|
+
* @return The updated transaction record
|
|
230
|
+
* @notice Requires STANDARD execution type and EXECUTE_META_CANCEL permission for the execution function
|
|
231
|
+
*/
|
|
232
|
+
function cancelTimeLockExecutionWithMetaTx(
|
|
233
|
+
EngineBlox.MetaTransaction memory metaTx
|
|
234
|
+
) public returns (uint256) {
|
|
235
|
+
// SECURITY: Prevent access to internal execution functions
|
|
236
|
+
_validateNotInternalFunction(metaTx.txRecord.params.target, metaTx.txRecord.params.executionSelector);
|
|
237
|
+
|
|
238
|
+
// Cancel via BaseStateMachine helper (validates permissions and whitelist in EngineBlox)
|
|
239
|
+
EngineBlox.TxRecord memory txRecord = _cancelTransactionWithMetaTx(metaTx);
|
|
240
|
+
return txRecord.txId;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* @dev Requests and approves a transaction in one step using a meta-transaction
|
|
245
|
+
* @param metaTx The meta-transaction containing the transaction record and signature
|
|
246
|
+
* @return The transaction record after request and approval
|
|
247
|
+
* @notice Requires STANDARD execution type
|
|
248
|
+
* @notice Validates function schema and permissions for the execution function (same as executeWithTimeLock)
|
|
249
|
+
* @notice Requires EXECUTE_META_REQUEST_AND_APPROVE permission for the execution function selector
|
|
250
|
+
*/
|
|
251
|
+
function requestAndApproveExecution(
|
|
252
|
+
EngineBlox.MetaTransaction memory metaTx
|
|
253
|
+
) public returns (uint256) {
|
|
254
|
+
// SECURITY: Prevent access to internal execution functions
|
|
255
|
+
_validateNotInternalFunction(metaTx.txRecord.params.target, metaTx.txRecord.params.executionSelector);
|
|
256
|
+
|
|
257
|
+
// Request and approve via BaseStateMachine helper (validates permissions and whitelist in EngineBlox)
|
|
258
|
+
EngineBlox.TxRecord memory txRecord = _requestAndApproveTransaction(metaTx);
|
|
259
|
+
return txRecord.txId;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Note: Meta-transaction utility functions (createMetaTxParams,
|
|
263
|
+
// generateUnsignedMetaTransactionForNew, generateUnsignedMetaTransactionForExisting)
|
|
264
|
+
// are already available through inheritance from BaseStateMachine
|
|
265
|
+
//
|
|
266
|
+
// Note: Permission validation is handled by EngineBlox library functions
|
|
267
|
+
// which validate both function schema existence and RBAC permissions for execution selectors
|
|
268
|
+
|
|
269
|
+
// ============ INTERNAL VALIDATION HELPERS ============
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* @dev Validates that GuardController is not attempting to access internal execution functions
|
|
273
|
+
* @param target The target contract address
|
|
274
|
+
* @param functionSelector The function selector to validate
|
|
275
|
+
* @notice Internal functions use validateInternalCallInternal and should only be called
|
|
276
|
+
* through the contract's own workflow, not via GuardController
|
|
277
|
+
* @notice Blocks all calls to address(this) to prevent bypassing internal-only protection
|
|
278
|
+
* @notice Exception: System macro selectors (e.g., NATIVE_TRANSFER_SELECTOR) are allowed
|
|
279
|
+
* to target address(this) for system-level operations like native token deposits
|
|
280
|
+
*/
|
|
281
|
+
function _validateNotInternalFunction(
|
|
282
|
+
address target,
|
|
283
|
+
bytes4 functionSelector
|
|
284
|
+
) internal view {
|
|
285
|
+
// SECURITY: Prevent GuardController from accessing internal execution functions
|
|
286
|
+
// Internal functions use validateInternalCallInternal and should only be called
|
|
287
|
+
// through the contract's own workflow, not via GuardController
|
|
288
|
+
|
|
289
|
+
// If target is this contract, we need to validate the function selector
|
|
290
|
+
if (target == address(this)) {
|
|
291
|
+
// Allow system macro selectors (e.g., NATIVE_TRANSFER_SELECTOR for native token deposits)
|
|
292
|
+
// These are special system-level operations that are safe to execute on address(this)
|
|
293
|
+
if (_isMacroSelector(functionSelector)) {
|
|
294
|
+
return; // Allow system macro selectors
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Block all other calls to address(this) to prevent bypassing internal-only protection
|
|
298
|
+
revert SharedValidation.InternalFunctionNotAccessible(functionSelector);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// ============ GUARD CONFIGURATION BATCH INTERFACE ============
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* @dev Requests and approves a Guard configuration batch using a meta-transaction
|
|
306
|
+
* @param metaTx The meta-transaction
|
|
307
|
+
* @return The transaction record
|
|
308
|
+
* @notice OWNER signs, BROADCASTER executes according to GuardControllerDefinitions
|
|
309
|
+
*/
|
|
310
|
+
function guardConfigBatchRequestAndApprove(
|
|
311
|
+
EngineBlox.MetaTransaction memory metaTx
|
|
312
|
+
) public returns (uint256) {
|
|
313
|
+
_validateBroadcaster(msg.sender);
|
|
314
|
+
EngineBlox.TxRecord memory txRecord = _requestAndApproveTransaction(metaTx);
|
|
315
|
+
return txRecord.txId;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* @dev External function that can only be called by the contract itself to execute a Guard configuration batch
|
|
320
|
+
* @param actions Encoded guard configuration actions
|
|
321
|
+
*/
|
|
322
|
+
function executeGuardConfigBatch(IGuardController.GuardConfigAction[] calldata actions) external {
|
|
323
|
+
_validateExecuteBySelf();
|
|
324
|
+
_executeGuardConfigBatch(actions);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// ============ HELPER FUNCTIONS ============
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* @dev Internal helper to execute a Guard configuration batch
|
|
331
|
+
* @param actions Encoded guard configuration actions
|
|
332
|
+
*/
|
|
333
|
+
function _executeGuardConfigBatch(IGuardController.GuardConfigAction[] calldata actions) internal {
|
|
334
|
+
_validateBatchSize(actions.length);
|
|
335
|
+
|
|
336
|
+
for (uint256 i = 0; i < actions.length; i++) {
|
|
337
|
+
IGuardController.GuardConfigAction calldata action = actions[i];
|
|
338
|
+
|
|
339
|
+
if (action.actionType == IGuardController.GuardConfigActionType.ADD_TARGET_TO_WHITELIST) {
|
|
340
|
+
_executeAddTargetToWhitelist(action.data);
|
|
341
|
+
} else if (action.actionType == IGuardController.GuardConfigActionType.REMOVE_TARGET_FROM_WHITELIST) {
|
|
342
|
+
_executeRemoveTargetFromWhitelist(action.data);
|
|
343
|
+
} else if (action.actionType == IGuardController.GuardConfigActionType.REGISTER_FUNCTION) {
|
|
344
|
+
_executeRegisterFunction(action.data);
|
|
345
|
+
} else if (action.actionType == IGuardController.GuardConfigActionType.UNREGISTER_FUNCTION) {
|
|
346
|
+
_executeUnregisterFunction(action.data);
|
|
347
|
+
} else {
|
|
348
|
+
revert SharedValidation.NotSupported();
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* @dev Executes ADD_TARGET_TO_WHITELIST: adds a target address to a function's call whitelist
|
|
355
|
+
* @param data ABI-encoded (bytes4 functionSelector, address target)
|
|
356
|
+
*/
|
|
357
|
+
function _executeAddTargetToWhitelist(bytes calldata data) internal {
|
|
358
|
+
(bytes4 functionSelector, address target) = abi.decode(data, (bytes4, address));
|
|
359
|
+
_addTargetToWhitelist(functionSelector, target);
|
|
360
|
+
_logGuardConfigEvent(IGuardController.GuardConfigActionType.ADD_TARGET_TO_WHITELIST, functionSelector, target);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* @dev Executes REMOVE_TARGET_FROM_WHITELIST: removes a target address from a function's call whitelist
|
|
365
|
+
* @param data ABI-encoded (bytes4 functionSelector, address target)
|
|
366
|
+
*/
|
|
367
|
+
function _executeRemoveTargetFromWhitelist(bytes calldata data) internal {
|
|
368
|
+
(bytes4 functionSelector, address target) = abi.decode(data, (bytes4, address));
|
|
369
|
+
_removeTargetFromWhitelist(functionSelector, target);
|
|
370
|
+
_logGuardConfigEvent(IGuardController.GuardConfigActionType.REMOVE_TARGET_FROM_WHITELIST, functionSelector, target);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* @dev Executes REGISTER_FUNCTION: registers a new function schema with signature, operation name, and supported actions
|
|
375
|
+
* @param data ABI-encoded (string functionSignature, string operationName, TxAction[] supportedActions)
|
|
376
|
+
*/
|
|
377
|
+
function _executeRegisterFunction(bytes calldata data) internal {
|
|
378
|
+
(
|
|
379
|
+
string memory functionSignature,
|
|
380
|
+
string memory operationName,
|
|
381
|
+
EngineBlox.TxAction[] memory supportedActions
|
|
382
|
+
) = abi.decode(data, (string, string, EngineBlox.TxAction[]));
|
|
383
|
+
|
|
384
|
+
bytes4 functionSelector = _registerGuardedFunction(functionSignature, operationName, supportedActions);
|
|
385
|
+
_logGuardConfigEvent(IGuardController.GuardConfigActionType.REGISTER_FUNCTION, functionSelector, address(0));
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* @dev Executes UNREGISTER_FUNCTION: unregisters a function schema by selector
|
|
390
|
+
* @param data ABI-encoded (bytes4 functionSelector, bool safeRemoval)
|
|
391
|
+
*/
|
|
392
|
+
function _executeUnregisterFunction(bytes calldata data) internal {
|
|
393
|
+
(bytes4 functionSelector, bool safeRemoval) = abi.decode(data, (bytes4, bool));
|
|
394
|
+
_unregisterFunction(functionSelector, safeRemoval);
|
|
395
|
+
_logGuardConfigEvent(IGuardController.GuardConfigActionType.UNREGISTER_FUNCTION, functionSelector, address(0));
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* @dev Encodes and logs a guard config event via ComponentEvent. Payload decodes as (GuardConfigActionType, bytes4 functionSelector, address target).
|
|
400
|
+
* @param actionType The guard config action type
|
|
401
|
+
* @param functionSelector The function selector (or zero for N/A)
|
|
402
|
+
* @param target The target address (or zero for N/A)
|
|
403
|
+
*/
|
|
404
|
+
function _logGuardConfigEvent(
|
|
405
|
+
IGuardController.GuardConfigActionType actionType,
|
|
406
|
+
bytes4 functionSelector,
|
|
407
|
+
address target
|
|
408
|
+
) internal {
|
|
409
|
+
_logComponentEvent(abi.encode(actionType, functionSelector, target));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// ============ INTERNAL FUNCTION SCHEMA HELPERS ============
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* @dev Internal helper to register a new function schema
|
|
416
|
+
* @param functionSignature The function signature
|
|
417
|
+
* @param operationName The operation name
|
|
418
|
+
* @param supportedActions Array of supported actions
|
|
419
|
+
* @return functionSelector The derived function selector
|
|
420
|
+
*/
|
|
421
|
+
function _registerGuardedFunction(
|
|
422
|
+
string memory functionSignature,
|
|
423
|
+
string memory operationName,
|
|
424
|
+
EngineBlox.TxAction[] memory supportedActions
|
|
425
|
+
) internal returns (bytes4 functionSelector) {
|
|
426
|
+
// Derive function selector from signature
|
|
427
|
+
functionSelector = bytes4(keccak256(bytes(functionSignature)));
|
|
428
|
+
|
|
429
|
+
// Convert actions array to bitmap
|
|
430
|
+
uint16 supportedActionsBitmap = _createBitmapFromActions(supportedActions);
|
|
431
|
+
|
|
432
|
+
// Create function schema directly (always non-protected)
|
|
433
|
+
// Dynamically registered functions are execution selectors (handlerForSelectors must contain self-reference)
|
|
434
|
+
// EngineBlox.registerFunction validates schema doesn't already exist (ResourceAlreadyExists)
|
|
435
|
+
bytes4[] memory executionHandlers = new bytes4[](1);
|
|
436
|
+
executionHandlers[0] = functionSelector; // Self-reference for execution selector
|
|
437
|
+
_registerFunction(
|
|
438
|
+
functionSignature,
|
|
439
|
+
functionSelector,
|
|
440
|
+
operationName,
|
|
441
|
+
supportedActionsBitmap,
|
|
442
|
+
false, // isProtected = false for dynamically registered functions
|
|
443
|
+
executionHandlers // handlerForSelectors with self-reference for execution selectors
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
}
|