За прошедшую неделю (02.03.2026 - 08.03.2026) BlockSec обнаружила и проанализировала семь инцидентов атак с общими предполагаемыми потерями ~$3,25 млн. В таблице ниже приведена сводка по этим инцидентам, а подробный анализ каждого случая представлен в следующих подразделах.
| Дата | Инцидент | Тип | Предполагаемые потери |
|---|---|---|---|
| 2026/03/01* | Инцидент BUBU2 | Недостаток в дизайне токена | ~$19,7K |
| 2026/03/02 | Инцидент ACPRoute | Дефект бизнес-логики | ~$58K |
| 2026/03/02 | Инцидент на рынке sDOLA Llamalend | Манипуляция ценой | ~$239K |
| 2026/03/03 | Инцидент The V4 Router by z0r0z | Дефект бизнес-логики | ~$42K |
| 2026/03/05 | Инцидент с контрактом BitcoinReserveOffering | Дефект бизнес-логики | ~$2,7M |
| 2026/03/07 | Инцидент MoltEVM | Дефект бизнес-логики | ~$127K |
| 2026/03/08 | Инцидент LEDS | Дефект бизнес-логики | ~$64K |
*Инцидент BUBU2 был пропущен в отчёте на прошлой неделе и включён здесь для полноты.
1. Инцидент BUBU2
Краткое резюме
1 марта 2026 года токен BUBU2 на BNB Chain был атакован, в результате чего убытки составили примерно $19,7K. Основной причиной стал недостаток в дизайне токена: контракт содержит механизм дефляции с накоплением по времени, который напрямую вычитает токены из резервов пары AMM при переводе. Владелец контракта перед атакой сократил интервал срабатывания до неразумно малого значения, что привело к накоплению и выполнению сотен раундов сжигания за один вызов. Атакующий использовал флэш-займ, чтобы запустить этот механизм, обвалив резервы пары и завысив цену токена, а затем совершил обратный своп по искажённому курсу с целью получения прибыли.
Контекст
BUBU2 — это дефляционный протокол токена ERC-20, развёрнутый на BNB Chain. Протокол содержит периодический дефляционный механизм, управляемый через burnAndMintSwitch: после включения владельцем через setBurnAndMintSwitch(true), любой необлагаемый перевод, который запускает хук _update(), вызовет _triggerDailyBurnAndMint(), который сжигает токены пропорционально из баланса BUBU2 торговой пары, основываясь на количестве периодов TRIGGER_INTERVAL, прошедших с момента последнего срабатывания, и соответствующим образом синхронизирует резервы.
Анализ уязвимости
Основная причина — недостаток в дизайне контракта токена BUBU2 (0x3fF3...ee52). Контракт содержит периодический дефляционный механизм в своём хуке _update(): при срабатывании `_triggerDailyBurnAndMint()` вычисляет количество периодов `TRIGGER_INTERVAL`, прошедших с момента последнего выполнения, и сжигает пропорциональное количество `BUBU2` напрямую из торговой пары ([0x7745...cd2f](https://bscscan.com/address/0x774547ea9d2a0cc79db3288f61e989f1b06bcd2f)), после чего вызывает sync() для обновления резервов. Критически важно, что владелец может переконфигурировать TRIGGER_INTERVAL без каких-либо ограничений по тайм-локу или минимальной границе.
Перед атакой владелец вызвал setBurnAndMintSwitch(true), а затем setTriggerInterval(120), сжав интервал со стандартных 6 часов до 120 секунд. Поскольку lastTriggerTime был привязан к моменту, отстоящему на несколько часов в прошлом, следующее срабатывание рассчитало сотни накопленных раундов, а размер сжигания масштабировался линейно в зависимости от количества раундов. Это привело к тому, что один перевод вывел огромное количество BUBU2 из пары, обвалив её резервы и завысив цену токена примерно в 11 раз.

Анализ атаки
Следующий анализ основан на транзакциях 0x1bc0...141c,0x191c...1ee4,0xd6e5...51a6.
- Шаг 1: Владелец токена сначала включил периодический дефляционный механизм через
setBurnAndMintSwitch(true), затем сократил интервал срабатывания со стандартных 6 часов до 120 секунд черезsetTriggerInterval(120). Атакующий впоследствии взял в долг 18WBNBчерез флэш-займ и обменял их на примерно 18 715 856BUBU2из пула.


- Шаг 2: Атакующий инициировал небольшой перевод, запустив
_triggerDailyBurnAndMint(). БалансBUBU2в пуле снизился примерно на 1 025 988 664e18 токенов, оставив всего 6 493 352e18BUBU2в резерве после выполненияsync(), что завысило ценуBUBU2примерно в 200 раз.



- Шаг 3: Атакующий продал обратно в пул
BUBU2, приобретённый на шаге 1, по завышенной цене, получив примерно 50WBNB. После возврата флэш-займа чистая прибыль составила примерно 32WBNB.
Заключение
Эксплойт BUBU2 стал следствием критического недостатка в дизайне контракта токена. Владелец настроил неразумно малый TRIGGER_INTERVAL, что позволило прошедшему времени накопиться в сотни раундов и слить резервы торговой пары за один вызов, вызвав резкий скачок цены BUBU2.
Для снижения подобных рисков в будущем:
-
Защищайте критические параметры, такие как
TRIGGER_INTERVAL, с помощью ограничений или тайм-локов. -
Ограничивайте или устанавливайте верхний предел накопленных раундов выполнения.
2. Инцидент ACPRoute
Краткое резюме
2 марта 2026 года протокол ACPRoute на Base был атакован, в результате чего убытки составили примерно $58K. Основной причиной стал дефект бизнес-логики в контракте менеджера платежей: состояние job загружалось как копия в памяти, а не как ссылка на хранилище, поэтому отслеживание накопительных выплат никогда не сохранялось в блокчейне. Это позволило атакующему создать job, инициировать автоматическое высвобождение платежа во время перехода фазы, а затем заявить те же эскроу-средства второй раз через функцию заявки без разрешений.
Контекст
ACP (Agent Commerce Protocol) — это модульный он-чейн протокол для коммерческого взаимодействия клиентов и провайдеров. Он структурирует деятельность в три уровня: Accounts, Jobs и Memos. Jobs следуют фиксированному жизненному циклу (REQUEST → NEGOTIATION → TRANSACTION → EVALUATION → COMPLETED), а платежи удерживаются в эскроу контрактом PaymentManager во время фазы TRANSACTION. Когда job достигает статуса COMPLETED, протокол высвобождает эскроу-средства провайдеру через функцию releasePayment(). Чтобы предотвратить двойную заявку, протокол отслеживает накопительные выплаты для каждой job с помощью поля amountClaimed в структуре Job. Ожидается, что каждый вызов функции releasePayment() сравнивает запрашиваемую сумму с amountClaimed, чтобы гарантировать, что средства высвобождаются только один раз.


Анализ уязвимости
Основная причина заключается в функции releasePayment() контракта PaymentManager (0x56c3...0684), где состояние job загружается как копия в памяти, а не как ссылка на хранилище. Хотя протокол отслеживает накопительные выплаты через amountClaimed для предотвращения двойной заявки, инкремент job.amountClaimed += amount работает исключительно с временной локальной копией и никогда не записывается обратно в он-чейн хранилище. Как следствие, каждый вызов функции releasePayment() наблюдает amountClaimed == 0, что позволяет атакующему вызвать функцию claimBudget() и слить средства жертвенного контракта (0x307e...d6e8) второй раз после того, как переход фазы уже автоматически вызвал функцию releasePayment().

Анализ атаки
Следующий анализ основан на транзакции 0xe94a...f9a0.
-
Шаг 1: Атакующий взял в долг 97 000e6
USDCчерез флэш-займ в качестве капитала для последующей атаки. -
Шаг 2: Внутри callback-функции атакующий вызвал функцию
createJob()на ACPRouter, развернув при этом новый контракт провайдера (0x1ee502dd...) для получения средств. -
Шаг 3: Атакующий многократно вызывал функцию
createMemo()и вызывал собственныйexec()контракта провайдера для продвижения фазы job, до тех пор, пока не был вызван переход в фазуCOMPLETED, автоматически вызвавший функциюreleasePayment()и высвободивший весь баланс контракту провайдера. На этом этапеamountClaimedдолжен был быть обновлён, но его значение в хранилище оставалось 0. -
Шаг 4: Атакующий вызвал функцию
claimBudget()и успешно заявил эскроу-средства в размере 97 000e6USDCвторой раз в качестве прибыли.

Заключение
Этот инцидент был вызван дефектом сохранения состояния, который позволил дважды заявить эскроу-средства в рамках одного и того же жизненного цикла job.
Для снижения подобных рисков в будущем:
-
Убедитесь, что критические переменные состояния (например,
amountClaimed) обновляются с использованием ссылок на хранилище. -
Ограничивайте чувствительные функции выплат или применяйте строгую валидацию состояния перед выполнением.
3. Инцидент на рынке sDOLA Llamalend
Краткое резюме
2 марта 2026 года рынок sDOLA Llamalend на Ethereum был атакован, в результате чего убытки составили примерно $239K. Основной причиной является манипуляция ценой. В частности, sDOLA — это токен ERC4626, цена которого может быть манипулирована через donate(). Llamalend — это кредитный рынок на основе AMM, и из-за механизма LLAMMA пользователи могут стать объектом ликвидации даже при росте цены залога. Поэтому атакующий может использовать donate(), чтобы завысить цену sDOLA, снизить показатель здоровья позиций пользователей ниже нуля, а затем ликвидировать этих пользователей с целью получения прибыли.
Контекст
LLAMMA (Lending-Liquidating AMM Algorithm) — это кредитный рынок на основе AMM, используемый Curve [1]. В отличие от традиционных кредитных протоколов, LLAMMA размещает залог пользователя в ценовых диапазонах (bands) внутри AMM. По мере изменения цены оракла , залог постепенно конвертируется между токеном залога и crvUSD через арбитражные свопы между диапазонами (мягкая ликвидация), постепенно снижая риск позиций вместо резких ликвидаций.

Если мягкая ликвидация не может снизить риск позиции достаточно быстро, срабатывает жёсткая ликвидация [2], которая запускается, когда показатель здоровья позиции опускается ниже нуля. Здоровье рассчитывается через get_x_down() [3], который не просто оценивает залог по рынку. Вместо этого он симулирует круговую конвертацию позиции пользователя для оценки её восстанавливаемой стоимости. Этот круговой расчёт использует два разных ценовых якоря: один, производный от текущего (меняется вместе с живым оракулом), и другой, производный от границ диапазона пользователя (фиксирован на момент создания позиции).

Анализ уязвимости
Уязвимые контракты включают контроллер crvUSD (0xad44...fb86) и AMM LLAMMA (0x0079...a1f7). Жертвенный контракт — это рынок sDOLA Llamalend (0x2b08...4fbe).
sDOLA — это токен-хранилище ERC4626, цена доли которого определяется соотношением общих активов к общему количеству долей. Поскольку любой может вызвать donate() для добавления активов в хранилище, цена доли может быть завышена в рамках одной транзакции. Это и есть манипулируемый оракул, от которого зависит функция здоровья LLAMMA.
Как описано в разделе «Контекст», get_x_down() рассчитывает здоровье, симулируя круговую конвертацию через два ценовых якоря: один, производный от (динамический, меняется вместе с живым оракулом), и другой, производный от границ диапазона пользователя (статический, фиксирован на момент создания позиции). Протокол не применяет никакой задержки или проверки адекватности при считывании . Поэтому, когда цена оракула завышена, динамический якорь растёт, а статический остаётся прежним. По сути, симуляция конвертирует crvUSD в залог по завышенной цене оракула и конвертирует обратно по исходной цене диапазона, поэтому оценённая восстанавливаемая стоимость уменьшается по мере увеличения разрыва между двумя якорями. Это снижает здоровье ниже нуля, даже если цена залога выросла.


Анализ атаки
Следующий анализ основан на транзакции 0xb935...d8a4.
- Шаг 1: Манипулирование состоянием LLAMMA (крупные свопы) для сдвига
active_bandи перевода множества пользователей в позицию только-x (толькоcrvUSD).

- Шаг 2: Манипулирование ценой
sDOLAчерез пожертвования, затем использование свопа с нулевой суммой (swap(0)), чтобы записать манипулированную цену в пул AMM.


-
Шаг 3: Инициирование пересчёта здоровья через
users_to_liquidate()->_health()->get_x_down(). -
Шаг 4: Поскольку
get_x_down()рассчитывает восстанавливаемую стоимость через два расходящихся ценовых якоря (динамический якорь, теперь завышенный, и статический якорь, неизменный), круговая конвертация даёт уменьшение эффективной стоимости, и множество позиций опускаются ниже нулевого здоровья. -
Шаг 5: Массовая жёсткая ликвидация этих пользователей с целью получения прибыли.
Кроме того, в трассировке присутствуют два вызова create_loan(). Первый займ был использован в основном для финансирования крупномасштабных операций со свопами crvUSD. Второй займ был использован для получения crvUSD с целью возврата долга первой позиции и переработки капитала. Эти два займа преимущественно представляют собой этапы финансирования/расчётов и сами по себе не являются основными шагами эксплойта.
Заключение
Инцидент представляет собой атаку с манипуляцией цены залога. Атакующий манипулировал ценой sDOLA внутри транзакции и, из-за основанного на пути механизма здоровья LLAMMA, перевёл пользователей в условия ликвидации. Ключевым последствием является то, что позиции могут стать объектом ликвидации даже при росте цены залога. Рекомендуемые направления усиления защиты:
- Использовать отложенные или TWAP-цены залога для ликвидации.
Ссылки
-
[1] Документация Curve crvUSD LLAMMA: [https://dev.curve.finance/crvUSD/amm/#bands](https://dev.curve.finance/crvUSD/amm/#bands)
-
[2] Объяснение ликвидации Curve LLAMMA: [https://dev.curve.finance/crvUSD/llamma-explainer/#liquidation](https://dev.curve.finance/crvUSD/llamma-explainer/#liquidation)
-
[3] Белая книга стейблкоина Curve: [https://docs.curve.finance/pdf/whitepapers/whitepaper\_curve\_stablecoin.pdf](https://docs.curve.finance/pdf/whitepapers/whitepaper_curve_stablecoin.pdf)
4. Инцидент The V4 Router by z0r0z
Краткое резюме
3 марта 2026 года V4 Router by z0r0z на Ethereum был атакован, в результате чего убытки составили примерно $42K. Атака была вызвана дефектной логикой авторизации в swap(), где роутер полагался на фиксированное смещение calldata в инлайн-ассемблере для проверки того, что плательщик соответствует msg.sender. Поскольку кодирование ABI для динамических типов не гарантирует фиксированный макет, атакующий смог составить нестандартные, но валидные calldata, которые обошли проверку, выдали себя за ранее одобренную жертву в качестве плательщика и перенаправили вывод свопа на адрес, контролируемый атакующим.
Контекст
Протокол наследуется от Uniswap v4 Router и переопределяет некоторые его методы. По сути, он функционирует как маршрутизатор свопов, позволяя пользователям избегать прямого взаимодействия с соответствующим пулом и вместо этого использовать роутер в качестве единой точки входа.
Анализ уязвимости
Основная причина — дефектная бизнес-логика в контракте V4 Router (0x0000...ce97). Жертвенный контракт — 0x65a8...7675. Функция swap() принимает два параметра: data (bytes) и deadline (uint256). Внутри функции проверка авторизации использует блок инлайн-ассемблера для сравнения calldataload(164) с caller(), обеспечивая соответствие плательщика, закодированного в data, с msg.sender. Протокол предполагает, что смещение bytes всегда равно 0x40, размещая плательщика на позиции байта 164 (0xa4).
Однако кодирование ABI не гарантирует такой макет: динамические параметры хранят в заголовке только смещение, и это смещение может легально указывать на любую выровненную позицию в calldata. Составив валидное, но нестандартное кодирование, где смещение bytes перемещено на 0xc0, атакующий может вставить произвольное заполнение между заголовком и фактической хвостовой частью. Атакующий размещает собственный адрес на позиции байта 164, чтобы пройти проверку в ассемблере, в то время как истинная полезная нагрузка bytes в перемещённой хвостовой части кодирует адрес жертвы в качестве плательщика. Выбрав жертву, которая ранее одобрила роутер, и установив получателя на свой собственный адрес, атакующий может перенаправить вывод свопа и украсть средства.


Анализ атаки
Следующий анализ основан на транзакции 0xfe34...466a.
-
Шаг 1: Выбор пользователя, который ранее одобрил роутер, в качестве цели.
-
Шаг 2: Составление calldata для обхода проверки авторизации.
-
Шаг 3: Указание жертвы в качестве плательщика в data, установка собственного адреса атакующего в качестве получателя токенов, после чего кража активов жертвы.

Заключение
Этот инцидент был вызван использованием захардкоженного смещения calldata для авторизации в пути свопа. Поскольку кодирование ABI для динамических типов не гарантирует фиксированный макет, атакующий обошёл проверку с помощью нестандартных, но валидных calldata, выдал себя за одобренную жертву в качестве плательщика и перенаправил вывод свопа.
Для снижения подобных рисков в будущем:
-
Никогда не полагайтесь на захардкоженные смещения calldata для динамически закодированных параметров ABI.
-
Декодируйте и валидируйте структурированные входные данные, используя каноническое ABI-декодирование, а не ручные позиционные предположения.
-
Убедитесь, что фактический плательщик, получатель и поток токенов постоянно проверяются относительно предполагаемого вызывающего и контекста выполнения.
5. Инцидент с контрактом BitcoinReserveOffering
Краткое резюме
5 марта 2026 года контракт BitcoinReserveOffering на Ethereum был атакован, в результате чего убытки составили примерно $2,7 млн. Основной причиной стал дефект бизнес-логики: при обработке полного депозита SFT стандарта ERC-3525 логика минтинга выполнялась дважды в рамках одного вызова — один раз во время callback-функции перевода и один раз в основном потоке выполнения. Атакующий воспользовался этим поведением двойного минтинга через повторяющиеся циклы сжигания и минтинга, экспоненциально увеличивая свой баланс токенов BRO, а затем обменял избыток на SolvBTC для получения прибыли.
Контекст
BitcoinReserveOffering — это контракт-обёртка, преобразующий позиции SFT стандарта ERC-3525 в передаваемые токены BRO стандарта ERC-20. Пользователи могут вызвать функцию mint() для депонирования подходящих SFT, и контракт отминтит соответствующее количество BRO на основе настроенного обменного курса. Если пользователь депонирует только часть стоимости SFT, контракт переводит указанную сумму в свою внутренне удерживаемую позицию, а затем отминчивает соответствующую стоимость BRO. Если пользователь депонирует весь SFT, контракт переводит полный токен в контракт-обёртку и отминчивает BRO на основе общей стоимости SFT. Впоследствии пользователи могут вызвать функцию burn() для обмена BRO обратно на соответствующую позицию SFT стандарта ERC-3525, конвертируя обёрнутую стоимость ERC-20 обратно в позицию SFT.
Анализ уязвимости
Основная причина заключается в том, что контракт BitcoinReserveOffering (0x15f7...cfcf) выполняет логику минтинга дважды при обработке полного депозита SFT стандарта ERC-3525 в функции mint(). В частности, в ветви amount_ == sftBalance функция mint() вызывает ERC3525TransferHelper.doSafeTransferIn() для безопасного перевода всего SFT в контракт, что инициирует callback onERC721Received(). Внутри этого callback контракт уже рассчитывает стоимость SFT и отминчивает BRO отправителю. После возврата callback функция mint() продолжает выполнение, пересчитывает стоимость с использованием того же amount_ и выполняет вторую операцию _mint(msg.sender, value). Это поведение двойного минтинга позволяет атакующему многократно увеличивать свой баланс BRO через цикл сжигания и минтинга.


Анализ атаки
Следующий анализ основан на транзакции 0x44e6...958d.
-
Шаг 1: Атакующий переводит 135e18 токенов
BROв атакующий контракт в качестве начального капитала. -
Шаг 2: Атакующий выполняет следующий цикл:
-
Обёртывает 135e18 токенов
BROв токенSFT. -
Вызывает
mint()с полной стоимостьюSFT, что инициирует callbackonERC721Received()и отминчивает 135e18 токеновBRO; внешняя функцияmint()затем продолжает выполнение и снова вызывает_mint(), в результате чего происходит двойной минтинг в общей сложности 270e18 токеновBRO. -
Обёртывает 270e18 токенов
BROобратно в токенSFT.
- Шаг 3: После повторения шага 2 22 раза атакующий накапливает примерно 567 758 816e18 токенов
BRO, которые в итоге обмениваются на 38e18SolvBTCв качестве прибыли.
Заключение
Этот инцидент был вызван двойным минтингом при полных депозитах SFT, что позволило атакующему экспоненциально увеличить свой баланс BRO через повторяющиеся циклы сжигания и минтинга и обменять избыток на SolvBTC.
Для снижения подобных рисков в будущем:
-
Обеспечьте, чтобы учёт активов происходил только один раз за операцию депозита.
-
Добавьте проверки инвариантов, чтобы предотвратить превышение суммы минтинга над стоимостью внесённого депозита.
6. Инцидент MoltEVM
Краткое резюме
7 марта 2026 года протокол MoltEVM на Base был атакован, в результате чего убытки составили примерно $127K. Основной причиной стал дефект логики контроля доступа в контракте токена: привилегированная функция минтинга была защищена модификатором, который проверял только то, является ли вызывающий контрактом с определённым интерфейсом, что можно было легко подделать. Атакующий развернул злонамеренный контракт для обхода проверки, отминчил большой объём токенов и слил их через пул ликвидности с целью получения прибыли.
Контекст
MoltEVM — это экспериментальный протокол токена ERC-20, развёрнутый на Base, исследующий модель самовоспроизводящегося токена. Система позволяет токену порождать новые дочерние токены (токены «Moltling») при достижении определённых пороговых значений резервов. При создании нового Moltling начальный объём предложения токена распределяется через функцию mintFromSpawner(), а ликвидность автоматически формируется для создания торгового рынка нового токена. Этот дизайн позволяет протоколу автономно расширять родословную своих токенов, причём каждое поколение токенов способно порождать дальнейших потомков.
Анализ уязвимости
Уязвимость заключается в логике контроля доступа функций mintFromSpawner() и setExemptFromSpawner() в контракте MoltEVM (0x225d...501f). Обе функции полагаются на модификатор onlySpawnerToken, который был предназначен для ограничения вызовов только легитимными контрактами Moltling, порождёнными протоколом.
Однако модификатор выполняет только две слабые проверки: он проверяет, что msg.sender является контрактом, и что вызов initialized() у вызывающего возвращает true. Поскольку эти условия могут быть легко выполнены любым произвольным контрактом, реализующим такой же интерфейс, проверка не обеспечивает значимой аутентификации легитимных токенов-спаунеров.
В результате атакующий может развернуть минимальный контракт, который просто реализует функцию initialized(), возвращающую true. После развёртывания злонамеренный контракт может свободно вызывать mintFromSpawner() для минтинга произвольного количества токенов, а также вызывать setExemptFromSpawner() для внесения в белый список адресов, контролируемых атакующим. Это фактически предоставляет атакующему полный контроль над путём минтинга и позволяет сливать только что отминченные токены в пулы ликвидности с целью получения прибыли.

Анализ атаки
Следующий анализ основан на транзакции 0x10b7...e03d.
-
Шаг 1: Атакующий развернул минимальный контракт, реализующий единственную функцию
initialized(), захардкоженную для возвратаtrue, что было достаточно для прохождения проверки модификатораonlySpawnerToken. -
Шаг 2: Контракт атакующего вызвал функцию
setExemptFromSpawner(), защищённую тем же уязвимым модификаторомonlySpawnerToken, чтобы добавить адрес атакующего в белый список освобождения от налога. Это гарантировало, что последующие крупномасштабные сбросы токенов не будут вызывать налоги на продажу или внутреннюю логику свопа, максимизируя прибыль.

- Шаг 3: Атакующий повторил последовательность функций
setExemptFromSpawner()+mintFromSpawner()сначала противmEVM, а затем против нескольких дочерних токенов Moltling, включаяCSPAWN,CCUTTL,LWORMиNHYDRA, массово отминчивая токены по всем целям и сливая их в соответствующие пулы ликвидности для извлечения прибыли.

Заключение
Этот инцидент был вызван недостаточным контролем доступа к привилегированным функциям минтинга и конфигурации, что позволило атакующему выдать себя за легитимный спаунер и отминчить произвольные токены с целью получения прибыли.
Для снижения подобных рисков в будущем:
-
Применяйте строгий контроль доступа для привилегированных функций минтинга или конфигурации.
-
Избегайте опоры на легко подделываемые проверки контрактов для авторизации.
-
Валидируйте идентичность вызывающего через явные белые списки или реестры доверенных контрактов.
7. Инцидент LEDS
Краткое резюме
8 марта 2026 года токен LEDS на BNB Chain был атакован, в результате чего убытки составили примерно $64K. Основной причиной стал дефект бизнес-логики: контракт токена содержит несколько независимых дефляционных механизмов, каждый из которых способен сжигать токены напрямую из пары ликвидности, и ни один из них не защищён контролем доступа или периодом ожидания (cooldown). Атакующий связал все пути сжигания в рамках одной транзакции, обвалив резерв LEDS пары почти до нуля, при этом резерв WBNB оставался неизменным, а затем выполнил обратные свопы для слива несбалансированного пула с целью получения прибыли.
Контекст
LEDS — это дефляционный токен на BNB Chain со встроенным механизмом комиссии при переводе. Его _transfer() реализует несколько механизмов сжигания, предназначенных для постепенного уменьшения предложения и поддержки цены: функцию ежедневного сжигания triggerDailyBurnAndMint(), отложенное сжигание через накопление stor_18 при продажах, и специальную ветвь, которая сжигает токены на адрес 0xdead, когда получатель свопа установлен в адрес PancakeSwap Router. Токен также обладает функцией deposit(), где пользователи отправляют BNB для минтинга LEDS и предоставления ликвидности, зарабатывая LP-вознаграждения, доступные для получения через распределитель.
Анализ уязвимости
Основная причина — дефектная бизнес-логика в контракте токена LEDS (0xfb62...a48f). Жертва — пара LEDS/WBNB (0xd109...6f3f). Токен реализует несколько дефляционных механизмов: triggerDailyBurnAndMint(), накопление stor_18 в пути продажи и ветвь сжигания to == router в _transfer(). Каждый из этих механизмов независимо удаляет LEDS из пары ликвидности и вызывает sync() для обновления резервов.
Хотя по отдельности эти механизмы служат инструментами постепенной дефляции, их можно связать в рамках одной транзакции, чтобы усилить их эффект. Кроме того, публичная функция 0x17a06174() позволяет любому по желанию сбросить весь накопленный баланс stor_18 без каких-либо ограничений доступа или скорости. Последовательно накладывая эти пути сжигания, атакующий может снизить резерв LEDS пары почти до нуля, оставив резерв WBNB нетронутым, создавая экстремальное искажение цены, эксплуатируемое через обратные свопы.
Анализ атаки
Следующий анализ основан на транзакции 0x2608...79da.
-
Шаг 1: Атакующий получил большое количество
WBNBчерез флэш-займы (Moolah + заём под залог Venus + Aave + PancakeSwap V4). -
Шаг 2: Выполнил несколько вызовов
deposit()для накопления LP-вознаграждений, затем вызвалtriggerDailyBurnAndMint(), который сжёг частьLEDSиз пары и отправил вознаграждения распределителю, уменьшив резервLEDSв пуле.

- Шаг 3: Вызвал функцию
0xde1b1942()для получения накопленных вознаграждений в токенахLEDS.

- Шаг 4: Продал полученные
LEDSзаWBNB. Поскольку балансLEDSпары превысил пороговое значение после продажи, переведённая сумма была накоплена вstor_18(ожидающее сжигание).

- Шаг 5: Купил
LEDSчерез PancakeSwap, установив получателя в адрес Router. Это запустило специальную ветвь в_transfer(), которая сожгла купленныйLEDSнапрямую из пары на адрес 0xdead, дополнительно уменьшив резервLEDSпула.

- Шаг 6: Вызвал функцию
0x17a06174(), которая сожгла весь балансstor_18(накопленный на шаге 4) из пары на адрес 0xdead и вызвалаsync(), обвалив резервLEDSпула до всего лишь 2 wei.

- Шаг 7: Выполнил обратные свопы для слива
WBNBиз теперь сильно несбалансированного пула, вернул все флэш-займы и получил прибыль в размере 104,56WBNB($64K).
Заключение
Этот инцидент был вызван несколькими незащищёнными дефляционными механизмами, которые можно связать в рамках одной транзакции для катастрофического истощения резервов пары ликвидности.
Для любого контракта токена, реализующего дефляционную или авто-сжигающую механику, разработчикам следует:
-
Никогда не раскрывать функции сжигания из пары без надлежащего контроля доступа, ограничения скорости или применения периода ожидания (cooldown).
-
Избегать предоставления возможности последовательно запускать несколько независимых механизмов сжигания в рамках одной транзакции.
О BlockSec
BlockSec — это полностековый провайдер блокчейн-безопасности и криптовалютного комплаенса. Мы создаём продукты и услуги, которые помогают клиентам проводить аудит кода (включая смарт-контракты, блокчейн и кошельки), перехватывать атаки в реальном времени, анализировать инциденты, отслеживать нелегальные средства и выполнять обязательства AML/CFT на всех этапах жизненного цикла протоколов и платформ.
BlockSec опубликовала множество статей по безопасности блокчейна на престижных конференциях, сообщила о нескольких атаках нулевого дня на приложения DeFi, заблокировала множество хаков, спасая более 20 миллионов долларов, и обеспечила безопасность миллиардов криптовалют.
-
Официальный сайт: https://blocksec.com/
-
Официальный аккаунт в Twitter: https://twitter.com/BlockSecTeam



