Solidity Uniswap V2 Router swapTokensForExactTokens

news2024/12/23 2:04:29

        最初的router合约实现了许多不同的交换方式。我们不会实现所有的方式,但我想向大家展示如何实现倒置交换:用未知量的输入Token交换精确量的输出代币。这是一个有趣的用例,可能并不常用,但仍有可能实现。

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

        让我们回到交换公式:

        (x+rΔx)(y−Δy)=xy

        现在,我们要找到的不是 Δy,而是 Δx:我们知道想要得到的输出Token的确切数量,但不知道需要提供多少输入Token。

        同样,在应用基本的代数运算后,我们可以得到

        同样,这是一个考虑到产出量(Δy)和费用 r 的储备金(x/y)关系式。

        现在我们就可以实现这一公式:

function getAmountIn(

    uint256 amountOut,

    uint256 reserveIn,

    uint256 reserveOut

) public pure returns (uint256) {

    if (amountOut == 0) revert InsufficientAmount();

    if (reserveIn == 0 || reserveOut == 0) revert InsufficientLiquidity();



    uint256 numerator = reserveIn * amountOut * 1000;

    uint256 denominator = (reserveOut - amountOut) * 997;



    return (numerator / denominator) + 1;

}

        一切都很清楚,除了最后的结果多了一个 1 ,为什么会这样?原因在于,Solidity 中的除法(即整除)会将结果向下舍入,这意味着结果会被截断。在计算输入金额时,我们希望保证计算出的金额能达到要求的输出金额。如果结果被截断,输出的金额就会稍小。

        接下来,我们需要 getAmountsIn 函数:

function getAmountsIn(

    address factory,

    uint256 amountOut,

    address[] memory path

) public returns (uint256[] memory) {

    if (path.length < 2) revert InvalidPath();

    uint256[] memory amounts = new uint256[](path.length);

    amounts[amounts.length - 1] = amountOut;



    for (uint256 i = path.length - 1; i > 0; i--) {

        (uint256 reserve0, uint256 reserve1) = getReserves(

            factory,

            path[i - 1],

            path[i]

        );

        amounts[i - 1] = getAmountIn(amounts[i], reserve0, reserve1);

    }



    return amounts;

}

        它复制了 getAmountsOut,但有一个显著的变化:遍历路径的顺序颠倒了。由于我们知道输出金额,并希望找到输入金额,因此我们从路径的末尾开始,以相反的顺序将输入金额填入金额数组。

        高级交换函数看起来也很熟悉:

function swapTokensForExactTokens(

    uint256 amountOut,

    uint256 amountInMax,

    address[] calldata path,

    address to

) public returns (uint256[] memory amounts) {

    amounts = ZuniswapV2Library.getAmountsIn(

        address(factory),

        amountOut,

        path

    );

    if (amounts[amounts.length - 1] > amountInMax)

        revert ExcessiveInputAmount();

    _safeTransferFrom(

        path[0],

        msg.sender,

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

        amounts[0]

    );

    _swap(amounts, path, to);

}

        它与我们之前实现的 swap 函数几乎完全相同,但它调用的是 getAmountsIn。同样有趣的是,即使金额是输入的,我们也可以使用相同的 _swap 函数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1553673.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

景联文科技高质量大模型训练数据汇总!

3月25日&#xff0c;2024年中国发展高层论坛年会上&#xff0c;国家数据局局长刘烈宏在“释放数据要素价值&#xff0c;助力可持续发展”的演讲中表示&#xff0c;中国10亿参数规模以上的大模型数量已超100个。 当前&#xff0c;国内AI大模型发展仍面临诸多困境。其中&#xff…

批量剪辑视频,批量调整片头片尾时长,批量剪辑更高效!

在视频剪辑的世界里&#xff0c;有时候我们需要对视频的片头片尾进行精细调整&#xff0c;以适应不同的需求和创意。然而&#xff0c;传统的视频剪辑软件往往操作繁琐&#xff0c;效率低下&#xff0c;让人望而却步。今天&#xff0c;我要为您介绍一种全新的批量剪辑方式&#…

一个传入省市区ID的级联框

省市区ID 功能edit页面(主要)script逻辑如何拿到当前级联下所有ID数组长ID数组是如何回显的 (1)长ID数组是如何回显的 (2) 功能 选择第一层传第一层下的所有 id 数组&#xff0c;选择第二层传递第二层以及第二层下的所有 id 数组 edit页面(主要) 编辑页的一个 Table&#xff0c…

Dynamo设置按链接视图显示

Hello大家好&#xff01;我是九哥~ 先来看一段视频&#xff1a; Dynamo设置链接视图 相信用Revit的小伙伴都用到过这个功能&#xff0c;就是在链接Revit模型时&#xff0c;为了便于出图&#xff0c;我们经常需要将链接模型从“按主体视图”改为“按链接视图”&#xff0c;这样能…

buy me a btc 使用数字货币进行打赏赞助

最近在调研使用加密货币打赏的平台&#xff0c;发现idatariver平台 https://idatariver.com 推出的buymeabtc功能刚好符合使用场景&#xff0c;下图为平台的演示项目, 演示项目入口 https://buymeabtc.com/idatariver 特点 不少人都听说过buymeacoffee&#xff0c;可以在上面发…

BabySQL【2019极客大挑战】

知识点&#xff1a; 功能分析 登录界面一般是 where username and password 可以从username出手&#xff0c;注释掉and语句单引号闭合绕过 通过测试和报错信息发现是一个单引号读取输入可以单引号闭合绕过关键字过滤 or and 过滤 || &&替换双写绕过select from wher…

【学习笔记】java项目—苍穹外卖day01

文章目录 苍穹外卖-day01课程内容1. 软件开发整体介绍1.1 软件开发流程1.2 角色分工1.3 软件环境 2. 苍穹外卖项目介绍2.1 项目介绍2.2 产品原型2.3 技术选型 3. 开发环境搭建3.1 前端环境搭建3.2 后端环境搭建3.2.1 熟悉项目结构3.2.2 Git版本控制3.2.3 数据库环境搭建3.2.4 前…

基于单片机环境监测温湿度PM2.5系统设计

**单片机设计介绍&#xff0c;基于单片机环境监测温湿度PM2.5系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机环境监测温湿度PM2.5系统是一个集成了传感器技术、单片机控制以及数据处理与显示功能的综合性系统…

30-3 越权漏洞 - 水平越权(横向越权)

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、定义 攻击者可以访问和操作与其拥有同级权限的用户资源。 示例: 学生A在教务系统上正常只能修改自己的作业内容,但由于不合理的权限校验规则等原因,学生A可以修改学生B的内…

五种免费的Python开发环境及具体下载网址

五种免费的Python开发环境及具体下载网址 目录 五种免费的Python开发环境及具体下载网址1.Anaconda2.PyCharm Community Edition3.Visual Studio Code4.Jupyter Notebook5. WinPython Python编程可选择不同的开发工具环境进行&#xff0c;本文介绍五种常用的&#xff0c;读者可…

R语言使用dietaryindex包计算NHANES数据多种营养指数(2)

健康饮食指数 (HEI) 是评估一组食物是否符合美国人膳食指南 (DGA) 的指标。Dietindex包提供用户友好的简化方法&#xff0c;将饮食摄入数据标准化为基于指数的饮食模式&#xff0c;从而能够评估流行病学和临床研究中对这些模式的遵守情况&#xff0c;从而促进精准营养。 该软件…

WhatsApp封号怎么办?看看原因与解封方法

相信各位小伙伴已经发现&#xff0c;WhatsApp新一轮风控已经启动&#xff0c;不少小伙伴已经受到封号潮的冲击。无论是老号还是新号都难以幸免。为了防止WhatsApp客户数据和聊天信息的丢失&#xff0c;针对封号的防封攻略请收藏&#xff01; 一、WhatsApp被封的8个原因 1、被过…

编译与链接(想了解编译与链接,那么看这一篇就足够了!)

前言&#xff1a;在我们练习编程的时候&#xff0c;我们只需要将代码写入、运行&#xff0c;就可以得到计算之后的结果了&#xff0c;但是你有没有想过&#xff0c;为什么就可以得到计算之后的结果呢&#xff0c;它的底层又到底是什么呢&#xff1f; ✨✨✨这里是秋刀鱼不做梦的…

算法之美:B+树原理、应用及Mysql索引底层原理剖析

B树的一种变种形式&#xff0c;B树上的叶子结点存储关键字以及相应记录的地址&#xff0c;同等存储空间下比B-Tree存储更多Key。非叶子节点不对关键字记录的指针进行保存&#xff0c;只进行数据索引 , 树的层级会更少 , 所有叶子节点都在同一层, 叶子节点的关键字从小到大有序排…

安装uim-ui插件不成功,成功解决

安装&#xff1a;这种安装&#xff0c;umi4 不支持&#xff0c;只有umi3才支持。而我发现官网现在默认使用的umi4。 yarn add umijs/preset-ui -D 解决&#xff1a;更改umi版本重新安装umi3 npm i ant-design/pro-cli3.1.0 -g #使用umi3 (指定umi3版本) pro create user-ce…

伪原创文章生成软件:自媒体文章写作好神器

自媒体的红利时代&#xff0c;许多人都纷纷参于其中&#xff0c;而文章写作是做自媒体的基本技能&#xff0c;但是随着技术的发展&#xff0c;如今&#xff0c;既使不会写作能力一样可以做起自媒体&#xff0c;方法就是利用伪原创文章生成软件来做内容的输出&#xff0c;其实伪…

【Vue3进阶】- 第2学堂小商城实战课程前言

该教程为进阶教程&#xff0c;如果你还不了解Vue3的基础知识&#xff0c;可以先前往Vue3基础教程&#xff0c;从入门到实战。 学习时遇到的任何疑问都欢迎在相应课文页面下方的问答区进行提问哦 我能学到什么&#xff1f; 编程写法千千万&#xff0c;实现需求是第一。 教程中…

如何在 Ubuntu 安装桌面环境

在 Ubuntu 上安装不同的桌面环境 如果你正在使用官方的 Ubuntu 发行版&#xff0c;它运行在 GNOME 上&#xff0c;那么你可以很容易地从默认的包管理器安装其他流行的桌面环境&#xff08;DE&#xff09;。让我们开始吧… 在 Ubuntu 上安装 KDE Plasma 如果你正在使用 GNOME…

8.6 循环神经网络的简洁实现

每个步长共用参数 加载数据 虽然 8.5节 对了解循环神经网络的实现方式具有指导意义&#xff0c;但并不方便。 本节将展示如何使用深度学习框架的高级API提供的函数更有效地实现相同的语言模型。 我们仍然从读取时光机器数据集开始。 import torch from torch import nn from…

面向对象:继承

文章目录 一、什么叫继承&#xff1f;二、单继承三、多继承3.1多继承的各种情况3.1.1一般情况3.1.1特殊情况&#xff08;菱形继承&#xff09; 四、菱形继承引发的问题4.1 问题1:数据冗余4.2 问题2:二义性&#xff08;无法确定到底是访问哪个&#xff09; 五、虚拟继承解决菱形…