Skip to content

0x-minato/EIP---7702

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EIP-7702 Delegated Execution PoC

This repository is a Foundry-based proof of concept showing how an Externally Owned Account (EOA) can execute delegated smart-account-style logic using EIP-7702-like transaction authorization tooling.

The demo focuses on two flows:

  • Direct authority flow: the authority EOA sends the transaction itself (scripts/run-poc.sh)
  • Relayer flow: a relayer pays gas and submits transactions signed by the authority (scripts/run-relayer-poc.sh)

What This PoC Demonstrates

At a high level:

  1. Deploy a delegated implementation contract (DelegateContractV2)
  2. Deploy a target app contract (Counter)
  3. Execute logic at the authority EOA address with delegated code via --auth
  4. Initialize guardian state in delegated storage
  5. Execute a guardian-authorized call that increments Counter.number
  6. Verify that state changed as expected

The relayer version extends this by separating:

  • Authority (signs delegation auth)
  • Relayer (submits transaction and pays gas)

How This Provides Account Abstraction

This PoC gives an EOA account-abstraction-like behavior by moving validation and execution policy into delegated contract logic while preserving the same EOA identity.

Why this qualifies as AA behavior:

  • Intent-based control: actions are authorized through delegated logic rather than plain EOA transfer semantics.
  • Programmable policy: guardian checks in DelegateContractV2 decide who can execute calls.
  • Batched programmable execution: executeGuardian(Call[]) can run one or many target calls from policy logic.
  • Gas abstraction path: in relayer mode, the relayer submits and pays gas while authority still controls delegation approval.
  • Stable identity: dApps still see the same authority address (ALICE) as the calling account context.

In short, the EOA keeps its address, but gains smart-account-like execution rules through EIP-7702 authorization + delegated code.

Account Abstraction Flow Diagram

sequenceDiagram
    autonumber
    participant A as Authority EOA (Alice)
    participant R as Relayer (optional)
    participant C as Ethereum Client
    participant D as Delegated Logic (DelegateContractV2)
    participant T as Target dApp (Counter)

    A->>C: Sign 7702 authorization for implementation
    Note over A,R: In direct flow, Alice is sender.\nIn relayer flow, relayer is sender.
    R->>C: Submit tx to ALICE with --auth (or Alice submits directly)
    C->>D: Execute delegated code in authority account context
    D->>D: Validate policy (guardian/authorization checks)
    D->>T: call increment() via executeGuardian(Call[])
    T-->>D: State updated (number += 1)
    D-->>C: Return success
    C-->>R: Tx confirmed (gas paid by tx sender)
Loading

Repository Layout

  • src/delegate.sol: delegated account-style logic (DelegateContractV2)
  • src/Counter.sol: simple target contract with increment()
  • scripts/run-poc.sh: end-to-end direct authority flow
  • scripts/run-relayer-poc.sh: relayer-submitted flow
  • test/Counter.t.sol: tests for a related 7702 account pattern (signature, replay, expiry checks)
  • EIP7702_EOA_AA_DEEP_DIVE.md: conceptual deep dive document

Prerequisites

Install:

  • Foundry (forge, cast, anvil)
  • Bash shell (Git Bash/WSL on Windows, or native on Linux/macOS)

Confirm tools:

forge --version
cast --version
anvil --version

Environment Variables

