博客

量化套利入门 08|替别人还债,为什么能拿到折价资产?

借款人的抵押品快撑不住债务时,协议会让任何人替他还一部分债,再从他的抵押品里多切一块给对方当酬劳。这块酬劳写在规则里,能不能真的落进口袋,要看你在暴跌和拥堵中跑得多快、卖得多好。

约 12 分钟量化套利入门系列

Aave 的官方 FAQ里有个小例子。Bob 存入 10 个 ETH,借出价值 5 个 ETH 的稳定币 GHO。后来 ETH 价格下跌,他的仓位越过了安全线。一个陌生人替 Bob 还了价值 2.5 个 ETH 的 GHO,协议从 Bob 的抵押品里拿出 2.625 个 ETH 交给这个人。

多出来的 0.125 个 ETH,就是清算奖金,也常被叫作清算折扣。替人还 2.5 的债,拿走 2.625 的货,相当于按九五折左右买到了 ETH。

这篇要回答的问题很简单。协议为什么愿意让外人打折拿走借款人的资产?这份折扣又有多少能真正变成利润?

先说结论。清算奖金由借款人支付,买的是速度。协议需要有人在价格下跌时立刻接手一件还在贬值的资产,于是开出加急费。但规则对所有人公开,成百上千个机器人在抢同一张单子。手续费、竞价和卖出时的价格冲击,会把纸面上的 5% 分掉将近一半。到了真正极端的行情,抢单的人突然消失,折扣又可能失控到接近 100%,这时候吃亏的就变成了借款人和协议本身。

复古金融终端风插画:市场暴雨中,清算机器人替借款人还债并接收折价抵押品
机器人替别人还债,协议从借款人的抵押品里多切一块给它。多出来的部分就是清算奖金。

那条安全线是怎么算出来的

可以先拿典当行做类比。你拿一块值 1 万的表去当,店家只肯借你 6 千。表价跌得太狠,店家就会卖表收回借款。链上借贷也是抵押多、借得少,跌破某条线就处置抵押品。

这个类比有两处不成立。典当行由店家自己卖货,链上借贷的合约不会主动做任何事,必须有外人发来一笔交易才会触发清算。另一处在于,典当行通常卖掉整件抵押品,链上协议往往只卖一部分,够把仓位拉回安全区就停。这两点正好是清算生意存在的原因,后面会一一展开。

Aave 用健康因子衡量仓位离那条线还有多远。算法是抵押品价值乘以清算阈值,再除以债务。清算阈值是协议给每种抵押品定的打折系数,意思是这件抵押品最多按百分之多少算作还债能力。Aave 的官方概览写明,健康因子低于 1 时,外部清算者可以偿还部分债务并换走抵押品。

代入数字走一遍。账户里有价值 10,000 美元的 ETH,清算阈值 80%,借了 6,000 美元。健康因子等于 10,000 × 0.8 ÷ 6,000,约 1.33。

ETH 跌了 25%,抵押品只值 7,500 美元。7,500 × 0.8 = 6,000,健康因子正好是 1。按规则,要低于 1 才能清算,所以此刻还安全。只要再跌一点,比如抵押品值 7,400 美元,健康因子变成 7,400 × 0.8 ÷ 6,000,约 0.99,清算的大门就打开了。

门打开后能清多少,也有规矩。按 Aave FAQ 目前的说明,健康因子还在 0.95 以上、抵押品和债务又都不少于 2,000 美元时,一次最多只能清掉一半债务。健康因子跌到 0.95 及以下,或者仓位太小,才允许一次清掉全部。

接着上面的账户算。抵押品值 7,400 美元,债务 6,000,健康因子约 0.99,所以清算者最多替他还 3,000 美元。假设 ETH 的奖金是 5%,清算者拿走价值 3,150 美元的 ETH。账户剩下 4,250 美元的抵押品和 3,000 美元的债务,健康因子变成 4,250 × 0.8 ÷ 3,000,约 1.13,又回到了安全区。借款人保住了另一半仓位,代价是多付的那 150 美元。

这里有个细节决定了清算机器人的工作方式。合约判断健康因子时,用的不是交易所屏幕上的最新成交价,而是预言机价格。预言机是把链外价格搬到链上的数据服务,它按固定频率或价格偏离到一定幅度时才更新。暴跌时,交易所价格先动,链上价格隔一会儿才跟上。机器人要提前算好哪些仓位会在下一次喂价后越线,同时还得提防自己连接的节点数据已经落后一两个区块。

奖金由谁出,为什么非给不可

从刚才的账可以看清楚,那 150 美元出自借款人的抵押品。协议没有掏一分钱,它只是规定了借款人一旦越线,要拿多少资产来请人帮忙。

