Solidity Uniswap V2 Router contract addLiquidity

2024-03-15 15:52

本文主要是介绍Solidity Uniswap V2 Router contract addLiquidity,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        router 合约是一种高级合约,是大多数用户应用程序的入口点。通过该合约,可以更轻松地创建交易对、添加和删除流动性、计算交换中的价格变化以及执行交换。Router 适用于通过工厂合约部署的所有交易对,是一种通用合约。

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

        它也是一个非常大的合约,我们可能不会实现它的所有功能,因为其中大部分都是交换功能的变形。让我们看看路由器的构造函数:路由器可以部署pair,因此它需要知道工厂合约的地址。

contract ZuniswapV2Router {error InsufficientAAmount();error InsufficientBAmount();error SafeTransferFailed();IZuniswapV2Factory factory;constructor(address factoryAddress) {factory = IZuniswapV2Factory(factoryAddress);}...

        今天,我们只实现流动性管理的一部分,让我们从 addLiquidity 开始:

function addLiquidity(address tokenA,address tokenB,uint256 amountADesired,uint256 amountBDesired,uint256 amountAMin,uint256 amountBMin,address to)publicreturns (uint256 amountA,uint256 amountB,uint256 liquidity)...

        与pair合约中的mint函数相比,该函数有很多参数!

        1、tokenA 和 tokenB 用于查找(或创建)我们希望增加流动性的货币对。

        2、amountADesired 和 amountBDesired 是我们希望存入货币对的金额。这些是上限。

        3、amountAMin 和 amountBMin 是我们希望存入的最小金额。还记得当我们存入不平衡的流动性时,pair合约总是发行较少的 LP-Token吗?。因此,最小参数允许我们控制准备损失多少流动性。

        4、to 地址是接收 LP-Token的地址。

...if (factory.pairs(tokenA, tokenB) == address(0)) {factory.createPair(tokenA, tokenB);}...

        如果指定的ERC20 Token没有pair合约,它将由router 合约创建。 factory.pairs方法是pairs映射,由于映射是嵌套的,Solidity 为该辅助方法设置了两个参数。

...(amountA, amountB) = _calculateLiquidity(tokenA,tokenB,amountADesired,amountBDesired,amountAMin,amountBMin);...

        下一步,我们将计算将存入的金额。稍后我们将回到这个函数。

...address pairAddress = ZuniswapV2Library.pairFor(address(factory),tokenA,tokenB);_safeTransferFrom(tokenA, msg.sender, pairAddress, amountA);_safeTransferFrom(tokenB, msg.sender, pairAddress, amountB);liquidity = IZuniswapV2Pair(pairAddress).mint(to);...

        计算完流动性金额后,我们就可以从用户处转移token,并铸造 LP-token作为交换。除了 pairFor 函数之外,这些代码中的大部分你都应该很熟悉了,我们将在实现 _calculateLiquidity 之后立即实现它。此外,请注意该合约并不希望用户手动转移代币,而是使用 ERC20 transferFrom 函数从用户余额中转移代币。

function _calculateLiquidity(address tokenA,address tokenB,uint256 amountADesired,uint256 amountBDesired,uint256 amountAMin,uint256 amountBMin) internal returns (uint256 amountA, uint256 amountB) {(uint256 reserveA, uint256 reserveB) = ZuniswapV2Library.getReserves(address(factory),tokenA,tokenB);...

        在这个函数中,我们要找到满足我们所需和最低金额的流动性金额。由于从我们在用户界面选择流动性金额到我们的交易被处理之间存在延迟,实际reserve比率可能会发生变化,这将导致我们损失一些 LP-token(作为对存入不平衡流动性的惩罚)。通过选择所需的最小金额,我们可以最大限度地减少这种损失。

        该功能的第一步是通过使用库合约获取池储备,我们下次就会实现这一点。得到了reserve,我们就可以计算出最佳流动性金额

...if (reserveA == 0 && reserveB == 0) {(amountA, amountB) = (amountADesired, amountBDesired);...

        如果储备金是空的,那么这是一对新的货币对,这意味着我们的流动性将决定储备金比率,这意味着我们不会因为提供不平衡的流动性而受到惩罚。因此,我们可以存入所需的全额资金。

...} else {uint256 amountBOptimal = ZuniswapV2Library.quote(amountADesired,reserveA,reserveB);if (amountBOptimal <= amountBDesired) {if (amountBOptimal <= amountBMin) revert InsufficientBAmount();(amountA, amountB) = (amountADesired, amountBOptimal);...

        否则,我们需要找到最优数量,我们从找到最优tokenB数量开始。报价是库合约中的另一个函数:通过输入金额和配对储备金,计算输出金额,即tokenA 的价格乘以token B 的输入金额。

        如果amountBOptimal 小于或等于我们的期望金额,并且高于我们的最小金额,则使用该金额。期望金额和最小金额之间的差额可以防止滑点。

        但是,如果最优金额BOptimal 大于我们的期望金额,则不能使用,我们需要找到另一个最优金额 A。

...} else {uint256 amountAOptimal = ZuniswapV2Library.quote(amountBDesired,reserveB,reserveA);assert(amountAOptimal <= amountADesired);if (amountAOptimal <= amountAMin) revert InsufficientAAmount();(amountA, amountB) = (amountAOptimal, amountBDesired);}

        使用相同的逻辑,我们可以找到 amountAOptimal:它也必须在我们的最小期望范围内。

这篇关于Solidity Uniswap V2 Router contract addLiquidity的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/812486

相关文章

【vue3|第28期】 Vue3 + Vue Router:探索路由重定向的使用与作用

日期:2024年9月8日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉在这里插入代码片得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方,还望各位大佬不吝赐教,谢谢^ - ^ 1.01365 = 37.7834;0.99365 = 0.0255 1.02365 = 1377.4083;0.98365 = 0.0006 说

野火霸天虎V2学习记录

文章目录 嵌入式开发常识汇总1、嵌入式Linux和stm32之间的区别和联系2、stm32程序下载方式3、Keil5安装芯片包4、芯片封装种类5、STM32命名6、数据手册和参考手册7、什么是寄存器、寄存器映射和内存映射8、芯片引脚顺序9、stm32芯片里有什么10、存储器空间的划分11、如何理解寄存器说明12、如何操作寄存器的某一位 STM32F407芯片学习1、stm32单片机启动流程s

vue中路由管理(vue-router,page)使用总结

现在的项目都以模块化的方式去开发,所以在这样的开发模式下,如何更好的去管理路由是开发中所需要考虑的重点,幸运的是当前的开发中已经有了成熟的中间件去管理,我们只需要用就可以了 下面是我在学习vue-router的时候在原来基础上修改出来的demo,也是为了有助于对vue-router的理解 首先理解下vue官网的一个示例demo https://jsfiddle.net/yyx990803/x

翻译Houdini官方对UE4新版插件的介绍:Houdini Engine for Unreal - V2

原视频:Houdini For Unreal - YouTube 目录 介绍0. 总览1. 简介HoudiniEngine2. UE4的HoudiniEngine - 第二版为什么要做“第二版” ?What's new? - 核心What's new? - 输出(1)What's new? - 输出(2)What's new? - 输入What's new? - 参数What's new?

Vue - 关于Router路由跳转时显示的animate.css动画

Vue - 关于Router路由跳转时显示的animate.css动画 在Vue中,操作路由跳转时页面是闪白的,没有动画效果,我们可以通过在router-view中设置transition,并搭配animate丰富的动画效果来美化路由跳转时的显示效果. 1.安装animate npm i -S animate.css 2.在main中引入animate.css import 'anim

Jaxb - com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 8 counts of IllegalAnnotationExcepti

一、异常 com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 8 counts of IllegalAnnotationExceptions类的两个属性具有相同名称 "orderName"his problem is related to the following location:at public java.lang.Stri

MapReduce V2---Yarn的架构及其执行原理

1. MRv1的局限性    1):扩展性差            MRv1中,Jobracker同事兼备了资源管理和作业控制(job的生命周期管理(task调度,跟踪task过程状态,task处理容错)两个功能。     单个的jobtracker无论在内存还是其他资源方面总存在瓶颈,在伸缩性、资源利用率、运行除mapreduce的其他任务等方面都会有限制。 MRv2 Y

golang中使用aws-sdk-go-v2

1.aws-sdk-go-v2常用api 1.引入所需包     import ("context""fmt""log""os""path/filepath""sync""time""github.com/aws/aws-sdk-go-v2/aws""github.com/aws/aws-sdk-go-v2/config""github.com/aws/aws-sdk-go-v2/crede

vue路由Router设置父路由默认选中第一个子路由,切换子路由让父路由激活高亮效果不会消失

import Vue from 'vue';import VueRouter from 'vue-router';// 导入组件import Home from '../views/Home.vue';import Parent from '../views/Parent.vue';import Child1 from '../views/Child1.vue';import Child

AttributeError: module ‘tensorflow_core._api.v2.config’ has no attribute ‘experimental_list_devices’

找到 tensorflow_backend.py 源文件的第506行 _LOCAL_DEVICES = tf.config.experimental_list_devices() 改成 devices = tf.config.list_logical_devices()_LOCAL_DEVICES = [x.name for x in devices]