Both scripts support environment overrides. Defaults target the first Anvil accounts.

  • RPC_URL (default: http://127.0.0.1:8545)
  • ALICE (authority address)
  • ALICE_PK (authority private key)
  • RELAYER (relayer address, relayer script only)
  • RELAYER_PK (relayer private key, relayer script only)
  • IMPL (implementation address, relayer script required)
  • COUNTER (counter address, relayer script required)

Process 1: Direct Authority Flow (run-poc.sh)

This script performs a complete deployment and execution cycle.

Step-by-step behavior

  1. RPC health check
    • cast chain-id verifies chain connectivity
  2. Compile contracts
    • forge build
  3. Deploy delegated implementation
    • Deploy DelegateContractV2 and parse Deployed to: output
  4. Deploy target contract
    • Deploy Counter and parse Deployed to: output
  5. Initialize delegated storage at authority address
    • Calls initialize(address[]) on ALICE using:
      • --auth "$IMPL" (delegation target)
      • --private-key "$ALICE_PK" (authority submits transaction)
    • Initializes guardians with [ALICE]
  6. Prepare calldata
    • Encodes increment() call bytes
  7. Execute through delegated logic
    • Calls executeGuardian((bytes,address,uint256)[]) on ALICE
    • Executes one call tuple: (incrementCalldata, COUNTER, 0)
  8. Verify result
    • Reads Counter.number and prints it

Run it

Terminal 1:

anvil

Terminal 2 (repo root):

bash scripts/run-poc.sh

Expected result:

  • Script prints deployed implementation and counter addresses
  • Counter.number = 1
  • POC complete.

Process 2: Relayer-Sponsored Flow (run-relayer-poc.sh)

This script demonstrates authority/relayer separation.

Important prerequisite

Unlike run-poc.sh, this script does not deploy contracts. It expects:

  • IMPL to already point to a deployed DelegateContractV2
  • COUNTER to already point to a deployed Counter

Because the script uses set -u, missing IMPL or COUNTER causes an immediate failure.

Step-by-step behavior

  1. RPC health check
    • cast chain-id
  2. Create authority-signed auth for initialization
    • cast wallet sign-auth "$IMPL" signed by ALICE_PK
  3. Relayer submits initialize transaction
    • Relayer calls initialize(address[]) on ALICE
    • Uses --auth "$AUTH_INIT" and --private-key "$RELAYER_PK"
    • Initializes guardians as [ALICE, RELAYER]
  4. Prepare target calldata
    • Encodes increment()
  5. Create fresh authority-signed auth for execution
    • New auth generated via cast wallet sign-auth
  6. Relayer submits execution transaction
    • Calls executeGuardian((bytes,address,uint256)[]) on ALICE
    • Executes call on COUNTER
  7. Verify result
    • Reads and prints Counter.number

Run it

Option A: deploy first using run-poc.sh, then reuse addresses manually.

export IMPL=<deployed_delegate_address>
export COUNTER=<deployed_counter_address>
bash scripts/run-relayer-poc.sh

Expected result:

  • Counter.number = 1 (or increments from current value)
  • Relayer POC complete.

Contract Logic Explained

DelegateContractV2 (src/delegate.sol)

Key elements:

  • initialize(address[] memory newGuardians)
    • One-time initializer (init guard)
    • Marks each provided address as guardian
  • execute(Call[] calldata calls)
    • Only callable by address(this) (self-call pattern)
  • executeGuardian(Call[] calldata calls)
    • Callable by any address marked as guardian
  • _execute(Call[] calldata calls)
    • Iterates over call list and performs low-level external calls

Call struct:

  • bytes data
  • address to
  • uint256 value

Counter (src/Counter.sol)

Simple state target:

  • number starts at 0
  • increment() adds 1
  • Emits Incremented(caller, newValue)

Typical End-to-End Session

  1. Start local chain (anvil)
  2. Run direct PoC (bash scripts/run-poc.sh)
  3. Capture IMPL and COUNTER from output
  4. Export captured values
  5. Run relayer PoC (bash scripts/run-relayer-poc.sh)
  6. Confirm Counter.number progressed as expected

Troubleshooting

  • Failed to parse ... deployment address
    • forge create output format changed or deployment failed
    • Re-run with verbose output by removing redirects
  • variable IMPL/COUNTER not set or unbound variable
    • Export IMPL and COUNTER before relayer script
  • Unauthorized() revert
    • Caller is not in guardians
    • Ensure initialization succeeded and includes expected guardian(s)
  • RPC connection errors
    • Ensure anvil is running
    • Verify RPC_URL
  • No state change in counter
    • Validate target COUNTER address and calldata encoding

Security Notes

This repository is a demonstration, not production wallet logic. Before real-world use, at minimum consider:

  • strict signature validation and domain separation
  • replay/nonce model hardening
  • relayer trust and fee policy
  • call allowlists and spend limits
  • comprehensive invariant/unit/fuzz testing
  • independent security audit

Additional Reading

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages