T4 · DeFi Engineer
从「实现一个金融机制」走到「说得出它在什么行情下会亏、亏给谁」。
面向金融工程方向。
本页里的「T4」指这条 Track。课程章节一律写成「第 T22 章」并带链接,两者不是一回事——章节 T4 讲的是 RPC 是什么。
这条 Track 适合谁
你实现过一个 AMM,但只验证过「数值算得对」。 滑点公式、手续费、添加撤出流动性,测试全绿。但有人问「价格在一个区块里跌 40% 会发生什么」,你没测过,也不知道该怎么测。
你分得清各种协议的名字,分不清它们的风险结构。 你知道借贷有清算、永续有资金费、AMM 有无常损失。再问一层——这三件事分别是谁在承担、谁在付钱——你答得含糊。
你写得出公式,但定不了参数。 抵押率设 75% 还是 80%、清算奖励给 5% 还是 8%、利率曲线的拐点放在 80% 还是 90%。你知道这些数字很重要,但你选它们的方式是抄一个现有协议。
你的协议只在「正常行情」下被测过。 你的测试里,价格是平稳的、流动性是充足的、清算人是及时的。而 DeFi 出事的时候,这三条同时不成立。
分界线是这一句:你交付的不是一个能跑的协议,是一份「它在什么条件下会产生坏账、坏账由谁吃掉」的说明书,外加实现它的代码。
前置
这条 Track 的前置横跨 Part A 和 Part B:机制的「为什么」在 Part A,实现的「怎么做」在 Part B,两边都不能省。 图谱里第 T19 章同时依赖第 14 章和第 T12 章,就是这个意思。
- 第 14–15 章
- 第 16–18 章
- 第 T9 章
- 第 T12 章
- 第 T19 章
- 第 T20 章
- 第 T21 章
- 第 T22 章
- 第 T23 章
| 必须先读 | 图谱里的理由 |
|---|---|
| 第 14 章 · DEX 为什么可以没有中心交易所 | 第 T19 章的直接前置。没有这一章,你写出的会是一段数学,不是一个市场 |
| 第 15 章 · 流动性是什么 | 「你真正能拿回来的钱」。这条 Track 的所有风险讨论都建立在它上面 |
| 第 16 章 与 第 18 章 | 图谱里分别是第 T22、T23 章的直接前置。信用问题被换成清算问题、杠杆带来反馈回路,这两句话是整条 Track 的主轴 |
| 第 T9 章 · ERC Standards | 第 T19 章的直接前置。你的协议要接的每一种代币都可能不按标准行事 |
| 第 T12 章 · Testing & Deployment | 同为第 T19 章的直接前置。金融协议的测试必须能 Fork 主网,否则你测的是一个不存在的市场 |
| 第 T19 章 与 第 T20 章 | 恒定乘积的代码化,以及报价、路由、执行为什么必须分层 |
| 第 T21 章 · Oracle | 图谱里它是第 T22 章的直接前置。先有价格,才谈得上清算 |
| 第 T22 章 与 第 T23 章 | 清算引擎与风险引擎。这条 Track 的毕业作品就落在这两章之上 |
第 T24 章 · MEV 不是硬前置,但强烈建议在动手前读完:你设计的每一个清算奖励和每一次报价更新,都会被交易顺序市场重新定价。
你会学什么
- AMM
- CLMM
- Order Book
- Lending
- Perp
- Oracle
- Risk Engine
七个 topic 分成三组加一个收口。
一、交易场所:AMM、CLMM、Order Book —— 回答「价格怎么形成」
三种市场结构不是三代技术,是三种在不同约束下的解。这一组要建立的判断力是:给一个资产对和一种链的成本结构,说得出该用哪一种,以及代价是什么。
| 结构 | 价格怎么来 | 做市方的主要风险 | 适合什么 |
|---|---|---|---|
| 恒定乘积 | 由储备比例算出,被动接受 | 价格变动带来的持仓偏移 | 长尾资产、无人主动做市的场景 |
| 集中流动性 | 同上,但只在一个区间内提供 | 同上,且价格走出区间后停止赚费 | 相关性高的资产对,资金效率是主要诉求 |
| 订单簿 | 由报价方主动定价 | 报价过期被吃单 | 撮合成本低的环境,专业做市方存在 |
集中流动性这一项要落到实现细节:区间与刻度的表示、跨区间时的状态切换、以及手续费按区间累计的记账方式。这部分的实现难度主要不在数学,在于把浮点直觉翻译成定点整数运算而不损失精度。
二、信贷与杠杆:Lending、Perp —— 回答「谁在承担风险」
借贷协议的安全边界是清算速度,不是利率模型的优雅程度。这一组要练的是把这句话拆成可实现的部分:
- 健康度的定义与它的更新时机——是每次交互算,还是靠外部触发
- 清算奖励怎么定:低了没人来,高了用户损失过大,而这个阈值随 Gas 成本和市场深度变化
- 坏账发生之后谁吃掉它:保险基金、LP 按比例分摊、还是社会化损失
- 永续这一侧多一层:保证金模式、资金费率的收敛作用、标记价格与指数价格的区别、以及自动减仓在什么时候触发
连环清算是这一组的压轴:一次清算压低价格,压低的价格触发下一批清算。你要能在测试里复现这个回路,并量化保险基金被消耗了多少。
三、价格来源:Oracle —— 回答「你凭什么相信这个数字」
预言机是协议最常见的单点。这一组要做到的是把「相信一个价格」拆成可检查的条件:更新频率、偏离阈值、心跳超时、数据过期时的降级策略。
以及那道必须自己算一遍的题:操纵这个价格源需要多少钱,能从你的协议里拿走多少钱。 两个数字放在一起,你就知道自己的取价方式安不安全。
四、收口:Risk Engine —— 把前面三组变成一个会拒绝的系统
风险引擎不是一个模块名,是一层职责:在执行之前,判断这笔操作会不会让系统进入不可接受的状态。 它管的是限额、保证金要求、持仓集中度、价格有效性、以及最重要的——什么时候该拒绝一笔完全合法的交易。
这一层就是你的毕业作品和一个「能跑的 DeFi demo」之间的全部区别。
毕业作品
一个带风险引擎的交易或借贷协议。
和毕业项目的分工:毕业项目要横向完整的系统,这条 Track 只要协议这一层,但要求你能把它在极端行情下的行为说清楚。「带风险引擎」是核心约束——没有风险引擎的协议,在这条 Track 里不算交付。
别人能不能跑起来。 clone 之后,一条命令装依赖,一条命令跑完全部测试,包括 Fork 测试。README 写清楚 Fork 的链与高度,以及为什么选这个高度(通常是因为那里有你需要的真实流动性)。
再给一个能在本地跑的极端行情脚本,别人执行一次就能看到你的协议在崩盘时的表现。
风险引擎能拒绝,而且拒绝有记录。 至少五类会被拒绝的情况:价格数据过期、偏离超阈值、单笔超过限额、持仓集中度超标、健康度不足。
每一类配一个测试:构造这个状态,确认操作被拒绝,并且拒绝原因是可区分的。一个只会通过的风险引擎,等于没有风险引擎。
有一次完整的极端行情演练。 构造价格在单个区块内大幅下跌的场景,跑完整个流程,记录三个数字:有多少仓位进入可清算状态、其中多少被及时清算、产生了多少坏账。
然后回答一个问题:这笔坏账由谁承担,承担的顺序是什么。 答不出来,说明你的协议还有一块没设计。
算出你的预言机攻击成本。 写明取价方式、操纵它需要的资金规模、需要维持多少个区块、以及攻击成功能从协议里拿走多少。
两个数字放在一起如果攻击划算,你要么换取价方式,要么在威胁模型里写明「我们不防这种情况,后果由谁承担」。明确放弃是专业,假装不存在不是。
参数有理由,不是抄来的。 抵押率、清算奖励、利率曲线拐点、资金费率系数——每一个都要写出选它的依据:基于什么样的波动率假设、什么样的市场深度、什么样的清算延迟。
允许你参考现有协议,但要说明为什么它的假设在你这里也成立。
如果要上主网,用测试网先跑完整轮,主网只投入小额,并且设好上限。 只交测试网部署加一份完整的参数论证,在评审里同样成立。
怎样判断自己达标了
攻击者在同一笔交易里完成三步:先在那个池子里大额买入把价格推高,再用被推高的价格作抵押从你的协议借出远超真实价值的资产,最后把池子里的仓位平掉。
关键在于这三步在同一个区块、同一笔交易里完成,所以池子价格没有恢复的机会,任何基于单点即时价格的检查都会通过。资金可以来自闪电贷,意味着攻击者的本金需求接近于零,只需要覆盖手续费。
防御方向有三条:用时间加权价格提高操纵成本、用多个独立来源交叉验证、以及给关键操作加上「同区块内不可完成」的约束。但要注意时间加权不是免费的——它让价格滞后,而滞后在剧烈行情中会让清算迟到。
第一,清算人的成本。包括 Gas、以及他为了抢到这笔清算而付出的交易顺序溢价。奖励必须高于这个成本,否则没有人来。
第二,市场深度。清算人拿到抵押品后要卖出,卖出会产生滑点。深度越差,他需要的缓冲越大。
第三,价格波动速度。从仓位变得可清算到清算真正执行,中间有延迟;这段时间里价格还在动。波动越快,需要的安全垫越厚。
反过来,奖励过高的代价是用户损失过大,以及它会激励清算人去制造清算条件。所以正确的答案永远是一个区间,而不是一个抄来的数字。加分项:提到这个区间会随 Gas 成本和市场状况变化,因此参数应该可调,而且调整要有时间锁。
它的作用是把合约价格拉回现货价格:合约价高于现货时,多头付钱给空头,持有多头变贵,从而抑制溢价。它是一个持续施加的经济压力,不是一个强制机制。
它失效的场景有两类。单边行情:所有人都想做多,即使资金费率很高也愿意付,因为预期收益更大。此时价差可以长期维持。流动性枯竭:套利者本该在价差出现时反向操作把它拉回,但如果现货侧借不到币或者深度不够,这个套利路径断掉,资金费率就只是一笔在多空之间转移的钱,不再有收敛作用。
推论:不要把资金费率当成安全机制。真正防住极端情况的是保证金要求、强平线和自动减仓,资金费率只负责平时。
定点运算的精度与取整方向。
区间边界用的是离散的刻度,价格与刻度之间是指数关系;流动性、手续费累计、跨区间时的状态切换,全都建立在整数运算上。任何一处取整方向搞反,都会在大量小额交易中累积成可被利用的偏差——每次只差一个最小单位,几百万次之后就是一笔真钱。
规则只有一条,和第 T28 章说的一样:取整方向必须永远对协议有利。 验证方式是把它写成不变量(比如「协议持有的资产不少于所有头寸应得之和」)交给 Fuzzing,而不是靠人工审阅每一处除法。
没有标准答案,检查三件事:
- 你有没有想到集中度风险:单一地址的仓位大到无法被正常清算时,你的清算流程还成立吗。
- 你有没有想到这笔钱可能随时全部撤走,以及那一刻依赖这部分流动性的其他功能会怎样。
- 你的风险引擎里有没有一条限额是针对「单一参与者占比」的,还是所有限额都只针对单笔金额。
第三条最常被漏掉:限额限的是每一笔,风险来自累计。
常见误区
「数值测试通过就等于机制正确」
单元测试验证的是「在我给定的输入下,公式算得对」。而 DeFi 的事故几乎从不来自算错,来自状态组合:价格在这个时刻、流动性在那个水平、清算人恰好没来。
正确做法:把机制的性质写成不变量交给有状态 Fuzzing,再补一组极端行情的情景测试。数值测试只是下限。
「抄一个成熟协议的参数就是安全的」
参数是对一整套假设的编码:那个协议的资产波动率、它所在链的 Gas 成本、它的清算人生态、它的市场深度。这些条件换一个环境就不成立。
正确做法:每个参数写清它背后的假设,并在测试里验证假设成立时的行为和不成立时的行为。参数可调、调整有时间锁,比一次选对更重要。
「我的协议不碰预言机,所以没有预言机风险」
只要你的协议在任何环节引用了一个「价格」——包括从自己的池子里读储备比例、包括依赖某个外部协议的报价——你就有预言机。区别只在于这个价格的操纵成本是高是低。
正确做法:把「我的价格从哪来、操纵它要多少钱」当成必答题。第 T21 章给的那笔账,每个协议都要自己算一遍。
「清算逻辑写对了,清算就会发生」
清算是一个需要外部参与者主动执行的动作。代码正确只保证「有人来的时候能成功」,不保证有人来。行情剧烈时,Gas 飙升、交易顺序被竞价、清算人的资金被占用,这三件事会同时发生。
正确做法:把清算人当成一个需要设计激励的外部角色,而不是一个假设存在的组件。在测试里显式模拟「清算延迟 N 个区块」的情况,看你的保险基金撑不撑得住。
接下来
- 带着自己的协议重读:第 T21 章、第 T22 章、第 T24 章。
- 攻击成本那张表在第 T29 章 · Protocol Security,参数定完之后一定要用它算一遍。
- 常见组合:加 Track T5 · Security Engineer 把风险引擎做成可被证明的东西,加 Track T1 · EVM Engineer 补实现深度,加 Track T3 · Onchain Data Engineer 让参数有真实数据支撑。
- 跨到非技术侧:Track N1 · Crypto Research & Investment。会实现清算引擎的人去做协议研究,天然比只看指标的人多一层——你知道哪些数字是设计出来的,哪些是市场跑出来的。
- 想把协议接成完整产品,去毕业项目。