UniSwap 公式推导

公式

以下公式推演参考自 这里,不过本文剔除了一些乱七八糟的东西,精简了一部分推导过程

交易

投入指定数量的 A 代币应该得到多少个 B 代币

我们以 $x$ 和 $y$ 分别代表参与兑换的两种代币的池子储存量,当没有手续费的时候,有:

由于已知的条件保证了:

整理上面三个式子后,有:

如果 $f$ 代表手续费,那么 $y_1$ 就不一样了,设 $y_1’$ 为修正后的 $y_1$ :

而我们要关心的 $\Delta y$ 根据上式表达出来就是:

目前手续费 $f=0.003$ 代入计算有:

得出的这个公式和 源码 里写的是一样的。

想得到指定数量的 B 代币需要投入多少个 A 代币

跟上面的情况一样,只是整理出的式子需要变一下:

有:

但是要考虑到手续费的话,真正需要投入的 A 代币就应该满足:

源码 写的公式基本一致,唯一不一样的地方是源码在最后的结果又 add(1) ,这个是为了防止算出来的 A 代币数值小于 1,导致手续费抽不出来,所以至少得付 1 个 B 代币(_这里提到的代币数量都是精度放大后的值_)。

铸币 UNI-V2

这里以注入流动性而铸币举例,根据 源码 可知,注入流动性的双方都是等比注入的,再加上 这里 铸币的逻辑可知铸币也同样是等比铸币的。以 s 表示 UNI-V2 的当前总储存量,那么就有:

设 $k=xy$ 接着就有:

那么:

以上各式累乘后有:

而根据 源码 可知 $s_0=\sqrt{k_0}$ ,变换并代入后:

那么通用地,很容易得出,在任意两个时刻 $i$ 和 $j$ 之间累计的手续费公式为:

然而现在 UniSwap 项目方没有打开收费开关,当开启收费后为了不影响现有持股人利益,必须按当前的持币比例增发对应数量的 UNI-V2 。如果开关打开后,设应该对 UniSwap 项目方增发的 UNI-V2 数量为 $\Delta s$ ,项目方准备收取手续费里的比例为 $F$ (当前这个版本这个 $F=1/6$),那么就必须要满足:

表示成 $\Delta s$ ,并代入 $F=1/6$ 有:

这个公式跟 源码 也是一致的。

好了,几个有代表性的公式就是这么推导出来的了,大家也不用害怕闷头抄代码心里不踏实了,项目方也可以安心出去骗钱了。

UPDATE

源码 里有一处我觉得应该是个 bug 的地方,下图那行里面传的参数应该是 balance0balance1 才对:

目前暂时不会对所有人造成影响,后续唯一会影响的是 UniSwap 项目方,因为即便某一天他们打开收费开关,因为这个 bug,他们也应该是收不到每笔交易里的 .05% 手续费的。

经过万圈朋友指点,这里没有 bug,swap 函数会更新储存量的,只有当连续发生两次注入流动性的时候才会复现这个问题,算是一个小瑕疵,不影响大局