多个 V2 Boost 池的严重漏洞报告Balancer漏洞分析

    Balancer官方发布公告表示收到影响多个V2Boost池的严重漏洞报告,只有1.4%的TVL受影响,多个池子已暂停,并通知用户尽快提取流动性LP。慢雾MistEye系统发现疑似Balancer漏洞被利用的攻击交易。由于池子无法暂停,一部分资金仍然受到攻击的影响,Balancer官方再次提醒用户将受影响池子中的LP取回。随后,Balancer官方于Medium发布了8月披露的漏洞细节,慢雾安全团队对其进行复盘,详情如下:Balancer漏洞分析Balancer官方在其披露中简单指出此次的问题在于,线性池的向下舍入以及可组合池的虚拟供应量导致bptSupply为0。首先让我们来简单了解一下与这次漏洞相关的Balancer协议中的内容。BalancerV2VaultBalancerV2[6]协议是一种基于以太坊的去中心化自动做市商(AMM)协议,它代表了可编程流动性的灵活构建块。其核心组件是Vault合约,该合约维护着所有池子的记录,并管理代币的记账和转移,甚至包括原生ETH的包装和解包。也就是说,Vault的实现是将代币记账和管理与池子逻辑分开。Vault中有四个接口,分别是joinPool,exitPool,swap和batchSwap(加入、退出和交换是分开的调用,不存在单次调用时的组合)。其中一个突出的特点是batchSwap,它能实现多个池子之间多次原子交换,将一个池子交换的输出与另一个池子的输入相连(GiveIn和GiveOut)。该系统还引入了闪电交换[7],类似于一个内部的闪电贷。LinearPools线性池Balancer为了提高LP的资本效率及warp和unwarp高额开销的问题,在V2中推出线性池作为解决方案,由此引入了BPT(ERC20BalancerPoolToken)代币。

    线性池[8]包含maintoken(底层资产),warppedtoken(包装代币)和BPT代币,通过已知汇率交换资产及其包装的、具有收益的对应物。包装代币的比例越高,收益率和资金池的资本效率就越高。在warp的过程中,通常都会通过缩放因子来确保不同代币以相同的精度进行计算。ComposablePools可组合池所有的Balancer池都是可组合池,池子包含其他代币,池子本身也有自己的代币。其中BPT币指的是ERC20平衡池代币,是所有池的基础。用户可以在其他池内使用BPT代币自由组合进行兑换。兑换总是涉及一个池和两个代币:GiveIn和GiveOut。In代表送入成分代币并接收BPT,而Out意味着送入BPT并接收成分代币。如果BPT本身就是成分代币,它就可以像其他代币一样进行交换。这样的实现构成了外部池中的基础资产和代币之间的一个简单batchSwap路径,用户可以用BPT交换到线性池的底层资产,这也是BalancerBoostedPool[9]的基础。通过以上的组合,Balancer的可组合池就形成了。一个bb-a-USD可组合稳定池由三个线性池组成,同时向外部协议(Aave)发送闲置流动性。

    例如,bb-a-DAI是一个包含DAI和waDAI(包装的aDAI)的线性池。当用户需要进行batchSwap时(如要将USDT换成DAI),交换路径举例如下:简单了解过前置知识后,我们进入漏洞分析环节。USDT线性池:将USDT兑换bb-a-USDT(进入USDT线性池)。bb-a-USD:bb-a-USDT兑换bb-a-DAI(线性BPT之间的交换)。DAI线性池:bb-a-DAI兑换为DAI(退出DAI线性池)。Balancer漏洞分析在8月27号时,慢雾安全团队收到MistEye系统识别,一笔疑似Balancer漏洞的在野利用发生。交易如下:攻击者首先从AAVE通过闪电贷借出300,000枚USDC。接着调用Vault的batchSwap操作,通过可组合稳定池bb-a-USD池进行BPT代币的兑换计算,最终将94,508枚USDC兑换为59,964枚bb-a-USDC,68,201枚bb-a-DAI和74,280枚bb-a-USDT。最后将获得的BPT代币通过Vault合约的exitPool退出池子换取底层资产,偿还闪电贷,并获利约108,843.7美元离场。由此可见,这次攻击的关键在batchSwap里,而batchSwap中具体发生了什么呢?我们深入了解一下。攻击者在整个batchSwap过程中,先在bb-a-USDC池中兑换出USDC,接着进行BPT代币间的兑换,将bb-a-USDC兑换为bb-a-DAI,bb-a-USDT和USDC。

    最后再将底层的main代币USDC兑换为bb-a-USDT。也就是说,bb-a-USDC作为关键的BPT代币充当GiveOut和GiveIn的成分代币。攻击者在第一步以固定的缩放因子在bb-a-USDC线性池中用BPT代币兑换出USDCmain代币,其增加的数量记录在池子中的bptBalance中。但是在第二次onSwap的兑换后,我们发现,同样的兑换过程,兑换出USDC的amountOut值却是0。这是为什么呢?深入onSwap函数,我们发现在这个过程中会先做一次精度处理nominal化并计算出对应代币的缩放因子。而在接下来调用_downscaleDown函数时,amountOut存在向下舍入的情况。如果amountOut和scalingFactors[indexOut]之间的值相差很大,计算出的_downscaleDown值就为零。也就是说当我们使用BPT代币来兑换main代币时,如果amountOut过小,返回值将向下舍入为零,且这个值就是小于由scalingFactors所计算来的1e12。但amountIn进来的bb-a-USDC数量仍然会加入到bptBalance虚拟数量当中,而此操作会增加bb-a-USDC池子中的余额,可以将其看作为单边添加bb-a-USDC流动性。接着利用可组合稳定池的特性,通过BPT代币之间的相互转换,首先将bb-a-USDC兑换为其他BPT代币。跟进这个兑换过程,可组合稳定池的以下调用路径bb-a-DAIonSwap->_swapGivenIn->_onSwapGivenIn先将bb-a-USDC依次换成bb-a-DAI和bb-a-USDT。

    与在线性池中不同的是,可组合稳定池在进行onSwap操作之前需要进行汇率的缓存更新。从代码中我们可以看到,在组合池中,onSwap会先判断是否需要更新缓存的token兑换率。经过之前的兑换,bb-a-USDC的数量发生了改变,并通过_toNominal名义化后的真实总量为totalBalance994,010,000,000,虚拟供应的BPT代币为20,000,000,000。可以计算出,更新后的汇率几乎是之前线性池原始缓存兑换率1,100,443,876,587,504,549的45倍,即49,700,500,000,000,000,000。随后,在线性池中将bb-a-USDC兑换为USDC。然而这一次的兑换同第二次的兑换一样,再一次造成amountOut向下舍入为0的情况,兑换路径和之前相同。而接下来的这一次兑换则是反向将USDC兑换成bb-a-USDC,兑换路径为onSwap->onSwapGivenIn->_swapGivenMainIn。在这个过程中,我们发现,在计算需要兑换的amountOut的时候,其中对于虚拟供应量的计算,是基于兑换后的BPT代币totalsupply与池中剩余量之间的差值,该差值为0。这是因为bptSupply为0,在计算BPTOut时直接通过调用_toNominal函数,而此路径的调用使得USDC兑bb-a-USDC的兑换比例接近1:1。严重漏洞报告总结batchSwap通过多个池子之间多次原子交换,将一个池子交换的输出与另一个池子的输入相连(tokenIn和tokenOut),将USDC兑换为BPT代币。在这个batchSwap中并不会发生实际代币转移,而是通过记录转入和转出的数量来确认最后的兑换数量。又因为线性池是通过底层资产代币进行兑换的,兑换方式是通过一个虚拟供应量且是固定的算法计算出Rate。因此,batchSwap中存在两个安全漏洞,可以发现,漏洞一为兑换增加了兑换率,而反向兑换时漏洞二再反向降低兑换率,攻击者利用了双重buff获利离场。一是线性池的向下舍入问题,攻击者通过舍入为池子单边添加main代币提高缓存代币的比率,从而操纵相应可组合池中的代币兑换率;二是由于可组合池的虚拟供应量特性,虚拟供应量通过BPT代币减去池子中的余额来计算,在兑换的时候如果GiveIn是BPT代币,那么之后的供应量就会扣掉这部分,攻击者只需要将BPT作为GiveIn来进行兑换,并将其供应量先操纵为0,之后进行反向swap,即BPT再作为GiveOut一方,这时候由于供应量是0,算法会按照接近1:1的比例低于线性池的兑换比例来进行实际兑换,使得GiveOut的BPT代币数量间接被操控。

Pixel Artist Pixel Artist
Happy Kittens Puzzle Happy Kittens Puzzle
Penguin Cafe Penguin Cafe
Animal Connection Animal Connection
Snakes N Ladders Snakes N Ladders
Pixel Skate Pixel Skate
BeeLine BeeLine
Draw Parking Draw Parking
Draw Racing Draw Racing
Soccer Balls Soccer Balls
Happy Fishing Happy Fishing
Crashy Cat Crashy Cat

FREE GAMES FOR KIDS ONLINE