文章详细介绍了 Uniswap V2 Library 的功能和使用方法,主要包括getAmountOut()、getAmountIn()、getAmountsOut()、getAmountsIn()、getReserves() 和 quote() 等函数的工作原理和数学推导过程,并提供了相关代码和图片说明。
Uniswap V2 Library 简化了与交易对合约的某些交互,并被路由合约广泛使用。它包含八个不会改变状态的函数,这些函数在从智能合约集成 Uniswap V2 时也很有用。
如果我们想预测如果我们提供一定数量的 token x
,将获得的 token y
的数量,那么我们可以通过下面的推导来得出输出数量(为了简单起见,忽略手续费)。让 x
为输入代币,y
为输出代币,Δx
为进入的数量,Δy
为输出的数量。
$$ \begin{align} xy &= (x + \Delta x)(y – \Delta y) \\ y – \Delta y &= \frac{xy}{x + \Delta x} \\ -\Delta y &= \frac{xy – y(x + \Delta x)}{x + \Delta x} \\ -\Delta y &= \frac{-y \Delta x}{x + \Delta x} \\ \Delta y &= \frac{y \Delta x}{x + \Delta x} \end{align} $$
$$ \text{amount_out} = \frac{\text{reserve_out} \cdot \text{amount_in}}{\text{reserve_in} + \text{amount_in}} $$
考虑到这一点,UniswapV2Library.sol
中的 getAmountOut()
函数应该是不言而喻的。请注意,这些数字被缩放了 1,000,以考虑 0.3% 的手续费。包含费用的 getAmountIn()
的推导留给读者练习。
如果一个交易者提供一系列的交易对,比如 (A, B), (B, C), (C, D),并且从一开始就以一定数量的 A
反复调用 getAmountOut
,那么可以预测得到的 D
代币的数量。
每个 (A, B), (B, C) 等的 UniswapV2 交易对合约地址是根据代币地址和部署该交易对的工厂地址通过 create2
函数确定的。给定两个代币 (A, B) 和一个工厂 address
,pairFor()
使用 sortTokens()
作为辅助函数来推导该对的 UniswapV2 池合约地址。
现在我们知道了所有对的地址,我们可以获取每个对的储备并预测在交换链结束时我们将收到多少代币。以下是 getAmountsOut()
的代码(强调“Amounts”而不是“Amount”)。getAmountsIn()
函数简单地反向做相同的事情,所以我们不在这里展示。
请注意几点:
amountOut
,还返回每一步的输出数量。getReserves
函数只是对 Uniswap V2 交易对合约中 getReserves
函数的一个封装,除了它还去除了最后更新时间戳。交易对合约中 getReserves
函数的实现也在此显示,便于比较(紫色注释)。
核心功能:
回想一下,一个资产的价格遵循以下公式:
$$ \mathsf{price}(\text{foo}) = \frac{\mathsf{reserve(\text{bar})}}{\mathsf{reserve}(\text{foo})} $$
此函数返回最后一次更新时 foo 的价格,用 bar 表示。该函数应谨慎使用,因为它容易受到闪电贷攻击。
如果你想预测在交易中投入多少金额或期望从交易中获得多少金额,或者跨对进行一系列交易,请使用 UniswapV2Library
。
尝试 DamnVulnerableDefi Puppet V2。此时你应该能够轻松识别安全问题。
此材料是我们高级 Solidity Bootcamp 的一部分。请查看该课程以了解更多信息。
原文发表于 2023 年 11 月 6 日
- 原文链接: rareskills.io/post/unisw...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!