Uniswap v3 上的三角套利

中级5/7/2024, 10:38:35 AM
三角套利作为加密交易中的一种策略,利用单个市场内或跨多个市场的汇率变动。

利用多跳互换实现

三角套利是加密交易中的一种策略,利用单个市场内或跨多个市场的汇率变动。该方法包括三个连续交易:将初始加密货币换成第二种,第二种换成第三种,最终将第三种加密货币换回初始加密货币,所有这些都是为了获利。因此,“三角”一词概括了其三步骤过程。

AI生成的图像

怎么运行的?

在去中心化交易所(DEX)上,三角套利的机会通常是由于多个池之间的流动性差异造成的。它们通常是短暂的,仅持续几秒甚至更短的时间,因为交易所会迅速调整任何价格差异。因此,配备了快速执行交易功能的自动化交易算法被用来利用这些短暂的差异。为了帮助理解这个概念,下面是一个例子:

以上的三角交易始于 01 — 用 60,000 美元的 USDC 购买了 1 个 wBTC,接着是 02 — 用 1 个 wBTC 购买了 16 个 WETH,最后是 03 — 用 16 个 WETH 卖出了 66,000 美元的 USDC。在旅程结束时,我们将获得 6,000 美元的 USDC 作为利润。

在 Uniswap v3 上实现多跳互换

在 Uniswap v3 上有两种多跳交换的方式:精确输入和精确输出。顾名思义,第一种方式期望以精确数量的代币作为交换的输入,并在交换结束时以指定数量的代币按照交换率输出;而后一种方式期望以指定数量的代币作为输出,只有足够数量的代币作为输入才能以交换率完成交换。

由于三角套利的业务特性,我们希望以精确数量的代币作为输入,将其交换成另一种加密货币,然后再次交换回原始代币以获取利润。

 address constant SWAP_ROUTER_02 = 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45;

 address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;

address constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;

contract MultiHopSwap {

 using SafeERC20 for IERC20;

ISwapRouter02 private constant ROUTER = ISwapRouter02(SWAP_ROUTER_02);

uint256 private constant MAX_INT =

   115792089237316195423570985008687907853269984665640564039457584007913129639935;

function swapExactInputMultiHop(uint256 amountIn) external {

   IERC20(USDC).safeApprove(address(ROUTER), MAX_INT);

   IERC20(WETH).safeApprove(address(ROUTER), MAX_INT);

   IERC20(DAI).safeApprove(address(ROUTER), MAX_INT);

   bytes memory path =

       abi.encodePacked(USDC, uint24(3000), WETH, uint24(3000), DAI, uint24(3000), USDC) ;

   ISwapRouter02.ExactInputParams memory params = ISwapRouter02

       .ExactInputParams({

       path: path,

       recipient: address(this),

       amountIn: amountIn,

       amountOutMinimum: 1

   });

   ROUTER.exactInput(params);

 }

}

路由器在促进流动性提供方面起着至关重要的作用。由于它们是无状态的,并且不持有代币余额,因此可以安全地替换路由器。因此,路由器具有从 01 开始的发布编号。在我们的实现中,我们在主网上使用 Router02,地址 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45

SafeERC20 是围绕 ERC20 交易构建的保护层,确保我们合约与 ERC20 代币进行安全交互。与常规的 ERC20 函数不同,SafeERC20 通过验证 ERC20 操作的布尔返回值来增强安全性。如果任何操作失败,交易将被回滚,从而最小化风险。此外,SafeERC20 还可适应缺乏布尔返回值的非标准 ERC20 代币,提供了在代币管理方面的灵活性和健壮性。通过批准最大数量,我们允许 Router02 代表我们转移代币。如果不这样做,您将期望看到 STF 错误消息,其中 STF 意味着 TransferHelper.safeTransferFrom 函数中的 require 断言导致执行被还原。

接下来,我们将看看如何定义三角路径:

 bytes memory path = abi.encodePacked(USDC, uint24(3000),

                                WETH, uint24(3000),

                                DAI,  uint24(3000),

                                USDC) ;

通过 abi.encodePacked,Solidity 将多个值紧密地打包在一起,而不添加任何填充。它串联了每个参数的原始二进制数据。不难理解,这些参数将套利交易与手续费在加密货币对之间顺序化。路径从 USDC 开始,停止在 USDC,期望获利。然后,它被 ExactInputParams 包装,加上其他必要的参数,并输入路由器进行多跳交换。

测试

我们使用相同的技术,通过模拟来分叉主网。一旦确认合约已经收到了 10 个 USDC,就可以触发多跳交换,如下所示:

it("performs multi hop swap", async () => {

 balance = await swap.tokenBalance(USDC);

console.log(`Current balance of USDC = ${balance}`);

console.log(`Swapping ${initialFundingHuman} USDC`);

const tx = await swap.swapExactInputMultiHop(ethers.parseUnits(initialFundingHuman, DECIMALS));

receipt = await tx.wait();

balance = await swap.tokenBalance(USDC);

console.log(`Current balance of USDC = ${balance}`);

expect(balance).not.equal(0);

});

测试结果应如下所示:

USDC balance of whale: 170961218210457n

Impersonation Started.

Impersonation completed.

Current balance of USDC = 100000000

Swapping 100 USDC

Current balance of USDC = 91677417

在经历了一番波折之后,我们亏损了 — 显然,路径上的现货汇率并不对我们有利,但你已经了解了在 Uniswap v3 上如何利用多跳交换进行三角套利的想法。

闪电贷款资助的三角套利

我还没说过吗?DeFi 生态系统中最强大的资金来源就是闪电贷款。你不需要太多创意,就可以构建一个利用闪电贷款和我所教的多跳交换的三角套利交易策略。更新后的顺序图如下所示:

闪电贷款资助的 Uniswap v3 三角套利顺序图(为简洁起见忽略了一些操作)

请查看我的源代码,其中包括在 Uniswap v3 上实现的闪电贷款和多跳交换 — https://medium.com/cryptocurrency-scripts/flash-loan-on-uniswap-v3-84bca2bfe255。消化这个顺序图,并完成自己的作业,以合并智能合约。

盈利能力的考虑

首先,我们要查看的是由三笔交易组成的路径:为了获利,它们必须是正确的三对加密货币以及正确的汇率。为了找到所有这些正确性,您需要开发一个程序,对三角套利模式中的可交易对进行排列组合,并模拟交换以检查盈利能力。从区块链中检索汇率可能很慢,如果有太多待验证盈利能力的路径,这将进一步减慢过程。您可能希望通过根据 DEX 的 GraphQL 定价端点(例如 Uniswap v3)提供的表面价格计算利润和损失来缩小三角路径的列表,因为 GraphQL API 比区块链更快地提供行情数据。一旦路径被缩小,再使用从链上检索的报价运行它们,以获得更准确的利润和损失计算。

通过闪电贷款增加投资可以进一步提高利润 —— 以低利率借入代币,并将其投资于有利可图的策略,总是一个好主意。从理论上讲,只要总利润足以覆盖闪电贷款和交换手续费,三角套利策略就被认为是盈利的。一个关键的技巧是在交易合约中设置逻辑,如果总盈利检查失败,则使闪电贷款交易失败,因为当交易失败时,所有操作将回滚,您无需承担损失甚至交易的费用。这段逻辑将起到一种全能的门卫作用,以防止对我们不利的滑点或汇率波动。

话虽如此,无论交易成功与否,燃气费都是您无法摆脱的东西,可能是您从三角套利中亏损的主要原因。始终评估您的策略交易燃气费,并将其计入净利润计算中。请参考我的源代码中的燃气费估算测试用例。

声明:

  1. 本文转载自[加密货币脚本],所有版权归原作者所有[Aaron Li]。若对本次转载有异议,请联系Gate Learn团队,他们会及时处理。
  2. 免责声明:本文所表达的观点和意见仅代表作者个人观点,不构成任何投资建议。
  3. Gate Learn 团队将文章翻译成其他语言。除非另有说明,否则禁止复制、分发或抄袭翻译文章。

Uniswap v3 上的三角套利

中级5/7/2024, 10:38:35 AM
三角套利作为加密交易中的一种策略,利用单个市场内或跨多个市场的汇率变动。

利用多跳互换实现

