Skip to content

Latest commit

 

History

History
106 lines (65 loc) · 5.64 KB

README-cn.md

File metadata and controls

106 lines (65 loc) · 5.64 KB

AMM Arbitrageur

套利原理

合约目前仅支持兼容 UniswapV2 接口的 AMM 之间套利。

假设我们要在 代币 TokenX 和代币 WETH 的交易对中套利,那么有交易对 TokenX/WETH:

  • 这里的 WETH 称作 Base Token,它可以是任意代币,但必须是「有价值」的,例如 USDT/USDC/DAI/BUSD/WBNB... 等等
  • 这里的 TokenX 称为 Quote Token,它可以是任意代币,即使毫无价值也没问题,因为套利结束后不会保留 Quote Token
  • 套利结束后,只会保留 Base Token,即赚取的利润是以 Base Token 计价的
  • 如果一个交易对中两个代币都可以作为 Base Token,那么会保留任意一个(随机)

套利使用 Uniswap v2 的 flashswap 功能,套利的流程为:

  • 假设有交易对 Pair0 和 Pair1,只要他们之间有差价,就可以进行套利条件(抛开 gas 费的考虑)
  • 调用合约开始套利
  • 合约计算 Quote Token 的价格,假设 Pair0 中 Quote Token 价格较低,那么套利过程为:
  1. 通过 flash swap ,从 Pair0 中借取数量为 x 的 Quote Token,此时我们产生了一笔负债,在交易结束前,我们需要向 Pair0 偿还数量为 y1 的 Base Token(借出 Token 和还入 Token 不同,这个是 Uni flash swap 的功能,只要保证交易对 k 值不变即可)
  2. 将借来的 Quote Token 在 Pair1 中全部卖出,得到数量为 y2 的 Base Token
  3. 向 Pair0 偿还 Base Token,数量为 y1
  4. 交易结束,净利润为 y2 - y1

这里的关键点是计算需要借出的 Quote Token 数量,使得套利的收益最大化。

我们假设 Pair0 和 Pair1 的初始状态如下:

Pair0 Pair1
Base Token 余额 a1 a2
Quote Token 余额 b1 b2

那么有:

因为借出的 Quote Token 数量相同,即 Delta b1 = Delta b2,我们令 x = \Delta b,那么利润与 x 关系的函数为:

我们需要求出当利润最大时 x 的值,此时 x 即为我们需要借出的 Quote Token 数量。先对上面的函数求导:

导函数为 0 时,函数有极限值,我们可以通过一些条件设定,忽略极小值时的解。可以解出:

我们可以令:

那么前面的方程式化为一般的一元二次方程:

解得:

最后求出满足条件的 x 值,即为我们需要借贷的 Quote Token 数量。

部署合约

  1. 编辑 hardhat.config.ts 中的网络配置。(目前都是 BSC 的地址)。

  2. 拷贝私钥配置文件:

$ cp .secret.ts.sample .secret.ts
  1. 填入部署账户的私钥和地址信息。运行脚本部署合约:
$ hardhart --network XXX run scripts/deploy.ts

Bot

合约提供了 getProfit(address pool1, address pool2) 接口,可以计算出两个交易对之间套利的最大利润(以 Base Tokne计价)。

Bot 需要在多个 AMM DEX 的多个代币对之间,调用 getProfit() 查询利润,一但利润满足设定的阈值,即可调用 flashArbitrage(pool1, pool2) 进行套利,获得的收益将保存在合约中。

项目实现了 typescript 版本的 bot,运行方式:

$ yarn run bot

BSC 上可套利的 DEX

运行 UT

$ hardhat test