Appearance
Coinfair OrderBook 产品文档
Coinfair 限价订单簿系统 - 基于 Aptos Move 的去中心化交易所订单簿模块
版本:1.0.0 | 生成时间:2025-10-31
📋 目录
产品概述
什么是 Coinfair OrderBook?
Coinfair OrderBook 是一个为去中心化交易所(DEX)设计的限价订单簿系统,专门为 Aptos 区块链上的交易场景优化。它实现了传统中心化交易所的订单匹配机制,同时保持了区块链的去中心化和透明性特点。
核心价值主张
传统 CEX 体验
Coinfair OrderBook
链上透明性
BMM 曲线定价
CLMM 集成
专业级交易体验
资金安全保障
高效价格发现
流动性深度融合
应用场景
- 专业交易者:精确控制交易价格,设置复杂的交易策略
- 做市商:提供流动性并赚取手续费
- 套利交易:跨池套利,价差交易
- DeFi 协议集成:为其他协议提供订单簿服务
核心特性
1. 多订单簿管理
支持为多个交易池创建独立的订单簿,每个订单簿管理一个特定交易对的限价单。
MultiOrderBook
全局管理器
Pool 1
APT/USDC
Pool 2
BTC/USDC
Pool 3
ETH/APT
Pool N
...
OrderBook 1
买单/卖单索引
OrderBook 2
买单/卖单索引
OrderBook 3
买单/卖单索引
OrderBook N
买单/卖单索引
2. 智能订单类型
订单类型(Order Type)
- BUY (买单) :使用 token_y 购买 token_x
- SELL (卖单) :卖出 token_x 换取 token_y
时间有效性(Time-In-Force, TIF)
订单时间有效性
Time-In-Force
POST_ONLY
只挂单模式
IOC
立即成交或取消
FOK
全部成交或取消
GTC_EXEC_ON_ADD
有效直至取消
不立即执行
保证提供流动性
适合做市商
尽可能执行
剩余部分取消
适合快速交易
必须完全成交
否则全部取消
适合大额交易
创建时尝试执行
剩余部分挂单
最常用类型
3. 价格-时间优先匹配引擎
实现专业级订单匹配算法:
- 价格优先:买单按价格从高到低匹配,卖单按价格从低到高匹配
- 时间优先:同价格订单按创建时间先后顺序匹配(FIFO)
- 高效索引:基于价格刻度(tick)的索引结构,O(log n) 时间复杂度
卖单簿 - 价格升序
买单簿 - 价格降序
Tick: 100 | Price: $1.10 | Amount: 500
Tick: 50 | Price: $1.05 | Amount: 1000
Tick: 0 | Price: $1.00 | Amount: 2000
市场价格
$1.02
Tick: 10 | Price: $1.01 | Amount: 800
Tick: 80 | Price: $1.08 | Amount: 1500
Tick: 150 | Price: $1.15 | Amount: 1200
4. BMM 曲线集成
支持 BMM(Balanced Market Maker)曲线定价模型 (),这是对传统 AMM 曲线的改进:
- 更平滑的价格曲线
- 更好的价格稳定性
- 减少滑点影响
订单簿
限价交易
深度整合
CLMM 池
BMM 曲线
价格发现
流动性共享
套利平衡
5. 双层执行机制
订单创建时采用智能双层执行策略:
CLMM 池订单簿用户 CLMM 池订单簿用户
第一层:集中式订单撮合
第二层:CLMM 池执行
[全部成交][部分成交]
创建限价单 → 查找可匹配订单 → 执行订单间撮合 → 返回成交数量 1
使用剩余数量闪兑 → 根据 BMM 曲线计算 → 返回成交数量 2
返回成交数量 2
订单已完成 → 将剩余部分挂单
订单部分成交,剩余挂单系统架构
整体架构图
集成层
├── 数据层
├── 核心业务层
├── 接口层
└── 用户层
├── 交易者
├── 做市商
└── DeFi 协议
接口层
├── 创建订单接口
├── 取消订单接口
├── 查询接口
└── Hook 接口
核心业务层
├── MultiOrderBook - 多订单簿管理器
├── OrderBook - 单池订单簿
├── Matching Engine - 撮合引擎
├── Execution Engine - 执行引擎
├── SmartTable - 订单存储
├── SmartTable - 价格索引
├── SmartTable - 用户索引
├── FungibleStore - 资产托管
├── CLMM Pool - 流动性池
└── IntegerMate - 数学库模块职责
| 模块 | 职责 | 关键函数 |
|---|---|---|
| MultiOrderBook | 全局管理所有池的订单簿 | register_pool(), get_mob_statistics() |
| OrderBook | 管理单个池的订单和索引 | insert_order(), remove_order() |
| MatchingEngine | 订单匹配算法实现 | find_matching_orders(), try_centralized_crossing() |
| ExecutionEngine | 订单执行和资产转移 | execute_single_order(), execute_orders() |
| AssetManager | 资产托管和转移 | get_or_create_asset_store() |
数据模型
核心数据结构
MultiOrderBook
├── +SmartTable<address,PoolInfo> registered_pools
├── +SmartTable<address,address> pool_orderbooks
├── +u64 global_order_book_id
└── +u64 total_pools
OrderBook
├── +u64 id
├── +SmartTable<u128,LimitOrder> orders
├── +SmartTable<address,vector<u128>> user_orders
├── +SmartTable<I64,vector<u128>> buy_orders_by_tick
├── +SmartTable<I64,vector<u128>> sell_orders_by_tick
├── +vector<I64> active_buy_ticks
├── +vector<I64> active_sell_ticks
├── +Option<I64> best_bid_tick
├── +Option<I64> best_ask_tick
├── +SmartTable<I64,u64> recently_executed
├── +address pool_address
├── +u64 next_id
├── +u64 total_orders
├── +u128 total_volume
└── +SmartTable<Metadata,FungibleStore> asset_stores
LimitOrder
├── +u128 id
├── +address owner
├── +address pool
├── +Object<Metadata> token_x
├── +u64 amount_x
├── +I64 tick
├── +u64 filled_x
├── +u8 status
├── +u8 order_type
├── +u64 created_at
├── +u64 updated_at
├── +u64 expiration_time
├── +Object<Metadata> token_deposited
└── +u64 amount_deposited
PoolInfo
├── +address pool
├── +Object<Metadata> token0
└── +Object<Metadata> token1+bool enable
订单状态机
创建订单
部分成交
完全成交
用户取消
订单过期
剩余部分成交
用户取消
订单过期
ACTIVE
PARTIALLY_FILLED
FILLED
CANCELLED
EXPIRED
订单已创建
等待成交
订单部分执行
剩余数量挂单
订单完全成交
从订单簿移除
订单 ID 设计
订单使用 128 位复合 ID,高 64 位存储订单簿 ID,低 64 位存储本地订单 ID:
订单ID (128 bits) = [订单簿ID (64 bits)][本地订单ID (64 bits)]
示例:
订单簿ID = 4294967296 (0x0000000100000000)
本地订单ID = 42 (0x000000000000002A)
复合订单ID = 18446744073709551914 (0x000000010000002A)优势:
- 可从订单 ID 直接识别所属订单簿
- 避免不同订单簿的 ID 冲突
- 支持高效的分布式 ID 生成
业务流程
1. 创建订单流程
FungibleStore ←→ CLMM 池 ←→ 撮合引擎 ←→ OrderBook ←→ MultiOrderBook ←→ 用户钱包
阶段 1:集中式订单撮合
create_limit_order(pool, token, amount, tick, tif)
→ 验证参数 validate_order_params()
→ 获取订单簿地址
→ 转发创建请求
→ 从用户转入代币 transfer_to_store()
→ 代币已托管
try_centralized_crossing()
→ find_matching_orders() 查找可匹配订单
→ loop[每个匹配订单]
→ execute_order_match() 执行撮合
→ 转账给双方
→ 更新订单状态
→ 发出 OrderExecutedEvent
→ 返回成交数量 1
阶段 2:CLMM 池执行
alt[TIF != POST_ONLY && 有剩余数量]
→ try_execute_on_add_clmm()
→ 使用剩余数量 flash_swap()
→ BMM 曲线计算
→ 偿还代币
→ 返回成交数量 2
alt[仍有剩余数量 && TIF 允许挂单]
→ insert_order_optimized() 将剩余部分挂单
→ 更新价格索引 update_tick_indices()
→ 发出 OrderCreatedEvent
alt[全部成交]
→ 标记订单为 FILLED
alt[IOC/FOK 不允许挂单]
→ 退还剩余代币
→ 发出 OrderCancelledEvent
返回订单 ID 和执行结果关键步骤说明:
- 参数验证:检查数量、价格刻度、过期时间是否合法
- 资产托管:用户代币转入订单簿的 FungibleStore
- 集中式撮合:在订单簿内匹配,价格-时间优先
- CLMM 执行:剩余数量通过流动性池闪兑
- 订单挂单:未成交部分插入订单簿,等待后续匹配
2. 取消订单流程
FungibleStore ←→ OrderBook ←→ 用户
cancel_limit_order(order_id)
→ 验证订单所有权 assert owner == caller
→ 检查订单状态 assert status != FILLED
→ 计算退款金额 remaining = amount - filled
→ 从托管中提取 withdraw(remaining)
→ 返回代币 FA
→ 转账退款 deposit(user, FA)
→ 从价格索引移除 remove_from_tick_index()
→ 更新订单状态为 CANCELLED
→ 发出 OrderCancelledEvent reason=USER_REQUEST
取消成功,代币已退还3. Hook 自动执行流程
OrderBook 与 CLMM 池深度集成,池的每次 swap 后会触发订单簿的 hook,自动执行可成交的限价单:
ExecutionEngine ←→ OrderBook ←→ after_swap_hook ←→ CLMM Pool ←→ 交易者
swap(amount_in)
→ 计算新价格
→ 基于 BMM 曲线执行 swap
after_swap_hook(new_price_tick)
→ 获取订单簿
→ execute_orders(new_price_tick)
→ find_executable_orders() 查找可执行订单
买单条件:order_tick >= current_tick
卖单条件:order_tick <= current_tick
→ loop[每个可执行订单]
→ flash_swap(order_amount, order_tick)
→ 根据 BMM 曲线计算输出
→ 返回输出代币
→ 转账给订单所有者
→ 更新订单状态
→ 从索引移除(如果完全成交)
→ 发出 OrderExecutedEvent
→ 返回已执行订单列表
Hook 执行完成
Swap 完成Hook 机制优势:
- 零延迟执行:价格变动立即触发订单执行
- 无需外部触发:不依赖 keeper 或机器人
- 价格保证:订单在限价或更优价格成交
4. 订单匹配算法详解
新订单到达
→ 订单类型?
→ 买单
→ 查找卖单
→ 筛选刻度 sell_tick <= buy_tick
→ 按价格升序排序(最低价优先)
→ 遍历卖单刻度
→ 处理该刻度的所有卖单(FIFO 顺序)
→ 剩余数量>0?
→ 是:继续下一个刻度
→ 否:匹配完成
→ 卖单
→ 查找买单
→ 筛选刻度 buy_tick >= sell_tick
→ 按价格降序排序(最高价优先)
→ 遍历买单刻度
→ 处理该刻度的所有买单(FIFO 顺序)
→ 剩余数量>0?
→ 是:继续下一个刻度
→ 否:匹配完成时间复杂度分析:
- 刻度查找:O(log N),其中 N 是活跃刻度数量
- 订单遍历:O(M),其中 M 是匹配的订单数量
- 总体:O(log N + M)
技术实现
1. 价格刻度系统
使用离散的价格刻度(tick) 表示价格,而非浮点数,避免精度问题:
价格刻度范围:[-443636, 443636]
刻度间距:可配置(例如10、60、200)
价格计算公式:
price = 1.0001 ^ tick
示例:
tick = 0 => price = 1.0
tick = 100 => price ≈ 1.0101
tick = 1000 => price ≈ 1.1052
tick = -100 => price ≈ 0.9901优势:
- 避免浮点数精度损失
- 高效的整数比较和索引
- 与 Uniswap v3 等协议兼容
2. 数据结构优化
索引 4 最优价格缓存
索引 3 活跃刻度缓存
索引 2 价格索引
索引 1 用户索引
主存储
SmartTable orders
order_id -> LimitOrder
所有订单的主存储
SmartTable user_orders
address -> vector order_ids
快速查询用户的所有订单
SmartTable buy_orders_by_tick
tick -> vector order_ids
买单按价格分组
SmartTable sell_orders_by_tick
tick -> vector order_ids
卖单按价格分组
vector active_buy_ticks
活跃买单刻度列表 降序
vector active_sell_ticks
活跃卖单刻度列表 升序
Option best_bid_tick
最高买价
Option best_ask_tick
最低卖价
索引维护策略:
| 操作 | 索引更新 | 时间复杂度 |
|---|---|---|
| 创建订单 | 更新所有索引 | O(log N) |
| 取消订单 | 从所有索引移除 | O(log N) |
| 部分成交 | 仅更新订单状态 | O(1) |
| 完全成交 | 从所有索引移除 | O(log N) |
3. BMM 曲线计算
BMM(Balanced Market Maker)曲线公式:
// 伪代码示例
function calculate_bmm_output(amount_in, order_price_q64, order_type) {
if (order_type == BUY) {
// 买单:存入 token_y,输出 token_x
// amount_out = amount_in / price
return (amount_in * Q64_RESOLUTION) / order_price_q64
} else {
// 卖单:存入 token_x,输出 token_y
// amount_out = amount_in * price
return (amount_in * order_price_q64) >> 64
}
}Q64 定点数:
使用 64 位定点数表示价格,精度为 :
Q64价格 = 实际价格 × 2^64
示例:
实际价格 = 1.5
Q64价格 = 1.5 × 2^64 = 27670116110564327424
运算:
乘法:(a × b) >> 64
除法:(a << 64) / b4. 资产托管机制
使用 Aptos 的 FungibleStore 实现安全的资产托管:
FungibleStore(订单簿托管)OrderBookPrimaryFungibleStore(用户主存储)用户钱包 FungibleStore(订单簿托管)OrderBookPrimaryFungibleStore(用户主存储)用户钱包创建订单时订单成交时取消订单时授权订单簿转账 withdraw(amount)FungibleAssetdeposit(FA)withdraw(filled_amount)FungibleAssetdeposit(counterparty, FA)withdraw(remaining)FungibleAssetdeposit(user, FA)
安全特性:
- 订单簿拥有独立的签名能力(SignerCapability)
- 每个代币创建专属的 FungibleStore
- 所有转账操作可审计和追溯
5. 事件系统
系统发出 4 类事件,支持前端实时监听和历史查询:
事件系统
OrderCreatedEvent
订单创建
OrderExecutedEvent
订单执行
OrderCancelledEvent
订单取消
PoolRegisteredEvent
池子注册
前端实时更新
数据分析
索引服务
事件结构示例:
// OrderExecutedEvent 事件
struct OrderExecutedEvent {
order_id: u128, // 订单ID
owner: address, // 订单所有者
amount_filled: u64, // 本次成交数量
amount_out: u64, // 获得的输出代币数量
remaining: u64, // 剩余未成交数量
execution_tick_abs: u64, // 执行价格刻度(绝对值)
execution_tick_neg: bool, // 执行价格刻度符号
timestamp: u64, // 执行时间戳
}集成指南
前端集成
1. 创建限价单
import { AptosClient, AptosAccount, Types } from "aptos";
// 初始化客户端
const client = new AptosClient("https://fullnode.mainnet.aptoslabs.com");
const account = new AptosAccount(); // 或从私钥恢复
// 创建买单:用 USDC 购买 APT
async function createBuyOrder() {
const payload: Types.TransactionPayload = {
type: "entry_function_payload",
function: "0xYOUR_ADDRESS::multi_order_book::create_limit_order",
type_arguments: [
"0x1::fungible_asset::Metadata", // token_x (APT)
"0x1::fungible_asset::Metadata" // token_y (USDC)
],
arguments: [
"0xPOOL_ADDRESS", // pool地址
"1000000", // amount_in (1 USDC,假设6位小数)
"100", // tick (价格刻度)
"0", // order_type (BUY)
Math.floor(Date.now() / 1000) + 86400, // expiration (24小时后)
"3" // tif (GTC_EXEC_ON_ADD)
],
};
const txn = await client.generateTransaction(account.address(), payload);
const signedTxn = await client.signTransaction(account, txn);
const result = await client.submitTransaction(signedTxn);
await client.waitForTransaction(result.hash);
console.log("订单创建成功:", result.hash);
}2. 取消订单
async function cancelOrder(orderId: string) {
const payload: Types.TransactionPayload = {
type: "entry_function_payload",
function: "0xYOUR_ADDRESS::multi_order_book::cancel_limit_order",
type_arguments: [],
arguments: [
orderId // 订单ID (u128)
],
};
const txn = await client.generateTransaction(account.address(), payload);
const signedTxn = await client.signTransaction(account, txn);
const result = await client.submitTransaction(signedTxn);
await client.waitForTransaction(result.hash);
console.log("订单取消成功:", result.hash);
}3. 查询订单
// 查询单个订单
async function getOrderDetails(orderId: string) {
const result = await client.view({
function: "0xYOUR_ADDRESS::multi_order_book::query_order",
type_arguments: [],
arguments: [orderId],
});
return {
id: result[0],
owner: result[1],
pool: result[2],
amount_x: result[3],
filled_x: result[4],
tick: result[5],
status: result[6],
order_type: result[7],
// ... 更多字段
};
}
// 查询用户所有订单
async function getUserOrders(userAddress: string, poolAddress: string) {
const result = await client.view({
function: "0xYOUR_ADDRESS::multi_order_book::get_user_orders",
type_arguments: [],
arguments: [userAddress, poolAddress],
});
return result; // 返回订单列表
}4. 监听事件
// 监听订单执行事件
async function watchOrderExecutions(poolAddress: string) {
const eventHandle = `0xYOUR_ADDRESS::multi_order_book::OrderExecutedEvent`;
// 从最新区块开始监听
let sequenceNumber = 0;
setInterval(async () => {
const events = await client.getEventsByEventHandle(
eventHandle,
poolAddress,
sequenceNumber,
10 // 每次获取10个事件
);
events.forEach(event => {
console.log("订单成交:", {
orderId: event.data.order_id,
amountFilled: event.data.amount_filled,
amountOut: event.data.amount_out,
timestamp: event.data.timestamp,
});
});
sequenceNumber += events.length;
}, 5000); // 每5秒查询一次
}智能合约集成
其他 Move 模块可以直接调用 OrderBook 的公开函数:
module your_protocol::trading_bot {
use coinfair_orderbook::multi_order_book;
use aptos_framework::fungible_asset::Metadata;
use integer_mate::i64;
// 自动化交易策略
public entry fun execute_strategy(
signer: &signer,
pool: address,
token_in: Object<Metadata>,
amount: u64
) {
// 计算目标价格刻度
let target_tick = i64::from(100); // 简化示例
// 创建限价单
multi_order_book::create_limit_order(
signer,
pool,
token_in,
amount,
target_tick,
0, // BUY
timestamp::now_seconds() + 3600, // 1小时后过期
3 // GTC_EXEC_ON_ADD
);
}
}安全性设计
1. 权限控制
权限层级
管理员
@coinfair_orderbook
管理员操作
初始化系统
init_module
注册池子
register_pool
更新手续费接收地址
普通用户
任何地址
用户操作
创建订单
create_limit_order
取消自己的订单
cancel_limit_order
查询订单
query_order
CLMM 池
注册的池地址
Hook 操作
执行订单
after_swap_hook
访问控制检查:
// 示例:只有订单所有者可以取消订单
public entry fun cancel_limit_order(
signer: &signer,
order_id: u128
) {
let caller = signer::address_of(signer);
let order = borrow_order(order_id);
// 权限检查
assert!(order.owner == caller, E_NOT_OWNER);
// 执行取消逻辑
// ...
}2. 参数验证
所有外部输入都经过严格验证:
| 参数 | 验证规则 | 错误码 |
|---|---|---|
| amount_in | 1 ≤ amount ≤ | E_INVALID_AMOUNT |
| tick | -443,636 ≤ tick ≤ 443,636 | E_INVALID_TICK |
| order_type | 0 (BUY) 或 1 (SELL) | E_INVALID_ORDER_TYPE |
| expiration_time | now + 60s ≤ exp ≤ now + 1 年 | E_ORDER_EXPIRED |
| tif | 0 ≤ tif ≤ 3 | E_INVALID_ORDER_TYPE |
| pool | 必须已注册 | E_POOL_NOT_REGISTERED |
| token | 必须属于池子 | E_INVALID_TOKEN_FOR_POOL |
3. 重入保护
Aptos Move 语言自带防重入特性:
- 引用规则:可变引用(
&mut)和不可变引用(&)不能同时存在 - 资源所有权:每个资源在同一时刻只能被一个函数修改
- 编译时检查:Move 编译器在编译时验证引用安全性
示例:
// 这段代码无法编译通过
fun unsafe_reentrancy(order_book: &mut OrderBook) {
let order_ref1 = &mut order_book.orders;
let order_ref2 = &mut order_book.orders; // 编译错误:不能有两个可变引用
// ...
}4. 溢出保护
使用 Move 的检查算术运算,防止整数溢出:
// 所有算术运算在溢出时会自动abort
let total = amount1 + amount2; // 如果溢出,交易回滚
// 使用128位整数存储累计值,避免溢出
struct OrderBook {
total_volume: u128, // 可存储高达 3.4 × 10^38
total_fees_collected: u128,
// ...
}5. 过期订单清理
系统提供两种机制清理过期订单:
过期订单
自动清理
手动清理
执行时检测
execute_single_order
取消时检测
cancel_limit_order
管理员调用
maintenance_cleanup
批量清理过期订单
从索引移除
性能优化
1. 刻度缓存机制
维护活跃刻度列表,避免遍历整个价格空间:
struct OrderBook {
// 活跃买单刻度(降序排列)
active_buy_ticks: vector<I64>, // [100, 50, 0, -50]
// 活跃卖单刻度(升序排列)
active_sell_ticks: vector<I64>, // [10, 80, 150, 200]
// 最优价格缓存
best_bid_tick: Option<I64>, // 100(最高买价)
best_ask_tick: Option<I64>, // 10(最低卖价)
}性能提升:
- 查找最优价格:O(1)
- 遍历可匹配刻度:O(k),k 是活跃刻度数量(通常 << N)
2. 最近执行缓存
避免短时间内重复执行同一价格的订单:
struct OrderBook {
// tick -> 最后执行时间戳
recently_executed: SmartTable<I64, u64>,
}
// 执行前检查
fun should_execute(order_book: &OrderBook, tick: I64): bool {
if (recently_executed.contains(tick)) {
let last_exec_time = *recently_executed.borrow(tick);
let now = timestamp::now_seconds();
// 60秒内不重复执行
if (now - last_exec_time < 60) {
return false
}
}
true
}缓存管理:
- 定期清理:每 100 次执行或缓存大小 > 1000
- LRU 策略:删除最久未执行的刻度
3. 批量操作优化
支持批量注册池子,减少交易次数:
// 单个池注册
public entry fun register_pool(admin: &signer, pool: address);
// 批量池注册
public entry fun register_mob_orderbook(
sender: &signer,
pools: vector<address>
) {
pools.for_each(|pool| {
register_pool_internal(mob, pool);
});
}4. 数据结构选择
| 场景 | 数据结构 | 时间复杂度 | 原因 |
|---|---|---|---|
| 订单存储 | SmartTable | O(1) 查找 | 需要频繁的 ID 查找 |
| 价格索引 | SmartTable | O(1) 查找 | 按刻度分组订单 |
| 活跃刻度 | Vector | O(n) 遍历 | 需要有序遍历,n 较小 |
| 用户索引 | SmartTable | O(1) 查找 | 按地址分组订单 |
SmartTable vs Table:
- SmartTable:基于 B+ 树,适合大数据量
- Table:基于哈希表,适合小数据量
- OrderBook 选择 SmartTable,支持海量订单
运维管理
1. 系统监控指标
订单簿健康度
// 获取订单簿统计信息
#[view]
public fun get_order_book_stats(pool: address): (u64, u64, u64, u64) {
let ob_address = get_pool_orderbook_address(pool);
let order_book = borrow_global<OrderBook>(ob_address);
(
order_book.total_orders, // 历史订单总数
count_active_orders(order_book), // 当前活跃订单数
order_book.active_buy_ticks.length(), // 买单刻度数
order_book.active_sell_ticks.length() // 卖单刻度数
)
}关键监控指标
| 指标 | 说明 | 警戒阈值 |
|---|---|---|
| 活跃订单数 | 当前挂单数量 | > 10,000 |
| 活跃刻度数 | 有订单的价格档位数 | > 500 |
| 缓存大小 | recently_executed 表大小 | > 1,000 |
| 过期订单比例 | 过期但未清理的订单 | > 10% |
| 订单执行率 | 成交订单 / 总订单 | < 50% |
2. 维护任务
过期订单清理
// 手动清理过期订单(管理员调用)
public entry fun maintenance_cleanup(
admin: &signer,
pool: address,
max_orders: u64
) {
// 验证管理员权限
assert!(signer::address_of(admin) == @coinfair_orderbook, E_INVALID_MANAGER);
let ob_address = get_pool_orderbook_address(pool);
let order_book = borrow_global_mut<OrderBook>(ob_address);
// 清理过期订单
let cleaned = 0;
let order_ids = get_all_order_ids(order_book);
order_ids.for_each(|order_id| {
if (cleaned >= max_orders) return;
let order = order_book.orders.borrow(order_id);
if (is_order_expired(order)) {
cleanup_expired_order(ob_address, order_book, order_id);
cleaned += 1;
}
});
}缓存清理
// 清理最近执行缓存
fun cleanup_recent_execution_cache(order_book: &mut OrderBook) {
let now = timestamp::now_seconds();
let keys_to_remove = vector::empty<I64>();
// 找出60秒以上未执行的刻度
order_book.recently_executed.for_each_ref(|tick, last_time| {
if (now - *last_time > RECENT_EXECUTION_WINDOW) {
keys_to_remove.push_back(*tick);
}
});
// 批量删除
keys_to_remove.for_each(|tick| {
order_book.recently_executed.remove(tick);
});
}3. 紧急操作
暂停池子
// 紧急暂停池子的订单簿(未实现,建议添加)
public entry fun emergency_pause_pool(
admin: &signer,
pool: address
) {
assert!(signer::address_of(admin) == @coinfair_orderbook, E_INVALID_MANAGER);
let mob = borrow_global_mut<MultiOrderBook>(mob_at());
let pool_info = mob.registered_pools.borrow_mut(pool);
pool_info.enable = false; // 禁用池子
}
// 恢复池子
public entry fun emergency_resume_pool(
admin: &signer,
pool: address
) {
assert!(signer::address_of(admin) == @coinfair_orderbook, E_INVALID_MANAGER);
let mob = borrow_global_mut<MultiOrderBook>(mob_at());
let pool_info = mob.registered_pools.borrow_mut(pool);
pool_info.enable = true; // 启用池子
}4. 数据导出
// 导出订单簿快照(用于分析和审计)
#[view]
public fun export_orderbook_snapshot(pool: address): vector<LimitOrder> {
let ob_address = get_pool_orderbook_address(pool);
let order_book = borrow_global<OrderBook>(ob_address);
let snapshot = vector::empty<LimitOrder>();
// 遍历所有订单
order_book.orders.for_each_ref(|_id, order| {
snapshot.push_back(*order);
});
snapshot
}
// 导出最优价格历史(需配合索引服务)
#[view]
public fun get_best_prices_all_pools(): vector<PoolPriceInfo> {
let mob = borrow_global<MultiOrderBook>(mob_at());
let result = vector::empty<PoolPriceInfo>();
mob.registered_pools.for_each_ref(|pool_addr, _info| {
let ob_address = *mob.pool_orderbooks.borrow(*pool_addr);
let order_book = borrow_global<OrderBook>(ob_address);
result.push_back(PoolPriceInfo {
pool_address: *pool_addr,
best_bid: order_book.best_bid_tick,
best_ask: order_book.best_ask_tick,
});
});
result
}附录
A. 常量定义速查表
| 常量名 | 值 | 说明 |
|---|---|---|
| 订单状态 | ||
| ORDER_STATUS_ACTIVE | 0 | 活跃状态 |
| ORDER_STATUS_PARTIALLY_FILLED | 1 | 部分成交 |
| ORDER_STATUS_FILLED | 2 | 完全成交 |
| ORDER_STATUS_CANCELLED | 3 | 已取消 |
| ORDER_STATUS_EXPIRED | 4 | 已过期 |
| 订单类型 | ||
| ORDER_TYPE_BUY | 0 | 买单 |
| ORDER_TYPE_SELL | 1 | 卖单 |
| Time-In-Force | ||
| TIF_POST_ONLY | 0 | 只挂单 |
| TIF_IOC | 1 | 立即成交或取消 |
| TIF_FOK | 2 | 全部成交或取消 |
| TIF_GTC_EXEC_ON_ADD | 3 | 有效直至取消 |
| 取消原因 | ||
| CANCEL_REASON_USER_REQUEST | 0 | 用户主动取消 |
| CANCEL_REASON_EXPIRED | 1 | 过期自动取消 |
| CANCEL_REASON_FOK | 2 | FOK 无法完全成交 |
| CANCEL_REASON_IOC | 3 | IOC 剩余部分取消 |
| 限制参数 | ||
| MAX_TICK | 443,636 | 最大价格刻度 |
| MIN_TICK | -443,636 | 最小价格刻度 |
| MAX_ORDER_AMOUNT | 最大订单数量 | |
| MAX_CACHE_SIZE | 1,000 | 最大缓存条目数 |
| RECENT_EXECUTION_WINDOW | 60 秒 | 最近执行窗口 |
| 手续费 | ||
| PLATFORM_FEE | 15 | 平台手续费(基点) |
| FEE_DENOMINATOR | 10,000 | 手续费分母 |
| 实际费率 | 0.15% | 15/10000 |
B. 错误码速查表
| 错误码 | 常量名 | 说明 |
|---|---|---|
| 1 | E_NOT_OWNER | 非订单所有者 |
| 2 | E_ORDER_NOT_FOUND | 订单不存在 |
| 3 | E_INVALID_ORDER_TYPE | 无效订单类型 |
| 4 | E_INVALID_AMOUNT | 无效数量 |
| 5 | E_INVALID_TICK | 无效价格刻度 |
| 6 | E_ORDER_EXPIRED | 订单过期 |
| 7 | E_INSUFFICIENT_BALANCE | 余额不足 |
| 8 | E_INVALID_STATUS | 无效状态 |
| 9 | E_INVALID_MANAGER | 非管理员 |
| 11 | E_SAME_TOKEN | 代币相同 |
| 12 | E_POOL_NOT_REGISTERED | 池未注册 |
| 13 | E_POOL_ALREADY_REGISTERED | 池已注册 |
| 14 | E_INVALID_TOKEN_FOR_POOL | 代币不属于池 |
| 15 | E_INVALID_MULTI_VECTOR_LEN | 向量长度不匹配 |
| 16 | E_ASSET_STORE_NOT_FOUND | 资产存储不存在 |
| 17 | E_INVALID_TOKEN_DIRECTION | 无效代币方向 |
| 18 | E_CACHE_SIZE_EXCEEDED | 缓存超限 |
| 19 | E_GLOBAL_ORDER_ID_OVERFLOW | 订单 ID 溢出 |
C. 公开函数接口
管理员函数
| 函数 | 参数 | 说明 |
|---|---|---|
register_pool | admin: &signer pool: address | 注册新池子 |
register_mob_orderbook | sender: &signer pools: vector<address> | 批量注册池子 |
用户交易函数
| 函数 | 参数 | 说明 |
|---|---|---|
create_limit_order | signer: &signer pool: address token_in: Object<Metadata> amount_in: u64 tick: I64 order_type: u8 expiration_time: u64 tif: u8 | 创建限价单 |
cancel_limit_order | signer: &signer order_id: u128 | 取消订单 |
查询函数(View)
| 函数 | 参数 | 返回值 | 说明 |
|---|---|---|---|
query_order | order_id: u128 | LimitOrder | 查询订单详情 |
get_user_orders | user: address pool: address | vector<LimitOrder> | 查询用户订单 |
get_best_prices | pool: address | (Option<I64>, Option<I64>) | 查询最优买卖价 |
get_order_book_stats | pool: address | (u64, u64, u64, u64) | 查询订单簿统计 |
get_mob_statistics | - | 统计信息 | 查询全局统计 |
Hook 函数
| 函数 | 参数 | 说明 |
|---|---|---|
after_swap_hook | pool: address new_price_tick: I64 | CLMM 池回调 |
D. 参考资源
- Aptos 官方文档:https://aptos.dev
- Move 语言指南:https://move-language.github.io/move/
- Uniswap V3 白皮书:https://uniswap.org/whitepaper-v3.pdf
- Coinfair GitHub:(待填写)
总结
Coinfair OrderBook 是一个功能完善、性能优异的去中心化订单簿系统,具有以下亮点:
- 专业级交易体验:支持多种订单类型和时间有效性,满足不同交易策略需求
- 高效撮合引擎:价格-时间优先算法,O(log N)时间复杂度
- 深度 CLMM 集成:双层执行机制,订单簿+流动性池双重保障
- 安全可靠:完善的权限控制、参数验证和资产托管机制
- 性能优化:多级缓存、智能索引,支持海量订单
- 可扩展性:支持多池管理,易于集成和扩展
适用于构建专业级去中心化交易所、DeFi 协议集成、自动化交易策略等场景。
文档版本:v1.0.0 生成时间:2025-10-31 维护者:Coinfair Team 联系方式:(待填写)