Hello, Modular Account
Authors: Noam Hurwitz, Jay Paik, Adam Egyed, Fangting Liu, David Philipson, Howy Ho
We’re thrilled to announce the launch of Modular Account, a new contract account implementation designed from the ground up for ERC-4337 and ERC-6900 compatibility.
Modular Account provides enterprise-grade security, best in class cost, and robust account extensibility to developers building embedded wallets on Ethereum L2s.
Start building today with Modular Account, and read on to learn more.
Why Contract Accounts
The web3 ecosystem has experienced unprecedented growth over the past few years, yet one of the most stubborn roadblocks to scaling our ecosystem still remains:
Poor UX.
Imagine trying to onboard the layman with no prior blockchain exposure and describing the various nuances of hot or cold wallets, private keys, gas, approvals, nonces, etc.
Now, to really understand the issue, let’s take this a step further and paint a picture of what the UX that crypto natives have become so accustomed to would look like applied to real-life scenarios:
Luckily for us, there is a solution to untangling the web of confusion from poor UX within our industry - Account Abstraction. Account Abstraction focuses on the idea of utilizing a smart contract account , or smart account colloquially, instead of an externally owned account (EOA) to shift transaction and activity management on the blockchain to a more adaptable entity.
By using a smart account instead of an EOA, you are “abstracting” away to a more versatile actor to handle transactions and activities on the blockchain.
Smart accounts are infinitely more flexible in their capabilities than EOAs. Each smart account can define different rules and configurations within its code.
We saw abstraction occur in the maturation of the internet via increasingly complex primitives getting layered into the infrastructure stack leading to today’s modern webapps. This packaging of technically complex features into well-scoped modules significantly simplified the end-user experience for those surfing the World Wide Web.
To illustrate abstraction further, we’ve provided you with a simple example below:
It is evident that we are at a crucial crossroads in Web3 where constructing a better UX is crucial for onboarding the next mass wave of users.
From single points of failure and asset custody concerns to simply reducing the immense friction for a net-new user to get started, we must move towards a future where we abstract away these complexities and push for a more streamlined experience for all users.
Why Modular Contract Accounts
It’s clear that smart accounts are required and that limitless improvements can be built into them. Different account implementations will inevitably share a lot of logical components such as account recovery, multi-sig support, and key permissions. Each new implementation of these components introduces new security risks to the account implementing them.
Instead, as is done with popular cryptographic libraries today, modular components can be hardened and maximally reused to avoid many teams independently writing complex account code. As the security adage goes: “don’t roll your own crypto” - this applies to account logic too. These components can be architected as plugins, that accounts can interchangeably install and interact with to add the desired functionality.
As soon as multiple accounts work with multiple plugins - as defined in ERC-6900 - there is reduced vendor lock-in to the on-chain account implementation. Users are protected from single points of failure, and if required or desired, can update their accounts to a different implementation while maintaining, for the most part, their existing functionalities via the plugins installed on the account.
On these two pillars of reusability and interoperability, developers can leverage an open ecosystem of modular accounts and plugins to accelerate development via compounding progress in account functionality and on-chain UX.
Introducing Modular Account
Alchemy’s Modular Account is an enterprise-grade implementation designed to scale with your users and be future proof with continued developments of the Account Abstraction ecosystem.
It’s extensible with a robust security model to ensure trustless and seamless user experiences. We’re releasing Modular Account with two plugins that facilitate significant UX and security unlocks: Multi Owner Plugin and the Session Key Plugin, as well as with SDK support for simple integration and development. Modular Account v1.0 is compatible with ERC-4337 v0.6 and ERC-6900 v0.7.
We’re excited to release Modular Account under a permissive open source license, and to keep our foot on the gas with respect to building and shipping public goods for helping to develop the account abstraction ecosystem.
Modular Account Demo: Worth of Words
One example that highlights the robust user experience and security features Modular Account provides is the game we built, Worth of Words. Worth of Words is a “Wordle Battle Royale,'' style game, where players compete against each other to guess their secret words. This game leverages the following to provide a web2 style gameplay:
Modular Account with a Session Keys Plugin so users only need to sign once to initiate a new game, and then safely enable the browser to sign transactions for them during gameplay for a transaction-less experience.
ERC-4337 Gas Manager to abstract gas from the user experience
Alchemy’s Rundler to relay UserOperations to the underlying network.
Zero-knowledge proofs to hide the words on-chain.
Learn more about Worth of Words here.
Technical Deep Dive
Modular Account uses the UUPSUpgradeable proxy pattern, and plugins are singleton contracts.
The Modular Account initial release includes multiple components:
Core Account
The base account supports core account abstraction functionality, including gas abstraction and batch execution. Its features include support for:
ERC-4337 for censorship resistant account abstraction.
ERC-165 for standard interface detection.
UUPSUpgradeable for account upgradeability with ERC-7201 for safe storage-collision resistant upgrades.
Execution triggered from plugins, which executes logic under the account’s context when the call originates from an allowed plugin.
Installation and uninstallation of any ERC-6900 compatible plugins, not just Alchemy’s.
View functions to fetch the plugin configuration of an account, including installed execution functions, validation functions, and hooks.
Strong ordering guarantees of plugin execution.
Receiving of ERC-721, ERC-777, and ERC-1155 tokens. Without a token receiver implementation, contract accounts cannot receive digital assets via the `safeTransfer` method standardized by OpenZeppelin.
Account Factory
The account factory contract that generates new Modular Account instances. These parameters can be user-specified and are the means to provide a deterministic address. CREATE2 is used to generate counterfactual addresses for users by using a combination of a provided salt and the assigned owner of the account.
In production, we expect some users to be allocated addresses that are used to receive assets before an account is deployed counterfactually to their allocated address.
Account Plugins
The initial release includes two ERC-6900 compatible plugins:
Multi Owner Plugin
The Multi Owner Plugin supports one or more EOA accounts or ERC-1271 compliant contracts as owners of the account. The plugin:
Supports ECDSA verification of signatures (standard EOA signatures verification).
Supports ERC-1271 signature verification (standard contract owner signatures verification).
Supports multiple equal owners who have the same root access to the account.
Implements EIP-712 to allow clients to signing prompts in a structured and readable format.
Adds user op and runtime validation functions to Modular Account’s native functions, including:
installPlugin
anduninstallPlugin
upgradeToAndCall
execute
andexecuteBatch
Session Key Plugin
The Session Key Plugin enables session keys to be added to conduct various scoped actions on behalf of the account under preset rules. They enable improved user experiences while providing on-chain security guardrails, enabling behavior like transactionless experiences and account automation. Session keys are used in the UserOperation context only. The plugin supports:
Key rotation. It can update the key while keeping the permissions in place.
Expiry / time range rules that restrict session keys’ access to a specified time range.
External contract address limitations that limit what external contract addresses a session key is allowed to call. This restriction may be an allowlist, denylist, or neither.
External contract method limitations, to limit what external contract methods a session key is allowed to call.
ERC-20 spend limits (total for a key, or refreshing on an interval).
ETH / Native token spend limitations (total for a key, or refreshing on an interval).
Gas spend limitations (total for a key, or refreshing on an interval). By default, the limit is not set, a session key that has permissions to do anything can spend an unbounded amount of gas.
ERC-721 permissions, which can be facilitated with contract method limitations (e.g., allowing
safeTransferFrom(address,address,uint256)
) as well as address limitations.Default internal call only scoping. If the session key permissions plugin is installed without initial specification of external call limitations, every external call will be disallowed by default.
Required paymaster rules, where a session key may only be used to validate a user operation if a specific paymaster address is used. This is an alternative way to prevent session keys from spending your native token on gas than the gas limit.
Account Libraries
The Account Libraries support the implementation of modular accounts and plugins with reusable code implementing specific functionality.
Data Structures
LinkedListSetLib
implements a “linked list set”, in which elements are held in a mapping from one element to the next. This allows for O(1) add, remove, and contains operations, while keeping the sets enumerable on-chain. This setup requires that the set prevent the addition of duplicate values, prevent addition of a zero value, and maintain a special value designated as the “sentinel” that identifies the start and end of the list. To achieve this, the data size available to the user is reduced to a maximum of abytes30
.In addition to supporting these efficient operations, the library also supports a less-efficient remove operation without knowledge of a predecessor, which traverses the linked list to find the element to remove.
Additionally, entries also support “flags” - these can be thought of as additional values attached to entries, much like a sub-mapping for each element within the set. 14 bits are available for flag values, the lowest two bits are reserved for the sentinel implementation and a list traversal optimization.
AssociatedLinkedListSetLib
implements a linked list set almost identically toLinkedListSetLib
, except that its entries are held in account-associated storage. This library is intended to be used by plugins, which must hold values in account-associated storage if they wish to access or update them during ERC-4337 validation.CountableLinkedListSetLib
extendsLinkedListSetLib
to allow adding a value more than once. It uses the upper byte (8 bits) of the 14 available flag bits for an entry to track this, and supports adding an entry up to 256 times. There does not exist a version of this library that is held in associated storage.The common types and constants used by these libraries are defined in
Constants.sol
.PluginStorageLib
is a more low-level library that provides utilities for getting storage slots in address-associated storage using varying amounts of input data as a key.
Types & Conversion Utilities
FunctionReferenceLib
provides a user-defined value type intended to hold a plugin address and a function id, for the purposes of calling plugin functions.CastLib
provides utility functions for casting and converting between various data types, including set values, function pointers, and addresses.
Audits
We took a multi-stage approach to security, with Spearbit performing a security review of the Modular Account protocol early in the development process, followed up by Spearbit and Quantstamp independently auditing the protocol at the current version. No major vulnerabilities were discovered as part of either audit.
The reports are available from Spearbit and Quantstamp respectively. We’re excited to partner with both Spearbit and Quantstamp to provide preferred rates and services for teams looking to develop on Modular Account and the broader ERC-6900 ecosystem.
Security & Permissions Model
Let's explore four key areas that highlight the security and permissions model of Modular Account.
Plugin Manifest
The plugin manifest feature is a key aspect of ERC-6900 and Modular Account, inspired by the Android OS permissions system. All ERC-6900 plugins are required to provide a list of execution functions, hooks, and permission requests a plugin requires to function. This can be displayed to the user on installation before the account installs the plugin and grants these requested permissions. This determines permissions at install time, guarding users against any unexpected runtime behavior.
Call vs. DelegateCall
Modular Account only executes call
s and not delegatecall
s to plugins. With delegatecall
, which executes in the account context, it is difficult to limit the damage a malicious plugin can cause without auditing the plugin code.
Modular Account Call Flow
The diagram below showcases the path that a call would make through Modular Account. The flow on the left is the UserOperation path for calls originating from the ERC-4337 Entrypoint, and the flow on the right is the runtime path for calls originating from all other sources - including other contracts.
Upgradeability
Modular Account has been designed to be future proof with respect to upgrades and storage collisions. Specifically:
There is no risk of storage collisions upgrading to and from a Modular Account, thanks to the use of the EIP-7201 initialized storage pattern.
Modular Account minor version changes will use the inherited storage pattern to prevent storage collisions and Modular Account major version releases would use a different storage slot.
Benchmarks
Modular Account provides best in class end user costs on Ethereum Rollups, including Arbitrum, Base, and Optimism. As we continue to push for the three core transitions required to onboard mainstream users onchain, Modular Account aims to provide a fundamental primitive optimized for a rollup centric future.
Specifically, it often sacrifices call data usage for increased execution costs, as to provide end users cheaper experiences. Additionally, as a durable user account, Modular Accounts contain guardrails for permissionless interoperable usage, extending beyond the per-app embedded account paradigm that is popular today to help drive forward an invisible and interoperable future. The account is heavily optimized for day to day usage, with certain security features adding some execution overhead at deploy time.
To measure cost, we built a comprehensive testing suite for smart contract accounts for accurate, transaction-based, fee measurements, and fee calculations. You can find the repository, full methodology, and full results here. The results below were benchmarked on Optimism on Feb 18, 2024.
Modular Account | Biconomy v2 | Kernel v2.1 | Safe | Light Account* | |
---|---|---|---|---|---|
UO: Account Creation | $0.59 | $0.67 | $0.69 | $0.89 | $0.57 |
UO: Native Transfer | $0.53 | $0.57 | $0.54 | $0.54 | $0.53 |
UO: ERC-20 Transfer | $0.58 | $0.62 | $0.59 | $0.59 | $0.57 |
UO: Session Key Creation | $0.82** | $0.61 | $0.64 | Unsupported | Unsupported |
UO: Session Key Native Transfer | $0.59 | Unsupported | $0.71 | Unsupported | Unsupported |
UO: Session Key ERC-20 Transfer | $0.63 | $0.82 | $0.78 | Unsupported | Unsupported |
Runtime: Account Creation | $0.20 | $0.23 | $0.28 | $0.43 | $0.17 |
Runtime: Native Transfer | $0.20 | Unsupported | $0.21 | $0.36 | $0.20 |
Runtime: ERC-20 Transfer | $0.25 | Unsupported | $0.26 | $0.41 | $0.25 |
* LightAccount is not a Modular Account and is added for reference for best in class smart accounts.
** The ERC-6900 session key plugin offers much more robust security controls versus other offerings.
Note that there is an inverse tradeoff in optimizing for rollups, versus optimizing for layer one Ethereum and side chains. These benchmarks capture performance as measured in the rollup ecosystem.
Bug Bounty
With the release of Modular Account, we’re also announcing the public launch of Alchemy’s paid bug bounty program. Bug bounties are a critical part of the security toolbox, and we’re excited to work with and reward ecosystem security researchers as they find opportunities to harden the overall protocol.
Starting today, anyone can report vulnerabilities on any package in the Modular Account release through our HackerOne hosted bug bounty platform. To learn more about the bug bounty program, see the overview on HackerOne.
Modular Account SDK & PluginGen
Alchemy’s AccountKit, featuring aa-sdk
, is the most widely used developer SDK for smart account development and abstracts away the overhead and complexity of building on smart accounts. As of today, AccountKit will have first class support for Modular Account including the multi-owner and session key plugins. Version 3.0 of the SDK greatly simplifies the overhead of building and submitting UserOperations, managing counterfactual addresses, upgrading to Modular Account, and utilizing advanced features like user sessions.
Additionally, this release also includes PluginGen, which can auto-generate client-side classes for working with and leveraging plugins, deriving information for any ERC-6900 plugin from the plugin manifest. This enables programmatic user experiences client-side, based on the state of the user’s account.
Using the PluginGen tool is as easy as adding a PluginGenConfig
describing your plugin within the aa-sdk and then running `yarn generate`:
export const MultiOwnerPluginGenConfig: PluginGenConfig = {
name: "MultiOwnerPlugin",
abi: MultiOwnerPluginAbi,
addresses: {
[sepolia.id]: "0x000000E8F14A838A00505d861c6EF15cdfB05455",
[baseSepolia.id]: "0x000000E8F14A838A00505d861c6EF15cdfB05455",
[polygon.id]: "0x000000E8F14A838A00505d861c6EF15cdfB05455",
},
chain: sepolia,
installConfig: {
initAbiParams: parseAbiParameters("address[]"),
},
};
Looking Forward
Modular Account Ecosystem Iterations
We look forward to continuing to work with the ERC-6900 community to develop a robust permissionless ecosystem of plugins and accounts. A few broader ideas we’re excited to purse include:
Building on the security model to create a concept of application level permissions as a composition of plugin level permissions.
Drawing an analogy to web2, when installing an application like WhatsApp, the operating system requests permissions for a set of privileges that the application, WhatsApp, needs to properly execute, such as location, camera, microphone, contacts, etc.
Given the existing security model around plugin-based permissions, we want to explore how this might expand to application-level permission sets.
Continuing to iterate towards a maximally hardened, maximally optimized account implementation.
We’re excited to explore techniques to simplify and streamline operations and iterate on the data models to improve understanding and reduce end user costs.
Working with teams to develop an accelerating ecosystem of interoperable plugins.
We’ve already seen work kick off work across several development teams, and we’re looking forward to seeing what use cases the ecosystem comes up with.
There’s huge unlocks available in user experience and user security that can be bolted onto existing accounts through well designed plugins.
Contributing to R&D for the next wave of challenges.
A lot of convergent threads need to land in order to be able to safely onboard 1B users on-chain. Two pieces in the account space that we’re excited to see more time invested in are cross-chain interoperability and user privacy. A lot of these advancements are predicated on pushing the envelope on zero-knowledge engineering and incorporating these primitives into solutions like keystore chains to help manage account configs across multiple chain deployments.
Leveraging Smart Accounts and L2s to Bring Down User Costs
One of the most common critiques we hear of smart accounts is cost. As the smart account ecosystem grows, we’re excited to work together with the community to show that actually, smart accounts enable cheaper transactions for end users than EOAs today.
There have been several researched methods to push down these costs, but a few that we’re keeping close tabs on for 2024 include:
Calldata compression
As mentioned above, the bulk of transaction cost of L2s is L1 data availability cost and not L2 execution cost. As such, it generally reduces overall cost if one can reduce calldata size by increasing the execution costs. The Ethereum Foundation’s WAX group has researched and prototyped UserOperation compression with some pretty compelling results, and we’re excited to see this technique adopted to improve operational efficiency.
Signature aggregation
In practice, signature aggregation is a similar technique of lowering data availability costs by aggregating all signatures in a bundle into a single fixed overhead. Most discussions here center around BLS signatures, but in practice, this can be extended using zero knowledge proofs to other signature schemes too. We’re excited to see some ERC-6900 plugins to support BLS signatures as well as features like zk-R1 or zk-K1 aggregation for getting similar outcomes on non-aggregatable elliptic curves.
Proto-Danksharding
With the much anticipated EIP-4844 landing as part of the Dencun hardfork, L2 networks will be able to make use of blobspace to post L2 calldata as opposed to storing it as L1 calldata. While estimates vary, proto-Danksharding is expected to substantially reduce the costs of transaction on L2s overall.
Acknowledgments
The work behind Modular Account extends far beyond Alchemy. First and foremost, we’d like to thank the dozens of developers working on and contributing to ERC-6900, driving forward the iterations that enable developers to securely onboard 1B users on-chain.
Specifically we’d like to shout out Yoav Weiss and Dror Tirosh from Ethereum Foundation’s Account Abstraction team, Huawei Gu, Daniel Lim, Zhiyu Zhang, and Alokik Bhasin from Circle’s Programmable Wallets team, and Seungmin Jeon, Sangyeup Kim, Brynn Park, and the rest of the folks at Decipher Global all for meaningfully pushing forward the specifications.
Additionally, we want to thank our excellent auditing teams. We’ve said this countless times, and we’ll say it again: security is table stakes when dealing with contract accounts. Gerard Persoon, Riley Holterhus, Blockdev, and Christos Pap at Spearbit as well as Nikita Belenkov, Alejandro Padilla, Shih-Hung Wang, and Ruben Koch from Quantstamp have been incredibly diligent on assessing and improving both the implementation and architecture of Modular Account.
We’d also like to thank the engineering team at a16z crypto, and especially Daejun Park and Matt Gleason, for early sessions on formal verification of smart accounts and the use of Modular Account iterations as testing criteria for Halmos - further improving the security posture and the development mindset around secure smart accounts.
Lastly, we want to thank the entire Modular Account ecosystem for supporting discourse and discussion to drive the space forward. There were many early iterations and architecture proposals that were worked through with the broader community, and we want to call out the folks at Safe, Biconomy, ZeroDev, and Rhinestone for frequently and commonly making excellent points and suggestions.
Related articles
Node API is now 50% cheaper
Key Node API methods are now 50% cheaper with some builders even seeing up to 98% savings.
Up to 40% Cheaper Data APIs
As part of our mission to bring 1 billion users onchain, we're reducing Compute Unit costs for our NFT API, Token API and Transfers API starting today.
Introducing Geist: the Members-Only Blockchain
Geist Mainnet, the first members-only blockchain built for gaming, is finally here!