Solidity Uniswap V2 Router swapExactTokensForTokens

        router合约实现了不同的Token交换方式。其中最常见的是,当我们拥有一定数量的Token,并希望通过计算得到一定数量的其他Token。

GitHub - XuHugo/solidityproject: DApp go go go !!!

function swapExactTokensForTokens(

    uint256 amountIn,

    uint256 amountOutMin,

    address[] calldata path,

    address to

) public returns (uint256[] memory amounts) {

  ...

        这是一个将精确的输入金额(amountIn)与不小于 amountOutMin 的输出金额进行交换的函数。它沿着指定路径(简单来说就是一组Token地址)进行链式交换。最终数量将发送到地址 to。

        路径参数看似复杂,其实只是一个Token地址数组。如果我们想直接用Token A 交换Token B,路径将只包含Token A 和Token B 的地址。如果我们想通过Token B 将Token A 换成Token C,路径将包含Token A 地址、Token B 地址、Token C 地址;合约将用Token A 交换Token B,然后用Token B 交换Token C。我们将在测试中看看效果如何。

        在函数中,我们首先要预先计算路径上的所有输出量:

amounts = ZuniswapV2Library.getAmountsOut(

    address(factory),

    amountIn,

    path

);

        getAmountsOut(注意复数 "amounts")是我们尚未实现的新函数。为简洁起见,我就不解释它的实现了,您可以查看代码来了解。该函数简单地从路径中提取标记对(例如[[tokenA, tokenB],[tokenB, tokenC]]),然后迭代调用每个标记对的 getAmountOut,以建立一个输出金额数组。

        获得输出金额后,我们就可以立即验证最终金额:

if (amounts[amounts.length - 1] < amountOutMin)

    revert InsufficientOutputAmount();

        如果最终的金额是适合的,合约就会通过向第一对发送输入代币来初始化交换:

_safeTransferFrom(

    path[0],

    msg.sender,

    ZuniswapV2Library.pairFor(address(factory), path[0], path[1]),

    amounts[0]

);

        然后执行链式交换:

_swap(amounts, path, to);

        让我们仔细看看这个函数实现:该函数接收一个输出量数组和一条路径,并对路径进行遍历。

function _swap(

    uint256[] memory amounts,

    address[] memory path,

    address to_

) internal {

    for (uint256 i; i < path.length - 1; i++) {

      ...

        它从路径中获取当前和下一个Token地址,并对它们进行排序。之所以需要排序,是因为在pair合约中,Token地址是按升序存储的,但在路径中,它们是按逻辑排序的:输入Token在前,然后是 0 个或多个中间输出Token,最后是最终输出Token。

(address input, address output) = (path[i], path[i + 1]);

(address token0, ) = ZuniswapV2Library.sortTokens(input, output);

        接下来,我们要对金额进行排序,使其与成对标记的顺序相匹配。在交换时,我们要正确选择输出Token。

uint256 amountOut = amounts[i + 1];

(uint256 amount0Out, uint256 amount1Out) = input == token0

    ? (uint256(0), amountOut)

    : (amountOut, uint256(0));

        算出金额后,我们需要找到最终Token的地址。这里我们有两个选择:

        1、如果当前pair不是路径中的最终配对,我们希望直接将代币发送到下一pair。这样可以节省gas。

        2、如果当前pair是最终pair,我们要将token发送到 to_ 地址,也就是发起交换的地址。

address to = i < path.length - 2

    ? ZuniswapV2Library.pairFor(

        address(factory),

        output,

        path[i + 2]

    )

    : to_;

        获得所有交换参数后,我们就可以进行实际交换了:

IZuniswapV2Pair(

    ZuniswapV2Library.pairFor(address(factory), input, output)

).swap(amount0Out, amount1Out, to, "");

相关推荐

  1. 作业2.2

    2024-04-03 18:00:02       27 阅读
  2. <span style='color:red;'>2</span>.<span style='color:red;'>2</span>作业

    2.2作业

    2024-04-03 18:00:02      33 阅读
  3. 2.2作业

    2024-04-03 18:00:02       29 阅读
  4. 假期作业 2.2

    2024-04-03 18:00:02       33 阅读
  5. 2024/2/2

    2024-04-03 18:00:02       30 阅读
  6. 作业2024/2/2

    2024-04-03 18:00:02       33 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-03 18:00:02       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-03 18:00:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-03 18:00:02       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-03 18:00:02       20 阅读

热门阅读

  1. free函数的用法和注意事项

    2024-04-03 18:00:02       14 阅读
  2. 基于Spring Boot的高校科研信息管理系统

    2024-04-03 18:00:02       16 阅读
  3. C 函数指针与回调函数

    2024-04-03 18:00:02       13 阅读
  4. 深度学习该如何入门?

    2024-04-03 18:00:02       13 阅读
  5. 【MySQL】数据类型2

    2024-04-03 18:00:02       13 阅读
  6. OpenCV轮廓分析

    2024-04-03 18:00:02       16 阅读
  7. 编写HTML文件时的注意事项

    2024-04-03 18:00:02       27 阅读
  8. ES 在浏览器上安装head插件

    2024-04-03 18:00:02       14 阅读
  9. oceanbase-OAT安装

    2024-04-03 18:00:02       17 阅读