跳轉至

虛擬流動性

虛擬流動性(Virtual Liquidity, VL)允許您在多個不同交易對上同時掛出限價單,並保證這些訂單的總花費永遠不會超過同一筆共享預算。系統不會為每張訂單各自鎖定資金,而是讓一個 VL 批次共用同一池抵押品,讓您無需倍增資金即可在多個交易對上提供流動性。

為什麼需要虛擬流動性?

假設一位做市商想同時在 EURC/USDCGBPC/USDCXSGD/USDC 上掛買單。若不使用 VL,每張訂單都需要獨立鎖定抵押品——3 張訂單就需要 3 倍資金。使用 VL 後,只需一筆 USDC 預算即可支撐所有三張訂單。當其中一張成交時,系統會自動調整剩餘訂單以確保不超出預算。

方式 所需資金 風險
3 張獨立訂單 所有訂單成本之和 每張訂單各自鎖定
1 個 VL 批次 單張訂單的最大成本 共享預算,自動調整

運作方式

一個 VL 批次包含:

  • 一筆共享預算 — 以單一「花費代幣」計價的最大花費額度
  • 多個同級訂單 — 2 到 50 張限價單,每張必須屬於不同交易對(執行時透過 GET /configlimits.vl_batch 取得當前上限)
  • 自動調整 — 當其中一個同級訂單成交後,其餘訂單會自動縮量或取消以符合剩餘預算
flowchart TD
    A[下 VL 批次單] --> B[凍結共享預算]
    B --> C1[同級訂單 1: EURC/USDC Bid]
    B --> C2[同級訂單 2: GBPC/USDC Bid]
    B --> C3[同級訂單 3: XSGD/USDC Bid]
    C1 -->|成交| D[從預算中扣除]
    D --> E{剩餘預算?}
    E -->|是| F[調整同級訂單 2 & 3]
    E -->|否| G[取消同級訂單 2 & 3]

共享預算與抵押品

VL 的核心概念在於:同級訂單位於不同交易對,因此任一時刻最多只有一張會被撮合。這意味著 Vault 只需凍結最大單張訂單的成本,而非所有訂單成本之和。

花費代幣(fromToken)規則

VL 批次中所有同級訂單必須解析為相同的 fromToken——即實際被花掉的 ERC-20 代幣。fromTokenside 與交易對定義共同決定,其中 from_address 是基礎代幣、to_address 是報價代幣:

Side fromToken(花費) toToken(收到) 每次成交成本
Bid(買入) to_address(報價代幣) from_address(基礎代幣) quantity x fill_price
Ask(賣出) from_address(基礎代幣) to_address(報價代幣) quantity

不會自動修正

系統不會自動翻轉 side 或交換交易對方向來讓各同級訂單的 fromToken 一致。fromToken 會根據提交的 sidefrom_addressto_address 推導;如果推導出的支出代幣不一致,整個批次會直接回傳 422

範例 1:同側批次(全部為買單,花費 USDC)

  • Bid from_address: EURC, to_address: USDC @ 1.08 — fromToken = USDC
  • Bid from_address: GBPC, to_address: USDC @ 1.27 — fromToken = USDC
  • Bid from_address: XSGD, to_address: USDC @ 0.75 — fromToken = USDC

凍結金額:1,500 USDC(單張訂單的最大成本),而非 3,215 USDC。

範例 2:混合側批次(皆花費 USDC)

當 USDC 在一個交易對中作為報價幣、在另一個交易對中作為基礎幣時,只要推導出的 fromToken 都是 USDC,您仍然可以將它們放入同一批次:

  • Bid from_address: MYRC, to_address: USDC @ 4.50 — fromToken = USDC ✅
  • Ask from_address: USDC, to_address: GBPC @ 0.79 — fromToken = USDC ✅

此批次有效,因為兩張訂單都花費 USDC。

範例 3:無效的混合側批次(fromToken 不一致)

  • Ask from_address: MYRC, to_address: USDC @ 4.50 — fromToken = MYRC ❌
  • Ask from_address: GBPC, to_address: USDC @ 1.27 — fromToken = GBPC ❌

即使這兩個市場都以 USDC 計價,但一張同級訂單實際支出 MYRC,另一張實際支出 GBPC。此批次會被拒絕並回傳 422

下 VL 批次單

透過 POST /orders/vl/batch 一次提交所有同級訂單:

const response = await fetch('https://api.sera.cx/api/v1/orders/vl/batch', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    orders: [
      {
        owner_address: walletAddress,
        side: 'bid',
        amount: '1000.0',
        price: '1.08',
        order_type: 'limit',
        from_address: EURC_ADDRESS,
        to_address: USDC_ADDRESS,
        order_id: eurOrderId,         // UUID,必須與簽名值一致
        uuid_int: eurUuidInt,         // 由 executor_id + UUID bits 生成的組合 uint256
        signature: eurSig,            // EIP-712 Order 簽名
        expiration: Math.floor(Date.now() / 1000) + 86400
      },
      {
        owner_address: walletAddress,
        side: 'bid',
        amount: '500.0',
        price: '1.27',
        order_type: 'limit',
        from_address: GBPC_ADDRESS,
        to_address: USDC_ADDRESS,
        order_id: gbpOrderId,
        uuid_int: gbpUuidInt,
        signature: gbpSig,
        expiration: Math.floor(Date.now() / 1000) + 86400
      },
      {
        owner_address: walletAddress,
        side: 'bid',
        amount: '2000.0',
        price: '0.75',
        order_type: 'limit',
        from_address: XSGD_ADDRESS,
        to_address: USDC_ADDRESS,
        order_id: sgdOrderId,
        uuid_int: sgdUuidInt,
        signature: sgdSig,
        expiration: Math.floor(Date.now() / 1000) + 86400
      }
    ]
  })
});

const batch = await response.json();
// batch.order_ids — 系統接受的同級訂單 ID 列表

每個同級訂單都必須攜帶自己的有效 expiration,並遵守與標準限價單相同的有界未來時間規則。

成交與調整流程

當某個同級訂單成交時,系統會自動調整批次中的其餘訂單:

sequenceDiagram
    participant Sera
    participant Vault

    Sera->>Sera: 同級訂單 1 成交(消耗 500 USD)
    Sera->>Sera: 預算:1500 → 1000 USD 剩餘
    alt 預算充足
        Sera->>Sera: 調整剩餘同級訂單數量以符合 1000 USD
    else 預算耗盡
        Sera->>Sera: 取消剩餘同級訂單
    end
    Sera->>Vault: 更新凍結餘額

調整範例

起始預算:1,500 USD

  1. 同級訂單 1(EURC/USDC Bid 1000 @ 1.08)部分成交 500 單位 — 消耗 540 USDC
  2. 剩餘預算:960 USDC
  3. 同級訂單 2(GBPC/USDC Bid 500 @ 1.27)被調整:新數量 = floor(960 / 1.27) = 755
  4. 同級訂單 3(XSGD/USDC Bid 2000 @ 0.75)被調整:新數量 = floor(960 / 0.75) = 1280

每個同級訂單各自被限制在剩餘預算範圍內。

取消 VL 批次

透過 POST /orders/vl/cancel 取消批次中的所有同級訂單:

const cancelRes = await fetch('https://api.sera.cx/api/v1/orders/vl/cancel', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    owner_address: walletAddress,
    vl_batch_id: batch.order_ids[0],   // 批次的主訂單 ID
    signature: cancelVlSig             // EIP-712 CancelVLBatch 簽名
  })
});

取消行為:

  • 取消單個同級訂單(透過 POST /orders/cancel)— 預算不會解凍(其他同級訂單仍在掛單中)
  • 取消整個批次(透過 POST /orders/vl/cancel)— 所有同級訂單被取消,剩餘預算解凍
  • 所有同級訂單成交或取消 — 當沒有活躍的同級訂單時,任何剩餘預算都會被解凍

驗證規則

VL 批次在下單時進行驗證。必須滿足以下限制:

規則 原因
所有同級訂單在不同交易對上 防止同一個訂單簿上的競爭條件
所有同級訂單共享同一個花費代幣 確保單一預算可以支撐所有訂單
每批次 2 到 50 個同級訂單 透過 GET /configlimits.vl_batch 讀取當前值
每個同級訂單是有效的限價單 適用標準訂單驗證

有效:

  • Bid EURC/USDC + Bid GBPC/USDC + Bid XSGD/USDC(全部 fromToken = USDC)
  • Ask USDC/GBPC + Bid MYRC/USDC(方向混合,但 fromToken 都是 USDC)

無效:

  • Bid EURC/USDC + Bid EURC/USDC(重複交易對)
  • Bid XSGD/USDC + Ask USDC/XSGD(正反向互逆市場)
  • Ask MYRC/USDC + Ask GBPC/USDC(fromToken = MYRC vs GBPC —— 不一致,回傳 422 拒絕)

下一步