Цей текст походить від: @Ehsan1579
Перекладено| Odaily Star Daily (@OdailyChina); Перекладач| Ethan (@ethanzhang_web3

Оглядаючи лише заголовок події, можна помилково вважати, що це атака з використанням вразливості.
Суть події полягає в тому, що хтось обміняв USDT на суму 50,4 мільйона доларів США, отримавши лише AAVE на суму 35 900 доларів США.
Коли я вперше почув про це, я був справді здивований. Тому я детально проаналізував увесь інцидент: відстеження транзакцій, шляхи розв’язувача, виклики контрактів, історичні резерви, дані заселення, процеси адаптерів, код інтерфейсу Aave, SDK CoW flash loan та код маршрутизації для визначення того, чи є пропозиція «обґрунтованою».
Це не було хакерською атакою. Основний протокол Aave не мав помилок. CoW-розрахунок не мав помилок. Uniswap не мав помилок. SushiSwap не мав помилок. Усі транзакції були дійсними, підписи були дійсними, і всі контракти виконувалися строго відповідно до коду. Однак майже вся економічна вартість була знищена лише тому, що їй дозволили пройти через абсурдний маршрут.
Проблема не в публічній ланцюжку, а в маршрутизації.
На мою думку, зведення цієї події до простого «помилкового дій користувача» — це необ’єктивний і нестрогий підхід. Хоча користувач і підписав замовлення, вся програмна система дозволила операцію зі зміною забезпечення майже на 50 мільйонів доларів США — від формування пропозиції, підписання, планування маршруту до фінального виконання — і всі кроки вказували на низьколіквідний пул, який мав лише близько 331 AAVE. Це мали бути абсолютно неможливими обставинами, які мають бути жорстко заблоковані системою ще до початку розрахунків.
Відстеження ключової інформації щодо торгівлі
Ця аномальна транзакція має хеш: 0x9fa9feab3c1989a33424728c23e6de07a40a26a98ff7ff5139f3492ce430801f, підтверджена на блок-висоті 24643151 основної мережі Ethereum 12 березня 2026 року, індекс транзакції — 1, спожито 3780570 одиниць газу, транзакція виконана успішно. Адреса гаманця, до якого належить замовлення, починається на 0x98b9, а адреса розв’язувача (відправника транзакції), який фактично виконав транзакцію, починається на 0x3980 і позначена як tsolver у даних CoW Competition.
Спочатку треба зрозуміти, що це не проста обмінна операція з USDT на AAVE на рівні гаманця. Продаваний токен — aEthUSDT, тобто сертифікат депозиту USDT з відсотками на платформі Aave. Купуваний токен — aEthAAVE, тобто сертифікат депозиту AAVE з відсотками на платформі Aave. Отже, це насправді переключення забезпечення на Aave через систему розрахунків CoW Protocol та її адаптер для молниєвих позик.
Перед угодою на гаманці було приблизно 50 432 693,075254 aEthUSDT та 0 aEthAAVE. Після угоди на ньому залишилося лише 4,980399 aEthUSDT, а отримано 327,241335505966487788 aEthAAVE. Фактично, гаманець продав майже всю позицію.
Метадані чітко вказують, що маршрут був «отруйним» ще до виконання. Замовлення походить із процесу aave-v3-interface-collateral-swap. API CoW відображає його як підписане продажне замовлення, а метадані додатка позначають його як ринкову заміну забезпечення з інтелектуальним ковзанням у 121 базисному пункті. Підписана сума продажу становить 50 432 688,41618 aEthUSDT. Підписана мінімальна сума купівлі — 324,949260918413591035 aEthAAVE. Фактично розраховано 327,241335505966487788 aEthAAVE.
Це надзвичайно важливий деталь. Цей ордер ніколи не мав на меті отримати тисячі AAVE, а потім якось зникнути посеред процесу. Він був створений з розрахунком на результат у кількість понад триста AAVE.
Повний ланцюжок збою маршрутизації
Як тільки ви почнете відстежувати угоди, весь процес стає жорсткою справою.
Основна транзакція капіталу здійснюється через контракт GPv2Settlement з початком 0x9008, що базується на протоколі CoW. Спочатку контракт HooksTrampoline з початком 0x60bf виконує авторизацію aEthUSDT, дозволяючи релеєру CoW-скарбниці отримувати активи користувача без окремої авторизації транзакції; потім контракт GPv2VaultRelayer з початком 0xc92e вилучає 50432688.41618 aEthUSDT з гаманця користувача для процесу розрахунків. На цьому етапі всі операції відповідають нормальній логіці.
Сетлмент-контракт надає права на операції з aEthUSDT контракту-помічника, який не має відкритого коду і починається на 0xd524, і ініціює виклик через селектор функції 0x494b3137; цей контракт-помічник передає права на виконання контракту-виконавцю, який не має відкритого коду і починається на 0x699c, після чого повна картина аномального маршруту торгівлі повністю виявляється.
Перший дійсний виклик спрямований до контракту Aave-фонду, що починається з 0x87870, через функцію withdraw (селектор 0x69328dec) знищує aEthUSDT та викупляє базовий нативний USDT; після цього маршрутизація перенаправляється до глибокого торгового пулу Uniswap V3, що починається з 0x4e68, де всі 50432688.41618 USDT обмінюються на 17957.810805702142342238 WETH.
На цьому етапі торгівля проходила повністю нормально: обмінний курс становив приблизно 2808,4 USDT за 1 WETH, що відповідало ринковим умовам того часу, не було проблем з ліквідністю, не було обчислювальних похибок, і перший ланцюжок торгівельної операції не мав жодних аномалій.
Проблема в другому стрибку: як тільки ви бачите резерви ліквідності, решта історії неуникнена.
Після отримання 17957.810805702142342238 WETH, виконавець перевів усі кошти на адресу 0xd75ea151a61d06868e31f8988d28dfe5e9df57b4 у торгівельний пул SushiSwap V2 AAVE/WETH.
Я перевірив історичні дані про резерви ліквідності цього пулу на момент перед тим, як відбулася аномальна угоду (висота блоку 24643150): у пулі зберігалося лише:
331.631982538108027323 AAVE, 17.653276196397688066 WETH
Це не помилка введення даних, а безапеляційна правда.
Цей маршрут угоди повністю влив близько 17 958 WETH у мініатюрний ліквіднісний пул, у якому резерв WETH становив лише 17,65 WETH, а загальний запас AAVE — 331,63 WETH. Обсяг введених WETH у 1017 разів перевищував резерв WETH у пулі.
Це не звичайна проблема зі “високим прослизанням” чи “недостатньою ліквідністю”, а надзвичайно абсурдний шлях виконання ринкового ордера, що еквівалентно змушуванню надзвичайно малого AMM-пулу з постійним добутком прийняти угоду, що в кілька тисяч разів перевищує його розмір.
AMM-пул виконав операцію за заданим алгоритмом, майже вичерпав усі резерви AAVE у пулі.
SushiSwap пари триггерує подію основного обміну Swap: виконавець надіслав 17957.810805702142342238 WETH і отримав лише 331.305315608938235428 AAVE. Після завершення угоди залишок ліквідності в цьому пулі становить приблизно:
0.326666929169791895 AAVE, 17975.464081898540030304 WETH
Просто кажучи, у пулі приблизно 99,9% AAVE було висосано за один хід.
На основі резервів до угоди, неявна ціна AAVE становить приблизно 149,50 долара США. Фактична ціна виконання користувача становить приблизно 154 114,66 USDT за 1 AAVE. Це на тисячу разів відрізняється від спот-ціни до угоди.
Потім ці AAVE повертаються до пулу Aave за допомогою селектора 0x617ba037, тобто supply(address,uint256,address,uint16). Як результат, новостворені aEthAAVE надсилаються назад до розрахункового контракту. Розрахунковий контракт у кінцевому підсумку перевів користувачеві 327.241335505966487788 aEthAAVE. Приблизно 4.06398010297174764 aEthAAVE залишилися в розрахунковому контракті як надлишок щодо сплати користувача.
Отже, розрахунок не спотворив добрий результат виконання на поганий — він просто остаточно підтвердив результат, який вже був отриманий маршрутизацією.
Це ключовий момент, який варто чітко сказати: катастрофічні наслідки були «передбачені» в ньому ще до виконання маршруту.
У даних виклику допоміжного контракту, вбудованого у маршрут, цільова сума для покупки становить приблизно 331,272185078031026739, мінімальна сума покупки, встановлена користувачем у підписаній угоді, — 324,949260918413591035, а фактична розрахункова сума — 327,241335505966487788. Усі ключові значення були заблоковані на рівні кількох сотень AAVE ще до розрахунку.
Цей маршрут був поганий з самого початку.
Де вразливість?
Відповідь: механізми перевірки на кожному рівні системи перевіряють помилки у відповідних аспектах.
Усі рівні перевіряють лише чи можлива укладення угоди, чи підпис дійсний, чи сума не нульова, але майже не перевіряють, чи економічно обґрунтований маршрут угоди на основному рівні — це основна причина порушення механізму.
Вада коду шляху оцінки адаптера інтерфейсу Aave
Перша помітна аномалія в коді виникає в процесі отримання пропозицій CoW-адаптера в інтерфейсі Aave: функція, яка раніше використовувалася для додавання спеціальних даних застосунку адаптера під час запиту пропозиції, була безпосередньо вимкнена.

Джерело: rates.helpers.ts:93 та adapters.helpers.ts:194
Це означає, що інтерфейс Aave під час запиту пропозицій у CoW не додає метадані про блискавкові кредити та гачки, які будуть додані під час фактичного розміщення замовлення. Іншими словами, те, що пропонується, не є повністю тим, що буде виконано. Навіть коментарі в коді стверджують, що метою цієї допоміжної функції є забезпечення більш точних пропозицій адаптером, але ця функція була жорстко вимкнена.
Логіка оцінки обґрунтованості пропозицій CoW занадто слабка (основна вразливість)
Друга, і найсерйозніша проблема, полягає в логіці конкуренції пропозицій протоколу CoW: у його відкритому коді сервісу будь-яка пропозиція з позитивною комісією Gas і ненульовою сумою виводу вважається «обґрунтованою пропозицією».

Джерело: quote.rs:31
Для системи маршрутизації, яка обробляє замовлення з вісімма цифрами, це дивовижно слабке визначення «розумності».
Система не підключена до оракула для перевірки цінової цілісності, не має механізму блокування «пропозицій, що відхиляються від спот-ціни більше ніж на 500 разів», не виявляє ризик «маршрутизація повністю висосе ліквідність», не надає попередження про «незбіг між останнім кроком ліквідності та розміром замовлення»; система приймає будь-який маршрут, який повертає розв’язувач, якщо він виконуваний і не нульовий — це основна вразливість цієї події.
Недоліки логіки моделювання ліквідності Uniswap V2
Третє питання стосується моделювання ліквідних пулів стилю Uniswap V2: код використовує лише стандартний алгоритм постійного добутку і відхиляє лише математично неможливі випадки, такі як нульові резерви, переповнення чисел або переповнення резервів, але не перевіряє економічну доцільність.

Джерело: pool_fetching.rs:118 та pool_fetching.rs:153
Цей код не перевіряє, чи обсяг ліквідності достатній для виконання відповідної транзакції за маршрутом, а лише визначає, чи математично дійсна операція обміну. Тому навіть мініатюрний пул з лише 331 AAVE буде вважатися придатним для виконання запиту на купівлю 17957 WETH, оскільки алгоритм постійного добутку дає ненульовий результат, повністю ігноруючи те, що цей результат призведе до руйнівної втрати активів.
Повторна поразка SDK для блискавкових позик та механізму перевірки замовлень
Після цього SDK швидких позик безпосередньо включив цю недійсну пропозицію в завантаження виконання замовлення та хука, не здійснюючи жодної додаткової блокування ризиків.

Далі:

Джерело: index.js:484 та index.js:591
Ось чому я завжди казав, що цей маршрут “поганий з народження”. Рівень адаптера не “виявляє” нову погану суму під час виконання. Він серіалізує вже вказану погану суму в дані хука та визначену адресу екземпляра. Коли погана пропозиція існує, решта механізмів вірно передають її далі.
Навіть логіка перевірки замовлень CoW тут не захищає користувачів, оскільки вона перевіряє лише, чи не перевищує замовлення ринкову ціну на момент котирування, але не перевіряє, чи не є сама котирування абсурдною щодо реальної ліквідності.

Джерело: order_validation.rs:694
Це перевірка на узгодженість. Якщо саме пропозиція вже є брехнею, замовлення все одно може бути виконане.
Механізм попереджень інтерфейсу користувача не працює
Інтерфейс Aave дійсно має попередження про високий вплив ціни, але це не жорсткий аварійний вимикач. Коли втрата вартості перевищує 20%, він перетворюється на позначку підтвердження.

Після того як користувач позначить прапорець, перешкода видалена:

Джерело: helpers.ts:24 та HighPriceImpactWarning.tsx:35
Тому, навіть якщо ця угоду майже повністю вичерпає всі активи, система вважає її лише операцією, що вимагає підтвердження користувача, а не високоризикованою угодою, яку система має обов’язково заборонити — попереджувальний механізм повністю втратив функцію блокування ризиків.
На основі всіх цих механізмів, я не можу погодитися з поверхневим висновком, що «це просто дурність користувача». Користувач дійсно підписав, але вся програмна система мала безліч можливостей зупинити цю катастрофу, але на кожному рівні виконувала лише базову перевірку — визначала «не нульовий, виконуваний, підписаний» і бездіяльно пропускала, що в кінцевому підсумку призвело до поганого наслідку.
Маршрут не був змінений
Цей етап є критично важливим і виключає велику кількість помилкових припущень: офіційний інтерфейс Aave для aave-v3-interface-collateral-swap обчислює виправлену на прослизання суму покупки у рядку 139 файлу useSwapOrderAmounts.ts, враховуючи ціну, комісії мережі, комісії партнерів та витрати на спливаючий кредит; у рядку 331 вона перетворюється на значення buyAmountBigInt; потім у рядку 191 файлу CollateralSwapActionsViaCoWAdapters.tsx ця сума точно підписується.
Подальші контракти-адаптери перевірятимуть збіг підписаних ордерів із збереженими значеннями у файлі AaveV3BaseAdapter.sol у рядку 141; контракт розрахунків CoW буде примусово застосовувати обмеження, встановлені підписом, у файлі GPv2Settlement.sol у рядку 337. Отже, результат виконання в ланцюжку не перевищує меж, дозволених підписаним ордером, і користувач отримує активів навіть більше, ніж мінімальний ліміт, встановлений підписом.
Цього достатньо, щоб довести: катастрофа відбулася до розрахунків, а не під час них — смертельна вада маршрутизації вже передбачала результат.
Куди поділася втрачена вартість?
Наступна транзакція в тому самому блоці (хеш, що починається з 0x45388b0f), яка здійснила арбітраж після атаки на резерв SushiSwap AAVE/WETH. Після того як зловмисна транзакція наповнила резерв великою кількістю WETH і висосала майже всю кількість AAVE, арбітражер негайно продав AAVE назад у резерв, вилучивши надлишкову вартість, створену через дисбаланс ліквідності.
За цей цикл арбітражу було вилучено приблизно 17929.770158685933 WETH, після чого було сплачено приблизно 13087.73 ETH побудовнику блоку та приблизно 4824.31 ETH адресі виконання арбітражу.
Повна економічна вартість, втрачена користувачем, майже миттєво перетворюється на дохід від MEV-арбітражу та дохід будівельника блоку в межах того самого блоку.
Додатково перевірка хронології на рівні блоків підтверджує: до цієї транзакції ніхто не маніпулював резервами SushiSwap, щоб обманути користувачів; першим використанням цієї пари AAVE/WETH була саме ця аномальна транзакція (індекс транзакції 1); негайно наступна транзакція (індекс транзакції 2) використала отримане спотворення ціни для першого відпрацювання; транзакція з індексом 3 також торкнулася цієї пари під час виправлення ринку. Хронологія чітко підтверджує: ця аномальна транзакція створила екстремальне спотворення ціни, а наступні транзакції безпосередньо отримали прибуток від цього спотворення.
То хто винен?
Якщо ви запитуєте, чи збійовий основний протокол Aave V3, відповідь — ні. Фонди Aave повністю виконують команди та нормально завершують процес викупу USDT та внесення AAVE.
Якщо ви запитуєте, чи збійний контракт GPv2Settlement CoW, то відповідь — ні. Система виконала розрахунок дійсного підписаного замовлення та сплатила суму, що перевищує мінімальний рівень, вказаний у підписі.
Якщо ви запитуєте, чи збоїв контракт торгової пари Uniswap V3 або SushiSwap, відповідь така ж — ні. Обидва типи пулу виконують ціноутворення відповідно до власних алгоритмів.
Системна невдача відбулася на більш високому рівні маршрутизації та контролю ризиків:
Основна відповідальність лежить на модулях маршрутизації, котирування та розв’язувача протоколу CoW: система має надто слабкі критерії для визначення «раціональної маршрутизації», дозволяючи мільйонні ордери потрапляти в мікроскопічні ліквідні пули, якщо тільки маршрут може бути виконаний і не є нульовим, повністю ігноруючи економічну абсурдність.
Другорядною відповідальною стороною є інтерфейс Aave: під час запиту пропозицій адаптером не надавалися дані додатка, пов’язані з хуком, помилкові результати безпосередньо передавалися в процес підпису, а також застосовувалася лише попереджувальна система без механізму жорсткого відмовлення; для таких екстремально великих угод ці заходи контролю ризиків повністю недостатні для запобігання ризикам.
Це був крайній провал якості маршрутизації угод та захисних механізмів контролю ризиків, що перетворив легітимну операцію зміни забезпечення на катастрофічну втрату активів.


