Solady — Vectorized's gas-optimized Solidity library — quietly went from 0.0.x to 0.1.0 over the past few months, and the version bump was not cosmetic. The 0.1.x release line includes first-class support for EIP-7702 (set-code transactions for EOAs), a redesigned ERC-4337 stack, and the new ERC-7821 minimal-call execution standard. For developers building wallets, paymasters, or anything in the account-abstraction (AA) ecosystem, this is the most consequential Solady release to date.
This post covers what changed, why EIP-7702 matters even if you are not building a wallet, and the security pitfalls to watch as the ecosystem migrates.
What is EIP-7702 and Why It Reshapes Wallets
EIP-7702 (live since the Pectra hard fork) lets an externally-owned account (EOA) temporarily delegate its address to a smart contract's code for the duration of a single transaction. Mechanically, a user signs a special set-code authorization that points their EOA at a designated contract; that contract's logic runs in the EOA's storage context.
The practical implications are large:
- An EOA can batch operations, run policy checks, sponsor gas, or use session keys — without first migrating to a contract wallet.
- The same private key that controls the EOA's funds today can opt into smart-wallet behavior on a per-transaction basis, then opt out.
- Existing EOA-based UX (Metamask, hardware wallets) can adopt AA features incrementally, instead of asking every user to deploy a new contract wallet.
For builders, this opens a new architectural pattern: proxies that activate behind an EOA. That is what EIP7702Proxy.sol (new in Solady 0.1.x) is for.
What Changed in Solady 0.0.x → 0.1.x
The diff is large (roughly +33,000 lines of additions, hundreds of files touched). The changes that matter most from a security and integration standpoint:
New: accounts/EIP7702Proxy.sol
A purpose-built proxy designed to be set as the delegated code for an EOA via EIP-7702. Key properties:
- Bricks initialization replays — once an EOA has been delegated to this proxy and initialized, subsequent re-delegation attempts cannot reset its storage.
- Minimal storage footprint — uses ERC-1967 storage slots so the EOA's storage layout does not collide with arbitrary contract data.
- Compatible with
LibEIP7702.sol— utility library for upgrade flows, deauthorization, and signature recovery against the delegated code.
New: accounts/ERC7821.sol
Solady's implementation of ERC-7821 — a minimal "execute" interface for AA wallets and proxies. Defines a single canonical execute(Call[] calls) entrypoint that bundlers, paymasters, and front-ends can call uniformly across wallet implementations.
Why it matters: before ERC-7821, every wallet vendor had its own executeBatch, executeOps, runUserOp signature. Bundler infrastructure had to special-case each one. ERC-7821 collapses that to a single interface, so a bundler can target every conforming wallet without per-vendor adapters.
New: accounts/Timelock.sol
A minimal timelock that integrates with Solady's Ownable and OwnableRoles access control. Designed for protocol upgrades behind a delay — typical use is wrapping admin actions on a smart wallet so a leaked admin key cannot drain funds instantly.
Refactored: accounts/ERC4337.sol, accounts/ERC4337Factory.sol
The 4337 stack was rewritten to align with the EntryPoint v0.7 changes that landed alongside Pectra. Notable:
- Validation logic now distinguishes between validation-time and execution-time storage access strictly (a 4337 v0.7 requirement to prevent simulation/execution divergence).
- Paymaster validation is more constrained — paymasters that wrote to storage during validation in 0.0.x may now revert simulation. This is a feature, not a bug.
- The factory's
createAccount(salt, owner)is unchanged but the deployed account's storage layout shifted, so factories must use a fresh salt namespace.
New: auth/EnumerableRoles.sol, auth/TimedRoles.sol
Two new access-control variants:
- EnumerableRoles — adds
getRoleMembers()andgetRoleMemberCount(), useful for protocols that want to display role assignments without walking events. - TimedRoles — roles that automatically expire after a deadline. Particularly relevant for session-key patterns where a key should grant limited authority for a finite window.
New: utils/ReentrancyGuardTransient.sol
EIP-1153 transient-storage version of the standard reentrancy guard. About 90% cheaper than the SLOAD/SSTORE-based original on chains that support transient storage.
New: utils/MerkleTreeLib.sol, utils/EfficientHashLib.sol
Hardened against the most common merkle-proof footguns (leaf malleability, length-extension on concatenated proofs). If your protocol uses Merkle proofs for airdrops, allowlists, or commitment schemes, the new library is worth migrating to.
The Three Security Pitfalls in Migrating
1. EIP-7702 Replay Across Chains
EIP-7702 authorizations include the chain ID by design — but the delegate target is a contract address, and contract addresses can be reused across chains via CREATE2. If an attacker deploys a malicious contract at the same address on a different chain and tricks a user into authorizing the same delegate there, they can execute arbitrary logic against that user's EOA on the attacker's chain.
Defense: never reuse a delegate target address across chains. Solady's EIP7702Proxy.sol is deployed at a chain-specific address by design; verify this if you are integrating it into a wallet.
2. Initialization Front-Run on Newly-Delegated EOAs
When an EOA delegates to a proxy via EIP-7702, the first transaction that interacts with the delegated code typically runs the proxy's initialize() function. An attacker watching the mempool can front-run that transaction, calling initialize() first with their own parameters (their owner address, their session keys).
Defense: bundle the delegation and the initialization in a single atomic transaction. Solady 0.1.x's proxy supports this pattern. Any wallet implementation that does not — or that allows initialization in a separate later transaction — has a front-running window.
3. ERC-4337 Validation/Execution Divergence
EntryPoint v0.7 enforces strict separation: a UserOp is simulated for validation, then executed. If the storage state read during validation differs from execution (e.g., a storage slot changes in between), the bundler can be slashed. Solady 0.1.x's account contracts are correct under v0.7 — but custom paymasters or wallets built on top need to be re-audited for this property if they were written for v0.6.
Defense: when migrating any 4337 contract from v0.6 to v0.7, audit every _validateUserOp for storage reads that could change between validation and execution. Move state-mutating logic to execute only.
Integration Notes for Auditors
For security teams reviewing a contract that imports Solady 0.1.x:
- Confirm the version pin.
package.jsonshould pin to0.1.x(or a specific commit SHA). A^0.1.0range will silently pull in newer minors with new features. - Check the import paths.
accounts/Receiver.sol,tokens/ERC20.sol, andutils/SafeTransferLib.solall received non-trivial changes between 0.0.182 and 0.1.26. If the audited code references functions that were renamed or moved, those references must be updated. - Look for transient-storage assumptions. If the project uses
ReentrancyGuardTransient, verify the deployment chain supports EIP-1153. Deploying to a chain without transient storage support will silently break reentrancy protection. - Verify EIP-7702 delegate addresses. If the project provides a delegate proxy, the address should be deterministic, the same across all chains the project targets, or clearly differentiated per chain to prevent cross-chain replay.
How ContractScan Handles Solady-Based Contracts
ContractScan's pre-flight check now detects Solady imports and informs the AI patch generator that Solady's conventions (SafeTransferLib, OwnableRoles, EnumerableRoles) should be preferred over OpenZeppelin equivalents in any patch suggestions. The vendored Solady inside our scanner is kept on 0.1.x to ensure that imports referencing newer files (EIP7702Proxy.sol, ERC7821.sol, MerkleTreeLib.sol) resolve cleanly during the verified-patch compile step.
For a concrete demonstration: paste a Solady 0.1.x contract into contract-scanner.raccoonworld.xyz and the report will explicitly cite Solady's APIs in any suggested fixes, rather than introducing OZ imports the contract does not have.
When to Migrate, When to Hold
If your project:
- Builds wallets or paymasters — migrate to 0.1.x. The 4337 v0.7 alignment alone is mandatory for any new deployment, and EIP-7702 support is rapidly becoming table stakes for AA UX.
- Uses Solady utility libraries (
SafeTransferLib,LibBitmap,FixedPointMathLib) — migrate at next dependency-bump cycle. Most utility APIs are unchanged but the gas micro-optimizations are real. - Pins to 0.0.x for a deployed-and-frozen contract — hold. Re-deploying a stable contract just for a Solady bump is rarely justified.
For teams starting fresh in 2026, there is no reason not to start on 0.1.x.
Related: ERC-4337 Account Abstraction Security: Bundler and Paymaster Vulnerabilities — the broader 4337 attack surface, including v0.7 changes.
Related: Verified Patch Generation: Why AI-Suggested Solidity Fixes Fail to Compile — how stack-aware patch generation handles Solady-vs-OZ choice automatically.
Important Notes
This post is for informational and educational purposes only. It does not constitute financial, legal, or investment advice. EIP-7702 is a relatively new mechanism — patterns and best practices are still being established by the wider community. Always conduct a professional audit before deploying production AA infrastructure, especially anything involving cross-chain delegation or paymaster sponsorship.