Skip to main content

ERC-7579: The Modular Smart Account Standard, Explained

Learn what ERC-7579 is and how modular smart accounts revolutionize blockchain wallets and stablecoin infrastructure.

Written by Eco

What Is ERC-7579?

ERC-7579 is a minimal modular smart account standard for Ethereum that defines a common interface for installing and removing modules across compatible accounts. Authored by Konrad Kopp (Rhinestone), Taek Lee (ZeroDev), Zeroknots, Filipp Makarov (Biconomy), and Elim Poon, the standard reached final status on the Ethereum Improvement Proposal track in 2024 after specifying four module types and a unified module manager interface.

Before ERC-7579, every smart account vendor shipped a custom module interface. A session-key plugin written for Safe could not run on Biconomy. A spending-limit module on Argent could not be reused on ZeroDev. ERC-7579 fixes that fragmentation by giving every compliant account the same installModule, uninstallModule, and isModuleInstalled functions, plus four canonical module types: validators, executors, fallback handlers, and hooks.

The standard is deliberately minimal. It does not dictate signature schemes, gas abstraction logic, or recovery models. It only specifies how modules attach to an account and how the account routes calls between them. Vendor implementations layer their own opinions on top: ZeroDev Kernel V3, Biconomy Nexus, Rhinestone reference implementation, and Safe's 7579 adapter all implement the same interface but differ in storage layout, validation rules, and gas costs.

How Does ERC-7579 Work?

An ERC-7579 account is a smart contract wallet that exposes a small set of standardized entry points. When a user signs a UserOperation under ERC-4337 account abstraction, the EntryPoint contract calls validateUserOp on the account, which delegates the check to one of the installed validator modules. Once validation passes, the account routes the call data through any active hooks, then either executes directly or hands off to an executor module for post-validation logic.

The four module types each have a defined role:

  • Validator (type 1): authenticates a UserOperation. The validator inspects the signature, nonce, and authorization data, then returns a packed validation result. Examples: ECDSA single-signer, multisig, passkey, session key, MultiFactor.

  • Executor (type 2): performs actions on behalf of the account after validation. Executors sit outside the normal call path and are invoked through executeFromExecutor. Use cases include automated DCA, scheduled transfers, and emergency withdrawals.

  • Fallback handler (type 3): handles calls to function selectors the account does not natively implement. Each selector maps to one fallback module, allowing accounts to support ERC-1271 signature verification, ERC-721 receiver hooks, and custom standards without changing the core contract.

  • Hook (type 4): runs code before and after each transaction. Hooks see the full call data and can revert if a policy fails. Spending limits, transaction whitelists, and rate limiters all fit this pattern.

The module manager interface is defined in the EIP text:

  • installModule(uint256 moduleTypeId, address module, bytes calldata initData) attaches a module and forwards initData to the module's onInstall hook.

  • uninstallModule(uint256 moduleTypeId, address module, bytes calldata deInitData) detaches it and runs onUninstall.

  • isModuleInstalled(uint256 moduleTypeId, address module, bytes calldata additionalContext) returns the install state.

  • getModulesPaginated(address cursor, uint256 size) lists installed modules in chunks for clients that need to enumerate state.

Each module declares its type through isModuleType(uint256 moduleTypeId), which lets the account verify compatibility before installation. A validator cannot accidentally be installed as a hook, because the install path checks the module's self-declared type against the requested slot.

Module Types in Practice

Validator Modules

Validators are the most widely deployed 7579 module category. The Rhinestone module registry lists OwnableValidator (single ECDSA signer), MultiFactor validator (combines two or more validators with quorum), and WebAuthnValidator (passkey signing via secp256r1).

Session keys are the highest-traffic validator type in production. A session key validator authorizes a temporary signer with scoped permissions: which contracts it can call, which selectors, what value range, and how long the session lasts. ZeroDev's session key implementation has handled millions of UserOperations across Polygon, Base, and Arbitrum since 2024 according to ZeroDev permissions docs. Once the session expires or the user revokes it, the validator rejects subsequent signatures.

