Crypto Training

ERC-7579 vs Safe Modules: Deep Architecture, Ecosystem, and Security Tradeoffs

A code-first deep dive into Safe modules, Zodiac, ERC-7579 architecture, and major module implementations (Safe7579, Kernel, Nexus, OpenZeppelin, Rhinestone Core). Focused on feature power versus security risk with concrete Solidity references and dense Mermaid diagrams.

Crypto Training2026-02-1927 min read

Smart-account modularity has split into two major lineages:

  1. Safe-native module architecture (and the Zodiac ecosystem built around it).
  2. ERC-7579 modular account standardization (cross-vendor interfaces for validators/executors/fallback/hooks).

Both lineages solve the same product problem: ship account features without redeploying a new account implementation for every new capability.

Both also create the same security problem: every extension point can become a privilege-escalation point.

This post is a deep technical comparison of those systems, with Solidity-level references, practical ecosystem mapping, and a risk-first model for auditors and wallet engineers.

Scope and methodology#

I reviewed local source snapshots from cloned repositories and pinned references to exact commits.

Primary standards/docs#

Repositories and pinned commits#

  • safe-global/safe-smart-account @ dc437e8fba8b4805d76bcbd1c668c9fd3d1e83be
  • rhinestonewtf/safe7579 @ f22a194148ff087f0c16125e530512e59794e188
  • erc7579/erc7579-implementation @ 16138d1afd4e9711f6c1425133538837bd7787b5
  • zerodevapp/kernel @ 6a098bc8f9a7001fe7ae801368e96a5ee635ddb1
  • bcnmy/nexus @ 7db9b00b7288eaefbe0124abd9ed2daa3f4ae2cc
  • OpenZeppelin/openzeppelin-community-contracts @ a12b30ca7affe3320777378eddf2d0cebae8c5b2
  • rhinestonewtf/core-modules @ 1f97c2920a17a43359413d8616a8228100c9f71a
  • gnosisguild/zodiac-modifier-roles @ 8c80d40b8b1354d1d3c5d2ee9d399a214fc4c790
  • gnosisguild/zodiac-module-exit @ 2720c7fa990842b9ea58f5b85aeb8769aff21331

Evolution of ideas#

flowchart TD Y2019["`2019: Safe module system matures sentinel list management and module execution lane`"] Y2021["`2021: Zodiac expands Safe expressiveness roles and specialized governance modules`"] Y2023A["`2023: ERC-7579 design converges minimal interoperable module interfaces`"] Y2023B["`2023: Safe 4337 launchpad experiments safe-modules PR 182 and PR 184`"] Y2024A[2024: Safe v1.5.0 introduces module guards] Y2024B[2024: Safe7579 adapter bridges Safe and ERC-7579] Y2026["`2024-2026: multi-vendor module ecosystems Kernel, Nexus, OZ modules, Rhinestone core, SDK layer`"] Y2019 --> Y2021 --> Y2023A --> Y2023B --> Y2024A --> Y2024B --> Y2026

Why this evolution happened#

  • Safe modules proved that account extension points are operationally powerful.
  • But Safe-native modules are Safe-specific, so portability across account vendors was weak.
  • ERC-7579 standardized only the minimal interoperability surfaces: execute/config/fallback/module interfaces and module types.
  • The ecosystem then split cleanly:
    • Account vendors compete on implementation and UX.
    • Module vendors compete on reusable security and feature modules.

Mental model: same goal, different abstraction layer#

flowchart LR A[User intent] --> B[Validation layer] B --> C[Execution layer] C --> D[Fallback extension layer] D --> E[Lifecycle controls] B1[Safe owners and signatures] --> B B2[ERC-7579 validators] --> B B3[Policy and signer modules] --> B C1[Safe module tx path] --> C C2[ERC-7579 execute and executeFromExecutor] --> C D1[Safe fallback handler] --> D D2[ERC-7579 typed fallback modules] --> D E1[Guards and timelocks] --> E E2[Prevalidation hooks and emergency uninstall] --> E

Safe modules deep dive#

Safe’s module architecture is still one of the cleanest production-grade modular account designs.

Core Safe module machinery#

sequenceDiagram participant Module as Enabled Module participant Safe as Safe ModuleManager participant Guard as Module Guard participant Target as External Target Module->>Safe: execTransactionFromModule(to,value,data,op) Safe->>Safe: verify module enabled Safe->>Guard: checkModuleTransaction(...) Safe->>Target: execute call or delegatecall Target-->>Safe: success or revert Safe->>Guard: checkAfterModuleExecution(hash,success) Safe-->>Module: success flag

