ERC-7562 - Account Abstraction Validation Scope Rules

Created 2023-09-01
Status Draft
Category ERC
Type Standards Track
Authors

Abstract

This document describes the rules Account Abstraction protocols should follow, during the validation phase of Account Abstraction transactions, such as ERC-4337 UserOperation or RIP-7560 (Native Account Abstraction), which are enforced off-chain by a block builder or a standalone bundler, and the rationale behind each one of them.

Motivation

With Account-Abstraction, instead of hard-coded logic for processing a transaction (validation, gas-payment, and execution), this logic is executed by EVM code. The benefits for the account are countless - - abstracting the validation allows the contract to use different signature schemes, multisig configuration, custom recovery, and more. - abstracting gas payments allows easy onboarding by 3rd party payments, paying with tokens, cross-chain gas payments - abstracting execution allows batch transactions

All of the above are missing from the EOA account model.

However, there is one rule a transaction must follow to preserve the decentralized network: once submitted into the network (the mempool), the transaction is guaranteed to pay. This comes to prevent denial-of-service attacks on the network.

The EOA model implicitly follows the rule: a valid transaction can't become invalid without payment by the account: e.g. account balance can't be reduced (except with a higher paying transaction)

This rule makes the network sustainable and DoS-protected: the network can't be cheaply attacked by a mass of transactions. An attack (sending a mass of transactions) is expensive, and gets more expensive as the network clogs. Legitimate users pay more, and can delay operations to avoid the cost, but the attacker pays a huge (and increasing) amount to keep the network clogged.

To mimic the same incentive structure in any Account Abstraction system, we suggest the following transaction validation rules. These validation rules only apply to the validation phase of Account Abstraction transactions, not their entire executed code path.

For the actual interfaces of those contract-based accounts see the definitions in ERC-4337 and RIP-7560.

This documentation uses the terminology "UserOperation" for a transaction created by a smart contract account, and closely follows ERC-4337 terminology. However, the rules apply to any Account Abstraction framework that uses EVM code to perform transaction validation and makes a distinction between validation (whether the operation is eligible for inclusion on the protocol level) and execution (on-chain execution and gas payment) in a public mempool.

Specification

Validation Rules Types

We define two types of validation rules: network-wide rules and local rules.

A violation of any validation rule by a UserOperation results in the UserOperation being dropped from the mempool and excluded from a bundle.

Network-wide rule is a rule, that its violation by a UserOperation validation should result in a reputation damage for the peer bundler that sent this UserOperation in the p2p mempool. A peer bundler with a critically low reputation will eventually be marked as a malicious spammer peer.

Local rule is a rule that is enforced in the context of each bundler's local state, which may be different for each bundler and different bundlers may not always be in agreement on these rules' violations. Thus, The bundler that sent the violating UserOperation should not suffer a p2p reputation damage by its peers.

Constants

