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, "");

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
抱歉,我理解错了您的问题。下面是 Uniswap 合约中的 `swapExactTokensForTokens` 和 `swapTokensForExactTokens` 函数的详细说明: `swapExactTokensForTokens` 函数用于在 Uniswap 上进行精确输入代币数量、输出代币数量的交易,具体来说,函数的参数如下: ```solidity function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); ``` - `amountIn`:输入代币数量; - `amountOutMin`:期望输出代币数量的下限,如果实际输出代币数量低于该值,交易将被取消; - `path`:交易路径,表示交易的输入代币和输出代币之间的路径,如 `[tokenA, tokenB, tokenC]`; - `to`:交易接收地址,用于接收输出代币; - `deadline`:交易截止时间; - `amounts`:返回值,表示实际交易中从输入代币到输出代币每个代币的数量。 `swapTokensForExactTokens` 函数用于在 Uniswap 上进行指定输出代币数量、最大输入代币数量的交易,具体来说,函数的参数如下: ```solidity function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); ``` - `amountOut`:期望输出代币数量; - `amountInMax`:输入代币数量上限,如果实际输入代币数量超过该值,交易将被取消; - `path`:交易路径,表示交易的输入代币和输出代币之间的路径,如 `[tokenA, tokenB, tokenC]`; - `to`:交易接收地址,用于接收输出代币; - `deadline`:交易截止时间; - `amounts`:返回值,表示实际交易中从输入代币到输出代币每个代币的数量。 这两个函数的具体实现可以参考 Uniswap 的代码:https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Pair.sol

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0xweb3q

有钱的捧个钱场,没钱的捧个人场

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值