Executor Modules

Executors carry out actions the account itself did not directly authorize in the current transaction. Common patterns include scheduled transactions (a Chainlink Automation job triggers execute at block N), recurring transfers (payroll runs every two weeks), and dead-man switches (if no signature appears for 90 days, transfer custody). The Rhinestone ScheduledTransfers executor implements this with a queue of pending transfers and a public trigger function.

Fallback Handlers

Fallback handlers expand an account's surface area without redeploying the core contract. The default Safe 7579 adapter ships with a Token Callback Handler that implements the receiver hooks for ERC-721 and ERC-1155 plus the EIP-1271 magic value for off-chain signature verification. Without a fallback handler, an account that holds an ERC-721 NFT cannot receive new transfers, because the spec requires the receiving contract to implement onERC721Received.

Hooks

Hooks gate every transaction. The two canonical hook patterns are spending limits (reject if cumulative outflow exceeds a daily threshold) and recovery delays (require a 48-hour cooldown before a guardian can replace the validator). Rhinestone's module registry publishes audit attestations for each hook so an account can refuse to install hooks that lack an attestation from a trusted auditor.

Hooks also support more nuanced policies than simple thresholds. A whitelist hook can refuse any transfer to a destination not on a pre-approved list. A circuit-breaker hook can pause all outbound transfers for 24 hours after detecting an unusual pattern. A KYC-gated hook can require a fresh attestation from a verified attestation contract before authorizing a swap above a regulatory threshold. Each pattern compiles down to the same preCheck/postCheck interface, which is what makes hooks composable across kernels.

ERC-7579 vs ERC-4337 vs ERC-6900

ERC-4337 and ERC-7579 solve different parts of the account abstraction stack. ERC-4337 is the off-chain side: it specifies the UserOperation object, the alternative mempool, the bundler nodes that batch UserOperations into transactions, and the EntryPoint contract that processes them. ERC-7579 is the on-chain side: it specifies how the smart account itself organizes its modules. A 4337 account does not need to be 7579-compliant, and a 7579 account can run outside the 4337 mempool by accepting direct calls.

The ERC-6900 standard from Alchemy and others competes directly with 7579. Both define module interfaces for smart accounts. The key differences:

  • Module granularity: 6900 splits validation into validation functions and pre-execution hooks with stricter ordering rules; 7579 keeps validators monolithic and treats hooks as a separate type.

  • Storage: 6900 mandates per-module storage namespacing through ERC-7201; 7579 leaves storage layout to the implementer.

  • Adoption: 6900 is implemented in Alchemy Modular Account; 7579 is implemented in Safe, ZeroDev, Biconomy, Rhinestone, and the OpenZeppelin Contracts modular account preset.

  • Specification surface: 6900 is roughly 3x the spec length of 7579 because it constrains more of the implementation.

Safe Modules predate both standards. The classic Safe module system uses a single execTransactionFromModule entry point with no type system. A Safe 7579 adapter, shipped by Rhinestone in 2024, lets a Safe expose 7579-style module slots while preserving its native Safe Modules so accounts can run both ecosystems side by side.

Adoption in 2026

ERC-7579 has become the de facto modular standard for new smart account projects. Implementations live across the wallet stack:

  • Rhinestone: maintains the reference 7579 implementation and the largest module registry. Used by smart account teams that build on ERC-7579 directly without picking a specific kernel.

  • ZeroDev Kernel V3: a 7579-native kernel powering ZeroDev's account abstraction stack. Kernel V3 docs describe full 7579 module support across 15+ EVM chains.

  • Biconomy Nexus: Biconomy's 7579 smart account, shipped in 2024 and integrated into the Biconomy SDK as the default account type for new deployments.

  • Safe: ships a 7579 adapter that wraps existing Safes. The adapter is a Safe Module that adds 7579 module slots. Safe 7579 docs cover the integration.

  • Coinbase Smart Wallet: launched in 2024, Coinbase Smart Wallet is a 4337 account with passkey-based ECDSA signing. It is not 7579-native today, but is built around modular validation and tracks the standard.

  • OpenZeppelin Contracts: ships an AccountERC7579 preset in the Contracts library that developers can extend.

  • Trust Wallet Smart Accounts: rolled out 7579-compatible smart accounts to Trust Wallet's mobile users, opting for a Biconomy Nexus base.

