UniswapV1自学系列05:LP代币机制的设计与实现在前面的文章中,我们已经实现了基本的流动性添加功能,但是还没有讨论一个至关重要的概念:LP代币(LiquidityProviderTokens)。LP代币是Uniswap设计的核心组件,它解决了如何公平奖励流动性提供者的问题。
在前面的文章中,我们已经实现了基本的流动性添加功能,但是还没有讨论一个至关重要的概念:LP 代币(Liquidity Provider Tokens)。LP 代币是 Uniswap 设计的核心组件,它解决了如何公平奖励流动性提供者的问题。
为了维持去中心化交易所的正常运作,我们必须建立一套机制来奖励流动性提供者。原因如下:
最佳的解决方案是从每笔代币兑换中收取少量手续费,然后将累积的费用分配给流动性提供者。这种方式具有以下优势:
为了确保公平分配,我们需要按照流动性提供者的贡献比例来分配费用:
LP 代币(Liquidity Provider Tokens)本质上是发行给流动性提供者的 ERC20 代币,用来代表他们在流动性池中的份额。LP 代币的工作机制类似于股份:
LP 代币系统需要满足以下关键要求:
传统的固定供应量方案存在明显缺陷:
固定供应量的问题:
无限供应的优势:
Exchange 合约存储着 ETH 和 ERC20 代币的储备量,在计算 LP 代币发行数量时可以有多种选择:
由于我们正在学习 Uniswap V1,我们采用基于 ETH 储备的计算方式。
LP 代币发行数量的计算公式为:
amountMinted = totalSupply * ethDeposited / ethReserve
公式解析:
amountMinted
:新铸造的 LP 代币数量totalSupply
:当前 LP 代币的总供应量ethDeposited
:用户此次存入的 ETH 数量ethReserve
:存入前池中的 ETH 储备量数学验证示例: 假设池中现有 100 ETH,总 LP 代币供应量为 100。如果用户存入 100 ETH(即现有储备的 100%),那么:
amountMinted = 100 * 100 / 100 = 100
首先,我们需要让 Exchange 合约继承 ERC20 合约:
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// 需要合约继承 ERC20 合约
contract Exchange is ERC20 {
address public tokenAddress;
/**
* @notice 初始化交易所合约
* @param _token 绑定的 ERC20 代币地址
*/
constructor(address _token) ERC20("Zuniswap-V1", "ZUNI-V1") {
require(_token != address(0), "invalid token address");
tokenAddress = _token;
}
}
设计说明:
当池子为空时,LP 代币的发行量等于存入的 ETH 数量:
function addLiquidity(uint256 _tokenAmount)
public
payable
returns (uint256)
{
if (getReserve() == 0) {
// 初始流动性添加的完整逻辑...
// 铸造 LP 代币,数量等于存入的 ETH 数量
uint256 liquidity = address(this).balance;
_mint(msg.sender, liquidity);
return liquidity;
设计考虑:
当池子已有流动性时,按比例铸造 LP 代币:
} else {
// 计算所需的代币数量和 ETH 储备...
// 按比例铸造 LP 代币
uint256 liquidity = (totalSupply() * msg.value) / ethReserve;
_mint(msg.sender, liquidity);
return liquidity;
}
}
关键点:
totalSupply()
获取当前 LP 代币总供应量通过数学公式确保:
通过仅仅几行代码,我们就成功实现了 LP 代币机制:
LP 代币机制是 AMM 设计的重要创新,它优雅地解决了去中心化流动性激励的难题。
完整的代码实现和测试用例可以在项目仓库中找到,建议克隆代码进行实践学习:
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!