EmergencyPauseHook
Circuit breaker with guardian-controlled pause/unpause and optional auto-unpause. Provides a kill switch for AI agent wallets.
Inheritance: ERC7579HookBase
Source: packages/contracts/src/modules/EmergencyPauseHook.sol
Storage
mapping(address account => PauseConfig) public pauseConfigs;
struct PauseConfig {
address guardian;
bool paused;
uint48 pausedAt;
uint48 autoUnpauseAfter;
uint48 lastPausedAt; // For cooldown enforcement
}Functions
onInstall
function onInstall(bytes calldata data) externalInitialize with guardian address and auto-unpause timeout. Called automatically during module installation.
| Data Field | Type | Description |
|---|---|---|
guardian | address | Address authorized to pause the account |
autoUnpauseAfter | uint48 | Seconds until auto-unpause (0 = manual only) |
pause
function pause(address account) externalPause the account, freezing all transaction activity. Only callable by the designated guardian.
A 1-hour cooldown is enforced between consecutive pauses to prevent griefing.
unpause
function unpause(address account) externalUnpause the account. Callable by the guardian or by the account itself.
isPaused
function isPaused(address account) external view returns (bool)Check if an account is currently paused. Accounts for auto-unpause: if autoUnpauseAfter is set and enough time has elapsed since pausedAt, this returns false even if paused is still true in storage.
setGuardian
function setGuardian(address newGuardian) externalChange the guardian address. Only callable by the account itself (via UserOp).
setAutoUnpauseTimeout
function setAutoUnpauseTimeout(uint48 timeout) externalChange the auto-unpause duration. Maximum 365 days. Set to 0 to require manual unpause. Only callable by the account itself.
preCheck
function preCheck(
address,
uint256,
bytes calldata
) external returns (bytes memory hookData)Hook entry point called by the HookMultiPlexer before every transaction. Reverts with AccountPaused if the account is currently paused (after accounting for auto-unpause).
Events
event Paused(address indexed account, address indexed guardian);
event Unpaused(address indexed account);
event GuardianChanged(address indexed account, address indexed newGuardian);Errors
error AccountPaused(address account);
error NotGuardian();
error PauseCooldown(); // < 1 hour since last pause
error InvalidAutoUnpauseTimeout(); // > 365 daysUsage Pattern
The EmergencyPauseHook is designed as a safety net for autonomous AI agents:
- Normal operation: The hook's
preCheckpasses through without interference - Anomaly detected: A monitoring system or human operator calls
pause()via the guardian key - Investigation: While paused, all UserOps from the wallet revert
- Resolution: The guardian calls
unpause()or the auto-unpause timer expires
Auto-Unpause
When autoUnpauseAfter is set, the wallet automatically becomes usable again after the specified duration without requiring an explicit unpause() call. This is useful for:
- Temporary cooldown periods after suspicious activity
- Preventing permanent lockout if the guardian key is lost
- Time-limited investigation windows
Cooldown
A 1-hour cooldown between pauses prevents a compromised guardian from repeatedly pausing and unpausing the wallet to cause disruption.