yueying007

Posted on Sep 17, 2022Read on Mirror.xyz

9月15日以太坊分叉网套利复盘

  1. 前期准备

知道以太坊Merge之后要分叉出POW链是一个月前,大概8月中下旬,当时有两个团队准备分叉以太坊,一个是宝二爷的团队EthereumPow,另一个是Classzz团队的EthereumFair。当时预想到,分叉会把以太坊上的所有状态复制一遍,在发生分叉以后,由于除了分叉币ETHW/ETHF有潜在价值,其它币都没有价值,所以一定会有人或者机器人通过事先准备好的前端页面或者程序,将所有token都兑换为分叉币,这种兑换大概率发生在Uniswap/Sushiswap/Curve这些Dex上面,导致分叉币的价格出现巨大波动,这时不同的Dex之间会出现巨大价差。

套利机器人分为两部分,一个是部署在以太坊上的Solidity合约,这个没有任何变动,因为分叉后合约也会复制一份,另一个是本地的监控机器人,代码在原来的基础上重做了一个分支,做了轻微改动:

(1) 套利的目标token从原来的任意token变为只要WETH

(2)只监控Curve/Uniswap/Suhiswap/Balancer上包含WETH(数量在10个以上)的池子

(3)为了在与其它机器人的竞争中占得先机,把初始的gas_price设置为基础gas_price+50gwei, 在钱包里放0.5个ETH作为支付初始gas的本金

(4)在发送交易的字段里加入chainId,防止transaction被拿到以太坊主网上进行重放攻击

(5)准备两套程序部署在美东的服务器上面,把RPCendpoint作为配置参数,等待官方公布时再更改

2. 插曲

9月初的时候,EthereumPow团队宣布冻结所有包含WETH数额大的池子,导致套利机器人直接失效,但后来又宣布不冻结,虚惊一场。

3. EthereumFair上线

9月15日下午,以太坊成功Merge,EthereumFair团队在16:00左右率先上线了分叉网并公布了RPC endpoint,测试了一下连接正常,但是区块高度一直不更新,官方说是矿工节点还没同步,就一直等到19:00点左右开始正常出块,于是改好配置文件上线机器人。

上线过程比预想的顺利,看了交易日志,第一个区块就获利2000个ETF,后面一直运行比较丝滑,看了一下每一笔交易的排名,基本上都在区块的前两名,说明这个链的竞争不是很激烈。由于官方给的区块链浏览器打不开,所以没法看到套利合约总共赚了多少个WETH,所以在本地写了个小程序监控合约里的WETH数量, 大概3000个的时候,暂停了一下程序,调用合约的WETHtoETH()换成ETH,然后调用turnOutETH取到钱包里。然后重启程序,这样钱包里就有足够的币支付后来的gas了。

过程中间偶尔会出现一些交易revert失败的情况,当时比较费解,因为Solidity代码里已经有避免出现revert的机制。由于不影响大局,所以暂时没有管它,准备EthereumPow的上线。

4. EthereumPow上线

EthereumPow的官推一直拖延到10:00才公布RPC endpoint, 公布的一瞬间就改了配置文件,上线。这次上线就不顺利了,过程磕磕绊绊。

首先从日志里了解到有一些交易成功了,然后就一直发送交易失败,日志滚动地飞快,我的脑袋也开始飞快运转。首先,检查一下套利合约里赚了多少个WETH,以及钱包里的0.5个分叉币还剩下多少? 我打开区块链浏览器,无法访问, 然后用刚才那个程序读取一下,也读不出来,连接超时!也就是说我本地无法访问它的RPC endpoint,换上VPN也不行。还有个办法,通过日志去分析,但这样就太耽误时间了。现在完全是黑箱状态。最后只有登录到服务器上写个小程序,这下读出来了,赚了500个WETH,应该是头几笔交易赚的。

程序还在报错,一直发送交易失败,想了几分钟,大概想明白了: 因为我的程序每发送一笔交易,会用web3.getTransactionReceipt获取交易结果(成功/失败), 如果过去两个区块还获取不到结果,就直接跳过去监控下一次交易机会。因为开盘几分钟的基础gas_price很大,所以我的gas费(基础gas_price+50gwei)也很大,这时由于网络拥堵gas_price持续增加到我的gas费之上,我的这笔交易就变成pending状态了,后来基础gas_price降下来了但是这笔交易不知什么原因还是pending状态,然后第二笔交易报进去使用的是同样的nonce,gas费还比上一笔交易低,这是不允许的(要replace上一笔交易必须gas费要更高),所以就一直报单不成功。找到问题之后立马暂停程序,把gas费修改为基础gas_price+200gwei,重启,后面的交易就成功了。

这时,监控套利合约里的WETH数量,以每个区块几个~几十个的速度增长,因为刚才一顿操作浪费了5~10分钟,已经错过了开盘几分钟的黄金时间。

这样持续了2个小时左右,程序突然掉线,无法连接RPC,不知道什么原因。打开区块链浏览器,还在正常出块,所以不是节点的原因,我推断因为我的机器人访问次数过多触发了PRC节点的保护机制,把我的IP给禁了。这个时候再租一个新的VPS服务器,部署上线又很花时间,所以这边只有放弃,转到EthereumFair那边去。

5. bug fixed

EthereumFair的程序依然时不时发出revert的交易。首先,为了防止revert,在套利合约里,在开始套利之前,会先去检查套利机会是否还存在。如果这笔交易上链时排在了其它套利机器人的后面,套利机会就不存在了,这个时候就直接返回不做任何操作,避免了交易被revert白白浪费gas。为什么交易还会revert呢?

通过日志发现,失败的交易都来自于和UniswapV3的池子进行交互,这时我 想到,在检查UniswapV3的套利机会时,会调用UniswapV3Quote合约计算套利结果,UniswapV3Quote合约里有个try catch的操作,可能跟这个有关。没来的及想具体原因,我先调用套利合约,把事先检查套利机会的开关关掉,这样就不会和UniswapV3Quote发生交互。由于这个链基本没有竞争对手,所以不用担心被其它机器人抢的问题。重新部署上线,果然没有失败的交易了。

6. 尾声

过了2个小时之后,EthereumPow的RPC节点又可以访问了,重新上线。每个区块能赚0.1~1.5个WETH,竞争还是十分激烈,交易经常排在几十名开外。EthereumFair的竞争虽然没那么激烈,但是每个区块的奖励也只有个位数,池子在被逐渐掏空。再过10个小时之后,基本上两个链都挖不到币了。

7. 总结

经过一夜的奋战,收获13000个ETF和1500个ETHW,冲到交易所直接卖掉,获利4w美刀。

EthereumFair的整个过程比较丝滑,访问没有出现任何问题,比预想的顺利,抛开币本身的价值,这个团队的技术还是比较过硬的。

EthereumPow比较可惜,由于自己代码上的bug导致错过了开盘的黄金时间,中途又掉线两个小时,最后只吃了一个鱼尾。

整个过程给自己打80分,写文章记录一下,虽然这里面的经验教训以后也用不到了,毕竟以太坊分叉一辈子就这一次了,但是以后给别人吹牛逼可以说自己是在以太坊分叉日撸过币的男人了。

Recommended Reading