Back to Blog

Инцидент с Balancer V2 №3: несоответствие округления нарушает инвариант и распространяется по сетям

Code Auditing
10 февраля 2026 г.
5 min read

#3 Инцидент с Balancer V2: несоответствие округления нарушает инвариант и распространяется по цепочкам

3 ноября 2025 года пулы Composable Stable Pools протокола Balancer V2, а также ряд форк-проектов в нескольких сетях подверглись скоординированной атаке, результатом которой стали совокупные потери на сумму более $125 миллионов, из которых, по имеющимся данным, около $45 миллионов удалось вернуть. Первопричиной стала манипуляция ценой, вызванная потерей точности при расчете инварианта, что стало следствием несоответствия округления между операциями масштабирования вверх и вниз, исказившими логику ценообразования BPT (токена пула Balancer).

Этот инцидент выделяется как один из десяти крупнейших инцидентов безопасности 2025 года не только из-за масштаба потерь, но и из-за сложности самой уязвимости. Более того, эксплойт быстро распространился по нескольким сетям, затронув как Balancer, так и его форки, что подчеркивает, как общие кодовые базы и компонуемая DeFi-инфраструктура могут значительно усиливать системные риски.

Мы опубликовали подробный отчет «Глубокий анализ: эксплойт Balancer V2» [1], который содержит детальный технический разбор. Ниже представлено краткое описание инцидента.

Предыстория

Composable Stable Pool в Balancer V2

Затронутым компонентом в этой атаке стал Composable Stable Pool [2] протокола Balancer V2. Эти пулы предназначены для активов, которые, как ожидается, поддерживают паритет 1:1 (или торгуются по известному курсу обмена), и позволяют совершать крупные свопы с минимальным влиянием на цену, тем самым значительно повышая эффективность капитала для аналогичных или коррелирующих активов. Каждый пул имеет свой токен Balancer Pool Token (BPT), представляющий долю поставщика ликвидности в пуле, наряду с соответствующими базовыми активами.

  • Этот пул использует Stable Math (основанную на модели Curve StableSwap), где инвариант D представляет собой виртуальную общую стоимость пула.

  • Цена BPT может быть аппроксимирована следующим образом:

Цена(BPT)Dобщий_объем_предложенияЦена(BPT) \approx \frac{D}{общий\_объем\_предложения}

Исходя из приведенной выше формулы, если D можно сделать меньше «на бумаге» (даже без фактической потери средств), цена BPT будет казаться ниже.

batchSwap() и onSwap()

Balancer V2 предоставляет функцию batchSwap(), которая позволяет выполнять многоходовые свопы внутри Vault [3]. Существует два типа свопов, определяемых параметром, передаваемым в эту функцию:

  • GIVEN_IN («С заданным входом»): вызывающая сторона указывает точное количество входного токена, а пул вычисляет соответствующее выходное количество.
  • GIVEN_OUT («С заданным выходом»): вызывающая сторона указывает желаемое выходное количество, а пул вычисляет необходимое входное количество.

Обычно batchSwap() состоит из нескольких свопов «токен-в-токен», выполняемых через функцию onSwap(). Этот процесс неизбежно включает вычисления сумм, привязанные к инварианту D [1].

Масштабирование и округление

Для нормализации вычислений между различными балансами токенов Balancer выполняет две следующие операции:

  • Масштабирование вверх (Upscaling): масштабирование балансов и сумм до единой внутренней точности перед выполнением вычислений.
  • Масштабирование вниз (Downscaling): преобразование результатов обратно к их исходной точности с применением направленного округления (например, входные суммы обычно округляются вверх, чтобы избежать недоплаты в сторону пула, в то время как выходные суммы часто округляются вниз).

Теоретически масштабирование вверх и вниз — это парные операции: умножение и деление соответственно. Однако в реализации этих двух операций существует несоответствие. В частности, операция масштабирования вниз имеет два варианта или направления: divUp и divDown. Напротив, операция масштабирования вверх имеет только одно направление, а именно mulDown.

Анализ уязвимости

Фундаментальная проблема возникает из операции округления вниз, выполняемой во время масштабирования вверх в функции BaseGeneralPool._swapGivenOut(). В частности, _swapGivenOut() некорректно округляет вниз swapRequest.amount через функцию _upscale(). Полученное округленное значение впоследствии используется как amountOut при расчете amountIn через _onSwapGivenOut(). Это поведение противоречит стандартной практике, согласно которой округление должно применяться таким образом, чтобы это было выгодно протоколу.

Таким образом, для заданного пула (wstETH/rETH/cbETH) вычисленное значение amountIn недооценивает фактически требуемый вход. Это позволяет пользователю обменять меньшее количество одного базового актива (например, wstETH) на другой (например, cbETH), тем самым уменьшая инвариант D в результате снижения эффективной ликвидности. Следовательно, цена соответствующего BPT (wstETH/rETH/cbETH) становится заниженной, так как цена BPT = D / общий объем предложения.

Анализ атаки

Злоумышленник провел двухэтапную атаку, вероятно, чтобы минимизировать риск обнаружения:

  • На первом этапе основной эксплойт был выполнен в рамках одной транзакции, не принесшей немедленной прибыли.
  • На втором этапе злоумышленник реализовал прибыль, выведя активы в отдельной транзакции.

