@@ -32,6 +32,12 @@ import {ERC7579Executor} from "./ERC7579Executor.sol";
32
32
* after a transition period defined by the current delay or {minSetback}, whichever
33
33
* is longer.
34
34
*
35
+ * ==== Authorization
36
+ *
37
+ * Authorization for scheduling and canceling operations is controlled through the {_validateSchedule}
38
+ * and {_validateCancel} functions. These functions can be overridden to implement custom
39
+ * authorization logic, such as requiring specific signers or roles.
40
+ *
35
41
* TIP: Use {_scheduleAt} to schedule operations at a specific points in time. This is
36
42
* useful to pre-schedule operations for non-deployed accounts (e.g. subscriptions).
37
43
*/
@@ -94,12 +100,6 @@ abstract contract ERC7579DelayedExecutor is ERC7579Executor {
94
100
bytes32 allowedStates
95
101
);
96
102
97
- /// @dev The operation is not authorized to be canceled.
98
- error ERC7579ExecutorUnauthorizedCancellation ();
99
-
100
- /// @dev The operation is not authorized to be scheduled.
101
- error ERC7579ExecutorUnauthorizedSchedule ();
102
-
103
103
/// @dev The module is not installed on the account.
104
104
error ERC7579ExecutorModuleNotInstalled ();
105
105
@@ -232,20 +232,18 @@ abstract contract ERC7579DelayedExecutor is ERC7579Executor {
232
232
*/
233
233
function schedule (address account , bytes32 salt , bytes32 mode , bytes calldata data ) public virtual {
234
234
require (_config[account].installed, ERC7579ExecutorModuleNotInstalled ());
235
- bool allowed = _validateSchedule (account, salt, mode, data);
235
+ _validateSchedule (account, salt, mode, data);
236
236
(uint32 executableAfter , , ) = getDelay (account);
237
237
_scheduleAt (account, salt, mode, data, Time.timestamp (), executableAfter);
238
- require (allowed, ERC7579ExecutorUnauthorizedSchedule ());
239
238
}
240
239
241
240
/**
242
241
* @dev Cancels a previously scheduled operation. Can only be called by the account that
243
242
* scheduled the operation. See {_cancel}.
244
243
*/
245
244
function cancel (address account , bytes32 salt , bytes32 mode , bytes calldata data ) public virtual {
246
- bool allowed = _validateCancel (account, salt, mode, data);
245
+ _validateCancel (account, salt, mode, data);
247
246
_cancel (account, mode, data, salt); // Prioritize errors thrown in _cancel
248
- require (allowed, ERC7579ExecutorUnauthorizedCancellation ());
249
247
}
250
248
251
249
/**
@@ -267,32 +265,30 @@ abstract contract ERC7579DelayedExecutor is ERC7579Executor {
267
265
_setExpiration (msg .sender , 0 );
268
266
}
269
267
270
- /// @inheritdoc ERC7579Executor
268
+ /**
269
+ * @dev Returns `data` as the execution calldata. See {ERC7579Executor-_execute}.
270
+ *
271
+ * NOTE: This function relies on the operation state validation in {_execute} for
272
+ * authorization. Extensions of this module should override this function to implement
273
+ * additional validation logic if needed.
274
+ */
271
275
function _validateExecution (
272
276
address /* account */ ,
273
277
bytes32 /* salt */ ,
274
278
bytes32 /* mode */ ,
275
279
bytes calldata data
276
- ) internal view virtual override returns (bool valid , bytes calldata executionCalldata ) {
277
- return ( true , data); // Anyone can execute, the state validation of the operation is enough
280
+ ) internal virtual override returns (bytes calldata ) {
281
+ return data;
278
282
}
279
283
280
284
/**
281
- * @dev Whether the caller is authorized to cancel operations.
282
- * By default, this checks if the caller is the account itself. Derived contracts can
283
- * override this to implement custom authorization logic.
285
+ * @dev Validates whether an operation can be canceled.
284
286
*
285
287
* Example extension:
286
288
*
287
289
* ```solidity
288
- * function _validateCancel(
289
- * address account,
290
- * bytes32 mode,
291
- * bytes calldata data,
292
- * bytes32 salt
293
- * ) internal view override returns (bool) {
294
- * bool isAuthorized = ...; // custom logic to check authorization
295
- * return isAuthorized || super._validateCancel(account, mode, data, salt);
290
+ * function _validateCancel(address account, bytes32 salt, bytes32 mode, bytes calldata data) internal override {
291
+ * // e.g. require(msg.sender == account);
296
292
* }
297
293
*```
298
294
*/
@@ -301,26 +297,16 @@ abstract contract ERC7579DelayedExecutor is ERC7579Executor {
301
297
bytes32 /* salt */ ,
302
298
bytes32 /* mode */ ,
303
299
bytes calldata /* data */
304
- ) internal view virtual returns (bool ) {
305
- return account == msg .sender ;
306
- }
300
+ ) internal virtual ;
307
301
308
302
/**
309
- * @dev Whether the caller is authorized to schedule operations.
310
- * By default, this checks if the caller is the account itself. Derived contracts can
311
- * override this to implement custom authorization logic.
303
+ * @dev Validates whether an operation can be scheduled.
312
304
*
313
305
* Example extension:
314
306
*
315
307
* ```solidity
316
- * function _validateSchedule(
317
- * address account,
318
- * bytes32 mode,
319
- * bytes calldata data,
320
- * bytes32 salt
321
- * ) internal view override returns (bool) {
322
- * bool isAuthorized = ...; // custom logic to check authorization
323
- * return isAuthorized || super._validateSchedule(account, mode, data, salt);
308
+ * function _validateSchedule(address account, bytes32 salt, bytes32 mode, bytes calldata data) internal override {
309
+ * // e.g. require(msg.sender == account);
324
310
* }
325
311
*```
326
312
*/
@@ -329,9 +315,7 @@ abstract contract ERC7579DelayedExecutor is ERC7579Executor {
329
315
bytes32 /* salt */ ,
330
316
bytes32 /* mode */ ,
331
317
bytes calldata /* data */
332
- ) internal view virtual returns (bool ) {
333
- return account == msg .sender ;
334
- }
318
+ ) internal virtual ;
335
319
336
320
/**
337
321
* @dev Internal implementation for setting an account's delay. See {getDelay}.
0 commit comments