Skip to content

Gas-optimized ERC-4337 multi-signature wallet with account abstraction, stable token payment paymaster, and comprehensive test coverage. Built with Foundry.

Notifications You must be signed in to change notification settings

Adeshh/safeSocial

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

15 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SafeSocial

A production-ready, gas-optimized ERC-4337 (Account Abstraction) multi-signature wallet implementation with token payment support. Built with Solidity and Foundry.

πŸš€ Features

  • ERC-4337 Account Abstraction - Full implementation of the account abstraction standard
  • Multi-signature Wallet - Configurable threshold-based multi-sig with gas-optimized signature validation
  • Token Payment Paymaster - Pay gas fees in ERC-20 tokens (DAI, USDC) using Chainlink price feeds
  • Factory Pattern - CREATE2 support for deterministic wallet addresses
  • Batch Execution - Execute multiple operations in a single transaction
  • Signature Validity Period - Time-bound signatures (1 hour) for enhanced security
  • Comprehensive Testing - 147+ tests with 80%+ coverage including unit, integration, fuzz, and invariant tests

πŸ“‹ Table of Contents

πŸ› οΈ Installation

Prerequisites

Setup

# Clone the repository git clone https://github.com/yourusername/safesocial.git cd safesocial # Install dependencies (submodules) git submodule update --init --recursive # Build contracts forge build # Run tests forge test

πŸš€ Quick Start

Deploy Contracts

# Deploy factory and paymaster forge script script/DeploySafeSocial.s.sol:DeploySafeSocial --rpc-url <RPC_URL> --broadcast --verify

Create a Wallet

// Deploy via factory address[] memory owners = [owner1, owner2, owner3]; uint256 threshold = 2; address wallet = factory.deployWallet(owners, threshold); // Or deploy deterministically with CREATE2 bytes32 salt = keccak256("my-wallet-salt"); address wallet = factory.deployWalletDeterministic(owners, threshold, salt);

Execute a Transaction

// Sign UserOperation with required threshold signatures PackedUserOperation memory userOp = /* ... */; // Execute via EntryPoint entryPoint.handleOps(userOps, beneficiary);

πŸ—οΈ Architecture

Core Contracts

  • SafeSocial.sol - Main multi-signature wallet contract implementing ERC-4337 IAccount
  • SafeSocialFactory.sol - Factory for deploying wallets with CREATE/CREATE2
  • SocialPaymaster.sol - Paymaster allowing token-based gas payments
  • OwnersAndThreshouldManager.sol - Owner and threshold management logic
  • TokenGasCalculator.sol - Library for calculating token amounts using Chainlink oracles

Contract Structure

All contracts follow Solidity's standard structure:

  1. Type Declarations (Structs, Enums)
  2. State Variables
  3. Mappings
  4. Constants
  5. Events
  6. Errors
  7. Modifiers
  8. Constructor
  9. External Functions
  10. Public Functions
  11. Internal Functions
  12. Private Functions
  13. View Functions

⚑ Key Optimizations

SafeSocial implements several gas optimizations targeting the signature validation hot path. See GAS_OPTIMIZATION.md for detailed analysis.

Gas Optimizations

  • Calldata Signature Parsing - Direct calldataload assembly (~300-500 gas saved per signature)
  • O(1) Owner Lookup - Single mapping with index offset pattern (~40k+ gas saved per transaction for 5 sigs with 10 owners)
  • Bitmap Duplicate Detection - O(1) duplicate checks vs O(n) array searches (~1k-2k gas saved)
  • Early Exit - Stop validation once threshold is met (~1.5k-1.8k gas saved when extra sigs provided)
  • Immutable Variables - EntryPoint and Factory embedded in bytecode (~2k gas saved per read)
  • Custom Errors - ~50% gas savings on reverts vs string messages (~150 gas saved per revert)
  • Unchecked Increments - Safe overflow skips in bounded loops (~100-150 gas saved)
  • Batch Execution - Single validation for multiple operations (~13.5k-17k gas saved per batch of 3 ops)

Design Decisions

  • Library Pattern - Separated oracle logic for reusability and testability
  • Factory-Only Deployment - Ensures paymaster integration and wallet tracking
  • CEI Pattern - All functions follow Checks-Effects-Interactions for security
  • Wallet Pays Gas - Wallet balance pays for gas in tokens (multisig-friendly)

Total Potential Savings: ~50,000-60,000+ gas per transaction for typical multi-sig operations (5 signatures, 10 owners).

πŸ”’ Security

Security Features

  • CEI Pattern - All state-changing functions follow Checks-Effects-Interactions
  • Signature Validity Period - 1-hour time-bound signatures prevent replay attacks
  • Input Validation - Comprehensive checks with custom errors
  • Reentrancy Protection - EntryPoint guards + CEI pattern
  • Factory Validation - Paymaster validates wallets are factory-deployed
  • SafeERC20 - Handles non-standard ERC20 tokens safely

Security Considerations

Access Control

  • EntryPoint-Only Execution: All execution functions (execute, executeBatch, validateUserOp) are protected by onlyEntryPoint modifier
  • Self-Call Pattern: Owner management functions (addOwner, removeOwner, updateThreshould) can only be called via execute(), ensuring multi-sig validation
  • Factory Validation: Paymaster validates wallets are deployed via factory to prevent unauthorized wallet usage

Signature Security

  • Time-Bound Signatures: Signatures are valid for 1 hour (SIGNATURE_VALIDITY_PERIOD) to prevent indefinite replay attacks
  • Duplicate Prevention: Bitmap-based duplicate detection prevents the same owner from signing multiple times
  • Threshold Enforcement: Requires exactly threshold number of unique owner signatures
  • ECDSA Recovery: Uses OpenZeppelin's ECDSA.recover with toEthSignedMessageHash for secure signature verification

Nonce Management

  • Sequential Nonces: EntryPoint handles nonce validation and sequential ordering before calling validateUserOp
  • Replay Protection: Invalid or reused nonces are rejected by EntryPoint before execution

Oracle Security (Paymaster)

  • Stale Price Protection: Maximum price age of 10 hours (considering mostly stable tokens will be added for gas payments) (MAX_PRICE_AGE) prevents using outdated prices
  • Zero/Negative Price Checks: Validates oracle prices are positive before calculations
  • Oracle Validation: Checks oracle addresses are non-zero before querying
  • Rounding Protection: Token amount calculations round up to ensure sufficient tokens are charged

Input Validation

  • Zero Address Checks: All critical addresses (owners, EntryPoint, Factory, tokens) are validated
  • Threshold Bounds: Threshold must be > 0 and <= owners.length
  • Duplicate Owner Prevention: Constructor and addOwner prevent duplicate owners
  • Owner Removal Protection: Cannot remove owner if it would violate threshold requirement

Reentrancy Protection

  • CEI Pattern: All functions follow Checks-Effects-Interactions pattern
  • EntryPoint Guards: EntryPoint's built-in reentrancy protection (tx.origin == msg.sender and msg.sender.code.length == 0)
  • State Changes Before External Calls: Events emitted and state updated before any external interactions

Owner Management Security

  • Owner Order Changes: removeOwner uses swap-with-last-element pattern, which changes owner array order (documented behavior)
  • Threshold Validation: Cannot update threshold to invalid values (0 or > owners.length)
  • Multi-Sig Required: All owner/threshold changes require threshold signatures via UserOperation

Paymaster Security

  • Wallet Restriction: Owner can restrict/unrestrict specific wallets from using paymaster
  • Token Support Validation: Only supported tokens (with valid oracle feeds) can be used
  • Balance/Allowance Checks: Validates wallet has sufficient balance and approval before charging
  • Factory Validation: Only factory-deployed wallets can use paymaster

Known Limitations & Considerations

  • Owner Order Changes: Removing an owner changes the order of remaining owners (by design for gas efficiency)
  • Signature Validity Window: 1-hour validity period may be too short for some use cases (can be adjusted)
  • Oracle Dependency: Paymaster relies on Chainlink oracles; stale prices or oracle failures could temporarily disable token payments
  • Factory Dependency: Direct wallet deployments won't work with paymaster (by design for security)
  • No Upgradeability: Contracts are not upgradeable; changes require redeployment
  • Centralization Risk: Paymaster owner has significant control (can restrict wallets, add/remove tokens)

Audit Status

⚠️ This code has not been audited. ...yet.

Security Best Practices

  • Multi-Sig Threshold: Use appropriate threshold (e.g., 2-of-3, 3-of-5) based on security requirements
  • Owner Key Management: Store owner private keys securely; consider using hardware wallets
  • Oracle Monitoring: Monitor Chainlink oracle feeds for staleness or failures
  • Paymaster Funding: Ensure paymaster has sufficient ETH deposit in EntryPoint
  • Regular Reviews: Review and update security practices as the ecosystem evolves

πŸ§ͺ Testing

The project includes comprehensive test coverage:

  • 147+ tests covering all functionality (core contracts coverage is 90%+)
  • Unit tests for core contracts
  • Integration tests for paymaster flows
  • Fuzz tests for edge cases
  • Invariant tests for critical properties

Run Tests

# Run all tests forge test # Run with verbosity forge test -vvv # Run specific test file forge test --match-path test/unit/SafeSocialTest.t.sol # Run with gas reporting forge test --gas-report # Run invariant tests forge test --match-path test/fuzz/**/*.t.sol

Test Coverage

# Generate coverage report forge coverage

πŸ“š Documentation

πŸ“ Project Structure

safesocial/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ SafeSocial.sol # Main wallet contract β”‚ β”œβ”€β”€ SafeSocialFactory.sol # Wallet deployment factory β”‚ β”œβ”€β”€ SocialPaymaster.sol # Token payment paymaster β”‚ β”œβ”€β”€ OwnersAndThreshouldManager.sol # Owner & threshold management β”‚ β”œβ”€β”€ interfaces/ # Contract interfaces β”‚ └── libraries/ β”‚ └── TokenGasCalculator.sol # Gas calculation library β”œβ”€β”€ test/ β”‚ β”œβ”€β”€ unit/ # Unit tests β”‚ β”œβ”€β”€ fuzz/ # Fuzz & invariant tests β”‚ β”œβ”€β”€ helpers/ β”‚ β”‚ └── TestHelper.sol # Shared test utilities β”‚ └── mocks/ # Mock contracts β”œβ”€β”€ script/ β”‚ β”œβ”€β”€ DeploySafeSocial.s.sol # Deployment script β”‚ └── HelperConfig.s.sol # Configuration helper β”œβ”€β”€ GAS_OPTIMIZATION.md # Detailed optimization docs └── README.md # This file 

πŸ› οΈ Foundry Commands

Build

forge build

Test

forge test

Format

forge fmt

Gas Snapshots

forge snapshot

Deploy

forge script script/DeploySafeSocial.s.sol:DeploySafeSocial \ --rpc-url <RPC_URL> \ --private-key <PRIVATE_KEY> \ --broadcast \ --verify

Anvil (Local Node)

anvil

Cast (CLI Tool)

# Get contract bytecode cast code <CONTRACT_ADDRESS> --rpc-url <RPC_URL> # Call a view function cast call <CONTRACT_ADDRESS> "functionName(uint256)" <ARG> --rpc-url <RPC_URL> # Send a transaction cast send <CONTRACT_ADDRESS> "functionName(uint256)" <ARG> \ --rpc-url <RPC_URL> \ --private-key <PRIVATE_KEY>

πŸ“Š Gas Analysis

For detailed gas optimization analysis, see GAS_OPTIMIZATION.md.

Summary

Optimization Gas Saved Impact
Calldata signature parsing ~300-500 per sig Critical (hot path)
Mapping-based owner lookup ~40k+ (5 sigs, 10 owners) Critical (hot path)
Bitmap duplicate detection ~1k-2k High
Early exit ~1.5k-1.8k (when extra sigs) Medium
Immutable variables ~2k per read Medium
Custom errors ~150 per revert Low
Batch execution ~13.5k-17k (3 ops) High (UX)

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Acknowledgments


Built with ❀️ using Foundry

About

Gas-optimized ERC-4337 multi-signature wallet with account abstraction, stable token payment paymaster, and comprehensive test coverage. Built with Foundry.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published