Solidity Uniswap V2 Router swapTokensForExactTokens

        最初的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 函数。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

联想 lenovoTab 拯救者平板 Y700 二代_TB320FC原厂ZUI_15.0.677 firmware 线刷包9008固件ROM root方法

联想 lenovoTab 拯救者平板 Y700 二代_TB320FC原厂ZUI_15.0.677 firmware 线刷包9008固件ROM root方法 ro.vendor.config.lgsi.market_name拯救者平板 Y700 ro.vendor.config.lgsi.en.market_nameLegion Tab Y700 #ro.vendor.config.lgsi.short_market_name联想平板 ZUI T # B…

JMM Java内存模型

JMM本身是一个抽象的概念,不是真实存在的,它仅仅是一种规定或者说是规范 1.用来实现线程和主内存直接的抽象关系 2.屏蔽各个硬件平台和操作系统的内存访问差异,使得java程序在各种平台都能达到一致的内存访问效果 JMM的三大特性 可见性 多线程环境下,某个线程修改了变量…

Day55:WEB攻防-XSS跨站CSP策略HttpOnly属性Filter过滤器标签闭合事件触发

目录 XSS跨站-安全防御-CSP XSS跨站-安全防御-HttpOnly XSS跨站-安全防御-XSSFilter(过滤器的意思) 1、无任何过滤 2、实体化 输入框没有 3、全部实体化 利用标签事件 单引号闭合 4、全部实体化 利用标签事件 双引号闭合 5、事件关键字过滤 利用其他标签调用 双引号闭合…

Groovy基础入门

一、Groovy简介 Groovy是运行在JVM中的一种动态语言&#xff0c;可以在Java平台上进行编程&#xff0c;使用方式基本与使用Java代码的方式相同&#xff0c;它的语法与Java语言的语法很相似&#xff0c;与Java相比&#xff0c;Groovy更加灵活、简洁&#xff0c;而且完成同样的功…

Python人工智能:气象数据可视化的新工具

Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;在数据处理、科学计算、数学建模、数据挖掘和数据可视化方面具备优异的性能&#xff0c;这些优势使得Python在气象、海洋、地理、气候、水文和生态等地学领域的科研和工程项目中得到广泛应用。可以…

Mybatis别名 动态sql语句 分页查询

给Mybatis的实体类起别名 给Mybatis的xml文件注册mapper映射文件 动态sql语句 1 if 2 choose 3 where 4 foreach 一&#xff09;if 查询指定名称商品信息 语法&#xff1a; SELECT * FROM goods where 11 <if test "gName!null"> and g.g_name like co…

微信小程序被删除的文件一编译又回来了

一开始创建错了位置&#xff0c;就想着删除文件重新创建&#xff0c;但是没想到每次重新编译的时候&#xff0c;之前被删除的js、wsml文件就又回来了&#xff0c;后来发现是我在app.json中的pages里面的代码没有被删除。 因为我最开始创建错了&#xff0c;快捷创建了页面&#…

黑苹果睡眠(电源设置参考),英特尔 NUC9 黑苹果 Sonoma 14.1.1

机型&#xff1a;英特尔 NUC9 i9-9980HK处理器 之前电源配置没设置好&#xff0c;导致经常睡眠被无故唤醒&#xff0c;处理好之后是这样子的设置&#xff0c;我是台式机&#xff0c;其它的不太清楚&#xff0c;可以提供一个参考给大家。 EFI 暂时没时间上传共享&#xff0c;到时…

react-navigation:

我的仓库地址&#xff1a;https://gitee.com/ruanjianbianjing/bj-hybrid react-navigation&#xff1a; 学习文档&#xff1a;https://reactnavigation.org 安装核心包: npm install react-navigation/native 安装react-navigation/native本身依赖的相关包: react-nativ…

计算机网络:物理层 - 信道极限容量

计算机网络&#xff1a;物理层 - 信道极限容量 实际信道中的数字信号奈式准则香农公式练习 实际信道中的数字信号 信号在传输过程中会受到各种因素的影响&#xff0c;如图所示&#xff1a; 这是一个数字信号&#xff0c;当它通过实际的信道后&#xff0c;波形会产生失真&#…

【论文阅读】FlipCAM:高分辨率遥感影像弱监督建筑物提取的特征级翻转增强方法

