Preliminary Analysis of the Balancer V2 Attack Incident

On November 3rd, the Balancer V2 protocol and its fork projects were attacked on multiple chains, resulting in severe losses exceeding $120M. BlockSec issued an early warning on [1] and provided an initial analysis conclusion [2]. This is a highly complex attack incident. Our preliminary analysis indicates that the root cause lies in the attacker manipulating the invariant, thereby distorting the price calculation of BPT (Balancer Pool Token ) – which is the LP token of the pool) to profit from a single batchSwap operation in a certain stable pool.

Background Knowledge

1. Scaling and Rounding

To unify the decimal places of different tokens, the Balancer contract will:

  • upscale: Scale the balance and amount to a unified internal precision before calculation;
  • downscale: Scale the results back to native precision and perform directional rounding (for example, the input side usually rounds up to ensure the pool does not lose collection; the output path often has truncation downwards).

Conclusion: In the same transaction, the asymmetry in the rounding direction used in different stages can lead to systemic small deviations when executed repeatedly in very small increments.

2. D and BPT price

The Balancer V2 protocol's Composable Stable Pool [3] and the forked protocols are affected by this attack. The Stable Pool is used for assets that are expected to maintain a close to 1:1 exchange ratio (or are exchanged at known rates), allowing for large exchanges without causing significant price impacts, thus greatly enhancing the capital efficiency between similar or related assets.

  • This pool uses Stable Math (based on Curve's StableSwap model), where the invariant D represents the “virtual total value” of the pool.
  • BPT (Pool's LP Token) price is approximately:

From the above formula, it can be seen that if D can be made smaller on the books (even if the funds have not actually been lost), the price of BPT can be cheaper. BTP represents the share of the Pool and is used to calculate how much Reserve from the Pool can be obtained when withdrawing liquidity. Therefore, if an attacker can obtain more BPT, they will profit when they finally withdraw liquidity.

Attack Analysis

Taking an attack transaction on Arbitrum as an example, the batchSwap operation can be divided into three stages:

Phase One: The attacker exchanges BP for underlying assets, precisely adjusting the balance of one of the tokens (cbETH) to the rounding boundary threshold (amount = 9). This step creates conditions for precision loss in the next phase.

Phase Two: The attacker uses a carefully constructed amount (= 8) to swap between another underlying asset (wstETH) and cbETH. Due to rounding down when scaling the token quantity, the calculated Δx is slightly smaller (from 8.918 to 8), which leads to an underestimation of Δy and causes the invariant D (derived from Curve's StableSwap model) to decrease. Since BPT price = D / totalSupply, the BPT price is artificially depressed.

Phase 3: The attacker reverses the underlying assets back to BP, profiting from the depressed BP price while restoring balance in the pool – obtaining more BP Tokens.

Finally, the attacker used another profitable transaction to withdraw liquidity, thus profiting from the additional BPT obtained from the other underlying assets in the Pool, (cbETH and wstETH).

Attack transaction:

Profitable trading:

Reference:

[1]

[2]

[3]

BPT2.92%
View Original
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
  • Reward
  • Comment
  • Repost
  • Share
Comment
0/400
No comments
  • Pin

Trade Crypto Anywhere Anytime
qrCode
Scan to download Gate App
Community
English
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)