ERC-8000: Operator contract for non delegated EOAs

Allowing operating batch executions on behalf of non delegated EOAs


Metadata
Status: DraftStandards Track: ERCCreated: 2025-07-02
Authors
Marcelo Morgado (@marcelomorgado), Manoj Patidar (@patidarmanoj10)

Abstract


This standard defines a contract interface that enables externally owned accounts (EOAs) to perform batch call executions via a standard Operator contract, without requiring them to delegate control or convert into smart contract accounts.

Motivation


The ERC-7702 allows EOAs to become powerful smart contract accounts (SCA), which solves many UX issues, like the double approve + transferFrom transactions.
While this new technology is still reaching wider adoption over time, we need a way to improve UX for the users that decide to not have code attached to their EOAs.
This proposal introduces a lightweight, backward-compatible mechanism to enhance UX for such users. By leveraging a standardized Operator contract, EOAs can batch multiple contract calls into a single transaction—assuming the target contracts are compatible (i.e., implement the Operated pattern).

Specification


The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

Definitions

  • Operator: The contract that executes calls on the sender's behalf.
  • Operated: The contract that supports calls through the Operator.

It's OPTIONAL but HIGHLY RECOMMENDED to have the Operator contract as a singleton.

Operator


Methods

execute Execute the calls sent by the actual sender.

MUST revert if any of the calls fail.
MUST return data from the calls.

onBehalfOf Used by the target contract to get the actual caller.

MUST return the actual msg.sender when called in the context of a call.
MUST revert when called outside of the context of a call.

Operated


Any contract can become compatible to execute the batch call by EOA using operator if it extends the Operated contract. The Operated contract overrides _msgSender() to return operator.onBehalfOf() when the call originates from the Operator. This ensures that the target contract recognizes the EOA initiating the batch execution, preserving correct sender context.

This behavior fits well with the usage of the _msgSender() function from ERC-2771.

Methods

_msgSender Returns msg.sender or operator.onBehalfOf()

Rationale


By having a trusted contract (Operator) that may act on behalf of the EOA wallet, this ERC provides batch call capabilities and keeps the EOA as the caller of the target contracts.

Backwards Compatibility


The main limitation of this ERC is that only contracts that implements the Operated logic will be able to receive calls through the Operator.

Reference Implementation


Operator


Worth noting that the usage of transient storage (EIP-1153) for storing the msg.sender is highly RECOMMENDED.

Operated


Security Considerations


  • The execute function MUST implement reentracy control to avoid having a callback call overriding the sender's storage.
  • The Operated contract MUST interact with a trusted Operator contract.

Copyright


Copyright and related rights waived via CC0.