Title Value Comment
MIN_UNSTAKE_DELAY 86400 1 day, which provides a sufficient withdrawal delay to prevent most sybil attacks
MIN_STAKE_VALUE Adjustable per chain value Equivalent to ~$1000 in native tokens, which provides a sufficient capital requirement to prevent most sybil attacks
SAME_SENDER_MEMPOOL_COUNT 4 Maximum number of allowed userops in the mempool from a single sender.
SAME_UNSTAKED_ENTITY_MEMPOOL_COUNT 10 Maximum number allowed in the mempool of UserOperations referencing the same unstaked entity
THROTTLED_ENTITY_MEMPOOL_COUNT 4 Number of UserOperations with a throttled entity that can stay in the mempool
THROTTLED_ENTITY_LIVE_BLOCKS 10 Number of blocks a UserOperations with a throttled entity can stay in mempool
THROTTLED_ENTITY_BUNDLE_COUNT 4 Number of UserOperations with a throttled entity that can be added in a single bundle
MIN_INCLUSION_RATE_DENOMINATOR 100 (client) \ 10 (bundler) A denominator of a formula for entity reputation calculation
THROTTLING_SLACK 10 Part of a reputation formula that allows entities to legitimately reject some transactions without being throttled
BAN_SLACK 50 Part of a reputation formula that allows throttled entities to reject some transactions without being throttled
BAN_OPS_SEEN_PENALTY 10000 A value to put into the opsSeen counter of entity to declare as banned
MAX_OPS_ALLOWED_UNSTAKED_ENTITY 10000
PRE_VERIFICATION_OVERHEAD_GAS 50000 Gas used by the EntryPoint per UserOp that cannot be tracked on-chain
MAX_VERIFICATION_GAS 500000 Maximum gas verification functions may use
MAX_USEROP_SIZE 8192 Maximum size of a single packed and ABI-encoded UserOperation in bytes
MAX_CONTEXT_SIZE 2048 Maximum size of a context byte array returned by a paymaster in a single UserOperation in bytes
MAX_BUNDLE_SIZE 262144 Maximum size of an ABI-encoded bundle call to the handleOps function in bytes
MAX_BUNDLE_CONTEXT_SIZE 65536 Maximum total size of all context byte arrays returned by all paymasters in all UserOperations in a bundle in bytes
VALIDATION_GAS_SLACK 4000 An amount of gas that must be added to the estimations of verificationGasLimit and paymasterVerificationGasLimit

Validation Rules

Definitions:

  1. Validation Phase: there are up to three frames during the validation phase onchain

    1. sender deployment frame (once per account)
    2. sender validation (required)
    3. paymaster validation frame (optional)
  2. Execution Phase: there are up to two frames during the execution phase onchain

  3. sender execution frame (required)
  4. paymaster post-transaction frame (optional)

The validation rules only apply during the validation phase. Once a UserOperation is validated, it is guaranteed to pay. There are no restrictions on execution, neither account (callData) nor paymaster (postOp)

  1. Entity: a contract that is explicitly specified by the UserOperation. Includes the factory, paymaster, aggregator, and staked account, as discussed below. \ Each "validation frame" is attributed to a single entity. \ Entity contracts must have non-empty code on-chain.
  2. Canonical Mempool: The rules defined in this document apply to the main mempool shared by all bundlers on the network.
  3. Staked Entity: an entity that has a locked stake of at least MIN_STAKE_VALUE and an unstake delay of at least MIN_UNSTAKE_DELAY.
  4. Associated storage: a storage slot of any smart contract is considered to be "associated" with address A if:
    1. The slot value is A
    2. The slot value was calculated as keccak(A||x)+n, where x is a bytes32 value, and n is a value in the range 0..128
  5. Using an address: accessing the code of a given address in any way. This can be done by executing *CALL or EXTCODE* opcodes for a given address.
  6. Spammer - a P2P peer bundler that attempts a DoS attack on the mempool by sending other peers with a large number of invalid UserOperations. Bundlers MUST detect and disconnect from such peers, as described in the Mempool Validation Rules section.

Reputation Definitions

  1. opsSeen: a per-entity counter of how many times a unique valid UserOperation referencing this entity was received by this bundler. This includes UserOperation received via incoming RPC calls or through a P2P mempool protocol.

  2. opsIncluded: a per-entity counter of how many times a unique valid UserOperation referencing this entity appeared in an actual included UserOperation. \ Calculation of this value is based on UserOperationEvents and is only counted for UserOperations that were previously counted as opsSeen by this bundler.

  3. Refresh rate: Both of the above values are updated every hour as value = value * 23 // 24 \ Effectively, the value is reduced to 1% after 4 days.
  4. inclusionRate: Ratio of opsIncluded to opsSeen

Reputation Calculation

We define a value max_seen = opsSeen // MIN_INCLUSION_RATE_DENOMINATOR.

The reputation state of each entity is determined as follows:

  1. BANNED: max_seen > opsIncluded + BAN_SLACK
  2. THROTTLED: max_seen > opsIncluded + THROTTLING_SLACK
  3. OK: otherwise

