dYdX 是链上永续合约里订单簿方向的代表, 从以太坊 L1 到 StarkEx 再到自建 Cosmos appchain, 经历了四个大版本. 本文梳理 v1 到 v4 的演进路径和每次迁移的技术取舍, 重点介绍 v4 的链上订单簿撮合机制和保证金清算设计.
一、术语表 1.1 订单簿核心
术语
英文
含义
订单簿
Order Book
买卖订单的集合, 按价格排列, 买方出价 (bid) 和卖方要价 (ask)
限价单
Limit Order
指定价格和数量的订单, 只在达到指定价格时成交
市价单
Market Order
以当前最优价格立即成交的订单
止损单
Stop Order
价格触达某个阈值后触发的订单 (止损/止盈)
做市商
Market Maker
同时挂买单和卖单, 提供流动性, 赚取 bid-ask spread
挂单方
Maker
提供流动性的一方, 挂出的订单在 order book 中等待成交
吃单方
Taker
消耗流动性的一方, 下单立即与 order book 中已有订单成交
买卖价差
Bid-Ask Spread
最高买价 (best bid) 和最低卖价 (best ask) 之间的差距
深度
Depth
订单簿中各价位累积的订单量, 深度越大, 大单滑点越小
滑点
Slippage
实际成交均价与预期价格的偏差, 由 depth 不足导致
1.2 dYdX 特有
术语
英文
含义
应用链
Appchain
为单一应用定制的独立区块链 (dYdX v4 用 Cosmos SDK 构建)
验证者
Validator
运行 dYdX 节点的实体, 同时维护链上状态和内存中的 order book
撮合引擎
Matching Engine
将买卖订单按价格-时间优先级配对的核心组件
区块提案者
Block Proposer
每轮共识中负责打包交易、撮合订单的验证者
去杠杆
Deleveraging (ADL)
保险基金耗尽后, 强制盈利方减仓来覆盖亏损方的穿仓损失
Maker Rebate
Maker Rebate
给 maker 的返佣 (负手续费), 激励做市商提供流动性
二、dYdX 发展历程 dYdX 经历了四个大版本, 每次迁移都是为了解决上一版的核心瓶颈:
dYdX 版本演进: v1 → v2/v3 → v4
v1 (2019)
Ethereum L1
Margin trading (非永续)
所有操作在 L1 上
Gas 费极高, 速度极慢
瓶颈: L1 吞吐量完全不够
v2/v3 (2021)
StarkEx (zk-rollup)
链下撮合 + 链上结算
StarkWare 提供 zk-proof
10 TPS → 1000+ TPS
瓶颈: 中心化撮合 + StarkEx 受限
v4 (2023)
Cosmos Appchain
完全去中心化订单簿
验证者运行撮合引擎
无中心化组件, 自主定制
当前版本: 完全去中心化
为什么从 StarkEx 迁移到 Cosmos?
1. 去中心化: v3 的撮合引擎由 dYdX Trading Inc 中心化运行, 单点故障 + 监管风险
2. 性能自主: StarkEx 是共享基础设施, 无法为 dYdX 单独优化 (如自定义 block time)
3. 费用归属: v3 的交易费进了 dYdX Trading 口袋, v4 费用分配给验证者和 staker
4. 协议主权: Cosmos appchain = 自己的链, 自己的共识, 自己的治理, 不受 L1/L2 限制
5. 定制化: 可以在共识层面做订单撮合, 而不是受限于 EVM 的 gas 模型
核心洞察: 永续合约 DEX 需要极高的吞吐量和极低的延迟
通用 L1/L2 无法同时满足, 所以 dYdX 选择了 "造一条专用链"
(Hyperliquid 也走了类似路线, 但选择了自研 L1 而非 Cosmos)
2.1 v1: Ethereum L1 尝试 2019 年, dYdX 在 Ethereum L1 上做 margin trading:
保证金交易 (不是永续合约)
每笔订单提交/取消都是一笔 L1 交易
Gas 费高, 成交慢, 体验极差
教训 : L1 根本不适合做高频交易场景.
2.2 v2/v3: StarkEx 混合架构 2021 年, dYdX 迁移到 StarkEx (StarkWare 提供的 zk-rollup):
dYdX v3 StarkEx 架构: 链下撮合 + 链上结算
Off-chain (dYdX Trading Inc)
← 中心化运行
Order Book
订单簿
Matching Engine
撮合引擎
StarkEx (zk-rollup)
← 验证撮合正确性
zk-STARK Proof 生成
Ethereum L1
← 最终结算
Settlement + Proof Verification
结算 + 证明验证
优点 : 性能大幅提升 (1000+ TPS), gas 费大幅降低缺点 : 撮合引擎是中心化的, dYdX Trading Inc 可以:
审查订单 (censor)
宕机导致整个协议停止
被监管机构要求关停
什么是 ZK-Rollup?
dYdX v3 用的 StarkEx 就是一种 ZK-Rollup. 两种 Rollup 都在链下执行交易, 把数据提交到 Ethereum, 区别在于 L1 怎么确认结果:
维度
Optimistic Rollup (如 Arbitrum)
ZK-Rollup (如 StarkEx)
验证方式
有人挑战才验证 (fraud proof)
每次都验证 (validity proof)
最终确认
~7 天 (挑战期)
几分钟 (proof 生成+验证)
提款到 L1
7 天等待
几分钟~几小时
EVM 兼容
完全兼容 (容易)
困难 (ZK 电路不天然兼容 EVM)
proof 成本
无 (只在被挑战时验证)
高 (每批都要生成 proof, 需 GPU 集群)
1 2 3 4 5 Optimistic : "先信你, 出了问题再查" → 7 天后确认ZK : "每次交卷附上解题过程" → 当场批改确认dYdX v3 选 ZK-Rollup: 提款快, 不用等 7 天dYdX v4 放弃 ZK-Rollup: StarkEx 是 StarkWare 的闭源产品, 想自主 → 改用 Cosmos
2.3 v4: Cosmos Appchain (当前版本) 2023 年 10 月, dYdX v4 在自己的 Cosmos appchain 上线:
完全去中心化 : 没有任何中心化组件
验证者运行 order book : 撮合发生在共识层面
费用归协议 : 交易费分配给验证者和 DYDX staker
协议主权 : 独立链, 自主升级, 自主治理
三、dYdX v4 架构
dYdX v4 Cosmos Appchain 架构
交易者 (Frontend / API client)
Indexer
读取链上数据, 构建
REST/WebSocket API
供前端查询 (只读)
验证者集群 (60 个活跃验证者)
单个验证者节点
In-Memory Order Book
不上链, 不进共识, 在内存中维护
Matching Engine
价格-时间优先撮合
CometBFT Consensus
2/3+ 验证者签名 = 最终确认
On-Chain State
持仓, 余额, 成交记录
V2
(同样结构)
V3
(同样结构)
...
V59
V60
P2P gossip 传播订单
一笔交易的生命周期
1. 用户提交订单 → 发送到最近的验证者节点
2. 验证者通过 P2P gossip 将订单广播给所有其他验证者
3. 每个验证者将订单加入自己的 in-memory order book
4. 轮到某个验证者做 block proposer 时, 它撮合订单, 将成交结果打包进区块
5. 其他验证者验证成交结果, 2/3+ 签名后区块确认, 状态更新 (持仓/余额变动)
3.1 核心设计: 链下 Order Book + 链上结算 dYdX v4 最精妙的设计是: order book 不上链 .
关键区分: 链下 vs 链上
不进共识 (内存)
- 未成交的订单
- 订单的提交/取消
- order book 状态
→ 在内存中, 极快
不占区块空间, 不需要共识
进入共识 (上链)
- 成交结果 (match)
- 持仓变动
- 余额变动
- 清算记录
→ 在区块中, 有共识保证
2/3+ 验证者确认, 不可篡改
为什么订单不上链?
一个活跃市场, 每秒可能有 100+ 笔订单提交和取消
如果每笔都要上链走共识, 吞吐量远远不够
CEX 的核心竞争力就是 “内存中的订单簿 + 极速撮合”
dYdX v4 把这个模式搬到了验证者节点里
3.1.1 两类订单: 短期 vs 长期 并非所有订单都只在内存中. dYdX 按订单生命周期分为两类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1. Short-Term Order (短期订单) - 默认类型, 类似 CEX 的普通限价单 / 市价单 - 只存在验证者内存中, 有效期极短 (最多 20 个区块 ≈ 几十秒) - 不上链, 不付 gas - 适合: 做市商高频报价, 普通用户市价单2. Stateful Order (长期订单 / 条件单) - 止损单, GTC (Good-Till-Cancel, 撤销前有效) 等 - 提交时上链 (写入区块, 付 gas), 取消时也上链 - 即使没有成交, 也在链上状态中持久保存 - 适合: 设好止损后关电脑走人的场景 为什么长期订单必须上链: 止损单可能挂几天甚至几周 如果只在内存中, 节点重启 → 止损丢失 → 用户不知道 → 爆仓 这个风险不可接受, 所以宁可付 gas 也要上链
3.1.2 节点间同步: Gossip 协议 (弱同步) 短期订单在验证者之间通过 P2P gossip (八卦协议) 传播:
1 2 3 4 5 6 7 8 9 10 传播过程: 用户提交订单 → 发到最近的验证者 A 验证者 A → gossip 给 B, C, D... B 收到后 → gossip 给 E, F... 通常几百 ms 内所有验证者都收到 这是弱同步 (最终一致性), 不是强同步: - 没有 "所有人确认收到" 的机制 - 不同验证者在同一瞬间可能看到不同的 order book - 谁当 block proposer, 就用自己内存里的版本来撮合
节点重启时会发生什么?
1 2 3 4 5 6 7 8 9 场景 1 : 节点 A 收到订单, 还没 gossip 出去就挂了 → 订单丢失, 用户需要重新提交 场景 2 : 订单已广播到其他节点, A 挂了 → 没影响, 其他节点继续撮合 场景 3 : 所有节点同时重启 (极端) → Short-Term Orders 全丢, 需要用户重发 → Stateful Orders 从链上状态恢复, 不丢
实际影响很小: 短期订单有效期只有几十秒, 做市商每秒都在更新报价会自动重发, 普通用户的市价单几百 ms 内就该成交了.
vs Hyperliquid: 架构取舍对比
维度
dYdX v4 (订单不上链)
Hyperliquid (订单全上链)
短期订单持久性
可能丢 (内存 + gossip)
不丢 (链上有记录)
吞吐量
高 (内存操作, 无共识开销)
受限于共识速度 (需 HyperBFT)
一致性
弱 (最终一致, 各节点瞬时可能不同)
强 (每个订单经过共识)
可审计性
中 (撮合过程不可验证)
高 (全链路可验证)
对共识层要求
低 (只处理成交结果)
极高 (处理每个订单)
dYdX 选择 “订单不上链” 换来高吞吐, 代价是弱一致性和可能丢单; Hyperliquid 选择 “每个订单上链” 保证不丢单和可审计, 代价是需要自研超高性能共识才扛得住.
3.2 CometBFT 共识 dYdX v4 使用 CometBFT (原 Tendermint) 作为共识引擎:
特性
说明
共识类型
BFT (Byzantine Fault Tolerant)
最终性
即时最终性: 区块确认后不会回滚 (无 reorg)
出块时间
~1-2 秒
验证者数量
60 个活跃验证者
容错
最多 1/3 验证者作恶仍能正常运行
vs Ethereum : Ethereum 有 reorg 风险, 需要等多个 block confirmation. CometBFT 一旦出块就是最终的, 这对交易所至关重要, 因为你不希望 “成交了的交易” 被回滚.
3.3 为什么选 Cosmos SDK?
需求
Cosmos 如何满足
自定义共识逻辑
ABCI 接口允许在共识过程中插入自定义逻辑 (如订单撮合)
独立出块节奏
appchain 独立运行, 不受其他链拥堵影响
无 gas 竞争
不与其他 DApp 争抢 block space
协议级定制
可以在应用层实现 order book, oracle, liquidation 等
主权治理
DYDX token holder 投票决定协议升级
Cosmos appchain (应用链) 是什么?
Cosmos 不是一条链, 而是一套造链工具包:
1 2 3 4 5 6 7 8 9 10 Cosmos SDK = 造链框架 (Go 语言) CometBFT = 共识引擎 (原名 Tendermint) IBC = 跨链通信协议 (Inter-Blockchain Communication) 用 Cosmos SDK 造出来的链 = appchain (应用链) 每条 appchain 都是独立的 L1, 有自己的验证者集合类比: 在 Arbitrum 部署合约 = 在商场里租铺位 (共享设施, 受商场规则限制) Cosmos appchain = 自己盖一栋楼 (完全自主, 但要自己招保安)
1 2 3 4 5 6 7 8 9 10 11 12 Cosmos 生态知名链 : Cosmos Hub (ATOM), Osmosis (DEX), dYdX Chain, Celestia (DA 层), Injective (交易链), Noble (USDC 发行链) 总计 70+ 条 appchain, 通过 IBC 互联 dYdX 用户存 USDC 的路径 : Ethereum USDC → Noble chain (Circle 在 Cosmos 的官方链) → IBC → dYdX IBC 特点 : 不需要信任第三方桥 (不像 Hyperliquid 的 bridge) 安全性由两条链的验证者共同保障 标准化协议, 所有 Cosmos 链原生支持
四、订单簿机制 4.1 订单类型
dYdX v4 订单类型
Limit Order (限价单)
"以 $3000 买入 1 ETH"
指定价格, 只在该价格或更优
价格成交. 挂在 book 上等待.
→ 通常作为 Maker 单
支持 GTC / IOC / FOK / GTT
Market Order (市价单)
"立即买入 1 ETH"
以当前最优价格立即成交
不指定价格, 优先确保成交
→ 一定是 Taker 单
有滑点风险 (depth 不足时)
Stop Order (止损/止盈)
"ETH 跌到 $2800 时卖出"
价格到达触发条件后
自动变成 market/limit order
→ Stop-Loss / Take-Profit
由验证者监控触发条件
Time in Force (订单有效期)
GTC (Good-Til-Cancel)
一直挂着, 直到成交或手动取消
IOC (Immediate-Or-Cancel)
立即成交能成交的部分, 剩余取消
FOK (Fill-Or-Kill)
全部成交或全部取消, 不接受部分成交
GTT (Good-Til-Time)
在指定时间之前有效, 过期自动取消
4.2 Maker vs Taker 这是理解订单簿的核心概念:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Maker (提供流动性) : - 挂出限价单, 放进 order book 等待 - 增加了 order book 的深度 → 对市场有益 - 通常享受更低手续费, 甚至 rebate (负手续费) Taker (消耗流动性) : - 下单立即与 book 中已有的订单成交 - 消耗了 order book 的深度 - 手续费较高 判定规则 : 不是看订单类型, 而是看是否立即成交 - 限价单如果刚提交就能与 book 中已有订单匹配 → 这笔限价单是 Taker - 限价单如果挂在 book 上等待 → 它是 Maker - 市价单一定是 Taker (它总是立即成交)
4.3 Price-Time Priority (价格-时间优先) dYdX v4 使用经典的 价格-时间优先 (Price-Time Priority) 撮合算法, 和 CEX 完全一致:
Price-Time Priority 撮合示例 (ETH-USD)
撮合规则:
1. 价格优先: 买单出价最高先成交, 卖单要价最低先成交
2. 时间优先: 同价格的订单, 先到的先成交
Asks (卖单, 价格从低到高)
Price
Size
Time
$3001
7 ETH
14:00 ← Best Ask
$3001
2 ETH
14:02
$3003
3 ETH
14:03
$3005
10 ETH
14:01
Bids (买单, 价格从高到低)
Price
Size
Time
$2998
5 ETH
14:00 ← Best Bid
$2997
8 ETH
13:58
$2995
15 ETH
14:02
$2990
20 ETH
13:55
Spread = $3001 - $2998 = $3
Taker 提交 "Market Buy 10 ETH": 撮合过程
1
吃 $3001 × 7 ETH (14:00 先到, 时间优先)
2
吃 $3001 × 2 ETH (14:02 后到)
3
还差 1 ETH, 吃 $3003 × 1 ETH (价格上升一档)
avg_price (成交均价) = (7×3001 + 2×3001 + 1×3003) / 10 = $3001.2
slippage (滑点) = $3001.2 - $3001 = $0.2
4.4 订单簿深度与滑点
Order Book Depth 可视化
Mid Price
← 低价
高价 →
Bids (买单)
Asks (卖单)
Spread
深度越大 (越宽越高), 大单滑点越小, 这就是为什么做市商如此重要
深度决定滑点 : 如果 order book 在 best ask 附近只有 5 ETH, 而你要买 50 ETH, 就需要往上 “吃” 很多层, 成交均价会远高于 best ask. 这就是 slippage.
vs GMX : GMX 用 oracle 定价, 理论上零滑点 (不管你买 1 ETH 还是 100 ETH, 价格一样). 但 GMX 有 open interest 上限, 大单可能根本无法成交. Order book 模式没有硬上限, 但大单会有滑点.
五、做市商 (Market Maker) 做市商是订单簿型 DEX 的 “生命线”. 没有做市商, order book 就是空的, 没有人能交易.
5.1 做市商的角色 1 2 3 4 5 6 7 8 9 10 11 12 13 做市商的核心工作: 同时在 bid 和 ask 两侧挂单 例: ETH 当前价格 $3000 做市商挂出: Buy (Bid): 100 ETH @ $2999 ← "我愿意以 $2999 买入" Sell (Ask): 100 ETH @ $3001 ← "我愿意以 $3001 卖出" 如果有人 market buy → 成交 $3001 如果有人 market sell → 成交 $2999 做市商赚取 spread (价差) = $3001 - $2999 = $2 每成交一对, 赚 $2 / ETH
5.2 做市商的风险 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 主要风险: Adverse Selection (逆向选择) 做市商挂了 Sell 100 ETH @ $3001 突然 ETH 暴涨到 $3100 知情交易者 (知道要涨) 立刻买走做市商的便宜货: 买入 100 ETH @ $3001 真实价值已经 $3100 做市商亏了 100 × ($3100 - $3001) = $9,900 做市商的 spread 收入远不够覆盖这笔亏损 → 这就是为什么做市商需要: 1. 极快的速度 (在价格变动时迅速撤单/更新报价) 2. 足够大的 spread (覆盖逆向选择风险) 3. 协议给的 maker rebate (降低成本)
5.3 dYdX 的做市商激励
激励机制
说明
Maker Rebate
maker 成交不收手续费, 反而获得 rebate (如 -0.011%)
低延迟
验证者间 P2P gossip 传播快, 做市商可以快速更新报价
Trading Rewards
DYDX token 奖励, 按交易量分配
API 支持
完善的 gRPC/REST/WebSocket API, 方便程序化做市
5.4 为什么 DEX 订单簿特别需要做市商? CEX 和 DEX 的订单簿结构相同, 但流动性来源完全不同:
CEX 的流动性来源 (多层叠加):
1 2 3 4 5 6 7 8 9 1. 散户挂限价单 (大量) - 用户习惯: "我想 $2950 买 ETH" → 挂单等着 - CEX 界面鼓励挂单, 几百万用户自然形成深度2. 量化团队 / 高频交易 - 部署做市机器人, 延迟 < 1ms3. 专业做市商 (Jump, Wintermute 等) - 提供核心流动性, 尤其在新币和小币上
DEX 订单簿的致命问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1. 用户习惯不同 - DeFi 用户被 Uniswap "一键 swap" 教育过 - 很少有人去 DEX 手动挂限价单2. 链上挂单有成本 - 每次挂单/撤单 = 一笔交易 = gas fee - 做市商每秒可能调整几十次报价 - CEX: 免费 vs 链上: 每次付 gas → 成本不可接受3. 延迟问题 - CEX 挂单生效 < 1ms, 链上等区块确认 几百 ms ~ 几秒 - 做市商需要在价格变动时瞬间撤单/更新报价 - 延迟太大 → 被套利者的 "毒流量" (toxic flow) 吃掉4. 死亡螺旋 - 没有散户挂单 → order book 空 → 滑点巨大 → 没人用 → 更没人挂单
CEX vs DEX 订单簿对比:
维度
CEX 订单簿
DEX 订单簿
散户挂单量
大量 (免费, 习惯)
几乎没有 (付 gas, 不习惯)
做市商调整成本
免费, < 1ms
每次付 gas, 几百 ms
自然深度
有 (百万级用户)
无 (用户都用 swap)
没有做市商会怎样
深度变薄, 但还能用
基本不可用, book 是空的
各协议的解决方案:
协议
方案
本质
dYdX v4
order book 放内存 (不付 gas) + Maker Rebate + DYDX token 奖励
花钱请做市商来填满 order book
Hyperliquid
自研高性能 L1 (~200ms) + HLP Vault (协议自己跑做市策略) + HIP-2 (新 token 自动做市)
做市商不来? 那协议自己当做市商
GMX
不用订单簿, Oracle 定价, LP 池当对手方
绕开了订单簿流动性问题, 代价是 LP 承担对手方风险
六、保证金与清算
保证金基础概念详见保证金管理与清算引擎. 这里只讲 dYdX v4 的特有实现.
6.1 Cross Margin (全仓保证金) dYdX v4 默认使用 cross margin 模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Cross Margin (全仓) : - 所有持仓共享同一个保证金池 - 任何一个持仓的未实现利润可以作为其他持仓的保证金 - 好处: 资金效率高, 不容易被清算 - 风险: 一个持仓大亏可能连带其他持仓一起被清算 例 : 账户 10,000 USDC - ETH Long: +$500 未实现利润 - BTC Short: -$300 未实现亏损 available margin (可用保证金) = 10,000 + 500 - 300 = $10,200 Isolated Margin (逐仓, 也支持) : - 每个持仓单独分配保证金 - 一个持仓爆仓不影响其他持仓 - 资金效率较低
6.2 验证者执行清算 dYdX v4 的清算机制与 GMX 有本质区别:
清算执行: dYdX vs GMX
dYdX v4: 验证者清算
验证者在每个区块中检查所有持仓
发现保证金不足 → 自动在区块中执行清算
优点: 无需外部 keeper, 无 MEV 竞争
清算是协议内置逻辑, 不是外部激励
清算订单直接放入 order book 成交
如果 order book 流动性不足 → 走 ADL (自动减仓)
GMX: Keeper 清算
外部 keeper 监控所有持仓
发现可清算 → 提交清算交易, 赚取奖励
依赖外部激励, 可能有延迟
Keeper 之间有 MEV 竞争
清算价格由 oracle 决定
穿仓部分由 GLP 池承担
dYdX 的清算更像 CEX (内置引擎), GMX 更像传统 DeFi (外部 keeper 激励)
6.3 Insurance Fund (保险基金) & ADL (自动减仓)
dYdX v4 清算流程
1
持仓保证金 < 维持保证金 (maintenance margin) → 触发清算
2
验证者将该持仓作为清算订单放入 order book (订单簿)
3
order book 流动性充足 → 正常清算, 剩余保证金进入 Insurance Fund (保险基金)
4
清算后亏损 (穿仓) → Insurance Fund 兜底
5
Insurance Fund 也不够 → 触发 ADL (Auto-Deleveraging, 自动减仓)
ADL: 按 "盈利比例 × 杠杆倍数" 排名, 从最高的对手方开始强制平仓, 用对手方的盈利覆盖穿仓损失
这是最后手段, 极端行情才会触发
七、Funding Rate dYdX v4 的 funding rate 机制与 CEX 标准一致 (详见永续合约机制详解 section 3):
7.1 计算方式 1 2 3 4 5 6 7 8 9 10 11 funding_rate (资金费率) = premium_component (溢价分量) + interest_component (利息分量) // v4 中 interest_component = 0 (已移除, v3 遗留), 实际 funding_rate = premium_component premium (溢价) = (mark_price (标记价格) - index_price (指数价格)) / index_price 其中: mark_price = order book 的 mid-price (中间价) = (best_bid (最高买价) + best_ask (最低卖价)) / 2 index_price = 验证者从多个 CEX 获取的加权价格 注意 vs GMX: GMX 没有 order book , 所以用不同的 premium 计算方式. dYdX 和 CEX 一样, 直接用 order book mid-price 和 index price 的偏差.
7.2 结算周期
参数
dYdX v4
dYdX v3 / CEX (Binance)
结算频率
每个区块连续累积
每 8 小时离散结算
结算时间
无固定时间点 (持续生效)
0:00, 8:00, 16:00 UTC
费率显示
以 8h 为单位显示 (方便对比)
以 8h 为单位
Premium 采样
每分钟采样, 取 8h 加权平均
类似
上限
有 clamp, 防止极端值
有 clamp
v4 vs v3 区别 : v3 和 CEX 一样, 在固定时间点 (每 8h) 离散结算 funding. v4 改为每个区块连续累积, 持仓者的 funding 每个区块都在更新. 费率仍以 “8h” 为单位显示, 便于和 CEX 对比, 但实际按区块时间等比例累计.
核心机制回顾 (详见永续合约机制详解):
永续价格 > 现货 → funding rate 正 → 多头付钱给空头 → 抑制做多, 拉回价格
永续价格 < 现货 → funding rate 负 → 空头付钱给多头 → 抑制做空, 拉回价格
八、Oracle dYdX v4 的 oracle 设计是完全去中心化的:
8.1 价格获取流程
dYdX v4 Oracle 价格获取流程
Binance
OKX
Coinbase
...
多个 CEX
每个验证者各自拉取价格
独立运行, 无中心化服务 (Slinky sidecar)
共识过程中确定最终价格
验证者提交各自价格 → 取中位数 → 2/3+ 签名确认
每个区块更新 (~1-2 秒), 无单点故障
8.2 Skip Protocol (Slinky) dYdX v4 集成了 Skip Protocol 的 Slinky oracle:
特性
说明
集成方式
作为验证者 sidecar 运行, 每个验证者节点旁边跑一个 Slinky 进程
数据源
多个 CEX (Binance, OKX, Coinbase, Kraken, etc.)
更新频率
每个区块都更新价格 (~1-2 秒)
安全模型
价格由 2/3+ 验证者共识确认, 无单点故障
vs Chainlink
Chainlink 是外部 oracle network; Slinky 内置在验证者中, 延迟更低
为什么不用 Chainlink?
dYdX 是 Cosmos appchain, Chainlink 主要服务 EVM 链
内置 oracle 延迟更低 (不需要等外部 oracle 更新)
安全模型统一: oracle 和协议用同一套验证者, 不需要信任第三方
九、费率结构 9.1 Maker/Taker 费率分层 dYdX v4 根据 30 天交易量分层收费:
层级
30d 交易量
Maker Fee
Taker Fee
1
< $1M
-0.011% (rebate)
0.050%
2
$1M - $5M
-0.011%
0.045%
3
$5M - $25M
-0.011%
0.040%
4
$25M - $125M
-0.011%
0.035%
5
> $125M
-0.011%
0.030%
注: 具体费率可能随治理提案调整, 以上为典型结构.
关键点 :
Maker 始终获得 rebate (负手续费 = 协议倒贴钱给你)
这是吸引做市商的核心手段
协议的收入来源是 taker fee
9.2 Trading Rewards 1 2 3 4 5 DYDX Token 奖励 : - 按交易量分配 DYDX token - 相当于额外降低了交易成本 - 激励早期用户和做市商 - 随时间递减 (类似流动性挖矿)
9.3 费用去向
dYdX 费用分配: v3 vs v4
v3:
交易费 → dYdX Trading Inc
中心化, 有争议
v4:
交易费 → 验证者 + DYDX staker
去中心化, 社区受益
v4 费用分配流程
Taker Fee
Maker Rebate
付给 maker (-0.011%)
验证者 + Staker
剩余费用的主要去向
Community Pool
社区治理基金
Taker Fee - Maker Rebate = 协议净收入 → 分配给验证者, staker, community pool
十、vs CEX 对比
dYdX v4 vs CEX (Binance Futures)
维度
dYdX v4
Binance Futures (CEX)
托管
非托管 (自己控制私钥)
托管 (资金存在交易所)
KYC
无 KYC (任何人可用)
强制 KYC, 部分地区封禁
透明度
完全链上可验证
黑箱, 需信任交易所
延迟
~1-2 秒 (区块时间)
~1-10 毫秒
深度
较薄 (做市商有限)
极深 (大量散户+做市商)
费率
Maker -0.011% / Taker 0.05%
Maker 0.02% / Taker 0.04%
交易对
~180+ 交易对
~300+ 交易对
单点故障
无 (60 个验证者分布式)
有 (服务器/监管/跑路)
dYdX 的真正优势不是 "比 CEX 更快更便宜", 而是 "非托管 + 无 KYC + 透明 + 抗审查"
如果你只在乎速度和深度, CEX 永远赢. 但如果你在乎资产主权和无许可交易, dYdX 是更好的选择.
10.1 dYdX vs GMX (定价与撮合方式对比) “Oracle 型” vs “订单簿型” 指的是定价机制和成交方式 的区别, 不是风控模型的区别, 两者都有 OI 限制等风控措施.
维度
dYdX v4 (订单簿型)
GMX (Oracle 型)
定价机制
Order book 供需撮合
Chainlink oracle 直接喂价
滑点
有 (取决于 depth)
零滑点 (但有 price impact)
对手方
其他交易者 (P2P)
GLP/GM 池 (交易者 vs LP)
做市商
需要专业做市商
不需要 (oracle 定价)
大单支持
取决于 depth
受 OI 上限限制
LP 角色
做市商提供报价
GLP holder 被动做对手方
价格发现
有 (自己的 order book)
无 (跟随外部 oracle)
复杂度
高 (需要 appchain)
低 (EVM 智能合约)
OI 限制
有, 治理参数设定每个市场的 OI Cap
有, Reserve 机制 (池子资产决定上限)
OI 调整方式
DYDX 持有者链上治理投票
由池子规模自动决定
关键洞察 : 订单簿型 perp 有 价格发现 能力: 它可以反映市场供需, 甚至领先于现货市场. Oracle 型 perp 只能跟随现货价格, 永远不会 “发现” 新价格. 这就是为什么 CEX 都用订单簿: 它不仅是交易场所, 也是价格发现场所.
十一、Go: 与 dYdX v4 交互 dYdX v4 是 Cosmos appchain, 可以通过 gRPC 和 REST API 交互.
11.1 查询 Order Book 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 package mainimport ( "context" "encoding/json" "fmt" "io" "net/http" "time" )const baseURL = "https://indexer.dydx.trade/v4" type OrderBookResponse struct { Bids []OrderBookEntry `json:"bids"` Asks []OrderBookEntry `json:"asks"` }type OrderBookEntry struct { Price string `json:"price"` Size string `json:"size"` }func GetOrderBook (ctx context.Context, ticker string ) (*OrderBookResponse, error ) { url := fmt.Sprintf("%s/orderbooks/perpetualMarket/%s" , baseURL, ticker) req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil ) if err != nil { return nil , fmt.Errorf("create request: %w" , err) } resp, err := http.DefaultClient.Do(req) if err != nil { return nil , fmt.Errorf("do request: %w" , err) } defer func () { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) return nil , fmt.Errorf("unexpected status %d: %s" , resp.StatusCode, body) } var book OrderBookResponse if err := json.NewDecoder(resp.Body).Decode(&book); err != nil { return nil , fmt.Errorf("decode response: %w" , err) } return &book, nil }func main () { ctx, cancel := context.WithTimeout(context.Background(), 10 *time.Second) defer cancel() book, err := GetOrderBook(ctx, "ETH-USD" ) if err != nil { fmt.Printf("Error: %v\n" , err) return } fmt.Println("=== ETH-USD Order Book ===" ) fmt.Printf("\nTop 5 Asks (卖单):\n" ) for i := range min(5 , len (book.Asks)) { fmt.Printf(" %s @ %s\n" , book.Asks[i].Size, book.Asks[i].Price) } fmt.Printf("\nTop 5 Bids (买单):\n" ) for i := range min(5 , len (book.Bids)) { fmt.Printf(" %s @ %s\n" , book.Bids[i].Size, book.Bids[i].Price) } }
11.2 查询持仓信息 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 type SubaccountResponse struct { Subaccount struct { Address string `json:"address"` SubaccountNumber int `json:"subaccountNumber"` Equity string `json:"equity"` FreeCollateral string `json:"freeCollateral"` OpenPerpPositions []struct { Market string `json:"market"` Side string `json:"side"` Size string `json:"size"` EntryPrice string `json:"entryPrice"` UnrealizedPnl string `json:"unrealizedPnl"` } `json:"openPerpetualPositions"` } `json:"subaccount"` }func GetSubaccount (ctx context.Context, address string , subaccountNum int ) (*SubaccountResponse, error ) { url := fmt.Sprintf("%s/addresses/%s/subaccountNumber/%d" , baseURL, address, subaccountNum) req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil ) if err != nil { return nil , fmt.Errorf("create request: %w" , err) } resp, err := http.DefaultClient.Do(req) if err != nil { return nil , fmt.Errorf("do request: %w" , err) } defer func () { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) return nil , fmt.Errorf("unexpected status %d: %s" , resp.StatusCode, body) } var result SubaccountResponse if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { return nil , fmt.Errorf("decode response: %w" , err) } return &result, nil }
11.3 查询 Funding Rate 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 type FundingRateResponse struct { HistoricalFunding []FundingEntry `json:"historicalFunding"` }type FundingEntry struct { Ticker string `json:"ticker"` Rate string `json:"rate"` Price string `json:"price"` EffectiveAt string `json:"effectiveAt"` }func GetFundingRates (ctx context.Context, ticker string , limit int ) (*FundingRateResponse, error ) { url := fmt.Sprintf("%s/historicalFunding/%s?limit=%d" , baseURL, ticker, limit) req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil ) if err != nil { return nil , fmt.Errorf("create request: %w" , err) } resp, err := http.DefaultClient.Do(req) if err != nil { return nil , fmt.Errorf("do request: %w" , err) } defer func () { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) return nil , fmt.Errorf("unexpected status %d: %s" , resp.StatusCode, body) } var result FundingRateResponse if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { return nil , fmt.Errorf("decode response: %w" , err) } return &result, nil }
11.4 通过 gRPC 查询链上数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" )func connectGRPC () (*grpc.ClientConn, error ) { conn, err := grpc.NewClient( "dydx-grpc.polkachu.com:23890" , grpc.WithTransportCredentials(insecure.NewCredentials()), ) if err != nil { return nil , fmt.Errorf("connect grpc: %w" , err) } return conn, nil }
十二、小结 12.1 核心要点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 1. dYdX 选择 "造自己的链" 来解决永续 DEX 的性能问题 - 通用 L1/L2 无法同时满足高吞吐 + 低延迟 + 自主定制2. 订单簿模式 vs Oracle 模式是两种根本不同的设计哲学: - 订单簿: 价格由供需决定, 有价格发现, 需要做市商, 有滑点 - Oracle: 价格由外部喂入, 无价格发现, 无需做市商, 零滑点但有上限3. dYdX v4 的关键创新: - In-memory order book (不上链, 极快) - 验证者即撮合引擎 (完全去中心化) - 内置 oracle (Slinky, 无需外部依赖) - 费用归社区 (验证者 + staker)4. 做市商是订单簿 DEX 的生命线: - 没有做市商 = 没有流动性 = 没有交易 - 所以 dYdX 必须用 maker rebate + rewards 吸引做市商5. dYdX 的真正优势不是 "比 CEX 快": - 而是 非托管 + 无 KYC + 透明 + 抗审查
12.2 下一步
vAMM 永续合约演进史 : 另一种 DEX 永续的实现方式, 用虚拟 AMM 替代 order book
该篇会讲 Perpetual Protocol 的 vAMM 和 Drift Protocol, 以及 vAMM 模型的 squeeze 风险
之后是 Hyperliquid 深度解析, 另一个订单簿型永续, 但走了自研 L1 而非 Cosmos 的路线
思考题 :
dYdX v4 的 in-memory order book 在验证者之间通过 gossip 同步, 如果不同验证者看到的 order book 状态不一致怎么办?
为什么 dYdX 选择 Cosmos 而不是自己从零写一条链 (像 Hyperliquid)?
如果 dYdX 上没有足够的做市商, 和 GMX 相比, 哪个模式对普通交易者更友好?