@@ -11,14 +11,13 @@ import {AccountERC7579} from "../AccountERC7579.sol";
11
11
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol " ;
12
12
13
13
/**
14
- * @title Implements a Social Recovery Executor module following ERC-7579
14
+ * @dev Implements a Social Recovery Executor module following ERC-7579
15
15
*
16
- * @dev Features:
17
- * - Timelocked Guardian-based recovery
18
- * - Recovery Execution Scope is limited to reconfiguring installed Validator Modules
19
- * - Recovery Reconfiguration can only be performed by the ERC-7579 Account
16
+ * Features:
17
+ * - Timelocked Guardian n of m recovery
18
+ * - Recovery Execution Scope is restricted to reconfiguring installed Validator Modules
19
+ * - Recovery Reconfiguration can only be performed by the installer ERC-7579 Account
20
20
* - Guardian Signatures replay attack protection via EIP-712 typed data signing
21
- * - Replay Attack protection includes: chains, accounts, executors, and recovery attempts
22
21
*/
23
22
contract SocialRecoveryExecutor is IERC7579Module , EIP712 , ReentrancyGuard {
24
23
using EnumerableSet for EnumerableSet.AddressSet;
@@ -148,6 +147,7 @@ contract SocialRecoveryExecutor is IERC7579Module, EIP712, ReentrancyGuard {
148
147
revert InvalidTimelock ();
149
148
}
150
149
150
+ // add guardians to the recovery config
151
151
for (uint256 i = 0 ; i < _guardians.length ; i++ ) {
152
152
if (_guardians[i] == address (0 )) {
153
153
revert InvalidGuardian ();
@@ -204,12 +204,12 @@ contract SocialRecoveryExecutor is IERC7579Module, EIP712, ReentrancyGuard {
204
204
revert InvalidGuardianSignatures ();
205
205
}
206
206
207
- // increment nonce.
208
- _recoveryConfigs[account].nonce++ ;
209
-
210
207
// set recovery start time.
211
208
_recoveryConfigs[account].recoveryStart = block .timestamp ;
212
209
210
+ // increment nonce.
211
+ _recoveryConfigs[account].nonce++ ;
212
+
213
213
emit RecoveryStarted (account);
214
214
}
215
215
@@ -230,12 +230,15 @@ contract SocialRecoveryExecutor is IERC7579Module, EIP712, ReentrancyGuard {
230
230
revert InvalidGuardianSignatures ();
231
231
}
232
232
233
- // exection data should be at least:20 bytes for targetValidatorModule, 32 for value and 4 for recovery selector.
233
+ // exection data should be at least:
234
+ // targetValidatorModule: 20 bytes,
235
+ // value: 32 bytes,
236
+ // recovery selector: 4 bytes.
234
237
if (executionCalldata.length < 56 ) {
235
238
revert InvalidRecoveryCallData ();
236
239
}
237
240
238
- // @TBD sending value to the validator module.
241
+ // @TBD implement sending value to the validator module.
239
242
// Rationale: In some very specific scenarios, the validator module might need to be paid for the recovery,
240
243
// or the recovery logic includes to take all the balance of the account.
241
244
(address targetValidatorModule , , ) = ERC7579Utils .decodeSingle (executionCalldata);
@@ -253,12 +256,12 @@ contract SocialRecoveryExecutor is IERC7579Module, EIP712, ReentrancyGuard {
253
256
ModePayload.wrap (bytes22 (0 )) // no payload needed
254
257
);
255
258
256
- // increment nonce.
257
- _recoveryConfigs[account].nonce++ ;
258
-
259
259
// reset recovery status.
260
260
_recoveryConfigs[account].recoveryStart = 0 ;
261
261
262
+ // increment nonce.
263
+ _recoveryConfigs[account].nonce++ ;
264
+
262
265
// execute the recovery.
263
266
AccountERC7579 (payable (account)).executeFromExecutor (Mode.unwrap (mode), executionCalldata);
264
267
@@ -289,7 +292,7 @@ contract SocialRecoveryExecutor is IERC7579Module, EIP712, ReentrancyGuard {
289
292
}
290
293
291
294
/// @notice Verifies multiple guardian signatures
292
- /// @dev Checks each signature against the current recovery digest
295
+ /// @dev Checks each signature against the current recovery digest and ensures no duplicates
293
296
/// @param account The account the signatures are for
294
297
/// @param guardianSignatures Array of guardian signatures to verify
295
298
/// @return True if all signatures are valid, false otherwise
@@ -306,7 +309,8 @@ contract SocialRecoveryExecutor is IERC7579Module, EIP712, ReentrancyGuard {
306
309
if (! guardianSignatureIsValid (account, guardianSignatures[i])) {
307
310
return false ;
308
311
}
309
- // check for signature duplication @TBD optimize O(n^2)
312
+ // check for signature duplication
313
+ // @TBD optimize O(n^2)
310
314
address currentSigner = guardianSignatures[i].signer;
311
315
for (uint256 j = 0 ; j < i; j++ ) {
312
316
if (guardianSignatures[j].signer == currentSigner) {
0 commit comments