Note that new entities start with an OK reputation.

Because of the reputation refresh rate, note that a malicious paymaster can at most cause the network (only the p2p network, not the blockchain) to process BAN_SLACK * MIN_INCLUSION_RATE_DENOMINATOR / 24 non-paying ops per hour.

Running the Validation Rules

  1. A block builder or a bundler should perform a full validation once before accepting a UserOperation into its mempool, and again before including it in a bundle/block.
  2. The bundler should trace the validation phase of the UserOperation and apply all the rules defined in this document.
  3. A bundler should also perform a full validation of the entire bundle before submission.
  4. The validation rules prevent an unstaked entity from altering its behavior between simulation and execution of the UserOperation. However, a malicious staked entity can detect that it is running in a bundle validation and cause a revert. Thus, a third tracing simulation of the entire bundle should be performed before submission.
  5. The failed UserOperation should be dropped from the bundle.
  6. The bundler should update the reputation of the staked entity that violated the rules, and consider it THROTTLED/BANNED as described below.

Mempool Validation Rules

  1. A UserOperation is broadcast over the P2P protocol with the following information:
    1. The UserOperation itself
    2. The blockhash this UserOperation was originally verified against.
  2. Once a UserOperation is received from another bundler it should be verified locally by a receiving bundler.
  3. A received UserOperation may fail any of the reasonable static checks, such as: invalid format, values below minimum, submitted with a blockhash that isn't recent, etc. In this case, the bundler should drop this particular UserOperation but keep the connection.
  4. The bundler should check the UserOperation against the nonces of last-included bundles and silently drop UserOperations with nonce that was recently included. This invalidation is likely attributable to a network race condition and should not cause a reputation change.
  5. If a received UserOperation fails against the current block:
    1. Retry the validation against the block the UserOperation was originally verified against.
    2. If it succeeds, silently drop the UserOperation and keep the connection.
    3. If it fails, mark the sender as a "spammer" (disconnect from that peer and block it permanently).

Opcode Rules

Code Rules

Storage Rules

The storage access with SLOAD and SSTORE (and TLOAD, TSTORE) instructions within each phase is limited as follows:

Local Rules

Local storage rules protect the bundler against denial of service at the time of bundling. They do not affect mempool propagation and cannot cause a bundler to be marked as a "spammer". * [STO-040] UserOperation may not use an entity address (factory/paymaster/aggregator) that is used as an "account" in another UserOperation in the mempool. \ This means that Paymaster, Factory or Aggregator contracts cannot practically be an "account" contract as well. * [STO-041] UserOperation may not use associated storage (of either its account or from staked entity) in a contract that is a "sender" of another UserOperation in the mempool.

General Reputation Rules

The following reputation rules apply for all staked entities, and for unstaked paymasters. All rules apply to all of these entities unless specified otherwise.

Staked Entities Reputation Rules

Entity-specific Rules

Unstaked Entities Reputation Rules

Alt-mempools Rules

Alternate mempool is an agreed-upon rule that the bundlers may opt into, in addition to the canonical mempool The alt-mempool "topic" is a unique identifier. By convention, this is the IPFS hash of the document describing (in clear test and YAML file) the specifics of this alt mempool.

Alt-mempool Reputation

Alt-mempools are served by the same bundlers participating in the canonical mempool, but change the rules and may introduce denial-of-service attack vectors. To prevent them from taking the canonical mempool or other alt mempools down with them, a reputation is managed for each. An alt mempool that causes too many invalidations gets throttled. This limits the scope of the attack and lets the bundler continue doing its work for other mempools.

Authorizations

Limitations

The validation rules attempt to guarantee a degree of isolation between individual UserOperations' validations. In order to prevent hitting the memory expansion limitations (imposed by ethereum EVM) when creating a bundle, UserOperations must meet the following limitations:

Rationale

