# 一道Uniswap v2面试题 问:一个Uniswap v2交易对,初始提供100ETH和10,000 token的流动性,获得1000枚LP。现在有一个用户手里有10ETH,如果他希望全部用来做市,应该将多少eth置换为token,以便和手里剩余的eth能正好组成LP? 答: 一、 在兑换之前,我们需要先确认当前池子的reserve0和reserve1。 根据[uniswap v2代码](https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol#L110),在首次添加流动性时: $$ liquidity = \sqrt{x \cdot y} - L_{min} $$ 其中,$L_{min} = 1000$,是为了防止首次铸币攻击而销毁的固定代币数量。 因此,当前的总流动性代币并不是$1000 * 10^{18}$,而是$1000 * 10^{18} - 1000$。(假设token的精度为$10^{18}$),reserve0为$100 * 10^{18}$,reserve1为$10000 * 10^{18}$。 二、 假设用户把$x_{in}$数量的eth用于兑换token,根据[getAmountOut](https://github.com/Uniswap/v2-periphery/blob/master/contracts/libraries/UniswapV2Library.sol#L43)方法可计算获得的token数量为: $$ y_{out} = \frac {997 \cdot x_{in} \cdot y_0}{1000 \cdot x_0 + 997 \cdot x_{in}} \tag{1} $$ 其中,$x_0 = 100 * 10^{18}$,$y_0 = 10000 * 10^{18}$。 此时池子里的ETH和token数量分别为: $$ reserve0 = x_0 + x_{in} = 100 * 10^{18} + x_{in} \tag{2} $$ $$ reserve1 = y_0 - y_{out} = 10000 * 10^{18} - y_{out} \tag{3} $$ 三、 兑换完成后,用户手里的ETH和token数量分别为: $$ x = 10 * 10^{18} - x_{in} \tag{4} $$ $$ y = y_{out} \tag{5} $$ 如果用户希望完全提供流动性,则需要满足: $$ \frac{x}{y} = \frac{reserve0}{reserve1} \tag{6} $$ 展开上述式子: $$ \frac{10 * 10^{18} - x_{in}}{y_{out}} = \frac{100 * 10^{18} + x_{in}}{10000 * 10^{18} - y_{out}} \tag{7} $$ 约去$10^{18}$: $$ \frac{10 - x_{in}}{y_{out}} = \frac{100 + x_{in}}{10000 - y_{out}} $$ $$ y_{out} = \frac{100000 - 10000 * x_{in}}{110} \tag{8} $$ 代入公式(1): $$ \frac {997 \cdot x_{in} \cdot y_0}{1000 \cdot x_0 + 997 \cdot x_{in}} = \frac{100000 - 10000 * x_{in}}{110} \tag{9} $$ 由于 $x_0 = 100 * 10^{18}$,$y_0 = 10000 * 10^{18}$,因此: $$ \frac{997 * x_{in}}{100000 + 997 * x_{in}} = \frac{10 - x_{in}}{110} \tag{10} $$ 解方程即可得: $$ x_{in}=4.8882173994193545 \tag{11} $$ 因此,用户需要将约4.89ETH兑换为token,然后组成LP提供流动性。