三角套利是加密交易中的一种策略,利用单个市场内或跨多个市场的汇率变动。该方法包括三个连续交易:将初始加密货币换成第二种,第二种换成第三种,最终将第三种加密货币换回初始加密货币,所有这些都是为了获利。因此,“三角”一词概括了其三步骤过程。

AI生成的图像

怎么运行的?

在去中心化交易所(DEX)上,三角套利的机会通常是由于多个池之间的流动性差异造成的。它们通常是短暂的,仅持续几秒甚至更短的时间,因为交易所会迅速调整任何价格差异。因此,配备了快速执行交易功能的自动化交易算法被用来利用这些短暂的差异。为了帮助理解这个概念,下面是一个例子:

以上的三角交易始于 01 — 用 60,000 美元的 USDC 购买了 1 个 wBTC,接着是 02 — 用 1 个 wBTC 购买了 16 个 WETH,最后是 03 — 用 16 个 WETH 卖出了 66,000 美元的 USDC。在旅程结束时,我们将获得 6,000 美元的 USDC 作为利润。

在 Uniswap v3 上实现多跳互换

在 Uniswap v3 上有两种多跳交换的方式:精确输入和精确输出。顾名思义,第一种方式期望以精确数量的代币作为交换的输入,并在交换结束时以指定数量的代币按照交换率输出;而后一种方式期望以指定数量的代币作为输出,只有足够数量的代币作为输入才能以交换率完成交换。

由于三角套利的业务特性,我们希望以精确数量的代币作为输入,将其交换成另一种加密货币,然后再次交换回原始代币以获取利润。

 address constant SWAP_ROUTER_02 = 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45;

 address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;

address constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;

contract MultiHopSwap {

 using SafeERC20 for IERC20;

ISwapRouter02 private constant ROUTER = ISwapRouter02(SWAP_ROUTER_02);

uint256 private constant MAX_INT =

   115792089237316195423570985008687907853269984665640564039457584007913129639935;

function swapExactInputMultiHop(uint256 amountIn) external {

   IERC20(USDC).safeApprove(address(ROUTER), MAX_INT);

   IERC20(WETH).safeApprove(address(ROUTER), MAX_INT);

   IERC20(DAI).safeApprove(address(ROUTER), MAX_INT);

   bytes memory path =

       abi.encodePacked(USDC, uint24(3000), WETH, uint24(3000), DAI, uint24(3000), USDC) ;

   ISwapRouter02.ExactInputParams memory params = ISwapRouter02

       .ExactInputParams({

       path: path,

       recipient: address(this),

       amountIn: amountIn,

       amountOutMinimum: 1

   });

   ROUTER.exactInput(params);

 }

}

路由器在促进流动性提供方面起着至关重要的作用。由于它们是无状态的,并且不持有代币余额,因此可以安全地替换路由器。因此,路由器具有从 01 开始的发布编号。在我们的实现中,我们在主网上使用 Router02,地址 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45

SafeERC20 是围绕 ERC20 交易构建的保护层,确保我们合约与 ERC20 代币进行安全交互。与常规的 ERC20 函数不同,SafeERC20 通过验证 ERC20 操作的布尔返回值来增强安全性。如果任何操作失败,交易将被回滚,从而最小化风险。此外,SafeERC20 还可适应缺乏布尔返回值的非标准 ERC20 代币,提供了在代币管理方面的灵活性和健壮性。通过批准最大数量,我们允许 Router02 代表我们转移代币。如果不这样做,您将期望看到 STF 错误消息,其中 STF 意味着 TransferHelper.safeTransferFrom 函数中的 require 断言导致执行被还原。

接下来,我们将看看如何定义三角路径:

 bytes memory path = abi.encodePacked(USDC, uint24(3000),

                                WETH, uint24(3000),

                                DAI,  uint24(3000),

                                USDC) ;

通过 abi.encodePacked,Solidity 将多个值紧密地打包在一起,而不添加任何填充。它串联了每个参数的原始二进制数据。不难理解,这些参数将套利交易与手续费在加密货币对之间顺序化。路径从 USDC 开始,停止在 USDC,期望获利。然后,它被 ExactInputParams 包装,加上其他必要的参数,并输入路由器进行多跳交换。