All transactions initiated by EOAs have an implicit validation phase where balance, nonce, and signature are checked to be valid for the current state of the Ethereum blockchain. Once the transaction is checked to be valid by a node, only another transaction by the same EOA can modify the Ethereum state in a way that makes the first transaction invalid.

With Account Abstraction, however, the validation can also include an arbitrary EVM code and rely on storage as well, which means that unrelated UserOperations or transactions may invalidate each other.

If not addressed, this would make the job of maintaining a mempool of valid UserOperations and producing valid bundles computationally infeasible and susceptible to DoS attacks.

This document describes a set of validation rules that if applied by a bundler before accepting a UserOperation into the mempool can prevent such attacks.

The high-level goal

The purpose of this specification is to define a consensus between nodes (bundlers or block-builders) when processing incoming UserOperations from an external source. This external source for UserOperations is either an end-user node (via RPC ERC-7769) or another node in the p2p network.

The protocol tries to detect "spam" - which are large bursts of UserOperations that cannot be included on-chain (and thus can't pay). The network is protected by throttling down requests from such spammer nodes.

All nodes in the network must have the same definition of "spam": otherwise, if some nodes accept some type of UserOperations and propagate them while others consider them spam, those "forgiving" nodes will be considered "spammers" by the rest of the nodes, and the network effectively gets split.

The processing flow of a UserOperation

The need for 2nd validation before submitting a block

A normal Ethereum transaction in the mempool can be invalidated if another transaction was received with the same nonce. That other transaction had to increase the gas price in order to replace the first one, so it satisfied the rule of "must pay to get included into the mempool". With contract-based accounts, since the UserOperation validity may depend on mutable state, other transactions may invalidate a previously valid UserOperation, so we must check it before inclusion.

Rationale of limiting opcodes:

Rationale for limiting storage access

Rationale of requiring a stake

We want to be able to allow globally-used contracts (paymasters, factories, aggregators) to use storage not associated with the account, but still prevent them from spamming the mempool. If a contract causes too many UserOperations to fail in their second validation after succeeding in their first, we can throttle its use in the mempool. By requiring such a contract to have a stake, we prevent a "Sybil attack", by making it expensive to create a large number of such paymasters to continue the spam attack.

By following the validation rules, we can detect contracts that cause spam UserOperations, and throttle them. The stake comes to prevent the fast re-creation of malicious entities. The stake is never slashed (since it is only used for off-chain detection) but is locked for a period of time, which makes such an attack much more expensive.

Definition of the mass invalidation attack

A possible set of actions is considered to be a mass invalidation attack on the network if a large number of UserOperations that did pass the initial validation and were accepted by nodes and propagated further into the mempool to other bundlers in the network becomes invalid and not eligible for inclusion in a block.

There are 3 ways to perform such an attack:

  1. Submit UserOperations that pass the initial validation, but later fail the re-validation that is performed during the bundle creation.
  2. Submit UserOperations that are valid in isolation during validation, but when bundled together become invalid.
  3. Submit valid UserOperations but "front-run" them by executing a state change on the network that causes them to become invalid. The "front-run" in question must be economically viable.

To prevent such attacks, we attempt to "sandbox" the validation code. We isolate the validation code from other UserOperations, from external changes to the storage, and from information about the environment such as a current block timestamp.

What is not considered a mass invalidation attack

A UserOperation that fails the initial validation by a receiving node without entering its mempool is not considered an attack. The node is expected to apply web2 security measures and throttle requests based on API key, source IP address, etc. RPC nodes already do that to prevent being spammed with invalid transactions which also have a validation cost. P2P nodes already have (and should apply) a scoring mechanism to determine spammer nodes.

Also, if the invalidation of N UserOperations from the mempool costs N*X with a sufficiently large X, it is not considered an economically viable attack.

Security Considerations

This document describes the security considerations bundlers must take to protect themselves (and the entire mempool network) from denial-of-service attacks.

Copyright

Copyright and related rights waived via CC0.