Feature-value in Safe modules#

  • Very direct execution path for trusted modules.
  • Strong production hardening and battle-tested tooling.
  • Explicit guard insertion points for policy enforcement.
  • Simple mental model for signers, modules, and fallback.

Risk surface in Safe modules#

  • Module trust is absolute: enabled modules can become de facto superusers.
  • Linked-list management complexity: operational mistakes can leave stale or unexpected module state.
  • Fallback abuse risk: handler mistakes can open privileged internal call reachability.
  • Guard assumptions: if teams assume guard coverage where none exists, control gaps emerge.

Zodiac as Safe module specialization#

Zodiac shows what happens when Safe modules are treated as composable middleware.

Roles Modifier (zodiac-modifier-roles)#

Key idea: scoped capability graphs, not just yes/no module rights.

flowchart TD A[Module call] --> B[Role resolution] B --> C[Target clearance] C --> D[Function-level condition tree] D --> E[Execution options checks] E --> F[Allowance and consumption updates] F --> G[Forward to avatar execution]

Risk tradeoff:

  • Feature: granular and expressive authorization.
  • Risk: condition-tree complexity creates policy-audit burden and misconfiguration risk.

Exit Module (zodiac-module-exit)#

Key idea: controlled proportional exits from avatar-managed treasury.

Risk tradeoff:

  • Feature: explicit ragequit-like mechanism.
  • Risk: denominator/source-of-truth assumptions (circulating supply contracts, token ordering constraints, denylist governance).

ERC-7579: what was standardized (and what was intentionally not)#

ERC-7579 is intentionally minimal.

  • Mandatory account interfaces for execution/config/module management.
  • Module types with typed install/uninstall semantics.
  • Optional hook extension.
  • Explicit fallback behavior expectations with ERC-2771 sender append semantics.

Spec reference: https://eips.ethereum.org/EIPS/eip-7579

classDiagram class IERC7579Execution { +execute(mode, executionCalldata) +executeFromExecutor(mode, executionCalldata) +executeUserOp(userOp, userOpHash) } class IERC7579AccountConfig { +accountId() +supportsExecutionMode(mode) +supportsModule(moduleTypeId) } class IERC7579ModuleConfig { +installModule(typeId, module, initData) +uninstallModule(typeId, module, deInitData) +isModuleInstalled(typeId, module, additionalContext) } class IERC7579Module { +onInstall(data) +onUninstall(data) +isModuleType(moduleTypeId) } class IERC7579Validator { +validateUserOp(userOp,userOpHash) +isValidSignatureWithSender(sender,hash,signature) } class IERC7579Hook { +preCheck(msgSender,value,msgData) +postCheck(hookData) } IERC7579Validator --|> IERC7579Module IERC7579Hook --|> IERC7579Module

The key design choice#

ERC-7579 standardized interfaces and behavior envelopes, not specific storage layouts or nonce/signature encoding schemes.

That is why Kernel, Nexus, Safe7579, and reference implementations all look different internally while still being recognizably ERC-7579 systems.

Safe modules vs ERC-7579 modules: precise differences#

DimensionSafe-native modulesERC-7579 modules
Interop targetSafe ecosystemCross-account vendor ecosystem
Module typingSafe-specific semanticsStandardized type IDs (validator/executor/fallback/hook + extensions)
Entry abstractionexecTransactionFromModule*execute, executeFromExecutor, typed config
Fallback expectationsSafe fallback handler patternSelector-routed fallback modules + ERC-2771 append requirement
Hook semanticsGuard model and optional patternsStandardized hook extension (preCheck/postCheck)
Validation compositionSafe signature model + optional modulesValidator modules as first-class standardized type
Upgrade pathSafe account/version roadmapVendor-specific, often proxy/UUPS with module ecosystem portability
flowchart LR subgraph SafeLineage S1[Safe Owners and Signatures] S2[Safe ModuleManager] S3[Safe Guards] S4[Safe FallbackHandler] S1 --> S2 --> S3 --> S4 end subgraph ERC7579Lineage E1[Validator Modules] E2[Executor Modules] E3[Fallback Modules] E4[Hook Modules] E5[Prevalidation Hooks] E1 --> E2 --> E3 --> E4 --> E5 end SafeLineage --> Bridge[Safe7579 Adapter] Bridge --> ERC7579Lineage

Implementation deep dives#

1) Safe7579 (Safe adapter)#

Repository: https://github.com/rhinestonewtf/safe7579

Key contracts:

Notable features#

  • Safe-backed execute and executeFromExecutor with mode decoding.
  • Validator selection from nonce high bits during validateUserOp.
  • Fallback signature route to Safe checkSignatures when validator is unset/uninstalled.
  • Selector-routed fallback modules with ERC-2771 appended sender semantics.
  • Global hook wrapping and dedicated prevalidation hooks for ERC-4337 and ERC-1271.
  • Emergency hook uninstall timelock mechanism.
  • Launchpad lifecycle for safe setup under 4337 flow (preValidationSetup -> validateUserOp -> setupSafe).
flowchart TD A[validateUserOp] --> B[Extract validator from nonce] B --> C[Run 4337 prevalidation hook if present] C --> D{validator installed?} D -- yes --> E[Call validator.validateUserOp] D -- no --> F[Fallback to Safe checkSignatures] E --> G[Pay prefund if needed] F --> G
stateDiagram-v2 [*] --> PreValidationSetup PreValidationSetup --> InitHashStored InitHashStored --> ValidationPhase: EntryPoint validateUserOp ValidationPhase --> ValidatorsInitialized ValidatorsInitialized --> SafeSetupPhase: EntryPoint setupSafe SafeSetupPhase --> SingletonSwapped SingletonSwapped --> SetupComplete SetupComplete --> [*]

Risk lens#

  • Strong feature velocity through adapter abstraction.
  • Risk shifts to composition correctness across Safe semantics + 7579 semantics.
  • Prevalidation hooks and fallback handlers are powerful and can create DoS/authorization bugs if misused.

2) ERC-7579 reference implementation#

Repository: https://github.com/erc7579/erc7579-implementation

Key contracts:

Important caveat#

The repository explicitly says it is not audited and not recommended for production use as-is.

Why it matters anyway#

It is the clearest map of core mechanics:

  • explicit module-type branching in install/uninstall
  • linked-list validator/executor stores
  • selector-based fallback routing with sender append
  • single-hook model + split prevalidation hook model
  • vendor-choice examples (validator-in-nonce encoding marked as implementation-specific)

3) Kernel (ZeroDev)#

Repository: https://github.com/zerodevapp/kernel

Key contracts:

Architecture character#

Kernel is a full policy engine, not just a module host.

  • Validation mode/type/id encoding in nonce.
  • Root validator + validator + permission + 7702 branches.
  • Selector grants bound to validation identifiers.
  • Permission mode with signer + policy chains.
  • Replayable signature lane (MAGIC_VALUE_SIG_REPLAYABLE).
  • Sentinel hook constants with distinct semantics (address(0), address(1), HOOK_ONLY_ENTRYPOINT).
flowchart TD A[userOp.nonce] --> B[decodeNonce] B --> C{ValidationType} C -- root --> D[root validator path] C -- validator --> E[validator module path] C -- permission --> F[policy + signer path] C -- 7702 --> G[7702 signature path] D --> H[selector authorization checks] E --> H F --> H G --> H H --> I[execution hook binding]

Risk lens#

  • Extremely powerful composition model.
  • Security complexity is high: policy graphs, selector mapping, nonce modes, and hook sentinels are easy to misconfigure.
  • At this pinned commit, Kernel.uninstallModule fallback branch appears to call _clearSelectorData(selector) without capturing the returned target, then checks an unassigned local target. That pattern deserves immediate manual verification and regression testing in downstream forks.

4) Nexus (Biconomy)#

Repository: https://github.com/bcnmy/nexus

Key contracts:

Architecture character#

  • Supports validate mode, module-enable mode, and PREP mode inside validation flow.
  • Default validator concept plus installed validators list.
  • Hooked execution wrappers across account and executor flows.
  • Multi-type module installation and emergency hook uninstall timelock.
  • UUPS upgrade path with dual-slot compatibility logic for prior account versions.
  • ERC-7702-aware initialization branch.
stateDiagram-v2 [*] --> Uninitialized Uninitialized --> PREPMode: validateUserOp prep nonce mode PREPMode --> Initialized Initialized --> ValidateMode: normal userOp validation ValidateMode --> Execute ValidateMode --> ModuleEnableMode ModuleEnableMode --> Execute

Risk lens#

  • Excellent operational flexibility (especially onboarding flows).
  • Increased control-plane complexity across nonce modes and init paths.
  • Hook and prevalidation hook composition means attack/DoS surface expands with each extension.

5) OpenZeppelin Community ERC-7579 modules#

Repository: https://github.com/OpenZeppelin/openzeppelin-community-contracts

Key contracts:

Architecture character#

  • Delayed executor provides explicit schedule/ready/expire lifecycle.
  • Multisig family provides signer sets, threshold checks, weighted/confirmation/storage flavors.
  • Selector executor provides function-level execution allowlists.
stateDiagram-v2 [*] --> Unknown Unknown --> Scheduled: schedule() Scheduled --> Ready: delay elapsed Ready --> Executed: execute() Scheduled --> Canceled: cancel() Ready --> Canceled: cancel() Ready --> Expired: expiration elapsed Executed --> [*] Canceled --> [*] Expired --> [*]

Risk lens#

  • This suite is great for explicit controls and composable policy.
  • Documented unbounded set-clearing operations can become gas-scaling hazards for very large signer/selector sets.

6) Rhinestone Core Modules#

Repository: https://github.com/rhinestonewtf/core-modules

Representative contracts:

Architecture character#

  • Practical security modules that map directly to consumer wallet needs.
  • Registry attestation checks (ERC-7484 style) integrated into hook paths.
  • Multi-validator composition and subhook multiplexing patterns.
flowchart TD A[HookMultiPlexer preCheck] --> B[Global hooks] B --> C[Signature-specific hooks] C --> D{Is execution call?} D -- yes --> E[Value hooks] D -- yes --> F[Target signature hooks] D -- yes --> G[Delegatecall hooks] D -- no --> H[Skip execution-specific sets] E --> I[Deduplicate and sort] F --> I G --> I H --> I I --> J[Call all subhooks preCheck] J --> K[Collect contexts] K --> L[postCheck calls with contexts]

Risk lens#

  • Feature density is high and useful.
  • Each additional validator/hook composition level multiplies review complexity.
  • Timelock, nominee, and guardian semantics are only as strong as install/update governance and fallback escape paths.

7) Adjacent modular account ecosystems (important in practice)#

Even when not all of these are pure ERC-7579 module sets, they shape real deployments.

Also relevant for delegation-style modularity and EIP-7702-adjacent account controls:

flowchart LR A[Account Vendors] --> B[Module Standards] C[Infra Providers] --> B D[Registries and Attesters] --> B E[Explorers and Observability] --> B A1[Safe] --> A A2[Kernel] --> A A3[Nexus] --> A A4[Thirdweb stack] --> A C1[Pimlico] --> C C2[ZeroDev] --> C C3[Biconomy] --> C D1[Rhinestone Registry] --> D D2[EAS patterns] --> D E1[JiffyScan UserOp visibility] --> E

Feature vs risk matrix#

CapabilityWhy teams want itRisk introducedTypical control
Validator modulesflexible auth (MFA, passkeys, guardians, policy signers)validation confusion, parser bugs, replay mistakesstrict domain separation, nonce discipline, minimal parser surface
Executor modulesdelegated execution and automationmodule privilege escalationstrict install governance, selector allowlists, module guards/hooks
Fallback modulesextend interface without account upgradesunauthorized fallback executionselector routing + ERC-2771 sender checks + forbidden selector filters
Hookspre/post policy checks and telemetryDoS via hook reverts, reentrancy complexityisolation patterns, emergency uninstall, hook timeouts
Prevalidation hookscustom auth pre-processingsignature/hash mutation mistakesdeterministic transforms, explicit test vectors
Multi-type modulesfewer installs and richer bundlescoupled failure domainsexplicit install order, typed context encoding tests
Launchpad/bootstrap flowsseamless first userOp onboardinginit replay and setup confusioninit-hash commitments, singleton swaps, strict setup selectors
Upgradeabilitypatchability and velocitygovernance key compromise, upgrade bugstimelocks, codehash allowlists, staged rollouts

Deep difference: trust boundaries#

The deepest distinction is not syntax, it is where trust sits.

flowchart TD subgraph SafeNative S1[Owners] --> S2[Safe core] S2 --> S3[Enabled modules] S3 --> S4[Module guard optional] end subgraph ERC7579World E1[Account vendor core] --> E2[Typed module interfaces] E2 --> E3[Validator ecosystem] E2 --> E4[Executor ecosystem] E2 --> E5[Fallback ecosystem] E2 --> E6[Hook ecosystem] end S3 -.high-trust module assumption.-> Risk1[Module compromise equals account compromise] E2 -.interop and composability.-> Risk2[Cross-module composition risk]

Safe-native systems concentrate trust in a well-understood account core plus explicitly enabled modules.

ERC-7579 systems distribute trust across standardized extension points and a larger third-party module market.

That trade makes portability and ecosystem growth possible, but demands stronger module vetting and integration discipline.

Audit checklist for modular accounts#

Use this list when reviewing either Safe-module or ERC-7579-module systems.

  1. Module lifecycle safety
  • Can malicious onUninstall reverts brick removal?
  • Are there safe-mode escape hatches (timelock emergency uninstall, forced delete, isolation)?
  1. Authorization boundaries
  • Are install/uninstall paths strictly entryPoint/self/root-restricted?
  • Can internal self-calls bypass stricter controls unintentionally?
  1. Fallback safety
  • Are forbidden selectors blocked (onInstall/onUninstall and dangerous internal selectors)?
  • Is sender forwarding explicit and verified consistently?
  1. Nonce and replay semantics
  • Is nonce encoding parse-safe and collision-resistant?
  • Are replayable lanes intentionally scoped?
  1. Hook behavior
  • Can hook reverts create permanent DoS?
  • Are hook pre/post state assumptions formally tested?
  1. Upgrade safety
  • Are upgrade call paths bound to robust authorization?
  • Is new implementation code existence checked?
  • Is storage layout compatibility proven?
  1. Registry/attestation assumptions
  • Is registry downtime or compromise handled?
  • Are attester thresholds and trust assumptions explicit?
  1. Gas-scaling hazards
  • Any unbounded loops in uninstall/clear operations?
  • Any arrays/sets likely to become practically uncallable?

Side-by-side execution mechanics#

At high level, all systems do the same thing: authorize then execute.

At audit depth, they differ in exactly where policy enters and where fallback logic can redirect control.

sequenceDiagram participant U as UserOp participant EP as EntryPoint participant SA as Safe account participant MM as Safe ModuleManager participant G as Guard or ModuleGuard participant T as Target U->>EP: handleOps EP->>SA: validateUserOp SA->>SA: Safe signature checks EP->>SA: execute or executeUserOp SA->>MM: execTransactionFromModule path (if module flow) MM->>G: optional pre-check MM->>T: call or delegatecall MM->>G: optional post-check
sequenceDiagram participant U as UserOp participant EP as EntryPoint participant A as ERC-7579 Account participant V as Validator module participant H as Hook or Prevalidation Hook participant E as Executor module participant T as Target U->>EP: handleOps EP->>A: validateUserOp A->>H: optional prevalidation transform A->>V: validateUserOp(userOpHash) EP->>A: execute or executeUserOp A->>H: preCheck A->>E: executeFromExecutor or internal execute path E->>T: target call graph A->>H: postCheck

Why this matters#

  • Safe-native paths are usually easier to reason about because they have fewer standardized layers.
  • ERC-7579 paths are usually easier to extend across vendors because typed extension points are first-class.
  • Security review effort tends to scale with the number of active extension points, not with the number of contracts alone.

Concrete failure modes (feature-to-exploit mapping)#

Below are practical failure classes that show up repeatedly in modular account reviews.

1) Fallback selector collisions#

If fallback selector routing is not strictly constrained, an attacker can route calls toward privileged paths or create ambiguous dispatch.

Defenses visible in production code:

flowchart TD A[Unknown selector call] --> B{fallback selector installed?} B -- no --> C[Revert] B -- yes --> D[Forward to handler] D --> E{Handler auth uses appended sender correctly?} E -- no --> F[Unauthorized execution risk] E -- yes --> G[Expected behavior]

2) Malicious or broken onUninstall hooks#

Module deinit callbacks are an attack surface.

  • If uninstall flow must call external module cleanup and that callback burns gas or reverts unexpectedly, removal may fail.
  • Multiple implementations explicitly use try or safe-call wrappers to reduce permanent lock risk, but this can leave residual module state if not paired with full storage cleanup.

Examples:

  • Safe7579 uses try-delegatecall patterns in uninstall paths.
  • Nexus uses excessivelySafeCall for uninstall callbacks.

3) Hook-based denial of service#

Hooks can intentionally or accidentally revert in preCheck or postCheck, blocking all operations passing through that hook.

Spec-level concern is explicit in ERC-7579 security considerations: https://eips.ethereum.org/EIPS/eip-7579

stateDiagram-v2 [*] --> HookInstalled HookInstalled --> RegularFlow: preCheck and postCheck succeed HookInstalled --> FrozenExecution: preCheck revert HookInstalled --> PartialFreeze: postCheck revert FrozenExecution --> EmergencyUninstallTimelock PartialFreeze --> EmergencyUninstallTimelock EmergencyUninstallTimelock --> HookRemoved HookRemoved --> [*]

4) Module-typing confusion#

If an account fails to differentiate validator/executor/fallback/hook types in storage and access checks, a lower-privilege type can be treated as higher privilege.

ERC-7579 explicitly calls out this risk and requires module-type differentiation in account storage/control: https://eips.ethereum.org/EIPS/eip-7579

5) Validation routing ambiguity#

Nonce-encoded or signature-encoded validator routing is powerful but fragile:

  • parse mistakes
  • short-signature corner cases
  • fallback-to-default-validator surprises

Where this appears:

  • Safe7579 validator-in-nonce + Safe fallback validation path
  • Kernel validation mode/type/id in nonce
  • Nexus mode branches including module-enable and PREP

6) Replay lanes that outgrow intent#

Replay-safe-by-default is hard once systems add “replayable” paths.

Kernel explicitly has replayable signature mechanics (MAGIC_VALUE_SIG_REPLAYABLE) and replayable hash derivation paths. These are useful for cross-domain flows, but they demand strict domain modeling and downstream UI clarity.

7) Governance over-upgrade risk#

Upgradeable account implementations plus module systems are a multiplicative trust surface:

  • account upgrade control
  • module install control
  • registry/attester control

If these controls are not independent and observable, one compromised role may own the full stack.

8) Gas griefing in large module/signature sets#

Any unbounded clear/iterate operation can become a practical liveness bug at scale.

OZ module comments explicitly warn about this in clear and copy-heavy set operations: https://github.com/OpenZeppelin/openzeppelin-community-contracts/tree/a12b30ca7affe3320777378eddf2d0cebae8c5b2/contracts/account/modules

Implementation scorecard (security posture view)#

This is not a “best project” ranking. It is a map of where review effort should go first.

StackStrength profilePrimary risk profileFirst audit priority
Safe core modulesbattle-tested base, clear guard modelprivileged module misuse and fallback assumptionsmodule inventory + guard coverage validation
Zodiac roles/exitexpressive constrained execution and treasury workflowspolicy complexity and config driftrole-condition invariant testing
Safe7579strong Safe bridge, mature module taxonomy support, emergency hook pathadapter complexity, dual semantic layersvalidator fallback path + hook uninstall drills
ERC-7579 referenceclear educational baselineexplicitly non-production postureuse as reference only, not deployment template
Kernelhighly expressive permissions and validation modesconfiguration complexity and mode errorsnonce/mode parser and selector authorization proofs
Nexuspractical production onboarding modes (module-enable, PREP), upgrade compatibilityflow complexity and extension interactioninit-mode hardening + uninstall and hook stress tests
OZ community moduleshigh-quality reusable building blocksoperational gas bounds and integration misusestate-machine correctness + boundedness checks
Rhinestone core modulesrich consumer security modules (social recovery, MFA, deadman, registry hook)composition and governance couplingcross-module interaction and escalation analysis

Implementation-specific audit heuristics#

This section is intentionally concrete. It is a checklist of where bugs usually hide in each architecture family.

Safe core and Zodiac#

  1. Verify module list integrity assumptions
  • Linked-list based module storage means every removal requires a valid predecessor.
  • Audit all code that supplies prevModule and all pagination clients that compute it offchain.
  • Regression test for stale pagination cursors and concurrent module mutations.
  1. Guard coverage mapping
  • Map which paths are covered by transaction guard vs module guard.
  • Confirm no critical path executes via module route without module guard where policy assumes one.
  • Ensure guard contracts themselves do not have external dependency reentrancy surprises.
  1. Zodiac Roles policy depth
  • Build execution trees for representative role configs.
  • Prove that wildcard scopes cannot accidentally cover high-risk selectors.
  • Verify allowance consumption commit/rollback semantics on failed inner tx.
  1. Zodiac Exit assumptions
  • Verify designated token and circulating supply source can not be manipulated by unauthorized parties.
  • Test proportional redemption for non-standard ERC20s and extreme decimal configurations.
  • Verify denylist governance path under adversarial sequencing.

Safe7579 adapter family#

  1. Dual-semantics validation
  • Safe7579 combines Safe-native signature semantics and ERC-7579 validator semantics.
  • Test both branches intentionally:
    • validator installed and selected
    • validator missing or zero selector path
  • Verify timestamp and validity-window handling remains coherent across both.
  1. Fallback routing and msg.sender forwarding
  • For every fallback selector route, confirm handler logic uses forwarded sender semantics (not raw msg.sender assumptions).
  • Confirm unsupported selectors return/revert according to expected token receiver compatibility behavior.
  1. Emergency uninstall survivability
  • Validate the full timelock lifecycle:
    • request
    • waiting period
    • reset window
    • execute uninstall
  • Confirm emergency signatures cannot be replayed due nonce mismanagement.
  1. Launchpad initialization integrity
  • Prove initHash commitment cannot be bypassed.
  • Prove only valid setup selector flows are accepted in validation.
  • Simulate malformed callData and partially initialized states.