The BundleBear dashboard tracks UserOperation volume across 4337 bundlers; in early 2026 it shows tens of millions of operations per month flowing through accounts whose underlying contracts implement 7579 either directly or through an adapter.

Adoption is uneven across surfaces. Wallet vendors building greenfield smart account products (Biconomy Nexus, ZeroDev Kernel V3, Trust Wallet Smart Accounts) chose 7579 as their native module standard. Vendors with installed bases of pre-7579 accounts (Safe with millions of deployed multisigs, Argent with its existing recovery model) wrap 7579 through adapters rather than migrate users. Vendors that prioritize a custodial-feeling UX over module flexibility (Coinbase Smart Wallet, with its passkey-only validation) have not adopted 7579 because their account contracts intentionally do not expose a module interface.

The standard's gravity comes from the module side, not the account side. Once a module is written for 7579 and audited, every kernel that adopts the standard inherits it without further work. That economic asymmetry, where module developers pay the audit cost once and every kernel benefits, is what makes 7579 the default choice for new smart account stacks in 2026.

A Session Key Walkthrough

The most common 7579 module to install is a session key validator. A typical flow looks like this on a Kernel V3 account, using the ZeroDev SDK as an example:

The user authorizes a session by signing a permission object that names the target contract, allowed selectors, value cap, and expiry. The SDK encodes that into initData for the session key validator. The account owner submits a UserOperation that calls installModule(1, sessionKeyValidatorAddress, initData). The session key is now installed as a validator with type 1.

From that point, the dApp holds a session key it can use to sign UserOperations on behalf of the account, scoped to the permissions encoded at install time. When the dApp submits a UserOperation, the EntryPoint calls validateUserOp; the account routes the validation to the session key validator, which checks the signature against the session key public key, verifies the call matches the encoded scope, and returns success. If the call falls outside scope, the validator returns failure and the bundler drops the UserOperation.

To revoke the session, the user submits a UserOperation that calls uninstallModule(1, sessionKeyValidatorAddress, deInitData). The validator's onUninstall hook clears any storage tied to that session, and subsequent UserOperations signed by the session key are rejected.

This pattern unlocks gaming sessions where a player signs once at game start and the game uses the session key to submit moves, agentic flows where an AI agent operates within a budget, and subscription debits where a service charges a fixed monthly amount with no further user prompts.

Session keys also compose with hooks for additional safety. A common configuration installs a session key validator alongside a spending-limit hook. The validator authorizes UserOperations from the dApp; the hook enforces a hard daily cap regardless of what the validator approves. If the dApp is compromised and tries to drain the account, the hook blocks transfers above the cap. The user only loses up to the daily cap before the cooldown halts further outflow. This is the canonical defense-in-depth pattern in production 7579 deployments.

Security Considerations

Modules execute with the account's authority. A malicious validator can authorize any UserOperation; a malicious executor can drain the account; a malicious hook can refuse to release funds. Every 7579 deployment treats module installation as a high-trust operation.

The Rhinestone module registry was built to address this. Each registered module carries one or more attestations from named auditors (Spearbit, ChainSecurity, OpenZeppelin, Trail of Bits). An account can be configured to refuse installations of modules without an attestation from a trusted auditor, or modules whose latest audit is older than a chosen threshold. The registry contract is deployed at a stable address across supported chains and queried in the install path.

Hook ordering is the second common attack surface. If two hooks check the same condition with different cached state, an attacker can race them. The 7579 spec leaves hook ordering to the account implementation, so different kernels handle this differently: ZeroDev Kernel orders hooks by install time, while Safe 7579 lets the user reorder hooks explicitly. Reading the kernel's hook documentation matters before installing more than one hook.