【论文阅读】FlipCAM&#xff1a;高分辨率遥感影像弱监督建筑物提取的特征级翻转增强方法 文章目录 【论文阅读】FlipCAM&#xff1a;高分辨率遥感影像弱监督建筑物提取的特征级翻转增强方法一、介绍二、方法2.1 准备2.2 一致性的架构2.3 SAM模块2.4 建筑提取模式 三、实验结果…

RISC-V特权架构 - 中断定义

RISC-V特权架构 - 中断定义 1 中断类型1.1 外部中断1.2 计时器中断1.3 软件中断1.4 调试中断 2 中断屏蔽3 中断等待4 中断优先级与仲裁5 中断嵌套6 异常相关寄存器 本文属于《 RISC-V指令集基础系列教程》之一&#xff0c;欢迎查看其它文章。 1 中断类型 RISC-V 架构定义的中…

力扣热门算法题 135. 分发糖果,146. LRU 缓存,148. 排序链表

135. 分发糖果&#xff0c;146. LRU 缓存&#xff0c;148. 排序链表&#xff0c;每题做详细思路梳理&#xff0c;配套Python&Java双语代码&#xff0c; 2024.03.28 可通过leetcode所有测试用例。 目录 135. 分发糖果 解题思路 完整代码 Python Java 146. LRU 缓存 …

图腾柱PFC:HP1010为您的电动两轮车之旅提供绿色,高效,安全的动力

电动两轮车不仅为当今生活提供了便利&#xff0c;更是一种健康和绿色的出行方式。想象一下&#xff0c;在经过一整晚的充分休息&#xff0c;骑上爱车&#xff0c;满血复活的准备开始新的一天。您会愿意带着如何给心爱的两轮车充电的担心开始这一天吗&#xff1f; 随着越来越…

Vue 04 Vue 中的 Ajax、slot 插槽

Vue学习 Vue 0401 Vue中的Ajax服务器准备axios使用跨域问题解决Vue-CLI 配置代理1Vue-CLI 配置代理2案例: 用户搜索vue-resource 02 slot插槽默认插槽具名插槽作用域插槽slot总结 Vue 04 B站 Vue全家桶&#xff08;BV1Zy4y1K7SH&#xff09; 学习笔记 Vue 中的 ajax 01 Vue中的…

jmeter总结之:Regular Expression Extractor元件

Regular Expression Extractor是一个后处理器元件&#xff0c;使用正则从服务器的响应中提取数据&#xff0c;并将这些数据保存到JMeter变量中&#xff0c;以便在后续的请求或断言中使用。在处理动态数据或验证响应中的特定信息时很有用。 添加Regular Expression Extractor元…

Docker进阶:使用Docker部署Harbor私有镜像仓库

Docker进阶&#xff1a;使用Docker部署Harbor私有镜像仓库 1、安装Docker和Docker Compose1、安装Docker、Docker Compose2、验证Docker和Docker Compose是否成功安装3、先启动运行docker服务 2、下载并配置Harbor1、下载最新版本的Harbor离线安装包2、配置Harbor的主机名和管理…

DDos系列攻击原理与防御原理

七层防御体系 静态过滤 命中黑名单 对确定是攻击的流量直接加入黑名单&#xff08;源地址命中黑名单直接丢弃&#xff0c;缺乏机动性和扩展性&#xff09; 畸形报文过滤 畸形报文攻击 TCP包含多个标记位&#xff0c;排列组合有规律 • 现象&#xff1a;TCP标记位全为1 …

基于SpringBoot和Vue的在线视频教育平台的设计与实现

今天要和大家聊的是一款基于SpringBoot和Vue的在线视频教育平台的设计与实现 &#xff01;&#xff01;&#xff01; 有需要的小伙伴可以通过文章末尾名片咨询我哦&#xff01;&#xff01;&#xff01; &#x1f495;&#x1f495;作者&#xff1a;李同学 &#x1f495;&…

IDEA一键备份MySQL数据库(mysqldump版)

问题 又到了搬MySQL数据库的时刻&#xff0c;这次我不想使用命令行备份&#xff0c;这次我想使用IDEA一键备份MySQL数据库。 解决 假设安装好mysqldump命令后&#xff0c;让IDEA使用mysqldump一键备份指定的数据库。具体IDEA配置如下&#xff1a; 这是IDEA上面的数据库到处…