Скануйте, щоб завантажити додаток Gate
qrCode
Більше варіантів завантаження
Не нагадувати сьогодні

Чорна магія маніпуляції цінами: аналіз уразливості обчислення незмінних значень Balancer V2

Компільовано: Простою мовою Блокчейн

!

3 листопада 2025 року комбінаційні стабільні басейни (Composable Stable Pools) Balancer V2 та кілька форк-проєктів на різних блокчейнах зазнали координаційної атаки, внаслідок якої загальні збитки перевищили 125 мільйонів доларів. BlockSec негайно випустив сигнал тривоги і потім опублікував попередній аналіз.

Це високо складна атака. Наше розслідування показало, що основною причиною є втрата точності при розрахунках невизначеності (invariant), що призвело до маніпуляцій з цінами, які спотворили розрахунки ціни BPT (Token Балансуючого пулу). Ця маніпуляція невизначеністю дозволяє атакуючому отримувати прибуток з одного конкретного стабільного пулу через одноразовий масовий обмін (batch swap). Хоча деякі дослідники надали проникливий аналіз, деякі інтерпретації є оманливими, а основна причина і процес атаки ще не були повністю пояснені. Цей блог має на меті надати всебічний та точний технічний аналіз цієї події.

Ключові моменти (TL;DR)

  • Основна причина: несоответствие округления та втрата точності
  • Операція збільшення (upscaling) використовує одностороннє округлення (округлення вниз), а операція зменшення (downscaling) використовує двостороннє округлення (округлення вгору та вниз).
  • Така несумісність призводить до втрати точності, коли її використовують через ретельно спроектовані обмінні шляхи, порушуючи основний принцип “округлення завжди має бути на користь протоколу”.
  • Виконання атаки
  • Зловмисник ретельно розробив параметри, включаючи кількість ітерацій та вхідні значення, щоб максимізувати вплив втрати точності.
  • Зловмисники використовують двоступеневий метод для уникнення виявлення: спочатку в одній транзакції виконується основна атака, не отримуючи негайного прибутку, а потім в іншій транзакції через вилучення активів реалізується прибуток.
  • Вплив на операції та розширення
  • Через певні обмеження протокол не може бути зупинено. Ця неможливість зупинити роботу ускладнила наслідки атак і призвела до великої кількості наступних або імітаційних атак.

У наступних розділах ми спочатку надамо ключову фонову інформацію про Balancer V2, а потім детально проаналізуємо виявлені проблеми та пов'язані атаки.

0x1 Фон

1. Комбінований стабільний пул Balancer V2

Компонентами, які постраждали під час цієї атаки, є комбіновані стабільні пулі протоколу Balancer V2. Ці пули спеціально розроблені для активів, які мають залишатися близько до 1:1 прив'язки (або торгуватися за відомим обмінним курсом), і дозволяють здійснювати великі обміни з мінімальним впливом на ціну, що суттєво підвищує капітальну ефективність між однорідними або пов'язаними активами. Кожен пул має свій власний токен Balancer (BPT), який представляє частку постачальника ліквідності в пулі, а також відповідні базові активи.

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

Ціна BPT може бути приблизно такою:

图像З наведеного виразу можна зробити висновок, що якщо D можна зменшити в обліку (навіть без фактичних фінансових втрат), то ціна BPT виглядатиме дешевшою.

2. batchSwap() і onSwap()

Balancer V2 надає функцію batchSwap(), яка підтримує багатоходові обміни (multi-hop swaps) у Vault. В залежності від параметрів, переданих цій функції, існує два типи обміну:

  • GIVEN_IN(“даний вхід”):викликатель вказує точну кількість вхідних токенів, пул обчислює відповідну кількість виходу.
  • GIVEN_OUT(“визначений вихід”):викликaч вказує очікувану кількість виходу, пул обчислює необхідну кількість входу.

Зазвичай, batchSwap() складається з декількох обмінів між токенами, виконуваними за допомогою функції onSwap(). Нижче наведено огляд шляху виконання, коли запит на обмін (SwapRequest) призначено як тип обміну GIVEN_OUT (зверніть увагу, що ComposableStablePool успадковується від BaseGeneralPool):

! [зображення] ()

Нижче показано розрахунок amount_in у типі обміну GIVEN_OUT, що включає інваріант D.

// inGivenOut токен x для y - поліноміальне рівняння для розв'язання // ax = кількість для розрахунку // bx = баланс токену в x = bx + ax (finalBalanceIn)
// D = інваріант // A = коефіцієнт підсилення // n = кількість токенів // S = сума остаточних залишків, але x // P = добуток фінальних балансів, але x

               Д Д^(n+1)  

