Uniswap V1-删除流动性学习

  • 李楠
  • 发布于 16小时前
  • 阅读 67

基础概念解释什么是流动性池?流动性池是一个智能合约,里面存放着两种资产(比如ETH和某个Token),用户可以在这个池子里进行代币的交换。什么是LP代币?LP(LiquidityProvider)代币是流动性提供者凭证,当你向池子添加流动性时,合约会给你LP代币作为凭证,证明你在这个池子里

基础概念解释

什么是流动性池?

流动性池是一个智能合约,里面存放着两种资产(比如ETH和某个Token),用户可以在这个池子里进行代币的交换。

什么是LP代币?

LP(Liquidity Provider)代币是流动性提供者凭证,当你向池子添加流动性时,合约会给你LP代币作为凭证,证明你在这个池子里有份额。就像银行存款凭证一样。LP 本身也是一种 ERC20 代币,所以是可以进行转账、交易的。

注意:如果 LP 你转账给了其他账户,就表示你把这部分 LP 的权益转发给了别人,别人可以用 LP 去池中兑换出相应的 ETH 和 Token。

什么是流动性提供者?

流动性提供者就是向池子里同时存入ETH和Token的用户,他们可以获得交易手续费收益。

源码

 /**
     * @notice 移除流动性,销毁LP代币,并按比例取回ETH和Token
     * @param amount 想要销毁的LP代币数量
     * @param min_eth 预期取回的最小ETH数量
     * @param min_tokens 预期取回的最小Token数量
     * @param deadline 交易的截止时间
     * @return 实际取回的ETH和Token数量
     */
    function removeLiquidity(uint256 amount, uint256 min_eth, uint256 min_tokens, uint256 deadline) external returns (uint256, uint256) {
        // 检查输入参数的有效性
        require(amount > 0, "Factory: INVALID_AMOUNT");  // LP代币数量必须大于0
        require(deadline >= block.timestamp, "Factory: DEADLINE_EXCEEDED");  // 确保交易未过期

        // 获取当前总流动性
        uint256 totalLiquidity = totalSupply;
        require(totalLiquidity > 0, "Factory: EMPTY_LIQUIDITY");  // 确保池中有流动性

        // 计算按比例应该返还的ETH和Token数量
        uint256 tokenReserve = IERC20(token).balanceOf(address(this));  // 获取当前合约中的Token余额
        uint256 ethWithdrawn = (amount * address(this).balance) / totalLiquidity;  // 按比例计算应返还的ETH
        uint256 tokenWithdrawn = (amount * tokenReserve) / totalLiquidity;  // 按比例计算应返还的Token

        // 确保返还的数量满足用户设定的最低要求(防止滑点)
        require(ethWithdrawn >= min_eth, "Factory: ETH_UNDERFLOW");
        require(tokenWithdrawn >= min_tokens, "Factory: TOKEN_UNDERFLOW");

        // 使用继承的 _burn 函数销毁用户提供的 LP 代币
        _burn(msg.sender, amount);

        // 将ETH安全地发送给用户
        (bool success, ) = msg.sender.call{value: ethWithdrawn}("");
        require(success, "Factory: ETH_TRANSFER_FAILED");  // 确保ETH转账成功
        // 将Token发送给用户
        require(IERC20(token).transfer(msg.sender, tokenWithdrawn), "Factory: TOKEN_TRANSFER_FAILED");

        // 触发移除流动性事件
        emit RemoveLiquidity(msg.sender, ethWithdrawn, tokenWithdrawn);
        // 返回实际提取的ETH和Token数量
        return (ethWithdrawn, tokenWithdrawn);
    }

用户操作流程

  1. 用户在Dapp界面操作:输入要提取的LP代币数量
  2. 设置滑点容忍度:比如设置5%滑点保护
  3. Dapp自动计算:根据滑点自动计算min_eth和min_tokens数值
  4. 用户确认交易:检查预估收到的ETH和Token数量,确认并支付Gas费
  5. 合约自动执行:销毁LP代币,返还ETH和Token给用户钱包

代码执行逻辑

代码的执行逻辑按以下顺序进行:

1. 安全检查

  • 参数验证:确保要销毁的LP代币数量大于0
  • 时间检查:确保交易在截止时间(deadline)内完成
  • 池子状态检查:确保池子里有足够的流动性

2. 计算应得的资产数量

根据用户持有的LP代币比例计算应该获得的ETH和Token数量

3. 滑点验证

检查计算出的数量是否达到用户设置的最小要求,防止因价格波动造成损失

4. 执行资产转移

  • 销毁用户的LP代币
  • 将ETH转账给用户
  • 将Token转账给用户

5. 记录操作

触发事件函数,记录这次流动性移除操作

按比例提取的计算原理

Uniswap V1 使用按比例分配的核心原理:

计算公式:

  • ETH 提取数量 = (用户LP代币数量 / 总LP代币数量) × 池中ETH总量
  • Token 提取数量 = (用户LP代币数量 / 总LP代币数量) × 池中Token总量

具体例子:

假设当前池子状态:
- 池子总共有 1000 个LP代币
- 池子里有 10 ETH 
- 池子里有 20000 个USDC Token
- 小明持有 100 个LP代币(占总量的10%)

小明可以提取:
- ETH数量:100 ÷ 1000 × 10 = 1 ETH
- USDC数量:100 ÷ 1000 × 20000 = 2000 USDC

这种机制确保了流动性提供者能够按其贡献的份额获得相应的资产,包括历史累积的交易手续费。

为什么要销毁LP代币?

LP代币代表用户在池子中的份额证明。当用户提取流动性时,必须销毁相应的LP代币,这样可以:

  • 确保剩余LP代币持有者的份额计算依然准确
  • 防止LP代币被重复使用
  • 保持池子中LP代币总量与资产总量的比例关系

滑点保护机制

什么是滑点?

滑点是指用户预期价格与实际执行价格之间的差异。在删除流动性时,滑点主要由价格波动引起。

滑点保护如何工作?

  • 用户在Dapp上设置滑点容忍度(比如5%)
  • Dapp根据当前价格和滑点计算出min_eth和min_tokens
  • 如果实际能获得的数量低于这个最小值,交易就会失败
  • 这样可以防止用户在价格剧烈波动时遭受意外损失

滑点计算示例:

假设用户期望提取 1 ETH,设置5%滑点保护:
min_eth = 1 × (1 - 5%) = 0.95 ETH

如果实际只能提取到 0.9 ETH,交易就会失败
如果能提取到 0.96 ETH,交易正常执行

专业术语解释

  • Gas费:在以太坊网络上执行交易需要支付的手续费,无论交易成功或失败都会扣除
  • 截止时间(deadline):防止交易在网络拥堵时被长时间挂起,超过时间就自动取消
  • 滑点保护:防止价格波动导致用户资产损失的保护机制
  • 事件(Event):区块链上的日志记录,方便用户和Dapp查询历史操作

风险提醒

⚠️ 重要风险提示:

  1. 不可逆操作:删除流动性是不可逆的,LP代币一旦销毁就无法恢复
  2. Gas费损失:无论交易成功或失败,Gas费都会被扣除
  3. 滑点风险:价格剧烈波动时可能因滑点保护导致交易失败
  4. 时机选择:建议在价格相对稳定时进行流动性操作
  5. 数量确认:删除前请仔细确认LP代币数量和预期收到的资产数量

最佳实践建议

  1. 合理设置滑点:一般设置2-5%即可,热门币种波动大时可适当调高
  2. 选择合适时机:避免在市场剧烈波动时操作
  3. 分批操作:大额流动性可以考虑分批移除,降低风险
  4. Gas费预估:在Gas费较低时进行操作可以节省成本
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
李楠
李楠
0x5418...e0f6
江湖只有他的大名,没有他的介绍。