ERC-7579 reference-style accounts#

  1. Treat as a design reference, not hardened product
  • The reference repo explicitly warns it is not audited.
  • Use it to reason about interfaces and extension points, not as default deployment.
  1. Hook + prevalidation interaction
  • Test with and without hooks.
  • Test hook mutation of hash/signature payloads and ensure deterministic behavior.
  • Verify function ordering invariants (prevalidation first, then validator, then execution hooks).
  1. Fallback and selector safety
  • Confirm reserved selectors cannot be rebound.
  • Confirm handler calltype constraints are enforced (single/static where required).

Kernel-style permission-rich systems#

  1. Nonce decoding matrix tests
  • Generate tests across all mode/type/id combinations.
  • Include malformed nonce patterns and legacy-client nonce encodings.
  • Prove type-specific parser cannot be confused into privileged mode.
  1. Selector authorization coherence
  • For each validation ID, assert selector grants match policy/signer expectations.
  • Test grant removal and permission revocation ordering.
  • Ensure stale selector grants cannot survive disabled validation IDs.
  1. Replayable signature lane containment
  • Validate replayable lane scope exactly equals intended domain.
  • Ensure replayable hash derivation cannot be triggered accidentally by normal signatures.
  • Test chain-ID/domain separation assumptions under L2 and forked environments.
  1. Hook sentinel semantics
  • Kernel uses sentinel addresses to represent hook states.
  • Explicitly test each sentinel branch in:
    • fallback dispatch
    • validation flow
    • executor flow
  • Sentinel confusion bugs are subtle and high impact.

Nexus-style onboarding-rich systems#

  1. Mode transition correctness
  • Validate transitions across validate mode, module-enable mode, and PREP mode.
  • Ensure PREP initialization cannot be replayed or reentered.
  • Ensure module-enable signatures bind module type, module address, and intended init hash.
  1. Default validator fallback behavior
  • Map all cases where _DEFAULT_VALIDATOR participates.
  • Ensure uninstalling optional validators cannot silently weaken expected auth policy.
  • Confirm isInitialized and validator initialization checks cannot be bypassed by partial state.
  1. Upgrade and compatibility logic
  • Nexus supports compatibility with prior storage slot conventions.
  • Verify both implementation-slot paths in tests and static checks.
  • Confirm account-upgrade auth is identical across both slot-reading branches.
  1. Excessively-safe uninstall implications
  • Safe-call wrappers reduce hard reverts but may hide partial cleanup.
  • Verify post-uninstall invariants, not only call success status.

OZ module stack integrations#

  1. Delayed executor lifecycle invariants
  • Scheduled operation can only move Unknown -> Scheduled -> Ready -> Executed/Expired/Canceled.
  • No path should permit Scheduled -> Executed before delay.
  • Expired should not be executable without rescheduling.
  1. Selector executor allowlist guarantees
  • Ensure extracted inner selector is exactly the selector intended for authorization.
  • Confirm no ABI encoding trick can shift the selector location.
  • Validate behavior for empty calldata and malformed single-call payloads.
  1. Multisig signer set safety
  • For signer add/remove/set-threshold, prove threshold reachability invariants always hold.
  • For storage-presigned flows, verify presigned entries cannot be abused by unauthorized signer entries.

Core module ecosystem (Rhinestone and peers)#

  1. Module composability liveness
  • Modules like DeadmanSwitch and SocialRecovery intentionally constrain execution patterns.
  • Ensure they cannot permanently lock critical maintenance paths.
  • Test interactions when multiple validators and hooks are active simultaneously.
  1. Registry-hook assumptions
  • Registry checks add supply-chain controls, but create external dependency.
  • Test behavior under registry failure, stale attestation, and threshold changes.
  1. HookMultiPlexer complexity
  • Ensure dedup and ordering logic cannot be manipulated to skip expected subhooks.
  • Validate postCheck context association cannot be desynced across subhook calls.
flowchart TD A[Choose stack] --> B[Map extension points] B --> C[Enumerate active modules and hooks] C --> D[Build auth matrix per entrypoint] D --> E[Test install and uninstall invariants] E --> F[Test fallback and selector routes] F --> G[Test nonce and replay semantics] G --> H[Test upgrade and governance controls] H --> I[Run adversarial liveness scenarios] I --> J[Ship with observability and rollback runbooks]

