Solidity Uniswap V2 Pair中移除流动性

2024-03-08 16:52

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

        移除流动性与提供流动性是截然相反的一个动作。从Pool中移除流动性意味着烧销毁LP-Token,以换取pair中相应数量的Token。返回的token数量与提供的流动性是这样计算的:

        简而言之,返回的Token数量,与持有的LP-Token数量与LP-Token总供应量成正比。你的LP-Token份额越大,你在burn后从reserve获得的份额就越大。

        这就是我们实现burn函数所需要知道的:

        当有人向池提供流动性时,他们会得到 LP-token作为回报。当流动性被移除时,这些 LP-token会被兑换成池流动性并被销毁。让用户向合约发送一定数量的 LP-token,在合约中计算出用户可以获取的token后,销毁 LP-token。

function burn(address to) public returns (uint256 amount0, uint256 amount1)  {uint256 balance0 = IERC20(token0).balanceOf(address(this));uint256 balance1 = IERC20(token1).balanceOf(address(this));uint256 liquidity = balanceOf[address(this)];uint256 amount0 = (liquidity * balance0) / totalSupply;uint256 amount1 = (liquidity * balance1) / totalSupply;if (amount0 <= 0 || amount1 <= 0) revert InsufficientLiquidityBurned();_burn(address(this), liquidity);bool success0 = IERC20(token0).transfer(to, amount0);if (!success0)revert TransferFailed();bool success1 = IERC20(token1).transfer(to, amount1);if (!success1)revert TransferFailed();balance0 = IERC20(token0).balanceOf(address(this));balance1 = IERC20(token1).balanceOf(address(this));(uint112 reserve0_, uint112 reserve1_, ) = getReserves();_update(balance0, balance1, reserve0_, reserve1_);emit Burn(msg.sender, amount0, amount1);}

接下来测试一下:

function testBurn() public {token0.transfer(address(pair), 1 ether);token1.transfer(address(pair), 1 ether);pair.mint(address(this));uint256 liquidity = pair.balanceOf(address(this));pair.transfer(address(pair), liquidity);pair.burn(address(this));assertEq(pair.balanceOf(address(this)), 0);assertReserves(1000, 1000);assertEq(pair.totalSupply(), 1000);assertEq(token0.balanceOf(address(this)), 10 ether - 1000);assertEq(token1.balanceOf(address(this)), 10 ether - 1000);}

我们可以看到,除了发送到零地址的最低流动性外,Pool又回到了未初始化的状态。

现在,让我们看看在提供不平衡的流动性后会发生什么:

function testBurnUnbalanced() public {token0.transfer(address(pair), 1 ether);token1.transfer(address(pair), 1 ether);pair.mint(address(this));token0.transfer(address(pair), 2 ether);token1.transfer(address(pair), 1 ether);pair.mint(address(this)); // + 1 LPuint256 liquidity = pair.balanceOf(address(this));pair.transfer(address(pair), liquidity);pair.burn(address(this));assertEq(pair.balanceOf(address(this)), 0);assertReserves(1500, 1000);assertEq(pair.totalSupply(), 1000);assertEq(token0.balanceOf(address(this)), 10 ether - 1500);assertEq(token1.balanceOf(address(this)), 10 ether - 1000);}

        我们在这里看到的是,我们损失了 500 wei的Token 0!这就是上文提到的对价格操纵的惩罚。但这个数额小得离谱,看起来一点都不重要。这是因为我们当前的用户是唯一的流动性提供者。如果我们向另一个用户初始化的池提供了不平衡的流动性,会怎么样呢?让我们来看看:

function testBurnUnbalancedDifferentUsers() public {testUser.provideLiquidity(address(pair),address(token0),address(token1),1 ether,1 ether);assertEq(pair.balanceOf(address(this)), 0);assertEq(pair.balanceOf(address(testUser)), 1 ether - 1000);assertEq(pair.totalSupply(), 1 ether);token0.transfer(address(pair), 2 ether);token1.transfer(address(pair), 1 ether);pair.mint(address(this)); // + 1 LPuint256 liquidity = pair.balanceOf(address(this));pair.transfer(address(pair), liquidity);pair.burn(address(this));// this user is penalized for providing unbalanced liquidityassertEq(pair.balanceOf(address(this)), 0);assertReserves(1.5 ether, 1 ether);assertEq(pair.totalSupply(), 1 ether);assertEq(token0.balanceOf(address(this)), 10 ether - 0.5 ether);assertEq(token1.balanceOf(address(this)), 10 ether);testUser.removeLiquidity(address(pair));// testUser receives the amount collected from this userassertEq(pair.balanceOf(address(testUser)), 0);assertReserves(1500, 1000);assertEq(pair.totalSupply(), 1000);assertEq(token0.balanceOf(address(testUser)),10 ether + 0.5 ether - 1500);assertEq(token1.balanceOf(address(testUser)), 10 ether - 1000);}

        现在看起来完全不同了!我们现在损失了 0.5 ether 的 token0,相当于我们存入资金的 1/4 。这可是一笔不小的数目!

        想一想,是谁最终得到了这 0.5 个以太币:合约还是用户?

这篇关于Solidity Uniswap V2 Pair中移除流动性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

野火霸天虎V2学习记录

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

如何将文件从stage移除

原文链接:http://oomusou.io/git/git-remove-stage/ git将文件分成三个阶段 - working directory - stage - repository 要进入repository之前,必须先进入stage,但实际上可能用了git add之后,才后悔发现这个文件不应该进stage,必须从stage中移除,由于必须考虑该文件是否已经存在于repo

【佳学基因检测】网站加密证书失效后,如何移除并为新的证书安装准备环境?

【佳学基因检测】网站加密证书失效后,如何移除并为新的证书安装准备环境? 当WoTrus DV Server CA证书失效后,你需要确保你的Nginx配置中不再引用该证书,并且移除或替换相关的证书文件。以下是具体步骤: 1. 确认Nginx配置文件 首先,检查Nginx的配置文件,确保它不再引用旧的WoTrus证书。如果你已经使用Certbot安装了Let’s Encrypt证书,Certbo

翻译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?

数据结构:(LeetCode203)移除链表元素

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。 示例 1: 输入:head = [1,2,6,3,4,5,6], val = 6输出:[1,2,3,4,5] 示例 2: 输入:head = [], val = 1输出:[] 示例 3: 输入:head = [7,7,7,7], va

代码随想录算法训练营Day03 | 链表理论基础、203.移除链表元素 、707.设计链表、206.反转链表

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 链表理论基础203.移除链表元素思路与重点 707.设计链表思路与重点 206.反转链表思路与重点 链表理论基础 C/C++的定义链表节点方式: // 单链表struct ListNode {int val; // 节点上存储的元素ListNode *next; // 指向下一个节点的指

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

(二十九)STL map容器(映射)与STL pair容器(值对)

C++中的map容器是什么?可以说这个是python中的字典(dict) T = {'1':5, '3':7, '5':4, '4':9, '2':6} print(T) 学过python的都知道字典的每一项都有一个键(key)和一个值(value),而且键是不能重复的 在C++还有一个特点:可以自排序 那值对pair又是个什么东西呢?一个pair可以存储两个数据,这是他的定义: te

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

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

【Get深一度】Win10 Setup will now quit. 系统管理员失去安装和移除软件的权利(求助帖)

1.问题详述 笔者在安装软件的时候无意在任务管理器中叉掉了一个进程,然后 ,悲剧了。。莫名其妙就失去了权限。  2.以安装mathtype为例 没到最后都会弹出一个Setup :  问题手打一遍:You do not appear to have the rights required to install or remove s