基础概念解释什么是流动性池?流动性池是一个智能合约,里面存放着两种资产(比如ETH和某个Token),用户可以在这个池子里进行代币的交换。什么是LP代币?LP(LiquidityProvider)代币是流动性提供者凭证,当你向池子添加流动性时,合约会给你LP代币作为凭证,证明你在这个池子里
流动性池是一个智能合约,里面存放着两种资产(比如ETH和某个Token),用户可以在这个池子里进行代币的交换。
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);
}
代码的执行逻辑按以下顺序进行:
根据用户持有的LP代币比例计算应该获得的ETH和Token数量
检查计算出的数量是否达到用户设置的最小要求,防止因价格波动造成损失
触发事件函数,记录这次流动性移除操作
Uniswap V1 使用按比例分配的核心原理:
计算公式:
具体例子:
假设当前池子状态:
- 池子总共有 1000 个LP代币
- 池子里有 10 ETH
- 池子里有 20000 个USDC Token
- 小明持有 100 个LP代币(占总量的10%)
小明可以提取:
- ETH数量:100 ÷ 1000 × 10 = 1 ETH
- USDC数量:100 ÷ 1000 × 20000 = 2000 USDC
这种机制确保了流动性提供者能够按其贡献的份额获得相应的资产,包括历史累积的交易手续费。
LP代币代表用户在池子中的份额证明。当用户提取流动性时,必须销毁相应的LP代币,这样可以:
滑点是指用户预期价格与实际执行价格之间的差异。在删除流动性时,滑点主要由价格波动引起。
假设用户期望提取 1 ETH,设置5%滑点保护:
min_eth = 1 × (1 - 5%) = 0.95 ETH
如果实际只能提取到 0.9 ETH,交易就会失败
如果能提取到 0.96 ETH,交易正常执行
⚠️ 重要风险提示:
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!