Skip to content

RoninBuild/escrow2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

18 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Handshake Escrow - Smart Contracts

Trustless escrow inside Towns. Lock USDC on Base β†’ Release/Refund β†’ Receipt.

On-chain escrow contracts for peer-to-peer deals with optional arbitration. Built for the Towns Bot Competition.

🎯 What This Does

  • Buyer locks USDC in a smart contract
  • Seller sees funds are guaranteed
  • Release when satisfied or Refund after deadline
  • Optional Arbiter for dispute resolution
  • All on Base L2 for low gas fees

πŸ“¦ Architecture

Contracts

  • EscrowFactory.sol - Creates and tracks all escrow deals
  • Escrow.sol - Individual escrow logic (one per deal)

Deal Lifecycle

CREATED β†’ FUNDED β†’ RELEASED/REFUNDED
              ↓
          DISPUTED β†’ RESOLVED (if arbiter exists)

Key Features

βœ… NonReentrant guards
βœ… SafeERC20 token handling
βœ… Role-based access control
βœ… Deadline-based refunds
βœ… Optional dispute resolution
βœ… USDC-only whitelist (extensible)

πŸš€ Quick Start

Prerequisites

Installation

# Clone repo
git clone <your-repo>
cd handshake-escrow

# Install dependencies
forge install foundry-rs/forge-std --no-commit
forge install OpenZeppelin/openzeppelin-contracts --no-commit

# Copy environment variables
cp .env.example .env
# Edit .env with your private key and RPC URLs

Run Tests

# Run all tests
forge test

# Run with verbosity
forge test -vvv

# Run specific test
forge test --match-test test_Release_Success

# Gas report
forge test --gas-report

Expected output: All tests passing βœ…

Deploy to Base Sepolia (Testnet)

# Load environment
source .env

# Deploy
forge script script/Deploy.s.sol:DeployScript \
  --rpc-url $BASE_SEPOLIA_RPC_URL \
  --broadcast \
  --verify \
  -vvvv

# Or use the testnet-specific function
forge script script/Deploy.s.sol:DeployScript \
  --sig "runTestnet()" \
  --rpc-url $BASE_SEPOLIA_RPC_URL \
  --broadcast \
  --verify \
  -vvvv

Deploy to Base Mainnet

forge script script/Deploy.s.sol:DeployScript \
  --rpc-url $BASE_RPC_URL \
  --broadcast \
  --verify \
  -vvvv

πŸ“ Contract Addresses

Base Mainnet

  • EscrowFactory: TBD
  • USDC: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913

Base Sepolia

  • EscrowFactory: TBD
  • USDC: 0x036CbD53842c5426634e7929541eC2318f3dCF7e

πŸ”§ Usage Example

1. Create Escrow

address seller = 0x...;
address usdc = 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913;
uint256 amount = 100e6; // 100 USDC
uint256 deadline = block.timestamp + 48 hours;
address arbiter = 0x...; // or address(0) for none
bytes32 memoHash = keccak256("Logo design for project");

address escrowAddr = factory.createEscrow(
    seller,
    usdc,
    amount,
    deadline,
    arbiter,
    memoHash
);

2. Fund Escrow (Buyer)

IERC20(usdc).approve(escrowAddr, amount);
Escrow(escrowAddr).fund();

3. Release Funds (Buyer)

Escrow(escrowAddr).release(); // Pays seller

4. Or Refund After Deadline

// After deadline passes
Escrow(escrowAddr).refundAfterDeadline(); // Returns to buyer

5. Dispute Resolution (Optional)

// Buyer or Seller opens dispute
Escrow(escrowAddr).openDispute();

// Arbiter resolves
Escrow(escrowAddr).resolve(true); // true = pay seller, false = refund buyer

πŸ§ͺ Testing Checklist

  • βœ… Factory: Create escrow, token whitelist
  • βœ… Fund: Success, unauthorized, after deadline
  • βœ… Release: Success, unauthorized, wrong status
  • βœ… Refund: Success, before deadline, wrong status
  • βœ… Dispute: Open, resolve, no arbiter, unauthorized
  • βœ… Registry: Track buyer/seller escrows

Coverage: 100% of functions

πŸ” Security Considerations

  1. No custody: Funds never held by bot/backend
  2. Immutable roles: Buyer/seller/arbiter set at creation
  3. Deadline enforcement: Refund only after deadline
  4. Reentrancy protection: NonReentrant on all state-changing functions
  5. Token whitelist: Only approved tokens (USDC)

πŸ“Š Gas Estimates

Function Gas Cost
createEscrow ~250k
fund ~90k
release ~55k
refundAfterDeadline ~55k
openDispute ~45k
resolve ~55k

Estimates on Base Sepolia. Mainnet may vary.

πŸ›  Development

# Format code
forge fmt

# Check formatting
forge fmt --check

# Update dependencies
forge update

# Build
forge build

# Clean
forge clean

πŸ“š Key Dependencies

πŸ— Architecture Decisions

Why Factory Pattern?

  • Easy indexing of all escrows
  • Track user activity (buyer/seller history)
  • Emit events for bot indexer

Why Immutable Parameters?

  • Gas savings
  • Cannot be manipulated post-creation
  • Clear audit trail

Why USDC-Only?

  • Simplifies MVP
  • Most liquid stablecoin on Base
  • Easy to extend later

🎯 Next Steps

  1. βœ… Deploy to Base mainnet
  2. πŸ”„ Integrate with Towns bot
  3. πŸ”„ Build miniapp frontend
  4. πŸ“ˆ Add analytics dashboard
  5. 🌟 Launch & gather feedback

πŸ“„ License

MIT

🀝 Contributing

Built for Towns Bot Competition. Feedback welcome!

πŸ”— Links


Built with 🀝 for trustless peer-to-peer deals

Releases

Packages

Contributors

Languages