Validator install collisions are a third risk. If the account permits multiple validators of the same type, the order in which the account checks them determines which validator authorizes a given UserOperation. Some kernels require explicit selection at sign time; others fall through to the first matching validator. The OpenZeppelin accounts API documents validator selection rules per implementation.

The audit landscape for 7579 modules is denser than for most smart contract categories. Spearbit, ChainSecurity, OpenZeppelin, Trail of Bits, Cantina, and Sherlock have each published 7579-related audits since the standard reached final status. Reports for the Rhinestone reference implementation, ZeroDev Kernel V3, and Biconomy Nexus are public. Module-specific audits (OwnableValidator, MultiFactor, ScheduledTransfers) are listed in the Rhinestone registry alongside the modules themselves. An account configured to enforce attestations refuses any module install whose attestation set does not include at least one of the user's trusted auditors, which closes the most common rug vector in plugin systems.

Recovery is a fourth area that 7579 does not solve directly. The standard does not specify a recovery model; instead, recovery is a module pattern. A typical setup installs a guardian validator type 1 (which can authorize replacement of the primary validator after a delay) plus a hook type 4 (which enforces the delay window). Loss of the primary signer triggers the guardian flow; the guardian signs a UserOperation that swaps the primary validator, the delay hook blocks execution for the cooldown period, and after the delay expires the new validator takes over. Vendors differ on whether to ship recovery as a default or leave it as an opt-in module.

Composability Across Vendors

The original promise of ERC-7579 was vendor-neutral modules. Before the standard, a developer who wrote a spending-limit hook for ZeroDev had to rewrite it for Biconomy, then again for Safe. With 7579, the same hook contract installs on every compliant account because the install path, the storage conventions, and the call routing are all standardized.

That promise is partially realized in 2026. The Rhinestone module registry tracks roughly 40 reusable modules across validators, executors, fallback handlers, and hooks. A module developer can deploy once to mainnet, register an attestation, and have any 7579 account install it. The most heavily used registry entries include OwnableValidator, MultiFactor, ScheduledTransfers, OwnableExecutor, and the WebAuthn-based PasskeyValidator.

Cross-vendor composition is not friction-free. Three issues recur in production. First, kernel-specific storage tricks: Kernel V3 packs validator state into a single storage slot for gas efficiency, while Safe 7579 uses Safe's existing storage layout. Modules that read raw account storage break across kernels. Second, hook ordering: a module that assumes hooks run in install order will misbehave on accounts that order by priority. Third, gas constraints: 4337 bundlers reject UserOperations whose validation phase exceeds spec gas limits, so a validator that runs heavy logic on Kernel V3 may revert on Nexus where the validation budget is tighter.

The practical fix is testing the module against each kernel before listing it as compatible. Rhinestone's ModuleKit framework spins up local instances of every major 7579 kernel and runs a module's test suite against each, catching kernel-specific failures before deployment.

The 4337 + 7579 Lifecycle

A typical UserOperation lifecycle on a 7579 account ties both standards together step by step. The user signs a UserOperation off-chain. A 4337 bundler picks it up from the alternative mempool and submits a transaction to the EntryPoint contract. EntryPoint calls validateUserOp on the account. The account inspects the validator nonce slot encoded in the UserOperation, fetches the validator address for that slot, and delegates the signature check to that validator's validateUserOp. The validator returns a packed result indicating success or failure, plus optional time bounds.

If validation succeeds, EntryPoint calls the account's execute path. Before the call data runs, every active hook's preCheck runs in sequence. Each hook can revert; if any reverts, the whole UserOperation reverts. After the main call data executes, every hook's postCheck runs to record state or enforce post-conditions. If the call data targets an executor (through executeFromExecutor), the account verifies the caller is an installed executor module before forwarding.