x^2 + ( S - ---------- - D) * x - ------------- = 0
(A * n^n) A * n^2n * P

3. Масштабування та округлення

Щоб нормалізувати обчислення між різними залишками токенів, Balancer виконує наступні дві операції:

  • Збільшення (Upscaling): Перед виконанням обчислень збільшуйте баланс та суму до єдиної внутрішньої точності.

! [зображення] ()

  • Зменшення (Downscaling): Перетворення результату назад до його рідної точності та застосування орієнтованого округлення (наприклад, сума введення зазвичай округляється вгору, щоб забезпечити, що пул не стягує недостатню плату, а сума виведення часто округляється вниз).

! [зображення] ()

Очевидно, що збільшення та зменшення в теорії є парними операціями — відповідно множенням і діленням. Проте, в реалізації цих двох операцій існує несумісність. Зокрема, операція зменшення має два варіанти або напрямки: divUp та divDown. У порівнянні, операція збільшення має лише один напрямок, а саме mulDown.

Причини цієї невідповідності наразі неясні. Згідно з коментарями в функції _upscale(), розробники вважають, що вплив одностороннього округлення є незначним.

// Збільшення (Upscale) округлення не обов'язково завжди буде в один і той же бік: наприклад, під час одного обміну,

// Баланс вхідного токена повинен округлюватися вгору, а баланс вихідного токена повинен округлюватися вниз. Це єдине місце, де ми округлюємо всі суми в одному напрямку,

// Оскільки очікується, що цей вплив округлення буде мінімальним

// (і якщо не буде перекрито _scalingFactor(), то не буде жодної помилки округлення).

0x2 Аналіз вразливостей

Основна проблема полягає в тому, що під час виконання операції масштабування (upscaling) у функції BaseGeneralPool._swapGivenOut() виконується округлення вниз. Зокрема, _swapGivenOut() неправильно округлює значення swapRequest.amount вниз через функцію _upscale(). Це округлене значення потім використовується як amountOut при обчисленні amountIn через _onSwapGivenOut(). Ця поведінка суперечить стандартній практиці “округлення має застосовуватися на користь протоколу”.

! [зображення] ()

Отже, для даного пулу (wstETH/rETH/cbETH) обчислене amountIn занижує фактичну необхідну кількість введення. Це дозволяє користувачам обмінювати меншу кількість одного базового активу (наприклад, wstETH) на інший актив (наприклад, cbETH), що, в свою чергу, призводить до зменшення незмінної величини D через зменшення ефективної ліквідності. Таким чином, відповідна ціна BPT (wstETH/rETH/cbETH) стає штучно зниженою (deflated), оскільки $\text{BPT price} = \frac{D}{\text{totalSupply}}$.

0x3 Аналіз атаки

Зловмисник виконав

Двоступеневий напад, можливо, щоб мінімізувати ризик виявлення:

  • На першому етапі ядро використовується для виконання одноразових транзакцій, без негайного отримання прибутку.
  • На другому етапі зловмисник отримує прибуток, витягуючи активи в іншій транзакції.

Перший етап можна поділити на два етапи: обчислення параметрів і масовий обмін. Нижче ми використовуємо приклад атаки транзакції (TX) на Arbitrum, щоб проілюструвати ці етапи.

етап обчислення параметрів

На цьому етапі зловмисник поєднує офлайн-обчислення з онлайн-моделюванням, точно налаштовуючи параметри кожного кроку на наступному етапі (масове обмінювання) відповідно до поточного стану комбінованого стабільного пулу (включаючи коефіцієнт масштабування, коефіцієнт розширення, обмінний курс BPT, комісії за обмін та інші параметри). Цікаво, що зловмисник також розгорнув допоміжний контракт для підтримки цих обчислень, що може бути зроблено для зменшення ризику “випередження”.

По-перше, зловмисники збирають основну інформацію про цільовий пул, включаючи масштабований фактор кожного токена, параметри збільшення, BPT обмінний курс та відсоток комісії за обмін. Потім вони обчислюють ключове значення trickAmt, яке є маніпульованою кількістю цільового токена, що викликає втрату точності.

Позначте масштабний фактор цільового токена (scaling factor) як sF, обчисліть наступним чином:

ЗображенняЩоб визначити параметри, що використовуються на наступному етапі (масовий обмін) кроку 2, зловмисник використовує наступний calldata для подальшого симуляційного виклику функції допоміжного контракту 0x524c9e20:

