guotie/simple7702
The simplest way to use EIP-7702. No Paymaster, no Bundler, no complex infrastructure required.
Simple7702
The simplest way to use EIP-7702. No Paymaster, no Bundler, no complex infrastructure required.
Why Simple7702?
Current EIP-7702 solutions are built on top of ERC-4337, requiring a complex stack:
| Component | ERC-4337 Stack | Simple7702 |
|---|---|---|
| Paymaster | ❌ Required | ✅ Not needed |
| Bundler | ❌ Required | ✅ Not needed |
| EntryPoint Contract | ❌ Required | ✅ Not needed |
| UserOp Mempool | ❌ Required | ✅ Not needed |
| Infrastructure Cost | High | Minimal |
| Setup Complexity | High | Low |
Simple7702 strips away the complexity. Just deploy and you're ready to sponsor transactions.
Two Implementations
This project provides two EIP-7702 account implementations:
Simple7702Account
A policy-controlled 7702 delegate with whitelist management for sponsors and targets.
Features:
- ✅ Policy Registry - Control who can sponsor transactions and what contracts can be called
- ✅ Sponsor Whitelist - Restrict who can execute actions on behalf of users
- ✅ Target Whitelist - Restrict what contracts can be called
- ✅ Bitmap Nonces - Allows parallel execution with different nonces
- ✅ EIP-712 Signatures - Human-readable, secure signing
Universal7702Account
A universal, permissionless 7702 delegate that anyone can relay signed actions.
Features:
- ✅ No Registry Required - Single contract deployment, no additional infrastructure
- ✅ Permissionless Execution - Anyone can execute actions on behalf of users
- ✅ Sequential Nonces - Simpler nonce management
- ✅ EIP-712 Signatures - Human-readable, secure signing
- ✅ Lower Gas Cost - No registry checks during execution
Comparison: Simple7702Account vs Universal7702Account
| Feature | Simple7702Account | Universal7702Account |
|---|---|---|
| Registry Required | ✅ Yes | ❌ No |
| Sponsor Whitelist | ✅ Supported | ❌ Not supported |
| Target Whitelist | ✅ Supported | ❌ Not supported |
| Nonce Type | Bitmap (parallel) | Sequential |
| Deployment Complexity | 2 contracts | 1 contract |
| Gas Overhead | Higher (registry checks) | Lower |
| Permission Model | Controlled | Permissionless |
When to Use Simple7702Account
✅ Recommended for:
- Enterprise applications requiring access control
- DApps that need to restrict who can sponsor transactions
- Applications with compliance requirements
- Scenarios where you want to limit callable contracts
- Multi-tenant platforms with different sponsor policies
Example Use Case: A DeFi protocol wants to sponsor user transactions but only through their approved relayers and only for their approved contracts.
When to Use Universal7702Account
✅ Recommended for:
- Open, permissionless applications
- Quick EIP-7702 integration without infrastructure
- Gas-sensitive applications
- Simple meta-transaction needs
- Protocols that want anyone to be able to relay
Example Use Case: A public goods project wants to allow any relayer to sponsor user transactions without maintaining a whitelist.
The Problem with ERC-4337 Stack
Building on EIP-7702 + ERC-4337 means:
- Run a Paymaster - Handle deposit management, gas estimation, sponsorship logic
- Run a Bundler - Aggregate UserOps, simulate, submit to EntryPoint
- Deploy EntryPoint - Another contract to manage, upgrade, secure
- Monitor Mempool - Track UserOps, handle replacements, timeouts
- Complex Integration - Client-side UserOp construction, signature schemes
This is overkill for many use cases. Simple7702 provides a simpler alternative.
How It Works
Simple7702Account Flow
┌─────────────┐ ┌──────────────────────┐
│ User │ │ Simple7702Account │
│ (EOA) │ │ (EIP-7702 Code) │
└──────┬──────┘ └──────────┬───────────┘
│ │
│ 1. Sign Action (off-chain) │
│─────────────────────────────────────►│
│ │
│ │
┌──────▼──────┐ ┌──────────▼───────────┐
│ Sponsor │ │ Policy Registry │
│ (Relayer) │ │ (Whitelist Ctrl) │
└──────┬──────┘ └──────────────────────┘
│
│ 2. Execute Action (pays gas)
│─────────────────────────────────────►
│ │
▼ ▼
Universal7702Account Flow
┌─────────────┐ ┌──────────────────────┐
│ User │ │ Universal7702Account│
│ (EOA) │ │ (EIP-7702 Code) │
└──────┬──────┘ └──────────┬───────────┘
│ │
│ 1. Sign Action (off-chain) │
│─────────────────────────────────────►│
│ │
│ │
┌──────▼──────┐ │
│ Any │ │
│ Relayer │ │
└──────┬──────┘ │
│ │
│ 2. Execute Action (pays gas) │
│─────────────────────────────────────►│
│ │
▼ ▼
Three simple steps:
- User signs an action - Off-chain, no gas required
- Relayer submits the action - Pays gas on behalf of user
- Contract verifies and executes - Signature + policy check (Simple7702) or just signature check (Universal7702)
That's it. No middleware, no additional services.
Quick Start
1. Deploy
# Clone and build
git clone https://github.com/your-org/simple7702.git
cd simple7702
forge build
# Deploy Simple7702Account (with policy registry)
./script/deploy.sh deploy amoy
# OR Deploy Universal7702Account (single contract)
./script/deploy_universal.sh deploy amoy2. Set Up Policy (Simple7702Account Only)
// Whitelist your relayer
registry.setSponsorWhitelist(relayerAddress, true);
// Or whitelist allowed targets
registry.setTargetWhitelist(uniswapRouter, true);3. Sponsor a Transaction
// User signs (off-chain, no gas)
const action = {
target: tokenAddress,
value: 0,
data: encodeTransfer(recipient, amount),
nonce: 1,
deadline: Math.floor(Date.now() / 1000) + 3600,
executor: relayerAddress
};
const signature = await user.signTypedData(domain, types, action);
// Relayer executes (pays gas)
await account.execute(action, signature);Done. No Paymaster deposit management. No bundler infrastructure.
Features
Core Capabilities
- ✅ Sponsored Transactions - Anyone can pay gas for user actions
- ✅ EIP-712 Signatures - Human-readable, secure signing
- ✅ Batch Execution - Multiple actions in one transaction
- ✅ Policy Controls - Whitelist sponsors and/or targets (Simple7702Account)
Security Features
- ✅ Signature Verification - EIP-712 with low-s enforcement
- ✅ Nonce Protection - Replay prevention (bitmap or sequential)
- ✅ Reentrancy Guard - Protection against nested calls
- ✅ Deadline Enforcement - Actions expire after deadline
Gas Optimized
- ✅ Assembly Hashing - EIP-712 digest computed in assembly
- ✅ Cached Constants - Pre-computed name/version hashes
- ✅ Bitmap Nonces - O(1) storage reads (Simple7702Account)
Supported Chains
The deployment scripts support the following EVM chains:
Mainnets
| Chain | Chain ID | RPC Env Variable |
|---|---|---|
| Ethereum | 1 | MAINNET_RPC_URL |
| Arbitrum | 42161 | ARBITRUM_RPC_URL |
| Optimism | 10 | OPTIMISM_RPC_URL |
| Base | 8453 | BASE_RPC_URL |
| Polygon | 137 | POLYGON_RPC_URL |
| BSC | 56 | BSC_RPC_URL |
| Avalanche | 43114 | AVALANCHE_RPC_URL |
| Fantom | 250 | FANTOM_RPC_URL |
| Gnosis | 100 | GNOSIS_RPC_URL |
| Scroll | 534352 | SCROLL_RPC_URL |
| zkSync | 324 | ZKSYNC_RPC_URL |
| Linea | 59144 | LINEA_RPC_URL |
| Mantle | 5000 | MANTLE_RPC_URL |
Testnets
| Chain | Chain ID | RPC Env Variable |
|---|---|---|
| Sepolia | 11155111 | SEPOLIA_RPC_URL |
| Base Goerli | 84531 | BASE_GOERLI_RPC_URL |
| Polygon Amoy | 80002 | POLYGON_AMOY_RPC_URL |
Deployment
Simple7702Account
# List supported chains
./script/deploy.sh
# Preview deployment
./script/deploy.sh preview amoy
# Deploy
./script/deploy.sh deploy amoy
# Verify contract
./script/deploy.sh verify amoy Simple7702Account <address> <registry>Universal7702Account
# List supported chains
./script/deploy_universal.sh list
# Preview deployment
./script/deploy_universal.sh preview mainnet
# Deploy (uses CREATE2 for deterministic address)
./script/deploy_universal.sh deploy arbitrum
# Verify contract
./script/deploy_universal.sh verify optimism <address>
# Show deterministic deployment address (same across all chains)
./script/deploy_universal.sh addressComparison
Simple7702 vs ERC-4337 Stack
| Aspect | ERC-4337 Stack | Simple7702 |
|---|---|---|
| Setup Time | Days to weeks | Minutes |
| Infrastructure | Paymaster + Bundler + EntryPoint | 1-2 contracts |
| Maintenance | High (multiple services) | Low (just contracts) |
| Gas Overhead | Higher (EntryPoint logic) | Lower (direct execution) |
| Complexity | High (UserOp, mempool) | Low (simple signature) |
| Flexibility | Constrained by EntryPoint | Full control |
Architecture
Contracts
| Contract | Lines | Description |
|---|---|---|
Simple7702Account |
~230 | Policy-controlled delegate contract |
Simple7702PolicyRegistry |
~80 | Whitelist management |
Universal7702Account |
~190 | Universal permissionless delegate |
Action Structure
struct Action {
address target; // Who to call
uint256 value; // ETH to send
bytes data; // What to call
uint256 nonce; // Replay protection
uint256 deadline; // When it expires
address executor; // Who can execute
}Usage Examples
Basic Sponsored Transfer
// User wants to transfer tokens but has no ETH
const action = {
target: usdcAddress,
value: 0,
data: usdc.interface.encodeFunctionData('transfer', [recipient, amount]),
nonce: 1,
deadline: deadline,
executor: sponsorAddress
};
// User signs (no gas needed)
const signature = await user.signTypedData(domain, types, action);
// Sponsor pays gas and executes
await account.connect(sponsor).execute(action, signature);Batch Operations
// Approve + swap in one sponsored transaction
const actions = [
{
target: usdcAddress,
data: usdc.interface.encodeFunctionData('approve', [router, amount]),
// ... other fields
},
{
target: routerAddress,
data: router.interface.encodeFunctionData('swapExactTokensForETH', [...]),
// ... other fields
}
];
const signatures = await Promise.all(
actions.map(a => user.signTypedData(domain, types, a))
);
await account.connect(sponsor).executeBatch(actions, signatures);Policy Configuration (Simple7702Account Only)
// Only allow specific sponsors
registry.setWhitelistFlags(true, false);
registry.setSponsorWhitelist(trustedRelayer, true);
// Or restrict callable targets
registry.setWhitelistFlags(false, true);
registry.setTargetWhitelist(allowedContract, true);
// Or both
registry.setWhitelistFlags(true, true);Installation
# Requirements: Foundry
curl -L https://foundry.paradigm.xyz | bash
foundryup
# Build
forge build
# Test
forge test
# Deploy Simple7702Account
./script/deploy.sh deploy amoy
# Deploy Universal7702Account
./script/deploy_universal.sh deploy amoyProject Structure
simple7702/
├── src/
│ ├── Simple7702Account.sol # Policy-controlled account (~230 lines)
│ ├── Simple7702PolicyRegistry.sol # Policy registry (~80 lines)
│ └── Universal7702Account.sol # Universal account (~190 lines)
├── script/
│ ├── Deploy.s.sol # Simple7702 deployment script
│ ├── DeployUniversal.s.sol # Universal7702 deployment script
│ ├── Create2Deployer.sol # Deterministic deployment
│ ├── deploy.sh # Simple7702 deploy command
│ ├── deploy_universal.sh # Universal7702 deploy command
│ └── config/
│ └── DeployConfig.sol # Chain configurations
├── test/
│ └── Simple7702Account.t.sol # Test suite
└── foundry.toml
License
MIT