ByAUJay
Summary: Scaling smart accounts isn’t only about throughput; it’s about control planes that keep costs predictable and abuse contained. This guide shows how to design rate limits, quotas, and guardrails across the ERC‑4337 stack (accounts, paymasters, bundlers, and mempools) with concrete settings, code patterns, and the latest protocol updates like ERC‑7562, shared mempools, and EIP‑7702.
Smart Accounts at Scale: Rate Limiting, Quotas, and Abuse Prevention
Decision-makers increasingly ask one question once pilot AA experiences go live: how do we keep this reliable and affordable at 10–100x traffic without getting griefed? In 2024–2025, the ecosystem quietly shipped the primitives you need: a formal validation/rate‑limit rulebook for mempools (ERC‑7562), shared mempool rollout, clearer EntryPoint versioning, and EOA upgrades via EIP‑7702. This post compresses what matters into a deployable playbook with parameters you can adopt today. (docs.erc4337.io)
What “abuse” looks like in AA
Abuse vectors in account abstraction differ from EOAs because validation is programmable:
- Gas griefing: craft user operations (UserOps) that are cheap to simulate but fail in‑bundle, burning bundler gas or paymaster deposits. (docs.erc4337.io)
- Sponsorship drain: trick or brute‑force a paymaster into sponsoring unintended calls, or spam many failing ops to chip away at deposits. (docs.erc4337.io)
- Mempool DoS: flood alt/AA mempools with costly-to-validate ops or repeat the same “valid‑until‑first” ticket to waste bundler cycles. (ethereum-magicians.org)
- Signature/packing pitfalls: inconsistencies in how userOps are hashed or verified allow re‑targeting previously issued sponsorships. Historical incidents show this class of bug. (alchemy.com)
Your controls must live at four layers: smart account, paymaster, bundler, and mempool/network. The sections below give precise settings and example policies for each.
The mempool rulebook you should lean on (ERC‑7562)
ERC‑7562 is the industry’s canonical set of validation and mempool rules designed to keep AA permissionless while bounding griefing. Two big takeaways:
- Reputation‑based throttling for unstaked entities.
- A precise list of banned/restricted opcodes and resource limits during validation.
Key defaults you can treat as “sane global limits” when planning capacity:
- SAME_SENDER_MEMPOOL_COUNT = 4 (max userOps per sender in mempool).
- SAME_UNSTAKED_ENTITY_MEMPOOL_COUNT = 10 (per unstaked paymaster/factory/aggregator).
- THROTTLED_ENTITY_MEMPOOL_COUNT = 4 (and THROTTLED_ENTITY_BUNDLE_COUNT = 4).
- MAX_USEROP_SIZE = 8192 bytes; MAX_CONTEXT_SIZE = 2048 bytes; MAX_VERIFICATION_GAS = 500,000.
- Reputation math uses opsSeen/opsIncluded with MIN_INCLUSION_RATE_DENOMINATOR (10 for bundlers), and slack values (THROTTLING_SLACK=10, BAN_SLACK=50). (eips.ethereum.org)
During validation, bundlers must reject non‑deterministic or state‑mutating behavior (e.g., BLOCKHASH, TIMESTAMP, NUMBER, SELFDESTRUCT) and enforce specific exceptions only for staked entities. This stops “validate‑passes‑off‑chain, reverts‑on‑chain” griefs. (ercs.ethereum.org)
What this means for you:
- If you run infra, configure your bundler to enforce ERC‑7562 as‑is; don’t reinvent limits.
- If you write accounts, factories, or paymasters, ensure your validate functions never touch banned opcodes, and keep external calls or shared state behind staking. (docs.erc4337.io)
Shared mempool is now the default posture
Until late 2024, many AA stacks relied on private queues; censorship resistance and redundancy were weak. The shared mempool is live on Ethereum, Optimism, and Arbitrum, with Polygon integration progressing—meaning your UserOps can propagate across multiple bundlers by default. This reduces single‑provider risk and helps honest inclusion. (docs.erc4337.io)
Design implications:
- Always integrate at least two bundler endpoints that participate in shared mempool.
- Implement resubmission with jitter if an op isn’t picked up within your SLO.
- Monitor “ops included by others” vs “ops seen by us” to detect censorship. (docs.erc4337.io)
Bundlers: practical rate limiting and observability
You can buy capacity (e.g., Alchemy’s Rundler) or run your own. Either way, get concrete:
- EntryPoint support and addresses: v0.7 is the current default; providers still support v0.6, with stated plans to deprecate in 2026. EntryPoint v0.7 address: 0x0000000071727De22E5E9d8BAf0edAc6f37da032; v0.6 address: 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789. (alchemy.com)
- RPC surface: eth_sendUserOperation, eth_estimateUserOperationGas, eth_getUserOperationReceipt, eth_supportedEntryPoints; some providers expose rundler_maxPriorityFeePerGas to guide fees. (alchemy.com)
- Proven implementation: Rundler (Rust) is open‑source, optimized for cloud, and tracks P2P/shared‑mempool support. (github.com)
- Monitoring: track ingress rate, validation pass/fail classes (signature vs paymaster vs initCode), bundle size/latency, and simulation‑vs‑execution gas deltas. Alert on spikes in rejects or deviation in gas usage. (docs.erc4337.io)
Operational quotas to set day one (map to ERC‑7562 where possible):
- Per‑sender inflight cap: 4 (align with SAME_SENDER_MEMPOOL_COUNT).
- Per‑paymaster inflight cap when unstaked: 10; when throttled: 4; auto‑evict after THROTTLED_ENTITY_LIVE_BLOCKS=10. (eips.ethereum.org)
- Replace‑by‑fee semantics: accept replacement only if priority fee increases sufficiently; reject low‑tip spam at ingress. (erc4337.io)
- Debug/forensics: expose debug_bundler_dumpReputation to inspect opsSeen/opsIncluded/status, and integrate into your on‑call runbooks. (ercs.eips.fyi)
Provider‑side limits matter too. Example: Pimlico’s published limits show how infra vendors meter API credits and requests/min; budget your peak campaign traffic accordingly or BYO bundler. (docs.pimlico.io)
Paymasters: the quota engine for product and cost control
Paymasters unlock gasless UX but become the “wallet of last resort.” Treat them like payment infrastructure with strict quotas.
Security baseline:
- Stake and deposit requirements are enforced by EntryPoint; misbehavior can be slashed. Keep validation deterministic, bounded, and simulatable. Use postOp for accounting only. (docs.erc4337.io)
Quota patterns we deploy for clients:
- Per‑user/day budgets (off‑chain ledger, on‑chain enforcement)
- Validation checks an off‑chain quota server for “remaining units” keyed by user identity.
- Identity = SIWE session (EIP‑4361), account address, or a signed nonce tied to a device. (eips.ethereum.org)
- Return context bytes that your postOp consumes to decrement quota atomically after success only. Respect MAX_CONTEXT_SIZE=2048. (eips.ethereum.org)
- Tiered sponsorship caps
- Free tier: 3 ops/day, max callGasLimit 250k, max value=0.
- Verified tier: 20 ops/day, per‑op gas cap 800k, allow specific contract allowlist.
- Enterprise: negotiated cap keyed to a “customer ID” in context, with rate of 10 ops/min burst, 1000/day. Encode limits in signed “tickets” with short expiry.
- Risk‑adjusted gas ceilings
- Hard cap verificationGasLimit and paymasterVerificationGasLimit; reject if estimates + VALIDATION_GAS_SLACK may overflow your budget. (eips.ethereum.org)
- Cap preVerificationGas to protect bundlers from oversized calldata; your fuel for data‑heavy signatures belongs in an aggregator (see below). (erc4337.io)
- Post‑op backpressure
- If failure rates > X% over last Y minutes, downgrade users to “free tier” or temporarily disable sponsorship for specific destinations. Implement rolling counters server‑side; keep postOp work gas‑lean. (docs.erc4337.io)
Practical format tips:
- v0.7 packed userOps support a dedicated paymaster signature path that lets the account and paymaster sign in parallel; use the PAYMASTER_SIG_MAGIC layout for predictable parsing and sizing. (docs.erc4337.io)
Known pitfalls:
- Historical packing/encoding issues in verifying paymasters led to signature re‑targeting risks; use current templates from reputable libraries and verify hash domains rigorously. (alchemy.com)
Smart accounts: rate limits “at the edge”
Move some throttling to accounts to reduce dependency on off‑chain checks:
- Nonce channels for parallel policies: ERC‑4337’s nonce is “keyed” (192‑bit key + 64‑bit sequence). Use one key for “admin/guardians,” another for “retail ops,” allowing independent sequencing and quota logic. Example: reject admin ops unless nonce key == ADMIN_KEY, while retail uses key 0. (eip.info)
- Module standards: ERC‑6900 and ERC‑7579 let you install validators/hooks as plug‑ins—e.g., a rate‑limit hook that enforces a per‑day cap per session key, and a pre‑execution allowlist. OpenZeppelin Contracts v5.2 ships utilities for ERC‑4337/7579 to accelerate secure implementations. (eips.ethereum.org)
- Signature aggregation: where signatures dominate calldata costs, adopt an aggregator per ERC‑7766 to validate batched signatures once, saving gas and reducing bandwidth pressure. Bundlers whitelist supported aggregators; keep them staked for shared‑state access during validation. (eips.ethereum.org)
Passkeys and device‑bound keys: L2s widely adopted the secp256r1 precompile (RIP‑7212) and Ethereum L1 is standardizing EIP‑7951. This cuts validation gas for passkey signatures from ~180–350k to a few thousand gas, making per‑user quota checks financially viable at scale. Plan for 3.45k gas on many L2s and ~6.9k gas on L1 with EIP‑7951. (eco.com)
EIP‑7702 “smart EOAs”: what changes for rate limiting
EIP‑7702 lets an EOA set code via a new transaction type with an authorization list, effectively behaving like a smart account until updated. Two relevant abuse‑prevention rules are already wired into 7562 mempool guards:
- Only one authorization tuple per UserOp; and only the authorized account can be the sender in that UserOp.
- If multiple UserOps for the same sender carry a 7702 authorization, they must all target the same delegate address. (eips.ethereum.org)
If you onboard users via 7702, keep your bundler on a shared mempool and preserve the same per‑sender/entity quotas; the same 7562 caps and reputation math apply. (docs.erc4337.io)
Reconciling EntryPoint versions and mempool limits
Teams often discover conflicting “how many ops per sender” rules across docs. Older bundler docs suggested “one per sender in pool,” while ERC‑7562 formalized a default of 4 per sender, with reputation controls for entities. In practice:
- Target EntryPoint v0.7 (v0.6 is supported, but migration is encouraged) and adopt the 7562 limits across your infra. Providers publicly document v0.7 support and deprecation intent for v0.6 in 2026. (alchemy.com)
Observability that actually catches abuse early
Track these, and auto‑escalate to throttling:
- Ingress rate by source (IP/apiKey) and by entity (sender, paymaster, factory).
- Validation failure classes: signature, nonce, banned opcode, paymaster, initCode.
- opsSeen vs opsIncluded, per entity and per alt‑mempool; alert when opsSeen grows faster than included (reputation will drop; you’ll throttle soon). (docs.erc4337.io)
- Simulated vs actual gas (verification and execution); alert on drift > N%. (docs.erc4337.io)
A reference “free-to-paid” policy that holds up under load
If you’re launching consumer UX with gas sponsorship:
-
Phase 0 (open beta)
- Shared mempool providers A+B.
- Paymaster: free 3 ops/day per account; callGasLimit ≤ 250k; destination allowlist only; per‑IP 30 RPM.
- Bundler: SAME_SENDER_MEMPOOL_COUNT=4; SAME_UNSTAKED_ENTITY_MEMPOOL_COUNT=10; reject userOps > 6kB; MAX_VERIFICATION_GAS=400k. (eips.ethereum.org)
-
Phase 1 (growth)
- SIWE‑gated verified tier: 20 ops/day; callGasLimit ≤ 800k; ERC‑20 approvals blocked; specific DEX paths denied in validation.
- Adopt signature aggregation for hot paths to reduce calldata cost. (eips.ethereum.org)
- Introduce “sponsorship tickets” expiring in 5 minutes; tie to nonce keys to prevent replay across parallel lanes. (eip.info)
-
Phase 2 (enterprise)
- Customer‑specific contexts with contractual quotas (ops/min, ops/day, total gas/month) enforced in paymaster validation and logged in postOp.
- Dedicated bundler instances or BYO Rundler with higher RPM; audit logs via debug_bundler_dumpReputation hourly to catch deterioration before users feel it. (github.com)
Future‑proofing: native AA on rollups
RIP‑7560 (native AA) and its mempool/nonce companions (RIP‑7711/7712) map the same rate‑limiting ideas into protocol‑level transactions. Your quotas and policies above port cleanly: reputation, nonces with keys, and shared mempool semantics continue—only the transport changes. Build modularly (ERC‑6900/7579) so your validators and hooks carry over. (rip7560.com)
Security notes you should bake into reviews
- Enforce “onlyEntryPoint” style checks in accounts. A 2023 UniPass incident showed swapping trusted EntryPoint can be catastrophic; ensure hard‑coded EntryPoint checks. (fireblocks.com)
- Validate paymaster signing domains meticulously; packing errors can enable re‑targeted sponsorships. Use audited libraries and current templates. (alchemy.com)
- Keep validation free of banned opcodes and mutable shared state unless staked; use bundler simulation + trace classification to drop risky ops pre‑inclusion. (ercs.ethereum.org)
Implementation snippets (sketches)
A minimal verifying paymaster flow with quotas:
// Pseudocode sketch — align with ERC-4337 v0.7 PackedUserOperation function validatePaymasterUserOp( PackedUserOperation calldata uo, bytes32 uoHash, uint256 maxCost ) external returns (bytes memory ctx, uint256 validationData) { // 1) Parse contextTicket signed by backend: {account, tier, expiry, maxGas, quotaRemaining, nonce} Ticket memory t = verifyTicket(uo.paymasterAndData, uoHash); // ECDSA over fixed domain // 2) Hard caps require(uo.callGasLimit <= t.maxGas, "cap"); require(block.timestamp <= t.expiry, "expired"); // 3) Check quota off-chain via signed counter embedded in ticket, // or via read-only call to staked registry (if using staked shared state). require(t.quotaRemaining > 0, "quota"); // 4) Return compact context to decrement on success only ctx = abi.encode(t.account, t.nonce, t.tier); return (ctx, 0); // 0 = valid signature; pack signature per v0.7 paymasterSig format off-chain } function postOp(PostOpMode mode, bytes calldata ctx, uint256 actualCost, uint256 actualPriorityFee) external { (address account, uint64 nonce, Tier tier) = abi.decode(ctx, (address, uint64, Tier)); if (mode == PostOpMode.opSucceeded) { // emit event for off-chain quota decrement or update staked registry emit Consumed(account, nonce, tier, actualCost); } }
This pattern keeps validation deterministic and bounded, uses postOp for accounting, and enforces gas caps before the call—aligned with 7562. (docs.erc4337.io)
Executive checklist
- Adopt ERC‑7562 limits in your bundler and paymaster configs; don’t loosen them without reason. (eips.ethereum.org)
- Use at least two shared‑mempool participants; alert on inclusion latency and opsSeen/opsIncluded drift. (docs.erc4337.io)
- Budget provider RPM/credits (or deploy Rundler) for product launches; avoid single choke points. (docs.pimlico.io)
- Modularize rate‑limit logic via ERC‑6900/7579 validators/hooks; prefer aggregated signatures for hot flows. (eips.ethereum.org)
- If you embrace passkeys, leverage secp256r1 precompiles (L2 today; EIP‑7951 for L1) to keep verification cheap under quota. (eco.com)
- Plan for 7702 users: enforce the authorization tuple rules in CI tests; treat them like smart accounts for quotas. (eips.ethereum.org)
Where 7Block Labs can help
- Capacity planning and SLOs for your AA traffic, with ERC‑7562‑aligned configs.
- Multi‑tenant paymaster designs with contractual quotas and finance reporting.
- Bundler deployment/hardening (Rundler) with shared‑mempool peering and dashboards.
- Module development under ERC‑6900/7579, including rate‑limit and risk hooks.
Scaling smart accounts is a control‑plane problem, not just a throughput problem. With the above defaults and patterns, you can ship delightful UX without handing attackers your gas card.
References: ERC‑4337/7562/EIP‑7702 specs and docs, provider docs, and ecosystem releases cited inline. (docs.erc4337.io)
Like what you're reading? Let's build together.
Get a free 30‑minute consultation with our engineering team.