This lifecycle gives every module a deterministic place to act. Validators see UserOperations before they execute and decide whether to authorize them. Executors run when invoked through the executor entry point, with the account's authority. Fallback handlers receive direct calls to function selectors the account does not natively implement. Hooks see every transaction the account performs, regardless of how it was triggered.

Account Storage and Upgradeability

ERC-7579 itself does not mandate a storage layout, but most kernels follow ERC-7201 namespaced storage to avoid collisions when modules access account state. Each module computes a deterministic storage namespace from its address and uses that as the base slot for any state it tracks. The kernel reserves its own namespace for validator lists, executor lists, hook lists, and fallback maps.

Upgradeability splits along similar lines. Most 7579 accounts are deployed behind an ERC-1967 proxy or ERC-6551 token-bound account proxy, with the implementation address stored at the standard slot. The kernel ships an admin-only function to swap the implementation, gated by a validator type check so that only the account's primary signer (or a designated guardian) can authorize the swap. Modules themselves are not upgradeable in place; instead, the user uninstalls the old version and installs the new one, calling onUninstall on the old module to clean up state and onInstall on the new module to seed initial state.

This forces modules to be migration-aware. A spending-limit hook that tracks daily outflow per address must export and re-import that state when the user upgrades to a new version of the same module, otherwise the daily counters reset. The pattern most production modules follow is to expose a read function for current state and an init function that accepts that state, so the upgrade is a three-step UserOperation: read state from old module, uninstall old module, install new module with that state as init data.

Why ERC-7579 Matters for Stablecoin Routing

Cross-chain stablecoin movement increasingly runs through smart accounts rather than externally owned accounts. A treasury account might hold USDC on Base, USDT on Arbitrum, and PYUSD on Ethereum, then rebalance into the chain that has the best yield this week. Doing that from an EOA means signing every leg manually. Doing it from a 7579 account means installing a session key validator scoped to a routing contract, then letting the routing layer pull the moves automatically inside the limits the user encoded.

This is where Eco fits. Eco is a stablecoin orchestration layer that takes an intent (move N USDC from chain A to chain B, or swap stablecoin X for stablecoin Y on the chain with the deepest liquidity) and selects the right combination of CCTP, LayerZero, and Hyperlane to execute it. When a 7579 account installs a session key validator scoped to Eco's routing contracts, the user signs once, and the orchestration layer fans out across rails. The validator constrains what Eco can do; Eco constrains what rail to use. The two compose cleanly because 7579 makes the account side a stable interface.

FAQ

What does ERC-7579 standardize?

ERC-7579 standardizes the interface for installing, uninstalling, and querying modules on smart contract accounts. It defines four module types (validators, executors, fallback handlers, hooks) and four module manager functions, leaving signature schemes, recovery, and gas abstraction to implementers.

Is ERC-7579 the same as ERC-4337?

No. ERC-4337 specifies the off-chain side of account abstraction (UserOperations, bundlers, EntryPoint), while ERC-7579 specifies the on-chain account interface for module composition. A 4337 account can be 7579-compliant or not; the two standards solve different layers of the stack.

How does ERC-7579 differ from ERC-6900?

Both define module interfaces for smart accounts. ERC-6900 from Alchemy is roughly 3x longer, mandates per-module storage namespacing, and splits validation into stricter sub-types. ERC-7579 keeps the surface minimal and leaves storage to implementers, which is why it has wider adoption.

Which wallets implement ERC-7579?

Rhinestone, ZeroDev Kernel V3, Biconomy Nexus, Safe (via the Rhinestone-built 7579 adapter), Trust Wallet Smart Accounts, and the OpenZeppelin Contracts AccountERC7579 preset all implement the standard. Coinbase Smart Wallet tracks the spec but is not 7579-native today.

What can I do with a session key on an ERC-7579 account?

Install a session key validator that authorizes a temporary signer with scoped permissions: target contracts, function selectors, value caps, and expiry. The dApp uses the session key to sign UserOperations on behalf of the account inside that scope, with no further user prompts until the session expires or is revoked.

Did this answer your question?