BSC meme 三明治机器人代码学习
September 4th, 2024

写在前面: 本文是 https://github.com/fuzzland/fourmeme-god.git 的学习笔记

三明治机器人原理

  1. 有人使用较大的滑点进行交易, 称此交易为 victim tx ,后面简称为 vtx

  2. 滑点代表的是对价格上升的容忍程度,较大的滑点导致在 vtx 买入代币,并且在 vtx 之后卖出代币的模式变得有利可图

  3. 三明治机器人构造 buy tx 和 sell tx(可能还有额外的 approve tx,以保证卖出交易的成功),并且将这些交易与原始的 vtx 按照如下顺序排列:[buy tx, vtx, approve tx(optional), sell tx]

  4. 找一个类似 flashbots 的交易捆绑服务商,将上面的交易 bundle(即上述的 tx 数组) 提交

构造一个三明治机器人的主要难点:

  1. 检测到有利可图的交易、协议

  2. 在合理的时间范围内构造出利润最大化的 bundle

个人感觉第 1 点,尤其对于短暂出现的 alpha 机会, 才是真正的难点。比如本例中的 meme 协议,合并并未开源,如何从一份未开源合约中提取到完成套利机器人的相关信息,是很复杂的.如何完成这一点在本文中不再展开,我们只需要知道 meme 协议是一个常量乘积 AMM 算法:即

x * y = k 并且会收取一定的交易手续费(体现在后续代码中的 fee_rate 和 min_fee)

下面主要讲套利交易构造部分: fourmeme-god 是基于 burberry (一个模块化的 mev 开发框架) 开发的。burberry 中, 一个 mev 项目被模块化的分解为:

  • collector(s), 负责搜集数据。支持多方数据源,异构数据源等

  • strategy, 负责解析搜集的数据,并且根据套利算法进行套利交易的构造

  • executor, 负责执行套利交易的最终执行

在本项目中, collectors 采用了两个 burberry 内置的数据采集类,主要负责采集最新的区块信息和 mempool pending tx 信息.两个数据源的主要作用分别为:

  • block 信息用于探测其他机器人竞争者,并且在后续的三明治套利中避免处理这些机器人地址的相关交易

  • pending tx 信息用于识别潜在的 victim tx.

在 strategy 中整体流程如下:

  1. 检查交易是不是一个 meme::Buy tx (通过解析 tx.data)

  2. 对于 buy 交易,根据 meme 当前池子信息和这个 buy tx 信息,计算最优的三明治交易组合(即计算提前买入多少)

  3. 计算一下加上 gas 消耗以后是否还有利可图(gas 根据链上交易设定固定值进行估算)

  4. 构造 bundle 提交到区块链上完成交易(未实现,可以自己选择 bundle 服务提供商)

这里重点讲一下 search::go 的逻辑。在不考虑任何数学和代码之前,很容易得到一个感性的结论:

  • 在一个临界点之前, 三明治机器人的利润肯定是随着买入 mev 机器人提前买入的代币数量的增加而增加。

  • 这个临界点存在的原因是买入太多会导致滑点太大,进而让 victim tx 失败 那如何找到这个临界点呢? 这里简单使用了一个类似二分搜索法的搜索: 将输入区间标记为 4 个点

起点----起点+m(A)----起点+2m(B)----终点

我们只需要反复比较买入量为 A 和 B 时候,机器人的利润,然后再进行区间的收缩即可。即如果 Porfit(B) < Profit(A) ,则代表 B 已经超过了上面提到的临界点,最优解必然在起点到 B 之间的一个点, 我们重新对这部分输入进行等分搜索。通过反复迭代,我们可以找到最优解。(你可以问问 ai 看看有什么更好的寻求解的办法)需要指出的是,因为 mev 本质上还是需要和时间赛跑,而且最优解也没有那么重要,所以迭代次数被设置为 100,这个数据可以根据你的 CPU 性能进行调优(比如机器差,就改小点,机器好就调大一点).

至于如何计算利润也比较简单,流程也是比较明朗的,给定你希望买入的 eth 数量(也就是 amount_in):

  1. 先计算可以 buy tx 的 amount_out(买入的代币数量)

  2. 模拟更新池子信息(内存中的数据)

  3. 按照 victim tx 进行计算, 得到 victim tx 真正可以得到的代币

  4. 模拟更新池子信息

  5. 构造卖出交易(卖出数量为 1 中的 amount_out), 得到卖出获取的 eth 数量

  6. 计算 mev 机器人的整体收益,即最终卖出 ETH 的数量减去 amount_in + fee

至此主要的逻辑我已经梳理完成,不过在读代码的过程中,我也遇到一些不理解的地方:

  1. 在搜索最优解的时候,trial_ultimate(&mut context, lower_bound + m) 函数调用使用的相同的 context 引用,这会持续修改 context(也就是内存中虚拟池子的信息),但是这个修改其实是不应该发生的,也就是计算不同点的利润的时候,输入都应该是相同的 context. 不确定是代码确实有问题还是我的理解有误. 后面希望可以和作者请教讨论
Subscribe to NealZhu
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.
More from NealZhu

Skeleton

Skeleton

Skeleton