uint256[] balances; // Баланси токенів пулу (не враховуючи BPT) uint256[] scalingFactors; // Масштабні фактори для кожного токена пулу uint tokenIn; // Індекс вхідного токена для цієї стрибка uint tokenOut; // Індекс вихідного токена цього стрибка uint256 amountOut; // Очікувана кількість вихідних токенів uint256 amp; // Параметр розширення пулу uint256 fee; // Відсоток комісії за обмін у пулі

Повернуті дані:

uint256[] balances; // Залишки токенів пулу після обміну (не включаючи BPT)

Конкретно, початкова сума та кількість ітерацій обчислюються поза блокчейном і передаються як параметри до контракту атакуючого (з відповідними значеннями 100,000,000,000 і 25). Кожна ітерація виконує три обміни:

  1. Обмін 1: Збільшити кількість цільового токена до trickAmt + 1, припустимо, що напрямок обміну 0 → 1.
  2. Обмін 2: Продовжуйте обмінювати trickAmt на цільовий токен, це викличе округлення вниз у виклику _upscale(). 320,000.

Зверніть увагу, що через використання методу Ньютона-Рафсона (Newton–Raphson) в обчисленнях StableMath цей крок може іноді зазнати невдачі. Щоб пом'якшити цю ситуацію, зловмисник реалізував дві спроби повторення, кожна з яких використовує 9/10 від початкового значення як запасне значення.

Допоміжний контракт атакуючого походить з бібліотеки StableMath Balancer V2, що можна підтвердити його наявністю кастомного повідомлення про помилку у стилі “BAL”.

$d$ Етап пакетного обміну

Потім операція batchSwap###( може бути розділена на три етапи:

  1. Крок 1: Зловмисник обмінює BPT )wstETH/rETH/cbETH( на базовий актив, щоб точно налаштувати баланс одного токена (cbETH) на межі округлення (amount = 9). Це створює умови для втрати точності на наступному етапі.
  2. Крок 2: Потім зловмисник використовує ретельно продуману кількість (= 8) для обміну між іншим базовим активом (wstETH) та cbETH. Оскільки під час масштабування кількості токенів відбувається округлення вниз, обчислене Δx стає трохи меншим (з 8.918 до 8), що призводить до заниження Δy, внаслідок чого інваріант (D, з моделі StableSwap Curve) зменшується. Оскільки $\text{BPT price} = \frac{D}{\text{totalSupply}}$, ціна BPT штучно знижується.

! [зображення] )( 3. Крок 3: Зловмисник назад обмінює базові активи на BPT, відновлюючи баланс, одночасно отримуючи прибуток від зниженої ціни BPT.

0x4: Напад і збитки

Ми підсумували ці атаки та відповідні втрати в таблиці нижче, загальні втрати перевищують 1,25 мільйона доларів.

! [зображення] )(

0x5 Висновок

Ця подія стосується серії атакуючих транзакцій проти протоколу Balancer V2 та його форк-проектів, що призвело до значних фінансових втрат. Після початкової атаки на кількох ланцюгах було спостережено велику кількість послідовних та імітаційних транзакцій. Ця подія підкреслює кілька ключових уроків щодо дизайну та безпеки DeFi протоколів:

  • Округлення та втрата точності: Одностороннє округлення (вниз) у процесі збільшення (upscaling) відрізняється від двостороннього округлення (вгору та вниз) у процесі зменшення (downscaling). Щоб уникнути подібних вразливостей, протокол повинен використовувати арифметику з вищою точністю та впроваджувати надійні перевірки валідації. Слід дотримуватись принципу “округлення завжди має бути на користь протоколу”.
  • Еволюція експлуатації вразливостей: зловмисник виконав складну двоетапну експлуатацію вразливості, спрямовану на уникнення виявлення. На першому етапі зловмисник виконав основну експлуатацію в одній транзакції, не отримуючи миттєвого прибутку. На другому етапі зловмисник отримав прибуток, витягуючи активи в іншій транзакції. Це ще раз підкреслює тривалу “гонку озброєнь” між дослідниками безпеки та зловмисниками.
  • Операційна свідомість та реагування на загрози: Ця подія підкреслює важливість своєчасних сповіщень про ініціалізацію та операційний стан, а також активні механізми виявлення та запобігання загрозам для зменшення потенційних втрат, спричинених постійними або імітаційними атаками.

Підтримуючи операційну та бізнесову безперервність, учасники галузі можуть використовувати BlockSec Phalcon як останній бар'єр для захисту своїх активів. Команда експертів BlockSec завжди готова провести всебічну оцінку безпеки для вашого проекту.

Ця стаття посилання:

Джерело:

BPT11.25%
Переглянути оригінал
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
  • Нагородити
  • Прокоментувати
  • Репост
  • Поділіться
Прокоментувати
0/400
Немає коментарів
  • Закріпити