20251103的Balancer攻击,是batchSwap还是价格操纵导致精度丢失?
摘要:攻击背景介绍 2025.11.03,Balancer V2 的 可组合稳定池(Composable Stable Pools)遭到了黑客攻击,攻击者首先通过 batchSwap 操作用 BPT 兑换出大量 WETH 和 osETH(大幅度移
攻击背景介绍
2025.11.03,Balancer V2 的 可组合稳定池(Composable Stable Pools)遭到了黑客攻击,攻击者首先通过 batchSwap 操作用 BPT 兑换出大量 WETH 和 osETH(大幅度移除 Pool 中的流动性),然后通过精度丢失问题减少 Pool 中 WETH 和 osETH 的余额(抬高其兑换 BPT 的比例),最后将高价的 WETH 和 osETH 兑换回 BPT 以平衡 batchSwap 的资产,获利高达 1.2 亿美元(包括其他 fork 项目)。
官方公告:
https://x.com/Balancer/status/1985390307245244573
https://x.com/Balancer/status/1986104426667401241
攻击交易:
TX1(Exploit):https://app.blocksec.com/explorer/tx/eth/0x6ed07db1a9fe5c0794d44cd36081d6a6df103fab868cdd75d581e3bd23bc9742
TX2(Claim):https://app.blocksec.com/explorer/tx/eth/0xd155207261712c35fa3d472ed1e51bfcd816e616dd4f517fa5959836f5b48569
相关合约:
Vault:https://etherscan.io/address/0xba12222222228d8ba445958a75a0704d566bf2c8
osETH/wETH-BPT(ComposableStablePool):https://etherscan.io/address/0xdacf5fa19b1f720111609043ac67a9818262850c
项目背景介绍
遭受攻击的其中一个 ComposableStablePool 是 osETH/wETH-BPT。
osETH/wETH-BPT 的相关信息如下:
PoolId: 0xdacf5fa19b1f720111609043ac67a9818262850c000000000000000000000635
token: [WETH, osETH/wETH-BPT, osETH]
balance:
WETH: 4922356564867078856521
osETH/wETH-BPT: 2596148429267421974637745197985291
osETH: 6851581236039298760900
ScalingFactors:
1000000000000000000
1000000000000000000
1058109553424427048
osETH/wETH-BPT 同时也是这个 Pool 的 LP Token,因为采用了 Composable 设计,它本身也被当作池内资产,从而可以被其他池子、vault、协议当作“普通 ERC20”来使用。
在这个具体的 osETH/wETH 池子里,osETH/wETH-BPT 的实际作用
代表你在这个 osETH ↔ WETH 稳定池中的流动性份额
你加流动性得到的 LP 就是这个 BPT。
支持“swap 即 join/exit”(代码里最核心的逻辑)
用 WETH swap 成 BPT → 等价于单边加入流动性(joinSwap)
用 BPT swap 成 WETH → 等价于单边退出流动性(exitSwap)
Trace 分析
黑客在 TX1 中攻击了两个 Pool,攻击手法相同,所以这里选择第一个 osETH/wETH-BPT 进行分析。
Phase1
攻击者通过 batchSwap 用 osETH/wETH-BPT 多次换出 WETH 和 osETH 代币,大幅降低 Pool 中的流动性。
在 batchSwap 中,用户可以在先不提供 Token 的情况下执行批量操作,在批量操作结束后统一结算所需要的代币。
每笔兑换采用了 GIVEN_OUT 的形式,的数量如下表所示。每次兑换的 amountOut 都约为 balance 的 99%,直到这两种代币在 Pool 中的余额为 67000 。
为什么要进行多次 swap 操作
黑客为什么要进行多次 swap 操作,而不是一次性把所需要的代币数量都 swap 出来?
编写了一个测试脚本尝试了一下,其中 amount = 4922356564867078789521,是黑客所有 swap 操作的 amountOut 总和。
