{"id":24390468,"url":"https://github.com/texora/arbitragebot","last_synced_at":"2025-03-12T23:14:19.071Z","repository":{"id":272792606,"uuid":"883594533","full_name":"texora/ArbitrageBot","owner":"texora","description":"This repo is written only for POC. The bot is implemented simply for demostration.","archived":false,"fork":false,"pushed_at":"2024-11-25T23:24:21.000Z","size":440,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-10T19:56:43.235Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/texora.png","metadata":{"files":{"readme":"README-cn.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-05T08:42:43.000Z","updated_at":"2024-11-05T16:36:10.000Z","dependencies_parsed_at":"2025-01-16T17:42:56.725Z","dependency_job_id":"c3519c42-3731-4676-81b1-a6ac575c84e4","html_url":"https://github.com/texora/ArbitrageBot","commit_stats":null,"previous_names":["texora/arbitragebot"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/texora%2FArbitrageBot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/texora%2FArbitrageBot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/texora%2FArbitrageBot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/texora%2FArbitrageBot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/texora","download_url":"https://codeload.github.com/texora/ArbitrageBot/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243307495,"owners_count":20270263,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-19T16:17:44.675Z","updated_at":"2025-03-12T23:14:19.048Z","avatar_url":"https://github.com/texora.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AMM Arbitrageur\n## 套利原理\n\n合约目前仅支持兼容 UniswapV2 接口的 AMM 之间套利。\n\n假设我们要在 代币 TokenX 和代币 WETH 的交易对中套利，那么有交易对 TokenX/WETH：\n\n- 这里的 WETH 称作 Base Token，它可以是任意代币，但必须是「有价值」的，例如 USDT/USDC/DAI/BUSD/WBNB... 等等\n- 这里的 TokenX 称为 Quote Token，它可以是任意代币，即使毫无价值也没问题，因为套利结束后不会保留 Quote Token\n- 套利结束后，只会保留 Base Token，即赚取的利润是以 Base Token 计价的\n- 如果一个交易对中两个代币都可以作为 Base Token，那么会保留任意一个（随机）\n\n套利使用 Uniswap v2 的 flashswap 功能，套利的流程为：\n\n- 假设有交易对 Pair0 和 Pair1，只要他们之间有差价，就可以进行套利条件（抛开 gas 费的考虑）\n- 调用合约开始套利\n- 合约计算 Quote Token 的价格，假设 Pair0 中 Quote Token 价格较低，那么套利过程为：\n\n1. 通过 flash swap ，从 Pair0 中借取数量为 x 的 Quote Token，此时我们产生了一笔负债，在交易结束前，我们需要向 Pair0 偿还数量为 y1 的 Base Token（借出 Token 和还入 Token 不同，这个是 Uni flash swap 的功能，只要保证交易对 k 值不变即可）\n2. 将借来的 Quote Token 在 Pair1 中全部卖出，得到数量为 y2 的 Base Token\n3. 向 Pair0 偿还 Base Token，数量为 y1\n4. 交易结束，净利润为 y2 - y1\n\n这里的关键点是计算需要借出的 Quote Token 数量，使得套利的收益最大化。\n\n我们假设 Pair0 和 Pair1 的初始状态如下：\n\n|                 | Pair0 | Pair1 |\n| :---------------| :---- | :---- |\n| Base Token 余额  | a1    |   a2  |\n| Quote Token 余额 | b1    |   b2  |\n\n那么有：\n\n\u003cimg src=\"https://latex.codecogs.com/svg.image?\\Delta\u0026space;a_1\u0026space;=\u0026space;\\frac{\\Delta\u0026space;b_1\u0026space;\\cdot\u0026space;a_1}{b_1\u0026space;-\u0026space;\\Delta\u0026space;b_1}\u0026space;\\\u0026space;\\\u0026space;\\\u0026space;\\Delta\u0026space;a_2\u0026space;=\u0026space;\\frac{\\Delta\u0026space;b_2\u0026space;\\cdot\u0026space;a_2}{b_2\u0026space;\u0026plus;\u0026space;\\Delta\u0026space;b_2}\" title=\"\\Delta a_1 = \\frac{\\Delta b_1 \\cdot a_1}{b_1 - \\Delta b_1} \\ \\ \\ \\Delta a_2 = \\frac{\\Delta b_2 \\cdot a_2}{b_2 + \\Delta b_2}\" /\u003e\n\n因为借出的 Quote Token 数量相同，即 `Delta b1` = `Delta b2`，我们令 `x = \\Delta b`，那么利润与 x 关系的函数为：\n\n\u003cimg src=\"https://latex.codecogs.com/svg.image?f(x)\u0026space;=\u0026space;\\Delta\u0026space;a_2\u0026space;-\u0026space;\\Delta\u0026space;a_1\u0026space;=\u0026space;\\frac\u0026space;{a_2\u0026space;\\cdot\u0026space;x}{b_2\u0026plus;x}\u0026space;-\u0026space;\\frac\u0026space;{a_1\u0026space;\\cdot\u0026space;x}{b_1-x}\" title=\"f(x) = \\Delta a_2 - \\Delta a_1 = \\frac {a_2 \\cdot x}{b_2+x} - \\frac {a_1 \\cdot x}{b_1-x}\" /\u003e\n\n我们需要求出当利润最大时 x 的值，此时 x 即为我们需要借出的 Quote Token 数量。先对上面的函数求导：\n\n\u003cimg src=\"https://latex.codecogs.com/svg.image?f'(x)\u0026space;=\u0026space;\\frac{a_2b_2}{(b_2\u0026plus;x)^2}\u0026space;-\u0026space;\u0026space;\\frac{a_1b_1}{(b_1-x)^2}\" title=\"f'(x) = \\frac{a_2b_2}{(b_2+x)^2} - \\frac{a_1b_1}{(b_1-x)^2}\" /\u003e\n\n导函数为 0 时，函数有极限值，我们可以通过一些条件设定，忽略极小值时的解。可以解出：\n\n\u003cimg src=\"https://latex.codecogs.com/svg.image?\\frac{a_2b_2}{(b_2\u0026plus;x)^2}\u0026space;-\u0026space;\u0026space;\\frac{a_1b_1}{(b_1-x)^2}\u0026space;=\u0026space;0\u0026space;\" title=\"\\frac{a_2b_2}{(b_2+x)^2} - \\frac{a_1b_1}{(b_1-x)^2} = 0 \" /\u003e\n\n\u003cimg src=\"https://latex.codecogs.com/svg.image?(a_1b_1-a_2b_2)x^2\u0026space;\u0026plus;\u0026space;2b_1b_2(a_1\u0026plus;a_2)x\u0026space;\u0026plus;\u0026space;b_1b_2(a_1b_2\u0026space;-\u0026space;a_2b_1)\u0026space;=\u0026space;0\u0026space;\" title=\"(a_1b_1-a_2b_2)x^2 + 2b_1b_2(a_1+a_2)x + b_1b_2(a_1b_2 - a_2b_1) = 0 \" /\u003e\n\n我们可以令：\n\n\u003cimg src=\"https://latex.codecogs.com/svg.image?\\begin{cases}a\u0026space;=\u0026space;a_1b_1\u0026space;-\u0026space;a_2b_2\u0026space;\\\\b\u0026space;=\u0026space;2b_1b_2(a_1\u0026space;\u0026plus;\u0026space;a_2)\u0026space;\\\\c\u0026space;=\u0026space;b_1b_2(a_1b_2\u0026space;-\u0026space;a_2b_1)\\end{cases}\u0026space;\" title=\"\\begin{cases}a = a_1b_1 - a_2b_2 \\\\b = 2b_1b_2(a_1 + a_2) \\\\c = b_1b_2(a_1b_2 - a_2b_1)\\end{cases} \" /\u003e\n\n那么前面的方程式化为一般的一元二次方程：\n\n\u003cimg src=\"https://latex.codecogs.com/svg.image?ax^2\u0026plus;bx\u0026plus;c=0\u0026space;\" title=\"ax^2+bx+c=0 \" /\u003e\n\n解得：\n\n\u003cimg src=\"https://latex.codecogs.com/svg.image?\\begin{cases}x=\\displaystyle\u0026space;\\frac{-b\u0026space;\\pm\u0026space;\\sqrt{b^2-4ac}}{2a}\u0026space;\\\\0\u0026space;\u003c\u0026space;x\u0026space;\u003c\u0026space;b_1\u0026space;\\\\x\u0026space;\u003c\u0026space;b_2\\end{cases}\" title=\"\\begin{cases}x=\\displaystyle \\frac{-b \\pm \\sqrt{b^2-4ac}}{2a} \\\\0 \u003c x \u003c b_1 \\\\x \u003c b_2\\end{cases}\" /\u003e\n\n最后求出满足条件的 x 值，即为我们需要借贷的 Quote Token 数量。\n\n## 部署合约\n1. 编辑 `hardhat.config.ts` 中的网络配置。（目前都是 BSC 的地址）。\n\n2. 拷贝私钥配置文件：\n\n```bash\n$ cp .secret.ts.sample .secret.ts\n```\n\n3. 填入部署账户的私钥和地址信息。运行脚本部署合约：\n\n\n```bash\n$ hardhart --network XXX run scripts/deploy.ts\n\n```\n\n## Bot\n\n合约提供了 `getProfit(address pool1, address pool2)` 接口，可以计算出两个交易对之间套利的最大利润（以 Base Tokne计价）。\n\nBot 需要在多个 AMM DEX 的多个代币对之间，调用 `getProfit()` 查询利润，一但利润满足设定的阈值，即可调用 `flashArbitrage(pool1, pool2)` 进行套利，获得的收益将保存在合约中。\n\n项目实现了 typescript 版本的 bot，运行方式：\n\n```bash\n$ yarn run bot\n```\n\n## BSC 上可套利的 DEX\n\n- [PancakeSwap](https://pancakeswap.finance/)\n- [MDEX](https://bsc.mdex.com/)\n- [BakerySwap](https://www.bakeryswap.org/#/swap)\n- [JulSwap](https://julswap.com/#/)\n- [~~ValueDeFi~~](https://bsc.valuedefi.io/) （暂不支持）\n\n## 运行 UT\n\n```bash\n$ hardhat test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftexora%2Farbitragebot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftexora%2Farbitragebot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftexora%2Farbitragebot/lists"}