Attack-path diagrams for reviewers#

Path A: Hook griefing to force emergency flow#

flowchart LR A[Attacker controls hook module] --> B[Hook installed on account] B --> C[preCheck starts reverting] C --> D[All executions blocked] D --> E[Emergency uninstall request starts timelock] E --> F[Timelock pending window] F --> G[Hook removed if signer path remains functional]

Review question: can the same malicious hook also block the signature path needed for emergency uninstall authorization?

Path B: Fallback misconfiguration to privilege escalation#

flowchart TD A[Admin installs fallback handler] --> B[Selector or callType misconfigured] B --> C[Handler gets calls beyond intended surface] C --> D[Auth logic relies on raw msg.sender] D --> E[ERC-2771 append semantics ignored] E --> F[Unauthorized state-changing execution]

Review question: does fallback auth use forwarded sender semantics consistently in every code path?

Path C: Permission drift in policy-rich validators#

flowchart TD A[Permission validator installed] --> B[Selector grants added] B --> C[Policy module set updated] C --> D[Signer module updated] D --> E{All old grants still coherent?} E -- no --> F[Residual over-privilege] E -- yes --> G[Expected least-privilege state]

Review question: are selector grants and policy/signer changes always atomic from a security perspective?

Operational runbook (production teams)#

Designing a modular account securely is only half of the job. Operating it safely is the other half.

  1. Maintain a machine-readable module inventory per account implementation
  • module address
  • module type(s)
  • install tx hash
  • governance authority that approved installation
  • expected uninstall fallback path
  1. Separate controls for:
  • account upgrades
  • module install/uninstall
  • guard/hook updates
  • registry and attester threshold changes
  1. Require canary rollout for new module versions
  • first on low-value accounts
  • then on medium-risk cohorts
  • then broad rollout only after monitoring quiet period
  1. Continuously monitor UserOp behavior
  • unknown validators appearing in nonce/signature routing
  • unexpected fallback selector usage
  • sudden spike in hook reverts
  • repeated uninstall attempts

Observability starting points:

  1. Practice disaster drills
  • emergency hook uninstall with real signer sets
  • fallback handler rollback
  • root validator rotation
  • upgrade freeze mode
  1. Build hard invariants into tests and audits
  • no untyped module can call executor-only paths
  • no fallback selector can target install/uninstall selectors
  • uninstall always progresses to a safe state even with malicious module callbacks
  • configuration self-calls cannot silently bypass stronger auth checks

ERC-7579 ecosystem maturity model#

Teams often ask whether the ecosystem is “ready.” The better question is: ready for which trust model?

flowchart TD A[Single-vendor account, minimal modules] --> B[Curated multi-module setup] B --> C[Third-party module marketplace usage] C --> D[Cross-chain and cross-vendor module portability] D --> E[High-assurance governance and registry-driven supply chain] A --> A1[Low feature surface] B --> B1[Moderate complexity] C --> C1[High composition risk] D --> D1[Interop gains with larger blast radius] E --> E1[Requires mature ops and security engineering]

In short:

  • ERC-7579 is mature enough for serious production use.
  • But production safety is mostly determined by module governance, not by interface compliance alone.

Migration patterns: Safe modules to ERC-7579 world#

flowchart LR A[Existing Safe account] --> B[Enable Safe7579 adapter module] B --> C[Set Safe7579 as fallback handler] C --> D[Install validator and executor modules] D --> E[Install optional hooks and prevalidation hooks] E --> F[Gradually move feature logic to ERC-7579 modules] F --> G[Keep Safe-native controls for defense in depth]

Practical advice:

  • Keep Safe-native guard/module hygiene during migration.
  • Treat adapter and first validator install as high-risk ceremony.
  • Stage rollout with low-privilege executor modules first.

Closing perspective#

Safe modules and ERC-7579 are not competitors in a zero-sum sense.

  • Safe modules proved that modular smart-account security can work in production.
  • ERC-7579 turned that lesson into a portable interface economy.
  • Safe7579 shows the bridge: a Safe account can keep its operational strengths while joining the ERC-7579 module ecosystem.

The strategic trade is clear:

  • More modularity gives faster feature evolution and richer wallet UX.
  • More modularity also gives larger authorization and composition attack surfaces.

Winning designs are not the ones with the most modules. Winning designs are the ones where module power, install governance, fallback behavior, and escape hatches are all deliberate, minimal, and test-proven.

Safe core#

Safe7579#

ERC-7579 reference#

Kernel#

Nexus#

OpenZeppelin community modules#

Rhinestone core modules#

Zodiac modules#