基于此攻击笔者也在DubheCTF出了一个相关的区块链CTF题目。 https://github.com/haoami/Ezswap-DubheCTF
uniswap v3
- 代码 https://github.com/Uniswap/v3-core
- 学习资料 https://hackmd.io/@adshao/SJT0-bVz9#Uniswap-v3-core
- 简介 https://y1cunhui.github.io/uniswapV3-book-zh-cn/docs/introduction/uniswap-v3/
- 白皮书 https://mirror.xyz/adshao.eth/tgZjDXOtL999iuPjXWrolR7Ns1nTZDADA6NLJaJpJJM
简介
数学原理
参考https://www.odaily.news/post/5174767
在数学原理上,V3 是基于 V2 的:它们使用了相同的底层公式,但实际上 V3 使用的是_增强版_。
L 被称作 流动性数量。池子中的流动性是两种 token 资产数量的组合。我们知道,按照公式,两种代币数量乘积为 k,因此我们可以用 来衡量池子流动性。实际上是 x 和 y 的几何平均数。
y/x 是 token0 相对于 token1 的价格。由于池子里两种代币的价格互为倒数,我们在计算中仅使用其中一个( Uniswap V3使用的是 y/x)。token1 相对于 token0 的价格即为 。类似地, .

价格

ticks

详情看推荐资料
攻击分析
详细分析参照 https://mp.weixin.qq.com/s/PkUqaJKlJFHsvRot1ij4qg?ref=www.ctfiot.com
漏洞原理
先说说kyerbswap 的一些特点:
- 一是由于kyberswap本身是二开的uniswap v3合约,所以大多数的逻辑都是相似的,但是kyberswap 算是众多fork univ3合约中改动较大的一版,将bitmap索引tick改为了双向链表索引,这样更加的节省gas以及方便查找。
- 二是kyberswap新增了手续费复投的概念,在每次swap的时候都会将用户的手续费复投到池子中,并参与swap过程。在数学原理上,kyber通过一系列数学魔法,把本身的swap兑换曲线和reinvest的概念合并到了一条新的曲线上。
一个简单的swap计算过程。
所以漏洞原理就出在复投之后的tick的计算上,在利用computeSwapStep计算出在这个区间的流动性所支持兑换的token数量后,会进行判断是否跨tick了,如果没有就直接计算currentTick,结束本次循环。
而在computeSwapStep存在着两次计算,第一次是计算当前区间流动性可以被使用的token数量,第二次是考虑了加入再投资流动性之后计算出来的价格。
所以在某种精确计算的情况下,可以找出一个精准的区间和流动性来使calcReachAmount计算出来的数量大于我们要兑换的数量,这样可以让系统认为我们并没有cross tick。但在最终调用calcReachAmount计算出最终价格的时候却已经是下一个区间的价格,从而在执行swapData.currentTick = TickMath.getTickAtSqrtRatio(swapData.sqrtP);的时候currentTick也成了区间上界tick或者下界tick。而系统认为我们并没有cross tick但实际上已经cross tick所以流动性本该减去却没有改变,当我们再反向swap时候流动性又会增加,导致流动性翻倍。