什么是抢先交易(Front-Running),如何避免抢先交易?

 2023-12-10 22:28:05发布 2023-12-10 23:15:08更新

抢先交易(Front-Running)也被称为抢跑,指的是某人利用技术或市场优势提前获得即将到来的交易信息的过程。这使得不法分子可以利用即将到来的价格波动,以那些引入这些交易的人的代价获得经济利益。

什么是抢先交易

通常,抢先交易是在一个已知的未来事务发生之前,在执行队列中第一个获取事务的行为。

一个简单例子是交换竞价,假设有人打算在 Uniswap 上购买大量 ETH,这足以推高 ETH 的价格。从这种情况中获益的一种方法是在购买大量 ETH 之前进行交易,同时价格保持较低,在价格飙升之后出售 ETH 获利。

除了这个套利例子,抢先交易进行许多其他交易也可能是有价值的,包括清算,购买罕见的 NFT,或简单的用户错误。

在以太坊上抢先交易是通过在交易中出价稍高的交易费来实现的,激励矿工在构建区块时更早地排序,较高的支付交易首先执行。

因此,如果两个从同一个合约调用中获利的交易被放在同一个区块中,只有第一个交易获得利润。

在所有抢先交易中,最典型最具危害性的就是针对 AMM 交易的三明治攻击(Sandwich Attacks)。

除此以外还有针对套利、清算交易、闪电贷等利用系统漏洞获利的抢先攻击,攻击者数量众多,且由自动化脚本控制,因此任何有利可图的交易都会遭受他们的攻击。

抢先交易机器人

抢先交易是使用加密机器人在毫秒尺度的时间内运行完成的。利用机器人,眨眼之间,他们就可以读取一串交易,计算出最佳交易规模和gas费,配置交易并执行。

抢先交易机器人的核心功能是侦听区块链上的未决交易。使用交互式脚本与区块链交互,机器人在买家之前购买,在买家之后立即出售。

机器人分析加密货币的趋势,并执行交易以获取利润。

抢先交易策略

当交易发生时,系统将其广播给区块链,要求矿工验证交易。但是在任何重要的区块链中,传入的交易流都大于后续块的容量。未挖掘的交易停留在内存池(mempool)中。

区块链内存池是透明的,抢先交易者正是利用了这一点。通过了解普通交易者的情绪,他们能够预测即将到来的价格走势,并相应地下达自己的订单。

他们在交易中设定更高的gas价格,从而鼓励在即将进行的交易之前挑选他们的交易,从而抢先于其他毫无防备的交易者。

真实攻击案例

以下是一个真实的三明治攻击案例,如图,三笔交易在同一个区块被打包,两笔攻击交易(打上了黑客标记的)中间夹着一笔正常交易,具体流程如下:

真实攻击案例

真实攻击案例

  1. 用户首先发起一笔正常交易,用 237000.705 USDC 买入 DG,设置 Gas Price 为 40.5 Gwei;
  2. 抢先交易机器人检测到这笔有利可图的交易后,随即展开攻击,发起一笔买入交易,设定 GasPrice 为 49.9 Gwei,凭借 Gas 竞争机制成功抢先用户的正常交易;
  3. 与此同时,机器人发出另一笔卖出交易,设置 GasPrice 同样为 40.5Gwei,因为时间顺序的原因,紧贴着用户正常交易完成。

一次完美的抢先攻击完成,算上手续费,机器人共赚取 16448.012-16310.3-15.2-10.61 = $111.9,而这种两笔攻击交易夹着一笔正常交易的攻击,就被形象的称为三明治攻击。

抢先交易的运作原理

现如今的主流 DEX 如 Uniswap 等,采用的都是 AMM 机制,其价格遵循恒定乘积公式。

例如,在 Uniswap 中建立一个 A 代币与 ETH 的流动池,A 数量为 1000,ETH 数量为 100,则两者数量乘积为 100000,当前 A 价格为 0.1ETH。

当 Alice 试图用 10 个 ETH 来池子里购买 A 时,他所得到的 A 的数量 X,可以用下面的公式推导:

(1000-X)\*(100+10)= 100000,X = 90.9

这笔交易中,A 的价格为 10/90.9 = 0.11,相比于原来 A 的价格,价格滑点为 :

(0.11-0.1)/0.1\*100% = 10%

一笔交易就让币价产生了 10% 的滑点,可见越是流动性差的池子,遇到大额交易,越是容易产生滑点。

如果,能在用户正常的大额交易前(预计该交易会产生较大滑点),抢先买入 A,再在用户正常交易后,将刚买入的 A 卖出,就可以获得一笔不低的收益。

同理,假设在 Alice 的交易前,Bob 抢先花 5 个 ETH 购买 A,然后在 Alice 的交易完成后,Bob 再把之前买入的 A 卖出,会产生以下结果。

首先是 Bob 的抢先交易:

(1000-X)\*(100+5) = 100000, X = 47.62

即,Bob 用 5ETH 购得 47.62 个 A接下来是 Alice 的正常交易,注意此时流动池中 A 的数量变为 952.38,ETH 的数量变为 105:

(952.38-X)\*(105+10) = 100000, X = 82.81

最后 Bob 卖出 47.62 个 A 的交易,此时流动性中 A 的数量为 869.57,ETH 的数量为 115:

(869.57+47.62)\*(115-Y)= 100000,Y = 5.97

通过这一次抢先攻击,Bob 净赚 5.97-5 = 0.97 个 ETH,而 Alice 净亏 90.9-82.81 = 8.09 个 A,Bob 通过使 Alice 蒙受更大的滑点损失来获得自己的收益!

需要注意的是,为简化计算,以上均未考虑手续费,实际的抢先攻击会更复杂,攻击者需要进行更精密的计算,以求实现以下两个目标:

  1. 让用户的交易结果无限逼近用户自己设置的最大滑点(max_slippage),以求达到理论上的最大套利空间;
  2. 在手续费竞争力和收益之间取得平衡,尽可能的在与其他机器人的竞争中获胜。

用图表描述这一过程如下:

抢先交易

抢先交易的目标

  1. 用户在 A 点,打算投入 in_amount(user) 个 USDT 购买 ETH,这笔交易正常会把当前状态推向 B,同时用户设置了最大滑点为 B(max_slippage);
  2. 抢先交易机器人监测到这笔交易,先于用户交易之前,进行了一笔  in_amount(robot) 个 USDT 的买入交易,将当前状态推到 A’;
  3. 用户的交易随后执行,达到其设置的最大滑点 B(max_slippage);
  4. 抢先交易机器人把步骤 2 中买入的 ETH 卖出,状态达到 C 点,得到 out_amount(robot) 个 USDT;
  5. 抢先交易机器人获得收益 out_amount(robot) – in_amount(robot)-手续费。

如何避免抢先交易

抢先交易是以太坊等公链上普遍存在的问题,没法消除,但是可以通过减少交易顺序或时间的重要性,减少被抢先交易。

作为一般用户,可以采取以下几种手段:

最大滑点不要太高

假设你在下了一个订单,并期望收到 500  USDT。如果你将滑点值设置为订单的1%,那么你收到的金额不会低于495 USDT。

但是,如果滑点容差越大,则偏差就越大。

因此,公式很简单:设置的最大滑点值不要太高,约0.5%-2%,从而避开抢先交易者。如果你要下一个大订单,保持你的滑点在较低水平。

抢先交易者希望你保持高滑点,所以你只需反其道而行之。

支付超额的Gas费

抢先交易者很高兴看到缓慢的交易,因为这给了他们更多的时间来设计订单,利用你的交易获利。Gas 价格过低会让你的交易排队时间更长,让抢先交易者有更多时间制定策略,损害你的利益。

支付更高的 gas 费会促使矿商更快地验证你的交易,从而降低你成为目标的几率。为了达到这个目的,你可以将 gas 价格设置为高于平均水平,或者简单地使用钱包上的快速 gas 的选项。

如果你下了一个很大的价值订单,更需要重视这一点,通过支付超额 gas 费来快速完成交易。

下价值小一点的订单

为了盈利,抢先交易者必须达到一些最低门槛。在进入和退出市场时,需要支付两次 gas 费,而且还需要返还 gas 费。他们只有在收回这些费用后才开始盈利。

当你进行一笔低价值交易时,你实际上是在让抢先交易者做一笔无利可图的冒险。

大多数时候,低于1000美元的交易是安全的。

AMM算法优化

在 AMM 机制下,大额交易产生过大的价格滑点(可理解为一个临时的错误价格),是抢先交易的利润空间,如果有一种 AMM 机制可以减少大额交易对后续交易价格的影响,就可以有效防止抢先交易攻击。

早在 2018 年,Vitalik 在以太坊技术社区中提供了一个 方案,当发生兑换交易时,交易池价格不会立刻调整成真实价格,而是在若干分钟内,缓慢的趋向真实价格,这就好像交易池凭空多出了很多流动性一样,这种技术称之为 Vitrual Balance (虚拟余额)技术。

这种新机制,可大大压缩套利者的利润空间,有效防御抢先交易攻击,同时还可以增加流动性做市商的收益,1inch 的 mooniswap 就是这个方案的一个实现版本。

增加流动性

抢先交易者青睐流动性较低的资金池,因为竞争的可能性较小,而且他们的交易也不会被一个意外改变资金池权重的大订单所扰乱。

所以,在大型流动性池中交易,可以大大降低受到抢先交易攻击的可能性。

推荐阅读