Skip to content

jojo2504/arc-escrow

Repository files navigation

⚡ ArcEscrow — Work Settlement Protocol

ETHGlobal Cannes 2026 · Best Smart Contracts on Arc with Advanced Stablecoin Logic

Programmable escrow + vesting + crosschain USDC settlement for DAO contributors.
Built on Arc Testnet · CCTP V2 · Circle Forwarding Service.


📁 Structure

arc-escrow/
├── src/
│   └── ArcEscrow.sol        ← Smart contract (tout est là)
├── test/
│   └── ArcEscrow.t.sol      ← Tests Foundry (à décommenter et run)
├── script/
│   └── Deploy.s.sol         ← Script de déploiement Foundry
├── frontend/
│   └── index.html           ← Demo frontend (ouvre dans le browser, zero build)
├── foundry.toml             ← Config Foundry
└── README.md

🚀 Quickstart — 4 étapes

1. Setup Foundry

curl -L https://foundry.paradigm.xyz | bash
foundryup

2. Initialiser le projet

forge init arc-escrow
cd arc-escrow

# Copier les fichiers
cp ArcEscrow.sol src/
cp ArcEscrow.t.sol test/
cp Deploy.s.sol script/

# Build
forge build

3. Déployer sur Arc Testnet

# Créer .env
echo "PRIVATE_KEY=0x..." > .env
echo "FEE_RECIPIENT=0x..." >> .env
source .env

# Déployer (mode local, sans CCTP)
forge script script/Deploy.s.sol \
  --rpc-url https://rpc.testnet.arc.network \
  --broadcast \
  --private-key $PRIVATE_KEY \
  -vvvv

Note : Dans Deploy.s.sol, décommenter les lignes ArcEscrow et choisir les adresses.

4. Ouvrir la démo frontend

# Option A — juste ouvrir dans le browser
open frontend/index.html

# Option B — servir localement
npx serve frontend/
# → http://localhost:3000

Coller l'adresse du contrat déployé dans le champ "Contract" du frontend.


🧪 Tests locaux (Foundry)

Les tests sont dans ArcEscrow.t.sol (commentés, prêts à décommenter) :

# Décommenter les tests dans ArcEscrow.t.sol puis :
forge test -vvvv

# Test spécifique
forge test --match-test test_HappyPath_LocalRelease -vvvv
forge test --match-test test_AutoRelease_After72h -vvvv
forge test --match-test test_DisputeResolution_ArbiterSplit -vvvv

🔑 Adresses Testnet

Asset/Contract Address
USDC Arc Testnet 0x3600000000000000000000000000000000000000
USDC Ethereum Sepolia 0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238
USDC Base Sepolia 0x036CbD53842c5426634e7929541eC2318f3dCF7e
TokenMessengerV2 (Sepolia) 0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa
Arc Testnet RPC https://rpc.testnet.arc.network
Arc Testnet Chain ID 2482601729
CCTP Domain Arc 26
Faucet USDC https://faucet.circle.com

📺 Scénario de démo (5 min)

Scénario 1 — Happy path

Client wallet:
  1. createJob(contractor, arbiter=0x0, 100 USDC, "Audit contract", false, -)
  2. fundJob(0)  ← 100 USDC locked

Contractor wallet:
  3. submitWork(0)  ← démarre timer 72h

Client wallet:
  4. approveWork(0)  ← USDC released to contractor (- 0.5% fee)

Scénario 2 — Dispute + auto-résolution

  1-3. Même que ci-dessus
  4. openDispute(0)  ← fonds gelés
  5. resolveDispute(0, 7000)  ← arbiter donne 70% au contractor

Scénario 3 — Auto-release (client ghost)

  1-3. Même que ci-dessus
  [Skip 72h → forge test ou warp]
  4. claimAutoRelease(0)  ← n'importe qui peut trigger

Scénario 4 — Crosschain release via CCTP

  1. createJob(..., crosschain=true, destRecipient=0xARC_ADDRESS)
  2. fundJob(0)
  3. submitWork(0)
  4. approveWork(0)
  → CCTP burn on source chain
  → Circle Forwarding Service relays attestation
  → USDC minted on Arc Testnet for contractor

