AMM 套利者
理由
以太坊和其他支持 EVM 的区块链上有很多 AMM。其中许多 AMM 是 UniswapV2 的分叉项目或与 UniswapV2 具有相同的接口。这些 AMM 的列表:
- Uniswap V2(以太坊)
- 寿司交换(以太坊)
- 煎饼掉期(BSC)
- MDEX(BSC/heco) ...
一旦相同代币对的价格在不同的 AMM 上出现差异,我们就可以在这些 AMM 之间进行套利。我们可以将套利交易封装在一个 EVM 交易中,这样我们在发送交易之前即使价格变动也不会损失任何钱。
假设我们想对代币对 TokenX/WETH 进行套利交易。TokenX/WETH 对必须存在于以太坊(或其他 EVM 兼容区块链,如 BSC)上的多个 AMM 上。
- 我们称 WETH 作为基础代币。可以是任何有实际价值的token,比如USDT/USDC/DAI/BUSD...
- 我们将 TokenX 称为报价代币。它可以是任何令牌,甚至是没有价值的假令牌。套利完成后不会保留报价代币。
- 套利后,只保留基础代币。所以我们的利润是以基础代币计价的。
- 如果一对中的两个令牌都可以被视为基础令牌。套利后可以保留任何一个。
可以使用flashswap
Uniswap V2 进行套利:
- 假设 pair0 和 pair1 是不同 AMM 上的两对相同的两个令牌。一旦价格出现分歧,我们就可以进行套利。
- 我们调用
FlashBot
合约开始套利 - 合约计算以报价代币计价的价格。假设 Pair0 中报价代币的价格较低:
- 通过使用 flash sawp,合约首先从 Pair0 借用一些报价代币,数量为x。合约需要偿还 Pair0 的债务。deby 可以用 base token 计价。这是 Uniswap V2 的功能。
- 在 Pair1 上出售所有借来的报价代币。合约获得数量为y2的基础代币。
- 用数量为y1的基础代币偿还 Pair0 的债务。
- 合同获得y2 - y1的利润。
该过程的重点是计算数量x的多少,以便我们可以获得尽可能多的利润。
假设Pair0和Pair1的初始状态如下:
对0 | 对1 | |
---|---|---|
基础代币数量 | a1 | a2 |
报价代币数量 | b1 | b2 |
于是我们得到:
借用 Quote Token 的数量是一些,所以Delta b1
= Delta b2
, let x = \Delta b
,那么利润作为 x 的函数是:
我们想在函数获得最大值时计算 x 值。首先我们需要得到函数的导数:
当导数函数为0时,函数有一个最大值/最小值,我们可以设置一些条件来忽略最小值处的解。有可能解决
让:
前面的方程简化为一般二次方程:
我们可以得到解决方案:
解决方案 x 是我们需要从 Pair0 借的金额。
部署合约
-
编辑网络配置
hardhat.config.ts
。(目前在repo中是BSC,你也可以使用以太坊主网) -
复制秘密示例配置:
$ cp .secret.ts.sample .secret.ts
-
在上面的配置中编辑私有和地址字段。
-
然后运行脚本进行部署。默认情况下,它部署到 BSC。如果您想部署到其他网络,您可能需要更改 .net 中的网络设置
hardhat.config.ts
。您还需要更改 中的 WETH 或其他代币地址deploy.ts
,默认为 WBNB 地址。
$ hardhart --network XXX run scripts/deploy.ts
例如,
<span style="color:#24292f"><span style="background-color:#ffffff"><span style="background-color:var(--color-canvas-subtle)"><code>$ npx hardhat --network bscTestnet run scripts/deploy.ts
</code></span></span></span>
机器人实施
合约有一个函数getProfit(address pool1, address pool2)
,可用于计算两对之间的最大利润(以基础代币计价)。
机器人需要调用getProfit()
以获得令牌对之间可能的利润。一旦有利可图,机器人就会调用flashArbitrage(pool1, pool2)
进行套利。利润将留在合约地址中。
合约所有者可以调用withdraw()
提取利润。
已经在打字稿中实现了一个机器人来运行它:
$ yarn run bot
BSC 上可用的 AMM
- 煎饼交换
- MDEX
- 面包店交换
- 七月掉期
- 猿交换
- 价值DeFi(不支持)
运行UT
$ hardhat test
FAQ
数学太多了,这个契约到底是干嘛的?
简单来说,它将不同 AMM 之间的价格移动到同一水平。这样做你就会获利。这份合同帮助您获得最大的利润。而且它使用 flashswap,所以你只需要很少的钱(只是一些 gas 费用)来运行它。
我怎么知道合同的正确性?
默认情况下,测试使用 BSC 主网的分叉网络(感谢强大的 hardhat 工具)。中的测试SwapTest.ts
表明合约可以正确地进行套利。你可以自己查一下。
但我没有通过运行你的机器人赚取任何利润
那么,在野外运行的机器人太多了,尤其是在 ETH 和 BSC 中。这个 repo 中的机器人代码太简单了,没有竞争力。你不能期望仅仅运行我的代码就可以赚到一大笔钱。您需要找出一些策略来自己赚钱。
如何更改机器人正在监控的令牌对?
第一次,机器人使用bscBaseTokens
, bscQuoteTokens
, 和bscDexes
intokens.ts
自动获取所有可能的令牌对并将它们保存到bsc-pairs.json
. 因此它可以在下次机器人启动时重用 json 文件。
如果你想要一些其他的对。您可以删除bsc-pairs.json
并编辑上面的三个变量。重新运行机器人,以便它使用新的对。您可以在 中检查新对bsc-pairs.json
。
有什么建议可以提高竞争力吗?
- 降低网络延迟,您可以使用自己的节点。
- 更高的汽油价格,确保您的交易得到足够快的处理以获利。这就像机器人之间的竞争,如果他们同时找到有利可图的机会。
- 监控较少的令牌,您监控的越多,机器人循环的频率就越低。您可以运行多个机器人来监控单独的令牌对。
- 转到其他一些网络,例如 FTM/Matic/...,它们上运行的机器人可能较少。
- 在balancer/curve/0x中做一些清算、套利等其他工作……需要自己实现这些功能。
为什么在运行“npx hardhat compile”时终端会卡住?
如果你在代理后面运行安全帽,也许你会遇到HH502: Couldn't download compiler versions list. Please check your connection
运行时的错误npx hardhat compile
。为了解决此错误,您需要在终端中设置HTTP_PROXY
或HTTPS_PROXY
。根据这个issue,hardhat version 2.4.0及之后的版本已经支持HTTP_PROXY
or HTTPS_PROXY
. 所以你需要在 package.json中将 hardhat 版本从 更改2.1.2
为或更高版本。2.4.0
运行“npx hardhat run --network xxx bot/index.ts”时出现错误
详细错误是TSError: x Unable to compile TypeScript. bot/index.ts:63:13 - error TS2571: Object is of type 'unknown'
。请运行您的 TypeScript 版本为 ^4.2.4。如果您的 TypeScipt 版本高于 4.4.x,您可能会遇到此错误。
错误“无法估计气体;交易可能会失败或可能需要手动气体限制”
如果您遇到此错误,请不要感到惊讶。首先,这个 bot 在 bscTestnet 中测试得不好。所以如果你想运行好它,你最好将它部署在 bscMainnet 中。其次,由于有很多令牌对已弃用,因此您需要修改pairs-bsc.json
.