Skip to content

This prototype mirrors the architecture of real-world payment system where: Stablecoin flows settle on-chain, and fiat transfers occur off-chain, coordinated by a backend oracle.

Notifications You must be signed in to change notification settings

FerdiKurt/crossborder-settlement

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

📘 Cross-Border Settlement Prototype

On-Chain Escrow + Off-Chain Fiat Oracle

This project demonstrates a full cross-border settlement pipeline:

  • 🟦 On-chain stablecoin escrow (ERC-20)
  • 🟩 Off-chain fiat payout simulation (Node.js + ethers.js)
  • 🔗 Event-driven orchestration
  • 🔒 Oracle-based settlement authorisation
  • TTL + refund safety logic
  • 🧪 Foundry tests
  • ⚙️ Forge automation scripts
  • 🚀 End-to-end local demo (Anvil + Foundry + Node)

This prototype mirrors the architecture of real-world payment system where:

Stablecoin flows settle on-chain, and fiat transfers occur off-chain, coordinated by a backend oracle.


🏗️ System Architecture Overview

                     ┌───────────────────────────────────────────┐
                     │               User / Client                │
                     │     (Fintech, Wallet, App, Merchant)       │
                     └───────────────────────────────────────────┘
                                      │
                                      ▼
                     ┌───────────────────────────────────────────┐
                     │      CrossBorderSettlement.sol (L1/L2)     │
                     │   - Escrows stablecoins                     │
                     │   - Emits PaymentInitiated                  │
                     │   - Oracle releases funds to payoutAgent    │
                     │   - Refunds on TTL expiry                   │
                     └───────────────────────────────────────────┘
                                      │ (event)
                                      ▼
                   ┌──────────────────────────────────────────────┐
                   │    Off-Chain Oracle (Node.js + Ethers.js)     │
                   │    - Listens for PaymentInitiated             │
                   │    - Simulates fiat payout                    │
                   │    - markCompleted(paymentId, ref) on-chain   │
                   └──────────────────────────────────────────────┘
                                      │ (transaction)
                                      ▼
                     ┌───────────────────────────────────────────┐
                     │      Liquidity Provider / Payout Agent     │
                     │   Receives tokens after oracle settlement  │
                     └───────────────────────────────────────────┘

🔄 End-to-End Payment Lifecycle (Sequence Diagram)

Happy Path – Successful Payment

User                Settlement Contract        Off-Chain Oracle              Payout Agent
 |                         |                            |                          |
 |-- initiatePayment() --> |                            |                          |
 |                         |-- emit PaymentInitiated -->|                          |
 |                         |                            |-- simulate payout -->    |
 |                         |                            |                          |
 |                         |                            |-- markCompleted() -----> |
 |                         |-- transfer to payoutAgent -------------------------------->|
 |                         |                            |                          |

⏳ Refund Flow (TTL Expiration)

Anyone (after TTL)        Settlement Contract
          |                         |
          |--- refund(paymentId) -->|
          |                         |
          |<-- funds returned ------|

Refund allowed if:

  • sender calls refund anytime before completion
  • oracle calls refund
  • any address can refund after TTL expiry

🧱 Components

🟦 1. CrossBorderSettlement.sol (on-chain)

Core responsibilities:

  • Escrow stablecoins
  • Maintain payment struct (sender, token, amount, corridor, payoutAgent, TTL, status)
  • Emit events
  • Release tokens to payout agent only on oracle confirmation
  • Allow refunds safely
  • Enforce role-based access control
  • Prevent re-entrancy
  • Pause the system when needed

Key Functions

initiatePayment()  // user → escrow
markCompleted()    // oracle → payout agent
refund()           // sender/oracle/anyone after TTL
pause()
unpause()

State machine:

Initiated → Completed
Initiated → Refunded
(No backwards transitions allowed)

🟩 2. Off-Chain Oracle (Node.js)

Imitates a real fiat payments backend:

  • Connects to RPC (Anvil, local node, testnet)
  • Subscribes to PaymentInitiated events
  • Simulates fiat payout with a mock delay
  • Calls markCompleted(paymentId, offchainRef)

🧪 3. Foundry Tests

  • escrow correctness
  • status machine
  • TTL-based expiries
  • refund controls
  • oracle-only settlement
  • pausing

⚙️ 4. Forge Scripts (Automation)

Deploy.s.sol

Deploys MockERC20 + settlement contract.

InitiatePayment.s.sol

Mints → approves → initiates a payment → triggers oracle.


🚀 Full Demo (Local E2E Flow)

1️⃣ Start Anvil

anvil

2️⃣ Deploy contracts

forge script script/Deploy.s.sol:Deploy --rpc-url http://127.0.0.1:8545 --broadcast

3️⃣ Start Oracle

cd offchain
npm start

4️⃣ Initiate a Payment

forge script script/InitiatePayment.s.sol:InitiatePayment --rpc-url http://127.0.0.1:8545 --broadcast

Oracle output:

New PaymentInitiated event:
Simulating off-chain fiat payout...
markCompleted tx sent: 0x...
Payment completed on-chain for paymentId: 0

📊 Payment State Machine Diagram

          ┌──────────────┐
          │  Initiated    │
          └──────────────┘
           /                      /              markCompleted         refund()
 (oracle)       (sender/oracle/anyone after TTL)
        |              |
        ▼              ▼
┌──────────────┐   ┌──────────────┐
│  Completed   │   │   Refunded   │
└──────────────┘   └──────────────┘

🔐 Security Properties

  • oracle-gated settlement
  • refund safety
  • TTL liveness guarantee
  • replay protection
  • role-based access control
  • non-reentrancy
  • pause protection

🌍 Mapping to Real World Example Architecture

This Demo Real Wordl
Escrow contract Cross-chain stablecoin settlement
Oracle service Payment orchestration backend
Mock payout Bank/PSP real payout
markCompleted Confirming off-chain fiat leg
TTL refund Fail-safes for async rails

🧩 Extensions Available

  • corridor limits
  • liquidity-provider registry
  • real stablecoin support
  • docker compose full stack
  • frontend dashboard

About

This prototype mirrors the architecture of real-world payment system where: Stablecoin flows settle on-chain, and fiat transfers occur off-chain, coordinated by a backend oracle.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published