RecoveryModule
RecoveryModule lets the Guardians of an identity give it a new MANAGEMENT key when its owner lost every key. Guardians sign a recovery, the module schedules it, and anyone executes it once a delay has elapsed. The contract is OpenZeppelin's ERC7579SocialRecoveryExecutor, deployed unchanged: a delayed executor with a weighted multisignature. The concept is in Account abstraction and recovery.
At a glance
Source
contracts/modules/executors/RecoveryModule.sol, which inherits ERC7579SocialRecoveryExecutor
Module type
Executor (ERC-7579, type 2)
Deployed as
One contract per network. It stores the Guardians, weights, threshold, delay and expiration of each identity that installs it
Needs on the identity
To be installed as an executor, and to hold a key of type MODULE with the purpose MANAGEMENT
Defaults
Expiration of 60 days (defaultExpiration()). A change of delay is spread over at most 5 days (delayChangeWindow())
Installation
The module is installed with Identity.installModule(2, recoveryModule, initData). initData is the two-byte length of the executor arguments, the executor arguments abi.encodePacked(uint32 delay, uint32 expiration), the two-byte length of the guardian arguments, and the guardian arguments abi.encode(bytes[] guardians, uint64 threshold, uint64[] weights).
The identity has no settings in the module
ERC7579DelayedExecutorAlreadyInstalled, ERC7579MultisigAlreadyInstalled
The guardian arguments decode and list at least one Guardian
ERC7579MultisigInvalidInitData, ERC7579MultisigEmptySigners
Each Guardian is at least 20 bytes long and listed once
ERC7579MultisigInvalidSigner, ERC7579MultisigAlreadyExists
One weight per Guardian, none of them zero
ERC7579MultisigMismatchedLength, ERC7579MultisigInvalidWeight
The threshold is above zero and within the total weight
ERC7579MultisigZeroThreshold, ERC7579MultisigUnreachableThreshold
Uninstalling the module clears the Guardians, the weights, the threshold and the scheduling settings of the identity. Guide: 28 Install the recovery module and manage guardians.
Recovery
startRecovery(identity, salt, mode, recoveryData, multisignature)
Anyone carrying signatures of Guardians that reach the threshold
ERC7579SocialRecoveryExecutorInvalidSchedule for an invalid bundle or weights below the threshold, ERC7579ExecutorModuleNotInstalled, ERC7579ExecutorUnexpectedOperationState when the same operation was already scheduled. Emits ERC7579ExecutorOperationScheduled
cancelRecovery(identity, salt, mode, recoveryData)
The identity
ERC7579SocialRecoveryExecutorInvalidCancel. Emits ERC7579ExecutorOperationCanceled
cancelRecovery(identity, salt, mode, recoveryData, multisignature)
Anyone carrying signatures of Guardians over the cancellation message
The same
executeRecovery(identity, salt, mode, recoveryData)
Anyone
ERC7579ExecutorUnexpectedOperationState unless the operation is Ready. ExecutorPurposeNotAuthorized, from the identity, when the module lacks the purpose the target requires
Signatures are scoped. Guardians sign in the ERC-712 domain of the identity they recover. A signature made to schedule cannot cancel, and the reverse.
An operation is used once. A cancelled or executed operation cannot be scheduled again with the same salt.
Guide: 21 Recover access to an ONCHAINID.
State of an operation
state(account, salt, mode, executionCalldata) and state(operationId) return one of six values.
Unknown
Never scheduled
Scheduled
Scheduled, the delay has not elapsed
Ready
The delay has elapsed and the expiration has not passed: it can execute
Expired
The expiration has passed
Executed
Executed
Canceled
Cancelled
hashOperation(account, salt, mode, executionCalldata) gives the operationId. getSchedule returns scheduledAt, executableAt and expiresAt, by parameters or by operationId.
Settings
Each function changes the settings of its caller, so the identity makes the call: see step 5 of guide 28.
addGuardians(guardians)
ERC7579MultisigInvalidSigner, ERC7579MultisigAlreadyExists
At once. Emits ERC7913SignerAdded. A new Guardian has the weight 1
removeGuardians(guardians)
ERC7579MultisigNonexistentSigner, ERC7579MultisigUnreachableThreshold
At once. Emits ERC7913SignerRemoved
setSignerWeights(guardians, weights)
ERC7579MultisigMismatchedLength, ERC7579MultisigNonexistentSigner, ERC7579MultisigInvalidWeight, ERC7579MultisigUnreachableThreshold
At once. Emits ERC7579MultisigWeightChanged
setThreshold(threshold)
ERC7579MultisigZeroThreshold, ERC7579MultisigUnreachableThreshold
At once. Emits ERC7913ThresholdSet
setExpiration(expiration)
At once. Emits ERC7579ExecutorExpirationUpdated
setDelay(delay)
Not at once. A longer delay takes effect after the new delay, capped at 5 days. A shorter delay takes effect after the difference between the current delay and the new one. Emits ERC7579ExecutorDelayUpdated
Reads
getGuardians(identity, start, end), getGuardianCount(identity)
The Guardians of an identity
signerWeight(identity, guardian), totalWeight(identity)
The weight of a Guardian (0 when it is not one), the sum of the weights
threshold(identity)
The weight a bundle of signatures must reach
getDelay(identity)
The current delay, the pending one and the time it takes effect
getExpiration(identity)
How long a scheduled operation stays executable after its delay
Events
ERC7579ExecutorOperationScheduled(account, operationId, salt, mode, executionCalldata, schedule)
A recovery is scheduled. schedule is the time from which it can execute
ERC7579ExecutorOperationCanceled(account, operationId)
A recovery is cancelled
ERC7579ExecutorDelayUpdated, ERC7579ExecutorExpirationUpdated
A scheduling setting changes
ERC7913SignerAdded, ERC7913SignerRemoved
A Guardian is added, removed
ERC7913ThresholdSet
The threshold changes
ERC7579MultisigWeightChanged(address indexed account, bytes indexed signer, uint64 weight)
A weight changes. Not emitted for the default weight of a new Guardian
Trust statement. Guardians whose weights reach the threshold can take control of the identity after the delay. The delay is the owner's protection: an owner who still holds a
MANAGEMENTkey cancels a recovery it did not ask for.
Last updated