协议之所以必须请人,是因为合约自己不会动。每次清算都需要有人盯着价格,准备好还债用的稳定币,支付链上手续费,也就是常说的 gas,然后接下一堆正在下跌的 ETH,再想办法卖掉。没有奖金,没人愿意在行情最乱的时候做这些事。

没人做的后果很具体。ETH 若继续下跌,抵押品的价值可能跌破债务本身。这时就算有人想清算也无利可图,差额只能变成坏账,最后由协议和存款人承担。奖金让清算发生在抵押品还够还债的时候。

奖金定多少是个权衡。太低,机器人算下来不划算,关键时刻没人出手。太高,借款人每次被清算都多割一刀肉,借贷产品就不好用了。所以不同资产的奖金不一样。Aave FAQ 的例子里,ETH 是 5%,波动更大的 YFI 是 15%。资产越难卖、越容易暴跌,协议就得开出越高的价钱请人接手。

5% 奖金落到账户里还剩多少

协议写的是毛奖金。机器人真正关心的是另一笔账。我们拿一笔假设的清算从头算到尾。

机器人替借款人偿还 10,000 USDC,协议给它价值 10,500 美元的 ETH。这是理论收益,500 美元。

拿到的是 ETH,不是美元。机器人要把它卖回稳定币才算锁定利润。暴跌时市场上的买单本来就薄,一口气卖出 10,500 美元的 ETH,会把价格往下砸一点,这种成交价比预期更差的损失叫滑点。最后只收到 10,360 USDC。此时账面上还剩 360 美元。

再扣成本。45 美元 gas,5 美元闪电贷费用,后面会讲闪电贷是什么。还有 20 美元的失败交易摊销,意思是以前抢单失败白白烧掉的手续费,要分摊到成功的单子上。10,360 − 10,000 − 45 − 5 − 20 = 290 美元。

网页上写着 5% 清算奖金,最终净利润是 2.9%。中间的差额,一部分给了接盘 ETH 的市场,一部分给了打包交易的网络。

所以程序不能只算债务乘奖金率。它要先查链上各个交易池实际能吃下多少 ETH,估出卖出回款,再扣掉网络费用、借款成本和失败概率。遇到冷门抵押品,结论甚至会反过来。5% 折扣的 ETH 能顺利卖掉,10% 折扣的冷门代币如果没人接,就只能躺在钱包里继续跌,账面上的 10% 随时可能变成亏损。

复古金融终端风插画:网络风暴中多台清算机器人拥堵碰撞,燃料成本不断升高
奖金写在协议里,能不能抢到是另一回事。拥堵、失败和卖出滑点都在分钱。

大家都看得见,谁先写进区块谁拿走

上面那笔账还默认了一件事,就是你抢到了。现实里这一步最难。

链上所有借款仓位和清算规则都是公开的。一个大仓位接近清算线,盯着它的机器人可能有几十个。机会出现的那个区块里,大家几乎同时提交相似的清算交易。同一笔债只能被还一次,谁的交易排在前面,谁拿奖金。

排序靠钱。以太坊上的交易除了基础手续费,还可以附加优先费,相当于给打包区块的人塞小费,小费越高越可能排在前面。大家一起抬小费,原本属于清算者的奖金,就有一部分转给了出块方。有的机器人干脆把交易直接发给区块构建者,通过私下竞价争取位置,这本质上还是在出钱买排序。

输掉的人也要付钱。你的交易晚了一步,债务已经被别人还掉,你的调用就会执行失败,所有改动被撤销,这叫回滚。但交易已经被打包上链,gas 照样扣。网络越拥堵,这笔白交的手续费越贵。

这时就要按期望值算账。假设一笔机会成功后净赚 300 美元,你抢到的概率只有 20%,每次失败损失 25 美元。期望值是 300 × 20% − 25 × 80%,也就是 60 − 20 = 40 美元,值得一试。如果大家同时抬价,失败成本涨到 80 美元,期望值变成 60 − 64 = −4 美元。看上去能赚 300 美元的单子,抢多了是亏的。

私下发给区块构建者的交易,有些通道可以设定失败了就不上链,失败的 gas 能省下来。代价是竞争换了一个地方,你得在出价上压过别人,否则照样拿不到单子。

还有一类协议不用固定折扣,而是把抵押品拿出来拍卖。固定折扣比的是谁更快写进区块,拍卖还要决定出多少钱。拍卖有可能让你用更好的价格拿到货,也可能在等待结果时眼看抵押品继续下跌。两种机制的风险来源不同,不能套用同一套收益模型。

没有本金也能清算,但不能没有买家

替人还 10,000 USDC,你手里得先有 10,000 USDC。大仓位清算动辄几百万美元,备着这么多闲钱等机会,资金成本不低。闪电贷解决了这个问题。

闪电贷是一种只在一笔交易内部存在的借款。你在同一笔交易里借钱、用钱、还钱,不需要抵押。只要最后一步还不上,整笔交易就像没发生过一样全部撤销,出借方的钱从未离开。这种全有或全无的性质,叫原子性。

接着前面的例子,一条清算路径是这样的。借 10,000 USDC,调用清算函数替人还债,拿到 ETH,再到去中心化交易所把 ETH 换回 USDC,最后归还 10,000 本金加 5 美元费用。按Aave V3 的闪电贷文档,费率部署时设为 0.05%,治理投票可以调整,以链上当前参数为准。机器人会给换币这一步设一个最低回款,比如 10,050 USDC。达不到这个数,说明利润已经不够覆盖成本,整笔交易直接回滚。

闪电贷解决的是钱从哪里来,没有解决抵押品卖给谁。整条路径能不能成立,取决于那一刻链上有没有足够的买单接住 ETH。路径越长、调用的合约越多,中间某一步出问题的机会也越大。

原子回滚也不等于免费试错。前面说过,上链后回滚的交易照样付 gas。最低回款的设置也很微妙。设得太宽,别人看到你的大额换币,可以在你前面先砸价、在你后面再买回,从你的滑点里赚钱,这叫夹子攻击。设得太紧,市场稍微一动交易就失败,白烧一笔手续费。

一台清算机器人真正难在哪里

写一个能调用清算函数的脚本不难。难的是在暴跌和拥堵中,它依然算得准、发得出、卖得掉。

一个能长期运行的系统通常分成几层。索引器维护全网的借款仓位,价格服务跟踪预言机更新和各交易池的可卖深度,策略层计算每个机会的净利润,执行层负责在本地用最新区块状态模拟整笔交易,确认不会失败后再签名广播。

交易发出去以后也没完。区块链偶尔会发生重组,刚确认的区块被另一条链替换掉。刚才显示成功的清算,可能在重组后消失或者变成别人的。监控层要重新确认仓位和余额。

记账同样容易出错。发现仓位时的区块高度、当时的预言机价格、模拟结果、发单参数、最终成交和卖出回款,都应该挂在同一个编号下。否则月底只看到钱包多了钱,却说不清利润来自清算奖金、手里的 ETH 碰巧涨了,还是一笔漏记的库存。

这些工程细节平时只决定你赚多赚少。真正检验它们的,是网络、预言机和市场同时出问题的那几个小时。

MakerDAO 的黑色星期四

2020 年 3 月 12 日,ETH 在很短时间内大幅下跌,以太坊网络严重拥堵。

当时 Maker 处理问题仓位的方式就是拍卖。仓位越线后,抵押的 ETH 被拿出来拍卖,外部的清算机器人用稳定币 DAI 出价竞买,Maker 社区管这些机器人叫 keeper。这套机制有个前提,就是有足够多的 keeper 在场竞价,价格才会被推到接近市价。

Maker 治理事后发起的金库补偿投票说明把过程记得很具体。暴跌带来巨大的网络流量,有些时段 gas 价格高得出乎意料,Maker 的价格预言机没能及时更新。keeper 同样被高 gas 拖住,手里也缺 DAI。结果许多拍卖以 0 DAI 或远低于市价的价格成交。

放回前面的框架就容易理解了。平时清算者之间的竞争,会把折扣压到一个合理水平。那天竞争者大面积缺席,如果一场拍卖只剩一个出价者,他报很低的价格也能赢。折扣从 5%、10% 这样的量级,一下子变成了白拿。

这笔账最后有人付。按那份投票说明,大部分损失由 Maker 协议承担,并通过 Flop 拍卖补回,也就是增发治理代币 MKR 卖出换取 DAI。金库持有人也受了损失,其中超出正常清算应有的部分,当时粗略估计不到 400 万 DAI。

这件事打掉了回测里两条最舒服的假设。一条是每场拍卖都有很多人参加,另一条是稳定币随时能买到。清算机制同时依赖预言机、网络、竞价者和稳定币流动性,缺掉一环,折扣就会变形。而且它往往在最需要清算的时候出问题,因为大跌、拥堵和资金紧张通常一起来。

回到最初的问题

替别人还债能拿到折价资产,是因为协议需要有人在最糟糕的时刻接手一件正在贬值的东西,而借款人在借钱那天就同意了为此付费。折扣是这份加急工作的报酬。

正常行情里,公开的规则会招来足够多的机器人,竞争把这份报酬压得很薄,不少流向了出块方和接盘的市场。极端行情里,竞争者可能突然离场,报酬会膨胀到不合理的地步,账单落到借款人和协议头上。

对清算者来说,奖金率只是起点。真正决定能不能赚钱的,是抢不抢得到、卖不卖得掉,以及当所有人都在逃的时候,你的系统还能不能正常发出交易。