Scénario 5 — Vesting stream

Client wallet:
  1. createStream(contractor, USDC, 1000 USDC, 30 days, false, -)
  [Time passes...]
Contractor wallet:
  2. claimStream(0)  ← withdraw vested portion
Client wallet:
  3. lockStream(0)   ← dispute-lock, vesting paused
  4. unlockStream(0) ← resume, end time extended

⚙️ Cast — Demo terminal

export RPC=https://rpc.testnet.arc.network
export ESCROW=0xYOUR_DEPLOYED_CONTRACT
export USDC=0x3600000000000000000000000000000000000000
export CLIENT_KEY=0x...
export CONTRACTOR_KEY=0x...

# Approve USDC
cast send $USDC "approve(address,uint256)" $ESCROW 100000000 \
  --rpc-url $RPC --private-key $CLIENT_KEY

# Create + Fund Job
cast send $ESCROW \
  "createJob(address,address,uint256,string,bool,address)" \
  $CONTRACTOR 0x0000000000000000000000000000000000000000 \
  100000000 "Build smart contract" false $CONTRACTOR \
  --rpc-url $RPC --private-key $CLIENT_KEY

cast send $ESCROW "fundJob(uint256)" 0 \
  --rpc-url $RPC --private-key $CLIENT_KEY

# Submit work (contractor)
cast send $ESCROW "submitWork(uint256)" 0 \
  --rpc-url $RPC --private-key $CONTRACTOR_KEY

# Approve (client)
cast send $ESCROW "approveWork(uint256)" 0 \
  --rpc-url $RPC --private-key $CLIENT_KEY

# Read job state
cast call $ESCROW "getJob(uint256)" 0 --rpc-url $RPC

🏗️ Architecture

┌─────────────────────────────────────────────────────────┐
│                    ArcEscrow.sol                        │
│              (Arc Testnet / Sepolia)                    │
│                                                         │
│  ┌──────────────────┐    ┌──────────────────────────┐  │
│  │  Milestone Escrow│    │   Streaming Vesting      │  │
│  │                  │    │                          │  │
│  │  CREATED         │    │  createStream()          │  │
│  │  → FUNDED        │    │  → linear per-second     │  │
│  │  → SUBMITTED     │    │  → lockStream() pause    │  │
│  │  → APPROVED ─────┤    │  → unlockStream() resume │  │
│  │  → DISPUTED      │    │  → cancelStream() split  │  │
│  │     → RESOLVED   │    └──────────────────────────┘  │
│  └──────────────────┘                                   │
│           │ crosschain=true                             │
│           ↓                                             │
│  ┌──────────────────────────────────────────────────┐  │
│  │            _release() via CCTP V2                │  │
│  │                                                  │  │
│  │  depositForBurnWithHook(                         │  │
│  │    amount,                                       │  │
│  │    destinationDomain = 26 (Arc),                 │  │
│  │    mintRecipient = contractor bytes32,           │  │
│  │    maxFee = 0.50 USDC,                           │  │
│  │    hookData = 0x636374702d... ← magic bytes      │  │
│  │  )                                               │  │
│  └──────────────────────────────────────────────────┘  │
│           │                                             │
│           ↓ Circle Forwarding Service                   │
│  ┌──────────────────────────────────────────────────┐  │
│  │  [Arc Testnet] USDC minted to contractor         │  │
│  │  No manual relay · No destination gas token      │  │
│  └──────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘

📦 Tech Stack

Layer Tech
Smart Contract Solidity 0.8.20
Dev Framework Foundry (forge, cast, anvil)
Stablecoin USDC (native Arc Testnet)
Crosschain CCTP V2 · Circle Forwarding Service
Gas abstraction Circle Paymaster (à intégrer next)
Frontend Vanilla HTML + ethers.js 6 (zero build)
Wallet MetaMask / any injected provider
Explorer testnet.arcscan.app

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors