Skip to content

About

Oracle-verified P2P escrow on Solana (Anchor) — buyer, seller, and a binary oracle verdict with a formal state machine.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Magican Oracle Escrow

Oracle-based P2P escrow on Solana (Anchor 1.0.2).

A buyer locks SPL tokens in a program-owned vault. A designated oracle issues a binary verdict — tokens either go to the seller (verdict true) or are refunded to the buyer (verdict false or timeout). The oracle never touches the funds.


Architecture

State Machine

Pending ── oracle_verify(true)  ──→ Released (vault → seller, accounts closed)
         │
         ├─ oracle_verify(false) ──→ Failed
         │
         └─ refund (expired & no verdict, or Failed) ──→ Refunded (vault → buyer, accounts closed)

Roles

Role Description
Buyer Locks tokens into the vault. Signs initialize and refund.
Seller Receives tokens on successful outcome. Signs initialize.
Oracle Binary verifier — sets the verdict via oracle_verify. Never holds funds.

PDA Seeds

  • Escrow: [b"escrow", buyer, seller, mint, nonce.to_le_bytes()]
  • Vault: [b"vault", escrow.key()]

The nonce allows multiple escrows between the same buyer/seller/mint pair.


Instructions

initialize

Creates an escrow PDA and a vault token account. Transfers amount tokens from buyer → vault via CPI transfer_checked.

  • Signers: buyer, seller
  • Args: amount, nonce, expires_at, oracle

oracle_verify

The oracle submits a binary verdict:

  • true → vault tokens transferred to seller, both accounts closed

  • false → state set to Failed, tokens remain in vault

  • Signer: oracle

  • Guard: has_one = oracle, state == Pending, oracle_verdict.is_none()

refund

Returns vault tokens to the buyer and closes both accounts. Allowed when:

  • State is Failed (oracle said false), or

  • State is Pending and expires_at has passed

  • Signer: buyer

  • Guards: has_one = buyer, state == Pending || Failed, expiry check


Security

13 guards from the Protocol Design Review are implemented:

  1. State machine validation
  2. PDA seed verification (Anchor seeds constraint)
  3. Signed seeds for CPI transfers
  4. Oracle authority (has_one = oracle)
  5. Buyer/seller signer checks
  6. close on vault + escrow in final states
  7. CPI transfer_checked (mint + decimals verified)
  8. Timeout guard in refund
  9. Double-verdict prevention
  10. Non-zero amount
  11. Future expiration
  12. Nonce-based PDA uniqueness
  13. Checked math (Anchor overflow protection)

Test Suite

# Test Type
1 Happy path: initialize → verify(true) → seller receives Success
2 Oracle false: initialize → verify(false) → refund → buyer receives Success
3 Timeout refund: initialize → expire → refund → buyer receives Success
4 Wrong oracle signer Failure
5 Double oracle_verify Failure
6 Refund before expiry Failure
7 Zero amount initialize Failure
8 Past expiration initialize Failure
9 Attacker (not buyer) calls refund Failure
10 Missing seller signer Failure

Tests run in two stacks:

  • Rust/litesvm — fast, unit-level (3 tests)
  • TypeScript/Mocha/Chai — full integration via anchor test (11 tests: the 10 scenarios above plus a validator-connectivity sanity check)

Deployment

Deployed on Solana devnet:

DuGYyHub8HMAXgeiA46bU1kapjLEaqLH7XxWtSWVWiqW

View on Solana Explorer

Prerequisites

  • Rust 1.81+ with solana toolchain
  • Solana CLI 3.x / 4.x
  • Anchor 1.0.2
  • Node.js 18+

Quick Start

git clone <repo>
cd magican-oracle-escrow
npm install
anchor build
anchor test

Project Structure

├── Anchor.toml
├── programs/
│   └── magican-oracle-escrow/
│       ├── src/
│       │   ├── lib.rs              # Entrypoint and instruction dispatch
│       │   ├── contexts.rs         # Account structs (Initialize, OracleVerify, Refund)
│       │   ├── instructions/
│       │   │   ├── initialize.rs
│       │   │   ├── oracle_verify.rs
│       │   │   └── refund.rs
│       │   ├── state.rs            # Escrow and EscrowState
│       │   ├── error.rs            # Custom error codes
│       │   └── constants.rs        # PDA seed strings
│       └── tests/
│           └── test_initialize.rs  # Rust/litesvm tests
├── tests/
│   └── escrow.ts                   # TypeScript integration tests
└── docs/
    ├── IDEA.md                     # Original concept
    ├── PDR.md                      # Protocol Design Review
    └── PROGRESS.md                 # Build progress (per-phase)

About

Oracle-verified P2P escrow on Solana (Anchor) — buyer, seller, and a binary oracle verdict with a formal state machine.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages