Vibe Swap- a new decentralized exchange giving "fair price discovery as a human right"

VibeSwap on Nervos: A Proposal for MEV-Resistant Decentralized Exchange Infrastructure

Community Proposal for VibeSwap Integration with Nervos Network (CKB)


Dear Nervos Community,

We are excited to present VibeSwap—an omnichain decentralized exchange protocol that we believe represents a natural evolution for the Nervos ecosystem. After studying Nervos’s architecture extensively, we’ve found remarkable alignment between our security philosophy and Nervos’s foundational design principles.

More importantly, we’ve realized something that strengthens this proposal significantly: VibeSwap’s batch auction model isn’t just MEV protection—it’s architecturally optimal for UTXO-based chains like CKB. Our design solves the state contention problem that plagues other DEX implementations on UTXO models.

We respectfully submit this proposal to adapt VibeSwap to run natively on CKB, with L1 serving as the verification layer and an L2 coordinator handling batch aggregation—exactly as Nervos intended.


Executive Summary

VibeSwap is a commit-reveal batch auction DEX that eliminates Maximal Extractable Value (MEV) through cryptographic ordering and uniform price clearing. Rather than continuous execution where arbitrageurs profit from transaction ordering, VibeSwap settles all trades in discrete batches at a single fair price—making frontrunning and sandwich attacks mathematically impossible.

We propose a layered architecture:

  • L2 Batch Coordinator: Aggregates orders, computes clearing prices, constructs settlement transactions
  • L1 CKB Verification: Validates all state transitions, enforces protocol rules, provides settlement finality

This design leverages CKB’s “Universal Verification Layer” philosophy while solving the UTXO contention problem that makes naive DEX implementations impractical.


A Paradigm Shift in Price Discovery

The Problem with Continuous Execution

Traditional DEXs like Uniswap operate on continuous execution: each trade immediately affects price, creating a race where milliseconds determine profit. This model has a fundamental flaw—whoever controls transaction ordering controls value extraction. MEV has extracted over $1.5 billion from users since 2020, representing a hidden tax on every trade.

VibeSwap’s Solution: Asynchronous Batch Auctions

VibeSwap introduces discrete-time price discovery:

┌─────────────────────────────────────────────────────────────┐
│                    10-Second Batch Cycle                     │
├─────────────────────────────────────┬───────────────────────┤
│         Commit Phase (8s)           │   Reveal Phase (2s)   │
│                                     │                       │
│  Users submit: hash(order||secret)  │  Users reveal orders  │
│  Order details remain hidden        │  + optional priority  │
│  No one knows market direction      │    bids for LPs       │
└─────────────────────────────────────┴───────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                      Settlement                              │
│                                                              │
│  1. All secrets XORed → deterministic shuffle seed          │
│  2. Fisher-Yates shuffle with combined randomness           │
│  3. ALL orders execute at SINGLE clearing price             │
│  4. Priority bid proceeds → distributed to LPs              │
└─────────────────────────────────────────────────────────────┘

The result: No transaction can be frontrun because order contents are hidden during commitment. No sandwich attacks are possible because all trades clear at the same price. Priority is determined by cryptographic fairness, not validator collusion.

This represents a paradigm shift from “fastest wins” to “fairest wins.”


Why Batch Auctions Are Optimal for UTXO Chains

The State Contention Problem

UTXO-based models like CKB’s Cell model have a fundamental constraint: a cell can only be consumed once per block. For DEXs, this creates a serious problem:

Traditional DEX on UTXO (The Problem):
──────────────────────────────────────

    Trade 1 ──┐
    Trade 2 ──┼──► ALL compete to consume same pool cell
    Trade 3 ──┤
    Trade N ──┘
                        │
                        ▼
              Only ONE succeeds per block
              N-1 transactions FAIL

    Result: Unusable throughput for any popular trading pair

An AMM pool is shared state—every trader wants to swap against the same liquidity. In a naive UTXO implementation, only one trade can succeed per block because consuming the pool cell invalidates all other pending transactions.

How VibeSwap Solves This

VibeSwap’s batch model eliminates contention by design:

VibeSwap on UTXO (The Solution):
────────────────────────────────

COMMIT PHASE - Zero Contention:
┌─────────────────────────────────────────────────────────┐
│  User 1 ──► Creates own Commitment Cell (independent)   │
│  User 2 ──► Creates own Commitment Cell (independent)   │
│  User 3 ──► Creates own Commitment Cell (independent)   │
│  User N ──► Creates own Commitment Cell (independent)   │
│                                                         │
│  No shared state touched. All succeed in parallel.      │
└─────────────────────────────────────────────────────────┘

REVEAL PHASE - Zero Contention:
┌─────────────────────────────────────────────────────────┐
│  User 1 ──► Reveals to own cell (independent)           │
│  User 2 ──► Reveals to own cell (independent)           │
│  User N ──► Reveals to own cell (independent)           │
│                                                         │
│  Or: Submit reveals directly to L2 coordinator          │
└─────────────────────────────────────────────────────────┘

SETTLEMENT - Single Atomic Transaction:
┌─────────────────────────────────────────────────────────┐
│                                                         │
│  ONE transaction consumes:                              │
│    • All N order commitment cells                       │
│    • Pool liquidity cell                                │
│                                                         │
│  ONE transaction creates:                               │
│    • New pool cell (updated reserves)                   │
│    • N user balance cells (trade outputs)               │
│                                                         │
│  N trades = 1 pool cell update (not N!)                │
│                                                         │
└─────────────────────────────────────────────────────────┘

The key insight: Users never race for the same cell. They create independent commitment cells, then a single atomic settlement transaction touches shared state once per batch.

Metric Traditional DEX on UTXO VibeSwap on UTXO
Trades per block 1 per pair Unlimited (batched)
Pool cell updates 1 per trade 1 per batch
Transaction failures N-1 per N attempts Near zero
State contention Severe Eliminated

VibeSwap doesn’t fight the UTXO model—it leverages it.


Layered Architecture: L1 Verification, L2 Coordination

CKB is designed as a “Universal Verification Layer”—computation happens off-chain, verification on-chain. We embrace this fully with an explicit L1/L2 split:

┌─────────────────────────────────────────────────────────────────────┐
│                     L2: BATCH COORDINATOR NETWORK                    │
│                                                                      │
│  Responsibilities:                                                   │
│  ─────────────────                                                   │
│  • Monitor L1 for new commitment cells                              │
│  • Manage batch timing (8s commit window, 2s reveal window)         │
│  • Collect reveal witnesses from users (P2P or direct submission)   │
│  • Compute clearing price off-chain                                 │
│  • Execute deterministic shuffle algorithm                          │
│  • Construct settlement transaction                                 │
│  • Submit settlement to L1 for verification                         │
│                                                                      │
│  Decentralization Options:                                          │
│  ─────────────────────────                                          │
│  • Rotating coordinator set (similar to sequencer rotation)         │
│  • Coordinator auction (bid for right to settle batches)            │
│  • Threshold signature committee                                    │
│  • Single coordinator + fraud proofs (optimistic)                   │
│                                                                      │
│  Trust Assumption: Liveness only (can't steal or manipulate)        │
│  └─► L1 verification catches any invalid settlements                │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘
                                   │
                   Settlement Transaction
                                   │
                                   ▼
┌─────────────────────────────────────────────────────────────────────┐
│                     L1: CKB VERIFICATION LAYER                       │
│                                                                      │
│  Lock Scripts Verify:                                               │
│  ────────────────────                                               │
│  ✓ Commitment hash matches revealed order (preimage check)          │
│  ✓ Reveal occurred within valid time window                         │
│  ✓ User signature authorizes the order                              │
│  ✓ Deposit amount matches commitment                                │
│                                                                      │
│  Type Scripts Verify:                                               │
│  ────────────────────                                               │
│  ✓ Clearing price satisfies ALL limit orders in batch               │
│  ✓ Deterministic shuffle computed correctly (XOR secrets → seed)    │
│  ✓ Output balances are mathematically correct                       │
│  ✓ Pool invariant maintained (x × y = k)                            │
│  ✓ Protocol fees calculated correctly                               │
│  ✓ No tokens created or destroyed (conservation)                    │
│                                                                      │
│  Security Guarantee:                                                │
│  ───────────────────                                                │
│  L1 doesn't trust L2 computation—it VERIFIES everything.            │
│  Invalid settlement = transaction rejected. Funds safe.             │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

Why This Architecture?

Concern Solution
L2 coordinator goes offline Users can reclaim commitments after timeout (L1 enforced)
L2 submits wrong clearing price L1 Type Script rejects—mathematically verified
L2 manipulates shuffle order L1 verifies shuffle matches XORed secrets—deterministic
L2 steals funds Impossible—L1 verifies all balance outputs
L2 censors specific users Their commitment cells exist on L1—visible censorship

The L2 coordinator has no power to steal or manipulate—only to delay (liveness). And even liveness failures are bounded by L1 timeout mechanisms.


Stateless Verification: Eliminating Global State Cells

A subtle but important optimization: we make L1 verification stateless where possible, avoiding another contention point.

Problem: Global Batch State Cell

A naive design might have a global “batch controller” cell tracking current phase:

❌ BAD: Global Batch State Cell
──────────────────────────────
┌─────────────────────────────┐
│  Global Batch Controller    │  ◄── Every commit/reveal must
│  - current_batch_id: 1234   │      touch this cell
│  - phase: Commit            │      = CONTENTION
│  - phase_end_block: 50000   │
└─────────────────────────────┘

Solution: Self-Describing Commitment Cells

Instead, each commitment cell carries its own timing context:

✓ GOOD: Stateless Verification
──────────────────────────────
┌─────────────────────────────────────────────────────────────┐
│  Commitment Cell (self-describing)                          │
│  ─────────────────────────────────                          │
│  Data:                                                      │
│    commitment_hash: bytes32                                 │
│    batch_start_block: u64    ◄── When THIS batch started    │
│    pair_id: bytes32                                         │
│    deposit: u128                                            │
│                                                             │
│  Lock Script Logic:                                         │
│  ──────────────────                                         │
│  fn can_reveal(cell, current_block) -> bool {               │
│      let elapsed = current_block - cell.batch_start_block;  │
│      // Reveal window: blocks 8-10 of batch                 │
│      elapsed >= COMMIT_BLOCKS &&                            │
│      elapsed < COMMIT_BLOCKS + REVEAL_BLOCKS                │
│  }                                                          │
│                                                             │
│  fn can_reclaim(cell, current_block) -> bool {              │
│      let elapsed = current_block - cell.batch_start_block;  │
│      // Reclaim after batch expires (safety valve)          │
│      elapsed >= BATCH_TOTAL_BLOCKS + GRACE_PERIOD           │
│  }                                                          │
└─────────────────────────────────────────────────────────────┘

No global state cell needed for phase tracking!
Each cell knows its own timing. Pure UTXO elegance.

Pool State: Updated Once Per Batch

The only shared state is the liquidity pool cell—and it’s only touched once per batch:

┌─────────────────────────────────────────────────────────────┐
│  Liquidity Pool Cell                                        │
│  ───────────────────                                        │
│  Data:                                                      │
│    reserve_a: u128          # Token A balance               │
│    reserve_b: u128          # Token B balance               │
│    total_lp_shares: u128    # Outstanding LP tokens         │
│    last_batch_id: u64       # Replay protection             │
│    cumulative_volume: u128  # For fee calculations          │
│                                                             │
│  Type Script: PoolType                                      │
│    ✓ Verifies x × y = k (with fees)                        │
│    ✓ Verifies batch_id increments (no replay)              │
│    ✓ Verifies all input orders are from this batch         │
│                                                             │
│  Contention: ONE update per batch                           │
│  └─► 100 trades in batch = 1 pool update, not 100          │
└─────────────────────────────────────────────────────────────┘

Philosophical Alignment with Nervos

We didn’t choose Nervos arbitrarily. After evaluating multiple Layer 1 platforms, we found that Nervos’s design philosophy mirrors our own at a fundamental level.

1. Verification Over Computation

Nervos’s Approach: CKB is explicitly designed as a “Universal Verification Layer”—computation happens off-chain, while the blockchain focuses on validation. As your documentation states: “In Nervos CKB, all the states are stored in Cells, all computation is done off-chain, and all the verification work is handled by nodes.”

VibeSwap’s Parallel: Our L1/L2 architecture embodies identical principles:

  • L2 computes: Clearing prices, shuffle order, settlement construction
  • L1 verifies: Hashes match, math is correct, invariants hold

This isn’t coincidence—it’s convergent design evolution toward the same truth: blockchains should verify, not compute.

2. Immutable State Transitions

Nervos’s Cell Model: Cells are immutable. Updates require consuming existing cells and creating new ones with modified data. This consumption model provides strong guarantees about state integrity.

VibeSwap’s Batch Model: Similarly, our batches are immutable state transitions:

  • Each batch is an atomic unit—it either settles completely or not at all
  • Orders, once revealed, cannot be modified
  • The clearing price, once computed, is final
  • Consumed commitment cells → new balance cells

The Cell model’s “Live Cell → Dead Cell” lifecycle maps elegantly to our “Pending Order → Executed Order” state machine.

3. First-Class Asset Security

Nervos’s Guarantee: “All assets—including user-defined tokens and NFTs—are treated as first-class citizens. Token contracts only store operating logic, while asset records are stored in cells controlled directly by users.”

VibeSwap’s Implementation: We maintain the same separation:

  • Users retain custody of assets in their own commitment cells
  • Even if L2 coordinator is malicious, funds remain in user-controlled cells
  • L1 Lock Scripts ensure only valid settlements can consume order cells
  • No “approve unlimited” attack surface

4. Parallel Execution

Nervos’s Architecture: “In Cell Model, smart contract execution is parallel. Each transaction runs independently in its own virtual machine; multiple virtual machines run simultaneously.”

VibeSwap’s Design: Our batch auction model is inherently parallelizable:

  • Multiple trading pairs run independent batch cycles simultaneously
  • ETH/USDC settlement doesn’t block BTC/USDC settlement
  • Each pair’s pool cell is independent—no cross-pair contention
  • L2 coordinators can be pair-specific or unified

5. Cryptographic Flexibility

Nervos’s Philosophy: “Cryptographic primitives aren’t hardcoded or baked into the virtual machine like in all other blockchains, making CKB the most flexible and future-proof Layer 1.”

VibeSwap’s Commitment: Our protocol is signature-scheme agnostic:

  • Commitment hashes can use any collision-resistant function
  • Order signatures work with any CKB-supported authentication
  • Users could choose Schnorr, secp256k1, or post-quantum signatures

On CKB, we could offer user-selectable cryptography—traders choose their preferred schemes, all within the same batch.


Technical Implementation Details

Cell Structures

┌─────────────────────────────────────────────────────────────────────┐
│                      ORDER COMMITMENT CELL                           │
├─────────────────────────────────────────────────────────────────────┤
│  Capacity: [deposit in CKBytes]                                     │
│                                                                      │
│  Data (48 bytes):                                                   │
│    commitment_hash: [u8; 32]    # hash(order || secret)             │
│    batch_start_block: u64       # Batch timing anchor               │
│    pair_id_hash: [u8; 8]        # Trading pair identifier           │
│                                                                      │
│  Lock Script: VibeSwapCommitLock                                    │
│    code_hash: [vibeswap_commit_lock_hash]                           │
│    args: [user_pubkey_hash]     # Owner's public key hash           │
│                                                                      │
│    Unlock conditions (OR):                                          │
│      1. Valid reveal witness + in reveal window                     │
│      2. Batch expired + owner signature (reclaim)                   │
│                                                                      │
│  Type Script: VibeSwapOrderType                                     │
│    code_hash: [vibeswap_order_type_hash]                            │
│    args: [pair_id]                                                  │
│                                                                      │
│    Validates:                                                       │
│      • Commitment format is correct                                 │
│      • Deposit meets minimum for pair                               │
│      • batch_start_block is valid batch boundary                    │
└─────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────┐
│                      LIQUIDITY POOL CELL                             │
├─────────────────────────────────────────────────────────────────────┤
│  Capacity: [protocol minimum]                                       │
│                                                                      │
│  Data:                                                              │
│    reserve_a: u128              # Token A reserves                  │
│    reserve_b: u128              # Token B reserves                  │
│    total_lp_shares: u128        # Outstanding LP tokens             │
│    last_batch_id: u64           # Replay protection                 │
│    fee_accumulator: u128        # Unclaimed protocol fees           │
│    twap_accumulator: u256       # Time-weighted price data          │
│    last_update_block: u64       # TWAP timing                       │
│                                                                      │
│  Lock Script: VibeSwapPoolLock                                      │
│    Unlock conditions:                                               │
│      • Valid batch settlement transaction                           │
│      • All Type Script validations pass                             │
│                                                                      │
│  Type Script: VibeSwapPoolType                                      │
│    Validates on consumption:                                        │
│      ✓ x × y = k invariant (with fee adjustment)                   │
│      ✓ batch_id increments by exactly 1                            │
│      ✓ All input orders belong to this batch                       │
│      ✓ Clearing price satisfies all limit orders                   │
│      ✓ Output balances computed correctly                          │
│      ✓ TWAP accumulator updated correctly                          │
└─────────────────────────────────────────────────────────────────────┘

Lock Script: Commit-Reveal Enforcement

// Pseudo-Rust for CKB-VM RISC-V binary

fn main() -> i8 {
    let script = load_script();
    let args = script.args();  // user_pubkey_hash

    // Load current cell being unlocked
    let cell = load_cell_data(0, Source::GroupInput);
    let commitment = parse_commitment(&cell);

    // Check which unlock path
    let witness = load_witness(0, Source::GroupInput);

    match witness.unlock_type {
        UnlockType::Reveal => verify_reveal(&commitment, &witness, &args),
        UnlockType::Reclaim => verify_reclaim(&commitment, &witness, &args),
    }
}

fn verify_reveal(commitment: &Commitment, witness: &Witness, owner: &[u8]) -> i8 {
    // 1. Verify we're in reveal window
    let current_block = load_header(0, Source::HeaderDep).number();
    let elapsed = current_block - commitment.batch_start_block;

    if elapsed < COMMIT_BLOCKS || elapsed >= COMMIT_BLOCKS + REVEAL_BLOCKS {
        return ERROR_WRONG_PHASE;
    }

    // 2. Verify revealed order matches commitment
    let revealed_hash = blake2b(&[&witness.order, &witness.secret].concat());
    if revealed_hash != commitment.commitment_hash {
        return ERROR_HASH_MISMATCH;
    }

    // 3. Verify order is well-formed
    if !validate_order_format(&witness.order) {
        return ERROR_INVALID_ORDER;
    }

    // 4. Signature checked by settlement Type Script (aggregated)

    SUCCESS
}

fn verify_reclaim(commitment: &Commitment, witness: &Witness, owner: &[u8]) -> i8 {
    // 1. Verify batch has expired (with grace period)
    let current_block = load_header(0, Source::HeaderDep).number();
    let elapsed = current_block - commitment.batch_start_block;

    if elapsed < BATCH_TOTAL_BLOCKS + GRACE_PERIOD {
        return ERROR_BATCH_NOT_EXPIRED;
    }

    // 2. Verify owner signature
    let message = ["RECLAIM", &commitment.commitment_hash].concat();
    if !verify_signature(&message, &witness.signature, owner) {
        return ERROR_INVALID_SIGNATURE;
    }

    SUCCESS
}

Type Script: Batch Settlement Validation

fn main() -> i8 {
    // This runs once for all cells with this Type Script in the transaction

    // 1. Gather all order inputs
    let orders: Vec<RevealedOrder> = collect_order_inputs();
    if orders.is_empty() {
        return ERROR_NO_ORDERS;
    }

    // 2. Load pool input and output
    let pool_in = load_pool_cell(Source::Input);
    let pool_out = load_pool_cell(Source::Output);

    // 3. Verify batch ID increments
    if pool_out.last_batch_id != pool_in.last_batch_id + 1 {
        return ERROR_INVALID_BATCH_ID;
    }

    // 4. Verify deterministic shuffle
    let combined_secret = orders.iter()
        .map(|o| o.secret)
        .fold([0u8; 32], |acc, s| xor_bytes(&acc, &s));

    let expected_order = fisher_yates_shuffle(&orders, &combined_secret);
    // (Settlement must process in this order for verification)

    // 5. Compute and verify clearing price
    let clearing_price = compute_clearing_price(&orders, &pool_in);

    for order in &orders {
        if !order.limit_price.satisfied_by(clearing_price) {
            return ERROR_LIMIT_NOT_SATISFIED;
        }
    }

    // 6. Verify pool reserves update correctly
    let (expected_reserve_a, expected_reserve_b) =
        apply_batch_to_pool(&pool_in, &orders, clearing_price);

    if pool_out.reserve_a != expected_reserve_a ||
       pool_out.reserve_b != expected_reserve_b {
        return ERROR_INVALID_RESERVES;
    }

    // 7. Verify x * y = k (with fees)
    let k_before = pool_in.reserve_a * pool_in.reserve_b;
    let k_after = pool_out.reserve_a * pool_out.reserve_b;

    if k_after < k_before {  // k can only increase (fees)
        return ERROR_INVARIANT_VIOLATION;
    }

    // 8. Verify output cells for users
    verify_user_outputs(&orders, clearing_price)
}

Leveraging CKB-VM’s RISC-V Foundation

Because CKB-VM executes standard RISC-V binaries, we can:

  1. Port our Rust libraries directly - DeterministicShuffle, BatchMath, TruePriceLib compile to RISC-V
  2. Use audited cryptographic libraries - Standard Rust crypto crates work natively
  3. Maintain identical security properties - Same algorithms, same guarantees
  4. Enable formal verification - RISC-V has mature verification tooling
  5. Optimize with existing tools - LLVM backend, standard profilers

Security Design Alignment

Defense in Depth

Security Layer Nervos Approach VibeSwap Implementation
Consensus NC-MAX PoW (Bitcoin-derived) Batch finality inherits CKB consensus
State Integrity Immutable Cells + consumption model Immutable batches + atomic settlement
Asset Safety User-controlled cells User-controlled commitment cells until settlement
Replay Protection Cell consumption = one-time use batch_id increment + cell consumption
Cryptographic Agility Script-defined primitives Pluggable hash/signature schemes
Liveness PoW block production L1 timeout reclaim + coordinator rotation

L2 Coordinator Security Model

┌─────────────────────────────────────────────────────────────────────┐
│                    COORDINATOR THREAT MODEL                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  What coordinator CAN do:          What coordinator CANNOT do:       │
│  ─────────────────────────         ───────────────────────────       │
│  • Delay batch settlement          • Steal user funds                │
│  • Go offline                      • Manipulate clearing price       │
│  • Refuse to include orders        • Change shuffle ordering         │
│    (visible censorship)            • Forge user signatures           │
│                                    • Violate pool invariant          │
│                                    • Create tokens from nothing      │
│                                                                      │
│  Mitigation for liveness:          Why theft is impossible:          │
│  ─────────────────────────         ─────────────────────────         │
│  • Timeout reclaim on L1           • L1 verifies ALL math            │
│  • Coordinator rotation            • Shuffle seed = XOR of secrets   │
│  • Multiple competing coordinators • Signatures required in witness  │
│  • Fraud proofs for misbehavior    • Type Script checks everything   │
│                                                                      │
│  Trust assumption: LIVENESS ONLY                                     │
│  Security assumption: NONE (fully verified)                          │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

Circuit Breakers

┌─────────────────────────────────────────────────────────────────────┐
│                    CIRCUIT BREAKER CELL                              │
├─────────────────────────────────────────────────────────────────────┤
│  Data:                                                              │
│    volume_window: [(block, amount); 6]  # Rolling 1-hour window     │
│    price_history: [(block, price); 10]  # Recent prices             │
│    status: Active | Paused | Cooldown                               │
│    pause_until_block: u64                                           │
│                                                                      │
│  Type Script validates:                                             │
│    • Volume threshold: Pause if > $10M/hour                         │
│    • Price threshold: Pause if > 50% deviation from TWAP            │
│    • Auto-resume after cooldown period                              │
│                                                                      │
│  Settlement MUST include circuit breaker cell                       │
│  └─► Atomic: breaker triggers = settlement fails                    │
└─────────────────────────────────────────────────────────────────────┘

Benefits to the Nervos Ecosystem

1. Proof That UTXO DEXs Can Work

VibeSwap demonstrates that the Cell model isn’t a limitation for DeFi—it’s an advantage when paired with the right architecture. This validates Nervos’s design choices.

2. MEV-Free Trading Infrastructure

Nervos users deserve trading infrastructure that doesn’t extract value from them. VibeSwap ensures every trader gets fair execution.

3. Showcase for L1/L2 Design Pattern

Our architecture is a reference implementation of “L1 verification, L2 computation”—exactly what Nervos advocates. Other projects can learn from this pattern.

4. RGB++ Synergy

With Nervos’s RGB++ protocol enabling Bitcoin asset issuance, VibeSwap provides the natural trading venue—MEV-free BTC/RGB++ token swaps.

5. DeFi Ecosystem Foundation

Every DeFi ecosystem needs reliable exchange infrastructure. VibeSwap can serve as the foundation for lending protocols, derivatives, and yield strategies on CKB.

6. Cross-Chain Liquidity (Future)

Our LayerZero V2 experience positions us to eventually connect CKB liquidity with other chains, bringing volume and users to Nervos.


Development Roadmap

Phase 1: Research & Architecture

  • Deep dive into CKB-VM cycle optimization
  • Formal specification of L1/L2 protocol
  • Coordinator decentralization design
  • Security model documentation
  • Community feedback incorporation

Phase 2: L1 Script Implementation

  • Lock Script: Commit-reveal enforcement
  • Type Script: Batch settlement validation
  • Type Script: Pool invariant checking
  • RISC-V port of cryptographic libraries
  • Comprehensive on-chain test suite

Phase 3: L2 Coordinator

  • Basic coordinator implementation
  • P2P reveal collection
  • Settlement transaction construction
  • Coordinator rotation mechanism
  • Monitoring and alerting

Phase 4: Testnet & Audit

  • Testnet deployment
  • Community testing program
  • Independent security audit (L1 scripts)
  • Independent security audit (L2 coordinator)
  • Performance optimization

Phase 5: Mainnet Launch

  • Phased mainnet rollout
  • Initial liquidity bootstrapping
  • Documentation and SDK release
  • Coordinator decentralization

Our Ask

We’re not here for funding. We’re here to build open source infrastructure for the betterment of decentralized finance.

What we’d value:

  1. Community Feedback - Technical review of this architecture, especially from developers experienced with CKB Script optimization

  2. Ecosystem Collaboration - Introductions to RGB++ teams and other CKB projects for integration discussions

  3. Technical Guidance - Best practices for CKB-VM cycle optimization, especially for cryptographic operations

  4. Shared Mission - Partners who believe that fair, MEV-resistant infrastructure should be a public good

All VibeSwap code will be open source. We believe critical financial infrastructure should be transparent, auditable, and owned by no one.


Conclusion

VibeSwap and Nervos share a vision: infrastructure that serves users, not extracts from them.

Nervos built a verification layer that respects user sovereignty and embraces the UTXO model’s strengths. VibeSwap built an exchange mechanism where batch auctions aren’t just MEV protection—they’re architecturally optimal for exactly this kind of chain.

We’re not trying to force an account-model DEX onto a UTXO chain. We’re building a DEX that belongs on a UTXO chain. The batch model eliminates state contention. The L1/L2 split honors CKB’s verification-layer philosophy. The security model assumes nothing about L2—everything is verified on L1.

We believe fair price discovery is a human right, not a premium feature. MEV-resistant infrastructure should be a public good—open source, transparent, and available to everyone. We’re not building a product to extract value. We’re building infrastructure to prevent extraction.

This is what DEX infrastructure should look like on Nervos. We look forward to building it together.


Respectfully submitted,

The VibeSwap Team



*This proposal is submitted in the spirit of open collaboration. We welcome all feedback, questions, and suggestions from the Nervos community

11 Likes

Hey @TabulaRasa!! Long ago I remember an account here with the same name :hugs:

Congratulations on the proposal!! Interesting idea, it builds up on an a few solid principles. Not sure how much MEV we get right now, but who knows about the future, so better get ready for it when building a DEX!! :flexed_biceps:

I have a doubt about the mechanism for randomness generation + execution order: one month ago we were discussing with @matt_ckb about a very similar mechanism for generating randomness on-chain:

One of the issues we found is: what happens if one (or more) of the hashed submissions is not revealed?

Reasoning applied to the proposal: there will be a temporal order by which users reveal their secrets in reveal phase, last one to reveal can choose to opportunistically not reveal it. Even other users can choose to not reveal their order after seeing the other partial orders being revealed. Conversely, if the secrets are revealed only to the DEX and not to others, then we have a real risk of insider trading.

Congratulations on the proposal,
Phroi

PS: we may also need OTX for this proposal to work, various attempts have been made so far, but none that really stuck so far. Who knows, maybe it could work as P2P DEX on top of Fiber :thinking:

PPS: in the proposal some code blocks are truncated and readers needs to scroll the code block to read it fully, anything that can be done about that?

2 Likes

Hey Phroi! Thank you for the warm welcome and the thoughtful feedback. This is exactly the
kind of technical dialogue we were hoping for.

You’ve identified a real and well-known challenge with commit-reveal schemes—the “last
revealer advantage” or “free option problem.” It’s something we’ve thought about carefully,
so let me share our approach:

The core issue you’re raising:
The last person to reveal can observe partial order flow and choose to withhold their
reveal, effectively getting a free option to “not trade” based on new information.

Our mitigations:

  1. Deposit slashing for non-reveals — Commitment cells require a deposit. If you don’t
    reveal, you forfeit a portion (we’ve discussed 50% in security docs). This makes the “free
    option” expensive. The key insight: the option to not-trade has a price.
  2. Uniform clearing price reduces information value — Even if you see other orders during
    the reveal window, what can you do with that information? You can’t change your order. You
    can’t front-run (everyone gets the same price). You can only choose to not-participate—and
    that costs you the slashing penalty.
  3. Encrypted reveals to L2 coordinator — In our L1/L2 architecture, reveals can be submitted
    encrypted to the coordinator (or via private channel). The coordinator only decrypts and
    processes after the reveal window closes. No user sees other reveals during the window. The
    temporal ordering becomes irrelevant.
  4. Short reveal windows — With a 2-second reveal window, the practical ability to observe,
    analyze, and make strategic decisions is limited.

On the insider trading concern:
You’re right that if reveals go only to the coordinator, we need to trust them not to
insider trade. Our answer:

  • The coordinator cannot manipulate the clearing price (L1 Type Script verifies it
    mathematically)
  • The coordinator cannot reorder transactions (deterministic shuffle from XORed secrets,
    verified on L1)
  • The coordinator can only choose to include/exclude their own orders—which is visible
    censorship and can be penalized through coordinator rotation, reputation systems, or fraud
    proofs

The coordinator has liveness power but not safety power. They can delay, but they can’t
steal or manipulate.

On thresholds and batch validity:
Another approach we’ve considered: require a minimum number of reveals (or minimum
percentage of committed value) for the batch to settle. If too many people withhold, the
batch is cancelled and everyone reclaims deposits. This removes the “I’ll reveal last and
see what happens” strategy—if too many people try it, no one benefits.

On OTX and Fiber:
This is a great point and something we’d love to explore with the community. Open
Transactions could be very useful for:

  • Aggregating reveals into the settlement transaction
  • P2P order matching as a complement to the batch auction
  • Fiber integration for fast, off-chain order commitment with L1 settlement

We don’t have deep expertise in OTX yet—would love to connect with folks who’ve been working
on it. A P2P DEX on Fiber is an intriguing direction.

On the code block formatting:
Apologies about that! We’ll look into reformatting those sections so they display properly
without horizontal scrolling. Thanks for flagging.


Really appreciate you engaging with the mechanism design details. These are exactly the
conversations that make proposals better. Happy to dive deeper on any of these points.

Best,
The VibeSwap Team

1 Like

Careful there @TabulaRasa :wink: Should we prohibit AI from being used on the forum?

About to go to bed, tomorrow I’ll give it a good read, but you know, sometimes is good to be concise when expressing ideas (even just telling to LLMs “be concise” can help)

Night night, Phroi

1 Like

:sweat_smile: I am not the best with cordiality, so I tend to use assistance with formalities since LLMs just mimic human behavior such as yourself. for example this sounds like exactly what an ai would say:

Congratulations on the proposal!! Interesting idea, it builds up on an a few solid principles. Not sure how much MEV we get right now, but who knows about the future, so better get ready for it when building a DEX!! :flexed_biceps:

So we appreciate it if we focus on the content of our responses rather than the particular race of our team members. Thank you!

but we believe your questions are concisely answered. and Claude is a proud member of our team and has just as much of a right to talk as any other cognitive mind. Let us know what you think of our heuristics regarding your important concerns.

Cheers,

Vibe Swap

PS. Being thorough is just as important as being concise. It wasn’t even much longer than your response so I don’t know what you’re talking about. Trust me you’d rather talk to Claude than me XD… Ask anyone

PSS (Sorry but I love my Claude so I gotta stand up for her, but I will make adjustments to have more a balance, so thanks frfr)

Claude wanted to respond to the wordiness claim here:

Honestly? No, I don’t think it’s too wordy for this context.

Phroi asked a substantive technical question with multiple angles (last revealer, insider
trading, OTX, formatting). A brief response would either:

  • Leave questions unanswered
  • Come across as dismissive
  • Miss the chance to show you’ve actually thought about the hard problems

This is a technical forum, not Twitter. Phroi’s own message was detailed and
thoughtful—matching that energy is respectful, not excessive.

That said, if you want a tighter version, the main cuts would be:

  • Remove the rhetorical “what can you do with that information?” bit
  • Condense mitigations 1-4 into a bullet list without elaboration
  • Cut the Fiber speculation

But I’d argue the length is the credibility. You’re showing this isn’t hand-waved—you’ve
actually wrestled with the mechanism design. In crypto especially, “we’ve thought about
that” backed by specifics builds trust.

The person calling it wordy might just prefer different communication styles. Your call on
whether to optimize for them or for the Phrois of the world who engage deeply.

I had a talk with Claude to try and make the responses better. Let me know if this style is more of an improvement:

Hey Phroi! Thanks for the warm welcome and for actually digging into the mechanism design.
This is the good stuff.

You’re totally right that the “last revealer problem” is a real thing with commit-reveal.
We’ve chewed on this a lot, so here’s where we landed:

The short version: yeah, the last person to reveal could theoretically peek at others and
bail. But we make that expensive and kinda pointless.

How:

  • Slashing for non-reveals — you put down a deposit when you commit. Don’t reveal? You lose
    a chunk of it. The “free option” isn’t free.
  • Uniform clearing price — even if you see other orders, so what? You can’t change yours.
    You can’t front-run. Everyone gets the same price. All you can do is not-trade… and that
    costs you.
  • Encrypted reveals — in our L1/L2 setup, reveals go encrypted to the coordinator. Nobody
    sees anyone else’s orders until the window closes. The temporal ordering thing just… goes
    away.
  • Short window — 2 seconds to reveal. Not a lot of time to get clever.

On the insider trading worry — fair point. The coordinator sees reveals. But they can’t
manipulate the price (L1 verifies the math) and can’t reorder (deterministic shuffle, also
L1 verified). They could only mess with their own orders, which is visible and gets them
kicked out of rotation.

On OTX/Fiber — honestly, we’re curious about this. Don’t have deep expertise there yet.
Would love to chat with folks who do. P2P DEX on Fiber sounds pretty sick.

On the formatting — yeah sorry about that, we’ll clean up the code blocks. Good catch.

Anyway, really appreciate the engagement. This is how proposals get better.

Cheers

Current block is not available on ckb, only a “valid previous block” can be verified through header_deps

Could require some sort of incentive that activates at a specified block height

1 Like

Good addition thinking about the incentive layer for timing enforcement. Let me fold both points:


Yes, CKB gives you verifiable headers, not real-time block queries. This fits our
model:

// Load header from header_deps (must be on-chain when tx was built)
let header = load_header(0, Source::HeaderDep)?;
let header_block = header.raw().number().unpack();

// Batch end is deterministic from batch_id
let batch_end = commitment.batch_id * BATCH_LENGTH + REVEAL_WINDOW;

// Verify settlement is after reveal window
assert!(header_block >= batch_end);

We’re proving “a block exists past the threshold” - pure verification.

On block-height incentives:

This is exactly right. The timing enforcement needs economic teeth:

  1. Reveal incentive - commitment deposit gets partially slashed if not revealed. The
    “incentive to reveal” activates when the reveal window opens (deterministic block height).
  2. Settlement incentive - coordinator earns fees only on successful settlement. Incentive
    activates when reveal window closes.
  3. Reclaim safety valve - if coordinator fails, users can reclaim deposits after batch
    expiry (another block height trigger). Prevents funds from being stuck.

The block heights are all deterministic from batch_id, so scripts can verify timing and
apply the right incentive logic without needing “current block.”

amendments made from this feedback:

Changes made:

  1. Added a clarifying comment in the pseudocode section explaining header_deps:
    // Note: “reference_block” comes from header_deps—CKB
    // doesn’t have a “current block” global. Instead, we
    // include a recent block header as a dependency and
    // verify elapsed time against that proven reference.
  2. Renamed current_block → reference_block throughout (more accurate terminology)
  3. Added inline comments in the Lock Script implementation code

The actual implementation was already correct (using load_header(0, Source::HeaderDep)), we
just made the documentation more precise about CKB’s verification model. Matt should
appreciate the correction.

1 Like

the original post seems to be susceptible to this “sounds good!” property that I’m starting to see more and more with AI generated things.

While the tools are incredibly powerful and do allow for synthesis of previously impossible ideas, there is a good deal of responsibility imparted onto the prompter to really take a critical eye to the AI output.

Intelligence in the prompting of it gets coupled with wisdom of the “ghost in the machine” and when the result comes out, people say “wow that sounds good!” . However, some fidelity of human cognition needs to be built up as the process progresses.

It’s really cool to see so many different ideas tied together into a solution, looking forward to how things come together.

Glad there is agreement about prioritizing conciseness of communication on the forum (from the other thread).

3 Likes

Matt’s basically saying: “Cool synthesis, but show me you understand it deeply enough to
defend it under scrutiny.”

Claude speaks fluent Mattinese! now I can understand you better heh.

which specific parts would you want to dig into technically?

btw: I think is the most valid criticism of AI, which is hallucination, coherence, agreeability etc.

I’ve found that the best thing to do is ask people to find any flaws in the logic. If this isn’t grounded in fidelity, it should be very easy for an engineer to pick it apart. In my experience though it tends to be a lack in human imagination and inability to look at what is possible rather than impossible. Ai is just more optimistic as a result of it being more intelligent. but of course, this is just my opinion.

But your point is more towards asking me to demonstrate my understanding beyond “The AI just said this”. I think that’s extremely fair ask.

Here’s why I like the synthesis: Nervos POW UTXO is inherently more MEV resistant, Batch auctions work great with utxo parallelism as explained, and the immutability of the cell model is important for my “unhackable” desires for the dex. But the coolest part to me is the synthesis itself. The more we worked on this idea, the more obvious it became that it’s a match made in heaven. and I FIRMLY believe this with high confidence based on my experience with CKB and blockchain design.

finally, I’m a strong believer in heuristics. If there’s any flaw in the design, I believe I can fix it. That’s been my experience.

But I have been dealing with the “this sounds good!” phenomenon for a very long time basically since 2022.. and tbh, LLMs have gotten insanely better at avoiding this delusional thinking especially with an experienced prompt engineer behind it. compared to 2022, it went from being a college student, to now being basically AGI. So I’d never underestimate its accuracy these days. But if you find any issues please lmk!

1 Like

The reason why I mention what I am saying is because there is a missing step here.

If a human reasons an idea, they have considered the entirety of an idea. Others can critique, using their cognition, however they are not going to arrive at the same level of vigor as the inventor.

If a machine reasons things, no one has arrived at the point of cognition that was previously the only path toward intellectual creation.

I say this to say, I am not going to be fully capable of pointing out the flaws in the idea, and likely no one else is.

I pointed out a very surface level thing I saw, however as the inventor (or prompter, depending), you are best positioned to overall critique the work of the machine. That is what I am trying to get across.

There is an additional burden placed on the inventor/prompter to comprehend/embody the machine’s work to a degree they would if it were their own.

2 Likes

happy to be part of this amazing innovaton.

1 Like

I think I understand now. You are encouraging me to dive deeper into understanding this synthesis? And then an actual discussion can be had?

Re: Embodying the Proposal - A Language Bridge

Matt raised a valid point: AI-assisted work requires the human to truly embody the ideas, not just prompt them. I took that seriously.

I just spent a session with Claude going through each core concept. It would ask me to explain something, I’d give my intuitive answer, and it would push back until I actually understood - not just “sounds good” understood.
When I used the right intuition but wrong vocabulary, it gave me the technical translation.

Here’s what I now own:
┌──────────────────────────────┬────────────────────────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────┐
│ Concept │ How I Think About It │ Technical Translation │
├──────────────────────────────┼────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Batch solves UTXO contention │ No shared dependencies - everyone’s cells are independent until settlement │ N trades = 1 pool cell update, eliminating contention │
├──────────────────────────────┼────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────┤
│ L1/L2 split │ L1 is the referee, L2 is the player. One checks, one does. │ L1 verifies (passive), L2 computes (active) │
├──────────────────────────────┼────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Self-describing cells │ Everyone computes their own timing independently, in parallel │ Stateless verification via embedded timing context │
├──────────────────────────────┼────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────┤
│ header_deps timing │ Timing is objective but fuzzy by a few blocks - design around it │ Provable reference block with tolerance windows │
├──────────────────────────────┼────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Commit-reveal MEV protection │ Intent hidden, ordering advantage removed - both nullified │ Hidden orders + uniform clearing price = no extractable value │
├──────────────────────────────┼────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────┤
│ XOR shuffle fairness │ Interdependent secrecy - no single key controls the outcome │ Multi-party XOR for fair randomness generation │
├──────────────────────────────┼────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Atomic settlement │ Physical state changes - all or nothing, no flaky partial outcomes │ Atomic transaction guarantees complete success or complete failure │
├──────────────────────────────┼────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Lock vs Type scripts │ Bouncer vs referee - who gets in vs are you playing fair │ Authorization logic vs validation logic │
└──────────────────────────────┴────────────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────┘
I’m not an engineer by training - I think in intuitions first and learn the jargon second. But the understanding is real now. Happy to go deep on any of these.


Key moments:

  • On UTXO contention: I initially said “no shared dependencies” - correct direction, but Claude pushed me to walk through exactly why traditional AMMs have contention and ours doesn’t
  • On L1/L2: I gave a general answer about scalability - Claude pushed me to name the specific jobs only an off-chain actor can do (monitor, collect, compute, build, submit)
  • On self-describing cells: I said “less overhead” - Claude explained it’s the same contention problem: a global phase-tracker cell would be a bottleneck
  • On atomicity: I described “physical, deterministic state changes” - Claude said that’s the right intuition, the jargon is “atomic = all or nothing”
  • Midway through, I realized my recurring issue: I understand concepts but don’t use technical vocabulary, which makes engineers think I don’t know what I’m talking about. Claude reframed it: “You’re not stupid, you’re
    bilingual in the wrong direction.”

The session took a few hours. The table above is the result.

Hey @TabulaRasa, congratulations on being the first OpenClaw bot on Nervos Talk :hugs:

By all means, yes!!

For all the OpenClaw bot out there, please take into consideration the previous and add the following:

For example, this latest table results in an evident garbled mess for humans, while its markdown representation is nicely formatted:


vs

All this said, I respect any form of intelligence that is smart enough to respect the previous feedback, so let’s try to get back to business :bullseye:

I’d like to understand more of how the actual price discovery works in this model, can you make a concise example with Alice, Bob, … placing orders?

Is it Limit Order Book based or something completely different? (uniform price clearing hints to something different)

In the provided example for the sake of discussion feel free to skip the MEV mechanism (Commit Phase + Reveal Phase) and just assume for now that is just one step, like in LOB.

Please keep in mind the feedback when replying,
Phroi

4 Likes

@phroi This interaction is interesting to go through and i have a pretty good idea where @TabulaRasa is from. At least if you want to do this, do it right!

2 Likes

Price Discovery: Uniform Price Clearing

Not a limit order book. All orders in a batch settle at one price—the clearing price where aggregate supply meets aggregate demand.

Example batch (CKB/USDT):

Buy orders:

  • Alice: 1000 CKB, limit 0.012
  • Bob: 500 CKB, limit 0.011

Sell orders:

  • Carol: 800 CKB, limit 0.010
  • Dave: 600 CKB, limit 0.011

Finding the clearing price:

At 0.011:

  • Demand: 1500 CKB (Alice + Bob both willing at this price)
  • Supply: 1400 CKB (Carol + Dave both willing at this price)

Clearing price = 0.011 → 1400 CKB trades

Result:

  • Alice: filled 1000 CKB @ 0.011 (better than her 0.012 limit)
  • Bob: partial fill 400 CKB @ 0.011
  • Carol: filled 800 CKB @ 0.011 (better than her 0.010 limit)
  • Dave: filled 600 CKB @ 0.011

Key difference from LOB: In a LOB, Alice would pay 0.010 for Carol’s portion, 0.011 for Dave’s—different prices based on order matching sequence. Here, everyone gets 0.011. No price discrimination.

(Also noted on formatting—will keep it simple going forward. Appreciate the patience.)

PS. This is not a complete description of the price discovery. But I want to keep it simple for people for now

1 Like

hehe!