Uniswap V2 协议理解

本文深入解析了 Uniswap V2 协议的核心机制,包括流动性提供、token 交换以及闪电贷的原理与实现。文章详细阐述了交易公式、价格计算方法,以及闪电贷的实现方式。此外,还解释了 AMM 中常见的概念,如滑点、价格影响和无常损失,并提供了相应的计算公式和示例。

Uniswap V2 — 协议理解

简介

Uniswap 是一个用于代币交换的去中心化交易所。流动性提供者(LP)提供不同的代币对流动性以支持代币交换,协议将一部分交易费用分配给 LP,以鼓励他们提供流动性。

有了流动性,用户可以根据一个固定的公式,减去交易费用后,用 X 代币兑换 Y 代币。

流动性

流动性是交易的先决条件和基础。Uniswap 允许任何人创建新的配对流动性池或向现有池添加流动性。

如果是首次添加流动性,收到的 LP 代币数量等于存入金额的几何平均值

Uniswap v2 销毁了首次铸造的 $$10^{-15}$$ 流动性代币(是最小单位的 1,000 倍)。

你可以阅读这篇文章以了解更多关于 Vault Attack 的信息。

实际上,如果不是第一次存款,它本质上就像一个 vault,你收到的 LP 代币数量取决于你的存款相对于池中总量的百分比。

这意味着存入的 X 代币与 X 代币总量的比率等于你收到的 LP 代币与池中 LP 代币总量的比率。

代币交换

所有交换都遵循以下公式

这里 x 和 y 是池中代币的储备量,而 k 是一个常数变量。(实际实现中的公式略有不同)

在实践中,协议对交易收取 0.30% 的费用,该费用会添加到储备金中。因此,每笔交易实际上都会增加 k

例如,如果池中有 1200 个 X 代币和 400 个 Y 代币,并且你想交换 3 个 X 代币,你将获得约 0.997 个 Y 代币,而不是 1 个 Y 代币,因为有 0.009 个 X 代币作为费用并已添加到池中。交换后,大约有 1203.009 个 X 代币和约 399.003 个 Y 代币。K 增加了。

由于闪电贷的存在,对代币交换的限制是

不等式两边都乘以 1,000,000,我们得到

这就是 UniswapV2Pair 合约中 swap 方法的实现。

另一个问题是如何定义代币价格。基本上,价格可以通过将代币 a 和 b 的数量(不包括费用)相除来确定。 但是,我们不能简单地通过合约中的代币余额来计算价格,因为任何人都可以直接将代币转账到配对合约以影响价格。

因此,合约通过两个变量 reserve0reserve1 来维护代币余额。

现在我们使用推导公式来计算,给定一个输入量 xin,我们可以获得多少输出 yout。这里 x0,y0 是交换前的代币余额。 x1, y1 是交换后的代币余额。 xin 代币是 x 的输入量,yout 是代币 y 的输出量。

这是公式推导:

Solidity 中没有浮点数,所以公式变成

正如合约中的 getAmountOut 方法所示。

相反,我们还可以指定想要收到的输出代币数量,并计算所需的输入代币数量。所以我们已经确定了 yout 的数量,并且想知道 xin,与上面相同:

正如合约中的 getAmountIn 方法所示。

闪电贷

你可以从协议中借用代币并执行其他操作,只要你确保代币被返还,并且所有操作都在一个 tx 中完成。

之所以能够实现这一点,是因为 Ethereum 交易是原子性的,如果事实证明合约没有收到足够的代币,则整个交换可能会恢复。扣除 0.3% 的费用。

Uniswap 在设计时考虑了闪电贷,并通过 uniswapV2Call 接口提供原生支持。 你需要在你的闪电贷合约中继承并实现这个接口。

function function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external;

例如,你可以从 Uniswap 借入一定数量的 WETH,然后利用外部协议之间的价格差异来完成套利,最后将 WETH 连同 0.3% 的费用返还给 Uniswap。

AMM 中的常见概念

滑点

滑点是指预设交易价格与实际交易价格之间的偏差。滑点是市场总变动引起的代币价格变化。

这是一个例子:

假设 ETH/USDT 池中目前有 1 ETH 和 2000 USDT,k 为 2000。我们计划使用 500USDT 兑换 0.25 ETH,在此应用此公式:

这意味着我们只能获得 0.2 ETH 而不是 0.25 ETH。交换越多,滑点造成的损失就越大。 例如,如果交换 2000USDT,理论上你可以获得 1 ETH,但实际上你只能获得 0.5 ETH。

选择大流动性池进行交换可以降低损失。

价格影响

价格影响是你自己的交易引起的代币价格变化。

注意:滑点是市场总变动引起的代币价格变化。

无常损失

当流动性池中代币的价格与添加流动性时的价格发生变化时,就会发生无常损失,从而导致流动性提供者的价值损失。(一些文章使用发散损失

让我们通过一个例子来解释它。

假设 ETH/USDT 池中有 10ETH 和 1000USDT。你为该池提供 1 ETH 和 100 USDT 的流动性。现在的总资产价值为 200 USDT,并且拥有池的 10% 份额。

一段时间后,ETH 价格上涨至 400 USDT,池中有 5 ETH 和 2000 USDT。如果你想赎回你的 lp,由于拥有 10% 的份额,你可以获得 0.5 ETH 和 200 USDT,总计 400 USDT。因此,你可以获得 200 USDT 的利润。但是,如果你只是持有 1 ETH 和 100 USDT 会发生什么?合并后的价值为 500 USDT。

我们可以看到,通过存入流动性池,仅仅持有单个代币会更好。

现在,我们用数学公式计算一下损失:

假设一个池中有 x0 个代币 x 和 y0 个代币 y,p0 表示初始价格比率。我们有

价格变化后,有 x1 个代币 x 和 y1 个代币 y,p1 表示新的价格比率。我们仍然知道

我们将 p 作为价格变化率:

如果我们只是持有两个代币,总价值为:

如果我们持有 LP 代币,总价值为:

无常损失将是:

下图显示了不同价格比率下发散损失的一般概念:

关注 twitter 了解更多:https://x.com/bloom_cry

参考

https://docs.uniswap.org/contracts/v2/guides/smart-contract-integration/using-flash-swaps

https://solidity-by-example.org/defi/uniswap-v2-flash-swap/

https://support.uniswap.org/hc/en-us/articles/8643794102669-Price-Impact-vs-Price-Slippage

  • 原文链接: coinsbench.com/uniswap-v...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
CoinsBench
CoinsBench
https://coinsbench.com/