Первый этап можно дополнительно разделить на две фазы: расчет параметров и пакетный своп. Ниже мы проиллюстрируем эти фазы на примере транзакции атаки (TX) в сети Arbitrum.

Фаза расчета параметров

На этой фазе злоумышленник объединил вычисления вне сети с симуляциями внутри сети, чтобы точно настроить параметры каждого «прыжка» в следующей (пакетной) фазе, основываясь на текущем состоянии Composable Stable Pool (включая масштабные коэффициенты, коэффициент усиления, курс BPT, торговые комиссии и другие параметры). Злоумышленник также развернул вспомогательный контракт для помощи в этих расчетах, что, возможно, было сделано для снижения вероятности фронтраннинга. Более подробную информацию см. в [1].

Фаза пакетного свопа

Операция batchSwap() может быть разбита на три шага:

Шаг 1: Злоумышленник обменивает BPT (wstETH/rETH/cbETH) на базовые активы, чтобы точно настроить баланс одного токена (cbETH) до границы округления (количество = 9). Это создает условия для потери точности на следующем шаге.

Шаг 2: Затем злоумышленник совершает своп между другим базовым активом (wstETH) и cbETH, используя специально подобранное количество (= 8). Из-за округления вниз при масштабировании сумм токенов вычисленное Δx становится чуть меньше (8.918 превращается в 8), что приводит к недооцененному Δy и, следовательно, к меньшему инварианту (D из модели Curve StableSwap). Поскольку цена BPT = D / общий объем предложения, цена BPT становится искусственно заниженной.

Шаг 3: Злоумышленник совершает обратный своп базовых активов в BPT, восстанавливая баланс и получая прибыль за счет заниженной цены BPT.

Резюме

Этот инцидент включал серию скоординированных транзакций эксплойта, нацеленных на пулы Balancer V2 Composable Stable и множество форк-проектов в разных сетях, что привело к существенным потерям. После первого эксплойта начали появляться подражатели, что показывает, как быстро паттерн атаки может распространиться после публикации.

Ключевые выводы:

  • Округление и обработка точности: Каждая операция масштабирования и точности с суммами токенов должна округляться в сторону, выгодную протоколу. Даже одного несоответствия между _upscale() (только округление вниз) и операциями масштабирования вниз (направленное округление) оказалось достаточно для создания уязвимости ценового искажения.
  • Гонка вооружений в безопасности: Злоумышленник разделил манипуляцию и вывод прибыли на разные транзакции, чтобы избежать обнаружения. Системы обнаружения должны коррелировать связанные транзакции, а не просто помечать отдельные из них.
  • Операционная безопасность: Как только паттерн эксплойта стал публичным, подражатели воспроизвели его в других сетях в течение нескольких минут. Протоколам, использующим общую кодовую базу, требуется скоординированный мониторинг и возможности быстрой межсетевой приостановки работы.

Ссылки

  1. https://blocksec.com/blog/in-depth-analysis-the-balancer-v2-exploit

  2. https://docs-v2.balancer.fi/concepts/pools/composable-stable.html

  3. https://docs-v2.balancer.fi/reference/swaps/batch-swaps.html


О компании BlockSec

BlockSec — поставщик комплексных услуг в области безопасности блокчейна и крипто-комплаенса. Мы создаем продукты и услуги, которые помогают клиентам проводить аудит кода (включая смарт-контракты, блокчейн и кошельки), перехватывать атаки в режиме реального времени, анализировать инциденты, отслеживать незаконные средства и соблюдать требования AML/CFT на протяжении всего жизненного цикла протоколов и платформ.

BlockSec опубликовала множество работ по безопасности блокчейн-систем на престижных конференциях, сообщила о нескольких атаках «нулевого дня» в DeFi-приложениях, заблокировала множество хакерских атак, спасая более 20 миллионов долларов, и обеспечила сохранность криптовалютных активов на миллиарды долларов.

Sign up for the latest updates
За пределами смарт-контракта: операционная безопасность доменов и DNS в Web3
Security Insights

За пределами смарт-контракта: операционная безопасность доменов и DNS в Web3

Аудит контрактов не проверяет сам контракт. Мы провели 800 SEAL-проверок DNS и регистраторов для 100 доменов из TVL Top 100 DefiLlama — лишь один домен прошёл все. Каких четырёх мер защиты не хватает большинству и почему это критично для пользователя.

Поверхности атаки Web3: обзор тестирования на проникновение

Поверхности атаки Web3: обзор тестирования на проникновение

Крипто-организации сохраняют все традиционные уязвимости и добавляют цепочку работы с деньгами. Статья описывает систему через четыре компонента: приложение, авторизацию и подпись, взаимодействие с блокчейном, инфраструктуру — с их зонами атак, а также пять специфичных для web3 областей: от эксплуатации и подписания до вывода средств и контрактов.

Потеряно ~23 млн $: эксплойты Cosmos EVM и Moonwell | BlockSec Weekly
Security Insights

Потеряно ~23 млн $: эксплойты Cosmos EVM и Moonwell | BlockSec Weekly

За период (22.08.2026–30.08.2026): 5 инцидентов, ~$22,7 млн убытков; Tectonic — $74–119,5 млн, откачены на Cronos. Взлом Cosmos EVM (~$5,7 млн) на TAC Chain, Moonwell, Ajna, Rain Card Exploit (Ed25519) на Solana.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit