区块链NFT投资,BTC/USDT/CGPAY,虚拟加密货币交易行情分析平台
多个 V2 Boost 池的严重漏洞报告Balancer漏洞分析
Balancer 官方发布公告表示收到影响多个 V2 Boost 池的严重漏洞报告,只有 1.4% 的 TVL 受影响,多个池子已暂停,并通知用户尽快提取流动性 LP。慢雾 MistEye 系统发现疑似 Balancer 漏洞被利用的攻击交易。由于池子无法暂停,一部分资金仍然受到攻击的影响,Balancer 官方再次提醒用户将受影响池子中的 LP 取回。随后,Balancer 官方于 Medium 发布了 8 月披露的漏洞细节,慢雾安全团队对其进行复盘,详情如下:
Balancer漏洞分析
Balancer 官方在其披露中简单指出此次的问题在于,线性池的向下舍入以及可组合池的虚拟供应量导致 bptSupply 为 0。首先让我们来简单了解一下与这次漏洞相关的 Balancer 协议中的内容。
Balancer V2 Vault
Balancer V2 [6] 协议是一种基于以太坊的去中心化自动做市商(AMM)协议,它代表了可编程流动性的灵活构建块。其核心组件是 Vault 合约,该合约维护着所有池子的记录,并管理代币的记账和转移,甚至包括原生 ETH 的包装和解包。也就是说,Vault 的实现是将代币记账和管理与池子逻辑分开。
Vault 中有四个接口,分别是 joinPool, exitPool, swap 和 batchSwap(加入、退出和交换是分开的调用,不存在单次调用时的组合)。其中一个突出的特点是 batchSwap,它能实现多个池子之间多次原子交换,将一个池子交换的输出与另一个池子的输入相连(GiveIn 和 GiveOut)。该系统还引入了闪电交换 [7],类似于一个内部的闪电贷。
Linear Pools 线性池
Balancer 为了提高 LP 的资本效率及 warp 和 unwarp 高额开销的问题,在 V2 中推出线性池作为解决方案,由此引入了 BPT (ERC20 Balancer Pool Token) 代币。
线性池 [8] 包含 main token(底层资产),warpped token(包装代币)和 BPT 代币,通过已知汇率交换资产及其包装的、具有收益的对应物。包装代币的比例越高,收益率和资金池的资本效率就越高。在 warp 的过程中,通常都会通过缩放因子来确保不同代币以相同的精度进行计算。
Composable Pools 可组合池
所有的 Balancer 池都是可组合池,池子包含其他代币,池子本身也有自己的代币。其中 BPT 币指的是 ERC20 平衡池代币,是所有池的基础。用户可以在其他池内使用 BPT 代币自由组合进行兑换。兑换总是涉及一个池和两个代币:GiveIn 和 GiveOut。In 代表送入成分代币并接收 BPT,而 Out 意味着送入 BPT 并接收成分代币。如果 BPT 本身就是成分代币,它就可以像其他代币一样进行交换。这样的实现构成了外部池中的基础资产和代币之间的一个简单 batchSwap 路径,用户可以用 BPT 交换到线性池的底层资产,这也是 Balancer Boosted Pool [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 代币兑换出 USDC main代币,其增加的数量记录在池子中的 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-DAI onSwap -> _swapGivenIn -> _onSwapGivenIn 先将 bb-a-USDC 依次换成 bb-a-DAI 和 bb-a-USDT。与在线性池中不同的是,可组合稳定池在进行 onSwap 操作之前需要进行汇率的缓存更新。从代码中我们可以看到,在组合池中,onSwap 会先判断是否需要更新缓存的 token 兑换率。
经过之前的兑换,bb-a-USDC 的数量发生了改变,并通过 _toNominal 名义化后的真实总量为 totalBalance 994,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,在计算 BPT Out 时直接通过调用 _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 代币数量间接被操控。
相关文章
- 日本交易所Bitflyer注册充值教程9个步骤完成,Bitf...
- 比特币交易基础教程(比特币老鸟对新人的忠告)
- 2024主流数字货币钱包大全,比特币钱包、数字货币...
- 2024全球十大数字货币交易所排名 (中文)
- 币安Binance交易所-比特币购买教程-币安买币教程
- 购宝钱包轻松4步骤完成购买币,购宝功能教程图文详解
- 当下我们是否需要掌握区块链技术?
- 区块链的四大特征
- 虚拟货币投资交易不受法律保护
- 区块链是否会带来一场技术变革?
- 理解信息的意义与掌握信息有多重要?
- 区块链所解决的问题及其应用场景
- 如何利用 AI 和 NFT 制定数字营销策略?
- 区块链如何辅助医疗数字化?
- 比特币钱包有哪几种类型?
- 什么是DeFi中的机枪池?
- 波币短线交易全攻略:如何在波币市场中获利掌握市...
- 夜间指定电子钱包USDT入款获奖金16,888
- EcoChain碳负货币引领绿色金融的未来
- 绿色地球碳负货币EcoChain的区块链技术与环保的完...
- 马斯克与加密货币的影响力与市场波动的交织幕后推手
- 电子钱包新手小白首次存款即享38元加码优惠
- 4种XRP替代品:如何在10周内将100美元的投资组合变...
- InSoBlokAI:人工智能与Web3区块链的完美结合
- 2025如何在波动的加密市场中稳赚不赔?专家分享获...
- 金蛇狂舞2025:赢取88,888元红包,电子钱包积分争...
- 2025年金蛇狂舞系列活动:春节热门钱包火箭十万豪...
- 365钱包15种常见问题解答FAQ
- 365钱包数字支付的全方位解决方案,线上游戏支付跨...
- 365钱包社交与成功共筑财富之路
- 365钱包的虚拟货币投资策略
- Pengu代币空投计划发市场热潮,NFT收藏品胖企鹅超...