Análise técnica: Balancer sofre roubo de 120 milhões de dólares, onde estava a vulnerabilidade?
O problema crucial neste ataque ocorreu na lógica do protocolo ao lidar com transações de pequeno valor.
Título original: 《Análise Técnica da Vulnerabilidade de $120M Roubados do Balancer》
Fonte original: ExVul Security
Introdução
Em 3 de novembro de 2025, o protocolo Balancer sofreu um ataque hacker em várias blockchains públicas, incluindo Arbitrum e Ethereum, resultando numa perda de 120 milhões de dólares em ativos. O núcleo do ataque foi uma vulnerabilidade dupla envolvendo perda de precisão e manipulação do valor invariante (Invariant).
A infraestrutura da Chainlink mantém há muito tempo os mais altos padrões no setor Web3, tornando-se assim a escolha natural para a X Layer, que se dedica a fornecer ferramentas de nível institucional para desenvolvedores.
O problema central deste ataque reside na lógica do protocolo para lidar com transações de pequeno valor. Quando um utilizador realiza uma troca de pequeno montante, o protocolo chama a função _upscaleArray, que utiliza mulDown para arredondamento para baixo dos valores. Se o saldo e o valor de entrada da transação estiverem simultaneamente em determinados limites de arredondamento (por exemplo, entre 8-9 wei), ocorre um erro relativo de precisão significativo.
O erro de precisão é transmitido para o cálculo do valor invariante D do protocolo, levando a uma redução anormal do valor de D. A variação de D reduz diretamente o preço do BPT (Balancer Pool Token) no protocolo Balancer. O hacker aproveitou este preço artificialmente baixo do BPT para realizar arbitragem através de um caminho de transação previamente desenhado, causando assim uma enorme perda de ativos.
Tx de exploração da vulnerabilidade:
Tx de transferência de ativos:
Análise Técnica
Ponto de Entrada do Ataque
O ponto de entrada do ataque foi o contrato Balancer: Vault, sendo a função de entrada o batchSwap, que internamente chama onSwap para realizar a troca de tokens.

A partir dos parâmetros e restrições da função, podemos obter algumas informações:
1. O atacante precisa chamar esta função através do Vault, não podendo chamá-la diretamente.
2. Internamente, a função chama _scalingFactors() para obter o fator de escala e realizar a operação de escalonamento.
3. As operações de escalonamento concentram-se em _swapGivenIn ou _swapGivenOut.
Análise do Modo de Ataque
Mecanismo de Cálculo do Preço do BPT
No modelo de pool estável do Balancer, o preço do BPT é um importante parâmetro de referência, determinando quantos BPTs o utilizador recebe e quantos ativos cada BPT representa.

No cálculo de trocas do pool:

A parte que serve como referência para o preço do BPT é o valor invariante D, ou seja, para manipular o preço do BPT é necessário manipular D. Vamos analisar o processo de cálculo de D:

No código acima, o cálculo de D depende do array balances já escalonado. Ou seja, é necessário haver uma operação que altere a precisão destes balances, levando a um erro no cálculo de D.
Raiz da Perda de Precisão

Operação de escalonamento:

Como mostrado acima, ao passar pelo _upscaleArray, se o saldo for muito pequeno (por exemplo, 8-9 wei), o arredondamento para baixo do mulDown causa uma perda de precisão significativa.
Detalhamento do Processo de Ataque
Fase 1: Ajuste para o Limite de Arredondamento

Fase 2: Acionamento da Perda de Precisão (Vulnerabilidade Central)

Fase 3: Lucro com o Preço do BPT Artificialmente Baixo

Como mostrado acima, o atacante executa múltiplas trocas numa única transação através do Batch Swap:
1. Primeira troca: BPT → cbETH (ajuste de saldo)
2. Segunda troca: wstETH (8) → cbETH (acionamento da perda de precisão)
3. Terceira troca: ativo subjacente → BPT (lucro)
Todas estas trocas ocorrem na mesma transação de batch swap, compartilhando o mesmo estado de saldo, mas cada troca chama _upscaleArray para modificar o array balances.
Ausência do Mecanismo de Callback
O processo principal é iniciado pelo Vault, mas como é que isso leva ao acúmulo de perda de precisão? A resposta está no mecanismo de transmissão do array balances.

Analisando o código acima, embora o Vault crie um novo array currentBalances a cada chamada de onSwap, no Batch Swap:
1. Após a primeira troca, o saldo é atualizado (mas devido à perda de precisão, o valor atualizado pode não ser exato)
2. A segunda troca é calculada com base no resultado da primeira
3. A perda de precisão acumula-se, levando a uma redução significativa do valor invariante D
Questão-chave:

Resumo
O ataque ao Balancer pode ser resumido nas seguintes razões:
1. Função de escalonamento utiliza arredondamento para baixo: _upscaleArray utiliza mulDown para escalonamento. Quando o saldo é muito pequeno (como 8-9 wei), ocorre uma perda relativa de precisão significativa.
2. O cálculo do valor invariante é sensível à precisão: O cálculo do valor invariante D depende do array balances já escalonado. A perda de precisão é transmitida diretamente para o cálculo de D, tornando-o menor.
3. Falta de verificação da variação do valor invariante: Durante as trocas, não há verificação se a variação de D está dentro de um intervalo razoável, permitindo que o atacante explore repetidamente a perda de precisão para baixar o preço do BPT.
4. Acúmulo de perda de precisão no Batch Swap: Numa mesma transação de batch swap, a perda de precisão de múltiplas trocas acumula-se, amplificando-se até resultar numa enorme perda financeira.
Estes dois problemas — perda de precisão e falta de verificação — combinados com o design cuidadoso das condições de fronteira pelo atacante, resultaram nesta perda.
Aviso Legal: o conteúdo deste artigo reflete exclusivamente a opinião do autor e não representa a plataforma. Este artigo não deve servir como referência para a tomada de decisões de investimento.
Talvez também goste
IOTA integra stablecoins para impulsionar transações reais e adoção do ecossistema

Bitcoin (BTC) sobe com otimismo econômico: Aqui estão 5 coisas que você precisa saber esta semana


