批量拍卖
STRIKE 使用 Frequent Batch Auctions (FBA),而不是连续撮合订单。这是决定交易如何执行的核心机制。
批次如何清算
Accumulate 订单 — 在批次间隔内,交易者可以下单和取消订单。订单会记录在链上,但尚未撮合。
Trigger 清算 — 任何人都可以调用
clearBatch(marketId)。该操作无需许可。链上不强制执行批次间隔;keeper 决定清算 cadence。Find 清算价格 — 合约使用线段树和二分搜索找到清算 tick:
Binary search 用于找到满足 cumulative bid >= cumulative ask 的最高 tick
Post-search correction: 检查 tick+1,确保
min(cumBid, cumAsk)对应最大匹配量这会处理 ask 在交叉 tick 超过 bid 的情况
Calculate 按比例成交 — 在清算 tick,如果一侧超额认购,该侧每笔订单获得
filledLots = (orderLots * matchedLots) / totalSideLots。存储结果并推进批次 — 写入
BatchResult:清算 tick、匹配手数、买卖总手数和时间戳。批次计数器随后推进,新订单进入下一个批次。原子化结算 — 所有订单在同一笔交易中内联结算:
已成交抵押资产(按清算价格,而非订单 tick)转入市场池
Excess 退款 =(按订单 tick 锁定)-(按清算 tick 计算的 cost),返回所有者
统一费用(20 bps)扣除并发送到协议费用收集器
Positions credited(bidder 获得 UP,asker 获得 DOWN)— 用于内部持仓市场;ERC-1155 代币用于基于代币的市场
未成交抵押资产返回所有者
GTC 订单会将剩余 lots 滚入下一个批次
抵押资产模型(USDT)
双方都锁定 USDT(ERC-20)。用户下单前必须授权金库。Asks 不需要预先持有 positions。
Bid 以 tick 50 买入 10 lots:锁定
10 × $0.01 × 50/100 = $0.05Ask 以 tick 50 卖出 10 lots:锁定
10 × $0.01 × 50/100 = $0.05每个 matched lot 合计 = LOT_SIZE(1e16 = $0.01),完全抵押
这比要求 askers 预先持有 positions 更简单,也为双方提供对称的 UX。
清算价格结算
所有成交都按清算 tick结算,而不是按各自订单的 limit tick。若一笔 bid 以 tick 70 提交,并以 tick 55 清算,则每 lot 只支付 55%,多出的 15% 自动退回。这保证同一 batch 中的所有参与者都以同一公平价格成交。
抗 MEV 价格保护
限价单提供内置价格保护。你的订单永远不会以差于你的 tick 的价格成交;如果清算价格超过你的 limit,订单不会成交,抵押资产会退回,或作为 GTC 订单滚入下一个批次。
这与 AMM 式滑点有本质区别。在连续 AMM 中,价格可能在你提交交易和交易执行之间移动。批量拍卖会先收集所有订单,再按单一统一价格一起清算。这里没有“抢跑窗口”,同一批次中的所有人都获得相同价格。
如果你愿意支付更高价格以提高成交概率,可以把订单 tick 设置在距离预期清算价格更远的位置。你的 tick 与实际清算价格之间的差额会自动退回。
成交逻辑
Bid at 或 above 清算 tick (non-oversubscribed side)
完全成交
Ask at 或 below 清算 tick (non-oversubscribed side)
完全成交
At 清算 tick (oversubscribed side)
部分成交(按比例)
Bid below 清算 tick
不成交
Ask above 清算 tick
不成交
为什么使用批量拍卖?
vs. 连续撮合
No speed advantage — 同一 batch 中的所有订单平等处理,消除延迟竞争
Uniform price — 所有人获得相同价格,而不是一串逐步推高或压低价格的成交
Maker-friendly — 做市方有完整批次间隔来取消过时报价
vs. 同注分彩池
Real 价格发现 — 价格由 supply 与 demand 决定,而不是由资金池比例决定
资本效率高 — 交易者可以在具体价格表达精确观点
二级市场 — positions 可以通过订单簿卖单交易
休眠订单(价格接近度过滤)
距离上次清算 tick 超过 PROXIMITY_THRESHOLD = 20 ticks 的订单会进入休眠列表,而不是插入线段树。这可以防止远离市场的订单形成虚假深度并扭曲清算价格。
休眠订单会正常锁定抵押资产/代币;它们是真实订单,只是停放在线段树外
OrderResting事件会触发,且独立于OrderPlaced每次
clearBatch开始时,pullRestingOrders会自动运行,将 in-range 休眠订单拉回线段树(paginated: max MAX_RESTING_PULL = 200 pulled, max MAX_RESTING_SCAN = 400 scanned per call)如果 GTC 订单在批次清算后远离价格,会通过
_tryRollOrCancel滚入休眠 list用户可以正常取消休眠订单
分块结算
Large batches 会跨多个 clearBatch 调用结算:
MAX_ORDERS_PER_BATCH = 1600 — v1.1 中从 400 提高
SETTLE_CHUNK_SIZE = 400 — 每次
clearBatch调用最多结算 400 笔订单超过 400 笔订单的 batches 需要多次
clearBatch调用才能完成结算预计算成交结果(清算 tick、匹配手数)会在第一次调用中存储,并被后续 chunks 复用,确保跨调用正确性
批次溢出
每个 batch 最多包含 MAX_ORDERS_PER_BATCH (1600) 笔订单。当一个 batch 已满,新订单会自动 spill into 下一个批次。这限制了 clearBatch() 的 Gas 成本,同时保持下单流程顺畅。
批次节奏
批次间隔在市场创建时可配置。链上不强制执行该间隔;keeper 决定何时调用 clearBatch()。
线段树
清算需要知道每个 tick 的累计成交量。朴素做法需要遍历全部 99 个 ticks,链上成本较高。STRIKE 使用线段树计算前缀和,并以 O(log N) operations 和最少存储写入找到清算 tick。
Last updated