测试

我们使用相同的技术,通过模拟来分叉主网。一旦确认合约已经收到了 10 个 USDC,就可以触发多跳交换,如下所示:

it("performs multi hop swap", async () => {

 balance = await swap.tokenBalance(USDC);

console.log(`Current balance of USDC = ${balance}`);

console.log(`Swapping ${initialFundingHuman} USDC`);

const tx = await swap.swapExactInputMultiHop(ethers.parseUnits(initialFundingHuman, DECIMALS));

receipt = await tx.wait();

balance = await swap.tokenBalance(USDC);

console.log(`Current balance of USDC = ${balance}`);

expect(balance).not.equal(0);

});

测试结果应如下所示:

USDC balance of whale: 170961218210457n

Impersonation Started.

Impersonation completed.

Current balance of USDC = 100000000

Swapping 100 USDC

Current balance of USDC = 91677417

在经历了一番波折之后,我们亏损了 — 显然,路径上的现货汇率并不对我们有利,但你已经了解了在 Uniswap v3 上如何利用多跳交换进行三角套利的想法。

闪电贷款资助的三角套利

我还没说过吗?DeFi 生态系统中最强大的资金来源就是闪电贷款。你不需要太多创意,就可以构建一个利用闪电贷款和我所教的多跳交换的三角套利交易策略。更新后的顺序图如下所示:

闪电贷款资助的 Uniswap v3 三角套利顺序图(为简洁起见忽略了一些操作)

请查看我的源代码,其中包括在 Uniswap v3 上实现的闪电贷款和多跳交换 — https://medium.com/cryptocurrency-scripts/flash-loan-on-uniswap-v3-84bca2bfe255。消化这个顺序图,并完成自己的作业,以合并智能合约。

盈利能力的考虑

首先,我们要查看的是由三笔交易组成的路径:为了获利,它们必须是正确的三对加密货币以及正确的汇率。为了找到所有这些正确性,您需要开发一个程序,对三角套利模式中的可交易对进行排列组合,并模拟交换以检查盈利能力。从区块链中检索汇率可能很慢,如果有太多待验证盈利能力的路径,这将进一步减慢过程。您可能希望通过根据 DEX 的 GraphQL 定价端点(例如 Uniswap v3)提供的表面价格计算利润和损失来缩小三角路径的列表,因为 GraphQL API 比区块链更快地提供行情数据。一旦路径被缩小,再使用从链上检索的报价运行它们,以获得更准确的利润和损失计算。

通过闪电贷款增加投资可以进一步提高利润 —— 以低利率借入代币,并将其投资于有利可图的策略,总是一个好主意。从理论上讲,只要总利润足以覆盖闪电贷款和交换手续费,三角套利策略就被认为是盈利的。一个关键的技巧是在交易合约中设置逻辑,如果总盈利检查失败,则使闪电贷款交易失败,因为当交易失败时,所有操作将回滚,您无需承担损失甚至交易的费用。这段逻辑将起到一种全能的门卫作用,以防止对我们不利的滑点或汇率波动。

话虽如此,无论交易成功与否,燃气费都是您无法摆脱的东西,可能是您从三角套利中亏损的主要原因。始终评估您的策略交易燃气费,并将其计入净利润计算中。请参考我的源代码中的燃气费估算测试用例。

声明:

  1. 本文转载自[加密货币脚本],所有版权归原作者所有[Aaron Li]。若对本次转载有异议,请联系Gate Learn团队,他们会及时处理。
  2. 免责声明:本文所表达的观点和意见仅代表作者个人观点,不构成任何投资建议。
  3. Gate Learn 团队将文章翻译成其他语言。除非另有说明,否则禁止复制、分发或抄袭翻译文章。
Розпочати зараз
Зареєструйтеся та отримайте ваучер на
$100
!
It seems that you are attempting to access our services from a Restricted Location where Gate.io is unable to provide services. We apologize for any inconvenience this may cause. Currently, the Restricted Locations include but not limited to: the United States of America, Canada, Cambodia, Cuba, Iran, North Korea and so on. For more information regarding the Restricted Locations, please refer to the User Agreement. Should you have any other questions, please contact our Customer Support Team.