Back to Blog

Еженедельный обзор инцидентов безопасности Web3 | 30 марта – 5 апреля 2026

Code Auditing
April 8, 2026
31 min read
Key Insights
  • Девять атак на Web3 за неделю, потери составили около 287 млн долларов; захват мультиподписи/устойчивого nonce в Drift составил примерно 99% всех потерь.

  • Повторяющиеся коренные причины: пробелы в контроле доступа, некорректная логика расчётов, устаревшие или манипулируемые данные о ценах, ошибки в оракулах и подмена резервов LP

За прошедшую неделю (30.03.2026 - 05.04.2026) BlockSec обнаружила и проанализировала девять инцидентов атак с общими предполагаемыми убытками ~$287M. В таблице ниже приведена сводка этих инцидентов, а подробный анализ каждого случая представлен в следующих подразделах.

Дата Инцидент Тип Предполагаемые убытки
2026/03/30 Инцидент с неизвестным протоколом Дефектная бизнес-логика ~$10K
2026/03/30 Инцидент с токеном WDGG Контроль доступа ~$40K
2026/03/31 Инцидент с i6Token Дефектная бизнес-логика ~$273.8K
2026/04/01 Инцидент с Drift Protocol Фишинговая атака ~$285.3M
2026/04/01 Инцидент с LML Staking Protocol Дефектная бизнес-логика ~$950K
2026/04/01 Инцидент с Tactile Манипуляция ценой ~$12K
2026/04/02 Инцидент с токеном SAS Дефектная бизнес-логика ~$12K
2026/04/03 Инцидент Unknown-EIP-7702 Контроль доступа ~$17.2K
2026/04/03 Инцидент с Silo Finance Ошибка конфигурации ~$359K

Лучший аудитор безопасности для Web3

Проверяйте дизайн, код и бизнес-логику перед запуском

1. Инцидент с неизвестным протоколом

Краткое описание

30 марта 2026 года неизвестный протокол в сети BNB Chain потерял ~$10K из-за дефектной бизнес-логики. Протокол выделял часть депозитов пользователей на покупку своего платформенного токена PSTART и добавление ликвидности, что означало, что пользователи фактически удерживали LP-позиции, подверженные колебаниям рыночной цены. Однако при выводе средств протокол не производил расчет на основе фактической выкупаемой стоимости LP на тот момент. Вместо этого он продолжал обещать фиксированную сумму стейблкоинов на основе исторического депозита и заранее установленных правил. В результате, после принудительного вложения капитала, атакующий смог вывести средства по заранее согласованной фиксированной стоимости, фактически перекладывая убытки, которые должна была нести LP-позиция, на протокол, в конечном итоге получив прибыль без затрат.

Предыстория

Протокол работает следующим образом: после того как пользователь вносит депозит BUSD, протокол автоматически использует часть средств для покупки PSTART, а затем объединяет их с оставшимися BUSD для добавления ликвидности в пул. Полученные LP-доли затем хранятся на кастодиальном хранении в Vault, а протокол фиксирует во внутреннем реестре заказ для пользователя, обещающий фиксированную ежедневную доходность.

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

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

Эта уязвимость проистекает из необоснованного дизайна протокола (0x587984...73a43c): логика расчетов оторвана от фактической стоимости базовых активов.

После того как пользователь вносит депозит BUSD, протокол использует часть средств для покупки PSTART и добавления ликвидности, что означает, что фактическая базовая позиция пользователя представляет собой экспозицию LP, стоимость которой колеблется вместе с рыночными ценами. Однако при выходе пользователя протокол не производит расчет на основе фактической выкупаемой стоимости LP на тот момент. Вместо этого он по-прежнему обещает выплатить фиксированную сумму стейблкоинов согласно историческому размеру депозита и заранее установленным правилам расчета.

Атакующий воспользовался этим недостатком, используя флэш-займ для получения большого объема капитала, а затем многократно выполняя deposit(). Тем самым атакующий вынуждал протокол непрерывно покупать PSTART и изменять состав активов в пуле, тем самым искусственно завышая цену PSTART и создавая арбитражную возможность.

Затем атакующий выполнил withdraw() и выкупил средства по заранее обещанной фиксированной стоимости, фактически перенеся убытки, которые должна была нести базовая LP-позиция, на сам протокол, в конечном итоге получив прибыль без затрат.

Анализ атаки

Следующий анализ основан на транзакции 0xf3b8...55e7.

  • Шаг 1: Атакующий получил примерно 2,000,000e18 BUSD через флэш-займ и обменял их в пуле на 19,013,120e18 PSTART.

  • Шаг 2: Атакующий многократно вызывал функцию deposit() контракта для стейкинга средств. При каждом депозите протокол вычислял, сколько BUSD следует использовать для покупки токенов, чтобы итоговое соотношение токен/BUSD, используемое для добавления ликвидности, более точно соответствовало текущему соотношению в пуле. Многократно внося депозиты, атакующий непрерывно вливал BUSD в пул, в то время как количество PSTART оставалось почти неизменным. В результате стоимость PSTART продолжала расти. На этом этапе LP, полученная за счет депозитов атакующего, фактически приобреталась в убыток.

  • Шаг 3: Затем атакующий продал PSTART, купленный на Шаге 1, обратно в пул. Поскольку Шаг 2 увеличил резервы BUSD в пуле, этот обмен вернул примерно 2,010,655e18 BUSD, принеся прибыль около 10,655 BUSD за один цикл атаки.

  • Шаг 4: Наконец, атакующий выполнил withdraw() для всех позиций стейкинга, открытых на Шаге 2. К этому моменту рыночная стоимость активов, соответствующих этим позициям, уже была намного ниже их первоначальной стоимости депозита. При нормальной экономической логике полный выкуп не должен был быть возможен. Однако протокол рассчитывал сумму BUSD, доступную для вывода, на основе исторического размера депозита, что позволило атакующему полностью вернуть все ранее вложенные принудительные инвестиционные затраты, не понеся никаких убытков.

Заключение

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

Атакующий воспользовался этим недостатком, многократно используя deposit() для изменения структуры активов пула и завышения цены PSTART, затем завершил арбитраж через внешнюю позицию и, наконец, использовал withdraw() для выкупа ранее убыточных позиций по балансовой стоимости. Таким образом, убытки, которые должны были нести сами позиции, были перенесены на протокол, что в конечном итоге позволило получить безрисковую прибыль.


Начните работу с Phalcon Explorer

Погрузитесь в транзакции, чтобы действовать разумно

Попробовать бесплатно

2. Инцидент с токеном WDGG

Краткое описание

30 марта 2026 года токен WDGG в сети BNB Chain подвергся эксплуатации, что привело к убыткам примерно в $40K. Первопричиной стало отсутствие контроля доступа в функции burnFrom(). В частности, функция burnFrom() позволяла любому пользователю сжигать токены WDGG с любого адреса. Атакующий воспользовался этим, сжигая токены WDGG из пула PancakeSwap, затем вызывая функцию sync() для уменьшения резервов WDGG в пуле, а впоследствии выполняя обратный обмен для извлечения прибыли.

Предыстория

Данный инцидент связан с единственным токеном WDGG, который является токеном с распределением дивидендов, взимающим комиссию с каждой транзакции.

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

Контракт токена WDGG (0x512de7...6b90c5) предоставлял burnFrom() без какой-либо авторизации вызывающей стороны. В результате любой адрес мог сжигать токены WDGG с любого держателя, включая сам пул PancakeSwap. В сочетании с публично вызываемой функцией sync() в PancakeSwap, которая приводит зафиксированные резервы в соответствие с фактическими балансами, этот недостаток позволял произвольно уменьшать резерв WDGG в пуле и нарушать инвариант постоянного произведения без какой-либо легитимной сделки, подвергая пул риску арбитража при ценовом дисбалансе.

Вторичный недостаток в функции setWdgAddress() позволял любому вызывающему помечать произвольный адрес как освобожденный от комиссии, что дополнительно максимизировало прибыль, извлекаемую через эту поверхность атаки.

Анализ атаки

Следующий анализ основан на транзакции 0x2da5...0bd1.

  • Шаг 1: Атакующий сначала вызвал setWdgAddress(), чтобы установить свой собственный адрес как освобожденный от комиссии, что позволило последующим переводам обходить комиссию за перевод токена.
  • Шаг 2: Атакующий затем обменял небольшое количество BNB на токены WDGG через пул PancakeSwap.

  • Шаг 3: Получив WDGG, атакующий вызвал burnFrom() для сжигания токенов WDGG непосредственно с адреса пары PancakeSwap.

  • Шаг 4: Затем атакующий вызвал sync(), вынуждая пару обновить свои резервы в соответствии с манипулированными балансами токенов. В результате резерв WDGG в пуле был уменьшен всего до 1 вея.

  • Шаг 5: С сильно искаженными резервами пула атакующий выполнил обратный обмен и извлек прибыль из ценового дисбаланса.

Заключение

Данный инцидент в конечном итоге был вызван отсутствием контроля доступа в функции burnFrom() контракта токена WDGG. В результате атакующий смог сжигать токены непосредственно из пула PancakeSwap, манипулировать резервами пула через sync() и извлекать прибыль из возникшего ценового дисбаланса.


3. Инцидент с i6Token

Краткое описание

31 марта 2026 года токен i6 в сети BNB Chain потерял ~$273.8K, поскольку invest() изменял спотовую цену пула, в то время как withdraw() производил расчет балансов через устаревшую TWAP, и эти две функции могли быть скомпонованы в одной и той же транзакции. Атакующий завысил спотовую цену через invest(), выкупил избыточный i6 по устаревшей TWAP через withdraw() и продал i6 обратно в завышенный пул с прибылью.

Предыстория

Протокол работает следующим образом. Когда пользователь вызывает invest(), вносится депозит USDT, часть которого используется для покупки i6 на PancakeSwap. Приобретенный i6 вместе с оставшимся USDT затем добавляется в качестве ликвидности в пул USDT/i6, а полученные LP-токены сжигаются. Протокол фиксирует балансы пользователя и рефералов, номинированные в USDT.

При вызове withdraw() протокол вычисляет накопленную стоимость пользователя в терминах USDT и конвертирует ее в i6, используя цену TWAP, поддерживаемую протоколом (twapPrice).

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

Первопричина в контракте протокола (0x1cb36b...2a18a) заключается в том, что invest() изменяет спотовую цену пула USDT/i6 в качестве побочного эффекта покупки i6 и добавления ликвидности, в то время как withdraw() производит расчет накопленных балансов, номинированных в USDT, в i6, используя поддерживаемую протоколом TWAP (twapPrice), которая обновляется только после истечения временного окна. Ничто в контракте не предотвращает выполнение этих двух функций в одной и той же транзакции.

Поскольку вызов invest() может завысить спотовую цену в той же транзакции, в которой последующий вызов withdraw() считывает еще не обновленную TWAP, эти две функции фактически видят две разные цены для одного и того же состояния пула. Баланс, номинированный в USDT и выкупаемый через withdraw(), затем выплачивается в i6 по устаревшей, значительно более низкой цене, хотя каждый i6 теперь может быть реализован за гораздо большую сумму USDT в самом пуле. Этот разрыв превращает любой накопленный баланс USDT в протоколе в эксплуатируемый спред между внутренним расчетом и живым пулом.

Анализ атаки

Следующий анализ основан на транзакции 0xc1b9...2f16.

  • Шаг 1: Атакующий сначала получил 270,000 WBNB через флэш-займ, затем предоставил его в качестве обеспечения на Venus и заимствовал большое количество USDT. Атакующий также развернул атакующий контракт A по адресу 0xda49 и вспомогательный контракт B по адресу 0x096a.

  • Шаг 2: Атакующий контракт выполнил первый вызов invest(). В процессе протокол сначала использовал 531,489e18 USDT для покупки 234,188e18 i6, а затем добавил 354,326e18 USDT вместе с 72,607e18 i6 в пул. В результате спотовая цена пула быстро выросла с примерно 1.05159 USDT/i6 до примерно 4.89287 USDT/i6, в то время как зафиксированная протоколом TWAP по-прежнему оставалась на уровне лишь 1.05159.

  • Шаг 3: Затем атакующий перевел 124,014,184e18 USDT на вспомогательный контракт B, который в свою очередь вызвал invest() с referrer = A. Этот шаг снова вынудил протокол выполнить массовую покупку USDT -> i6 и addLiquidity(), подтолкнув резервы пула к новому состоянию, соответствующему спотовой цене примерно 15,528 USDT/i6. Однако, поскольку новое временное окно еще не истекло, протокол не обновил TWAP соответствующим образом.

  • Шаг 4: После завершения второго вызова invest() атакующий контракт A, выступающий в качестве реферала, немедленно получил право на реферальное вознаграждение, номинированное в USDT. Затем атакующий вызвал withdraw(). Протокол использовал устаревшую TWAP для расчета суммы i6, подлежащей выплате, и перевел токены из собственного баланса, в результате чего общая выплата составила 5,896,508e18 i6.

  • Шаг 5: Получив i6, атакующий немедленно вызвал swapExactTokensForTokensSupportingFeeOnTransferTokens(), чтобы продать все 5,896,508e18 i6 обратно в пул в обмен на 125,177,224e18 USDT. Поскольку эти токены i6 были рассчитаны по устаревшей TWAP, составлявшей около 1.05159 USDT/i6, в то время как они были проданы против спотовой цены пула, которую атакующий подтолкнул до примерно 15,528 USDT/i6, атакующий смог напрямую реализовать огромный спред между этими двумя ценами.

  • Шаг 6: После погашения флэш-займа атакующий сохранил 273,802e18 USDT, что и составило фактическую прибыль от атаки.

Заключение

Первопричина заключается в том, что функция, влияющая на спотовую цену (invest()), и функция, производящая расчет по TWAP (withdraw()), могли быть скомпонованы в рамках одной транзакции, позволяя им видеть разные цены для одного и того же состояния пула.

Чтобы предотвратить этот класс недостатков, протоколам, сочетающим взаимодействия с AMM с отложенным ценообразованием, следует избегать расчета балансов по TWAP в той же транзакции, в которой сопутствующая функция изменяет спотовую цену базового пула, и вместо этого привязывать выплаты к реальной реализуемой стоимости пула, а не к устаревшей или производной цене.


4. Инцидент с Drift Protocol

Краткое описание

1 апреля 2026 года (UTC) Drift Protocol в сети Solana был скомпрометирован на сумму примерно $285.3M. Первопричиной был не баг смарт-контракта, а сбой в процессе авторизации мультиподписи, усугубленный конфигурацией Security Council 2-из-5 с нулевым таймлоком и механизмом устойчивых nonce Solana, который позволял заранее собранным одобрениям мультиподписи оставаться действительными бесконечно долго, пока атакующий не решит их исполнить. После недель подготовки атакующий побудил двух из пяти подписантов заранее подписать вредоносные транзакции управления, привязанные к аккаунтам устойчивых nonce, впоследствии отправил их для захвата административного контроля, а затем ввел сфабрикованный залоговый актив (CVT), завысил его оракульную цену, ослабил лимиты вывода и вывел реальные активы через Drift Vault (JCNCMF...XJfrw).

Предыстория

Drift Protocol — это DeFi-протокол в сети Solana, поддерживающий маржинальную торговлю, кредитование, спотовые рынки и деривативы. Его высокопривилегированные операции, включая изменения администраторов, создание рынков, конфигурацию оракулов, обновление параметров риска и корректировку лимитов вывода, управляются через фреймворк мультиподписи Squads, а не через единый приватный ключ. На момент атаки Security Council Drift функционировал по конфигурации с порогом 2-из-5 и нулевым таймлоком, что означало, что любые два из пяти подписантов могли авторизовать административные действия с немедленным вступлением в силу. Безопасность этой системы зависит не только от хранения ключей подписантов, но и от целостности всего конвейера одобрения: какая транзакция была создана, что, по мнению подписантов, они одобряли, и совпадали ли итоговые исполненные инструкции с этим контекстом проверки.

Отдельно, аккаунты устойчивых nonce Solana заменяют короткоживущий blockhash на постоянный nonce, хранящийся в выделенном аккаунте, позволяя подписанной транзакции оставаться действительной бесконечно долго, пока nonce не будет продвинут. Этот механизм предназначен для легитимных случаев использования, таких как офлайн-подписание и отложенная отправка, но он вводит критический примитив атаки, разделяя момент подписания транзакции и момент ее исполнения в сети. Как только подписант одобряет транзакцию с устойчивым nonce, одобрение не может быть отозвано, если только владелец nonce вручную не продвинет аккаунт nonce.

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

Первопричина заключается не в баге смарт-контракта, а в трех структурных слабостях в конфигурации управления Drift, которые вместе превратили возможность социальной инженерии в потери $285.3M. Во-первых, устойчивые nonce устранили неявную сеть безопасности истечения срока действия подписи. При нормальных транзакциях на основе blockhash одобрение обманутого подписанта либо исполняется незамедлительно, либо безвредно истекает в узком временном окне, ограничивая масштаб скоординированной эксплуатации. Устойчивые nonce устраняют это ограничение: как только два подписанта Security Council были вынуждены одобрить вредоносные транзакции управления через вводящие в заблуждение запросы на подписание, их подписи оставались эксплуатируемыми бесконечно долго, давая атакующему полный контроль над временем исполнения.

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

Анализ атаки

Атака развернулась в трех отдельных фазах: Предварительная подготовка, в ходе которой атакующий провел многонедельную операцию по созданию фиктивного залогового актива и получению доступа к управлению через вводящие в заблуждение запросы на подписание; Захват управления, в ходе которой две заранее подписанные транзакции с устойчивыми nonce были отправлены в быстрой последовательности для захвата административного контроля; и Извлечение средств, в ходе которой атакующий манипулировал параметрами протокола и вывел реальные активы через пути кредитования протокола. Диаграмма ниже иллюстрирует последовательность выполнения на этих трех фазах.

  • Фаза 1 (Предварительная подготовка): Начиная с 11 марта, атакующий вывел 10 ETH из Tornado Cash и развернул CarbonVote Token (CVT), выпустив 750 миллионов единиц, затем разместил ликвидность на Raydium и использовал wash-трейдинг для формирования искусственной истории цен около $1. Параллельно, к 23 марта было создано четыре аккаунта устойчивых nonce, два из которых связаны с членами Security Council Drift, а два контролируются атакующим, что указывает на то, что по меньшей мере два из пяти подписантов уже подписали транзакции, привязанные к аккаунтам устойчивых nonce. 27 марта Drift провела запланированную миграцию Security Council из-за смены участника, аннулировав ранее собранные подписи; однако к 30 марта атакующий заново получил требуемый порог в новой конфигурации, демонстрируя активный мониторинг изменений в управлении сетью и адаптацию в реальном времени.

  • Фаза 2 (Захват управления): 1 апреля примерно в 16:05 UTC, спустя около одной минуты после того, как Drift выполнила легитимный тестовый вывод средств из страхового фонда, атакующий отправил две заранее подписанные транзакции с устойчивыми nonce с интервалом в четыре слота. Первая транзакция (2HvMSg...2C4H) создала и одобрила вредоносное предложение о передаче прав администратора. Вторая транзакция (4BKBmA...RsN1) одобрила и исполнила его, начиная с AdvanceNonceAccount для активации сохраненного nonce, проходя через proposalApprove и vaultTransactionExecute, и в конечном итоге вызвав UpdateAdmin для передачи административного контроля на адрес, контролируемый атакующим.

  • Фаза 3 (Извлечение средств): Получив полные административные привилегии, атакующий создал залоговый рынок для CVT, переключился на контролируемый им оракул для завышения его балансовой цены, а также повысил или полностью снял лимиты вывода на основных рынках активов. Затем атакующий внес большое количество завышенного CVT в протокол и выполнил 31 быстрый вывод средств примерно за 12 минут, выведя USDC, JLP, SOL, cbBTC, USDT, wETH, dSOL, WBTC, JTO и FARTCOIN на общую сумму убытков примерно $285.3M, рассчитанную на основе счета вывода атакующего (HkGz4K...pZES).

Заключение

Первопричиной данного инцидента является не уязвимость смарт-контракта или компрометация ключа, а сбой в процессе авторизации мультиподписи в сочетании с отложенным исполнением на основе устойчивых nonce и административным путем с нулевым таймлоком. Заранее собранные одобрения, которые в норме истекли бы в течение нескольких минут, оставались бесконечно эксплуатируемыми, и как только они были отправлены, захват прав администратора и последующее извлечение средств не оставили окна для вмешательства.

Смягчение этого класса риска требует защиты всего конвейера авторизации, а не только хранения ключей подписантов, обеспечения таймлоков для высокопривилегированных операций и рассмотрения механизмов отложенного исполнения, таких как устойчивые nonce, как отдельной поверхности угрозы, требующей более высоких порогов подписи, ограниченных по времени или отзываемых одобрений, а также ограничений против бесконечно действительных подписанных транзакций.


5. Инцидент с LML Staking Protocol

Краткое описание

1 апреля 2026 года протокол стейкинга LML в сети BNB Chain был эксплуатирован на сумму примерно $950K. Первопричиной была несогласованность в логике расчета вознаграждений: конвертация вознаграждений считывала сохраненную цену LML/USDT, заблокированную периодом обновления в 3600 секунд, в то время как выплачиваемый LML мог быть выкуплен по живой цене AMM без какой-либо проверки отклонения между этими двумя значениями. Атакующий использовал флэш-займы для завышения спотовой цены пула и делегирование кода EIP-7702 для пакетного получения вознаграждений для 11 предварительно застейканных EOA-адресов в одной транзакции, получая непропорционально большое количество LML по устаревшей сохраненной цене и продавая его обратно через теперь сильно искаженный пул с прибылью.

Предыстория

LML — это протокол стейкинга в сети BNB Chain, где пользователи стейкают BNB через контракт APower для получения токенов LML в качестве вознаграждения. Вознаграждения вычисляются в терминах USDT, а затем конвертируются в суммы LML на основе сохраненной протоколом цены LML/USDT перед распределением. Сохраненная цена обновляется функцией updatePrice(), которая считывает спотовую цену AMM, но обеспечивает соблюдение периода охлаждения в 3600 секунд между обновлениями. Заявки на вознаграждение инициируются через receive() контракта APower на основе msg.sender, поэтому только исходный адрес стейкинга может получить свои собственные вознаграждения.

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

Основной недостаток в контракте стейкинга (0xbe9713...adce19) заключается в том, что начисление и погашение вознаграждений привязаны к двум разным ценам одного и того же пула без какой-либо проверки согласованности между ними. Формула вознаграждения reward += (10^18 * base_reward) / stored_price вычисляет выплату в LML на основе _prices[] — сохраненной протоколом цены LML/USDT, которая обновляется функцией updatePrice() только после периода охлаждения в 3600 секунд, однако выплачиваемый LML немедленно может быть выкуплен по живой спотовой цене AMM. Любая внешняя активность, изменяющая спотовую цену в течение этого периода охлаждения, открывает разрыв между замороженной ценой начисления и живой ценой продажи, и ничто в контракте не отклоняет заявку, когда этот разрыв становится необоснованным.

Второй структурный недостаток заключается в том, как пополняется источник вознаграждений. Когда баланса LML контракта PROOF недостаточно для выплаты заявки, функция swapBack() пополняет его, вызывая super._transfer(swapPair, PROOF, deficit) с последующим sync(), напрямую выводя LML из резервов LP-пары и приводя сохраненное состояние пары в соответствие, а не проходя через обычный обмен. Поскольку этот путь обходит механизм ценообразования пары, каждая заявка, запускающая его, уменьшает резервы LML пары и еще больше смещает спотовую цену без какого-либо компенсирующего притока токенов, поэтому повторяющиеся заявки механически увеличивают разрыв между замороженной сохраненной ценой и живой ценой продажи.

Анализ атаки

Следующий анализ основан на транзакциях 0x805d...5b47, 0x70f7...3572.

  • Шаг 1: Атакующий агрегировал большое количество USDT и WBNB через флэш-займы от Moolah, заимствуя у Venus и Moolah Pool (используя WBNB в качестве обеспечения), а также флэш-займы от PancakeSwap V4, нескольких пулов V3 и пулов V2. Этот капитал был необходим для манипуляции ценой пары LML/USDT.

  • Шаг 2: Атакующий вызвал swapAndTrans() в контракте токена LML, что обменяло накопленные в контракте комиссии LML на USDT. Это истощило собственный баланс LML контракта LML, а это означало, что он больше не мог служить локальным источником токенов, и любое последующее распределение вознаграждений должно было бы забирать LML из LP-пары через swapBack().

  • Шаг 3: Атакующий обменял USDT на LML через PancakeRouter swapExactTokensForTokensSupportingFeeOnTransferTokens, при этом получателем был установлен мертвый адрес. Приобретенные токены LML были сожжены, а не получены атакующим. Единственной целью было истощить LML из пары и завысить цену LML на AMM, атакующему не нужны были сами токены, только ценовое искажение.
  • Шаг 4: Атакующий ранее внес депозиты в протокол стейкинга, используя 11 EOA-адресов. Поскольку receive() контракта APower запускает _claimReward(msg.sender) на основе msg.sender, вознаграждения могут быть получены только самим адресом, внесшим депозит. Чтобы получить вознаграждения для всех 11 EOA в рамках одной транзакции, атакующий использовал EIP-7702 для установки кода на этих EOA, позволяя вызывать их как контракты из основного контракта атакующего. Каждый EOA исполнял функцию transfer(rst, fte), которая отправляла небольшое количество BNB в APower, запуская receive(), _claimReward(EOA). Внутри каждой заявки: updatePrice() пропускался (период охлаждения 3600 секунд не был соблюден, поэтому stored_price оставалась на историческом низком уровне), updateUser() вычислял вознаграждение по устаревшей низкой цене, sendMining() переводил LML из PROOF в APower, а затем запускал swapBack(), который пополнял PROOF, забирая LML из LP-пары и вызывая sync(), дополнительно уменьшая резервы пары. Наконец, claimReward() распределял LML на EOA, и каждый EOA переводил полученный LML обратно на контракт атакующего.
  • Шаг 5: Атакующий обменял накопленный LML обратно на USDT через теперь сильно истощенный пул по чрезвычайно завышенной цене.

  • Шаг 6: Погасил все флэш-займы, заимствования и комиссии. Перевел оставшуюся прибыль.

Заключение

Первопричина заключается в несоответствии между начислением и погашением вознаграждений в контракте стейкинга: выплаты рассчитываются на основе сохраненной цены LML/USDT, заблокированной периодом охлаждения в 3600 секунд, но рассчитываются в LML, реальная стоимость которого отслеживает живую цену AMM, без какой-либо проверки отклонения, связывающей эти два значения. Путь пополнения swapBack() усиливает этот недостаток, забирая LML непосредственно из LP-пары при каждой заявке, механически увеличивая разрыв между замороженной сохраненной ценой и живой ценой продажи по мере обработки большего числа заявок.

Протоколам стейкинга, которые рассчитывают вознаграждения на основе цен, полученных из AMM, следует обеспечивать проверку отклонения между сохраненной ценой и текущей спотовой ценой в момент заявки и отклонять транзакцию, когда разрыв превышает безопасный порог, а также избегать механизмов пополнения, которые изменяют резервы LP вне обычных путей обмена, поскольку такие механизмы обходят механизм ценообразования, который в противном случае ограничивал бы ущерб от устаревшего ценообразования.


6. Инцидент с Tactile

Краткое описание

1 апреля 2026 года Tactile, протокол многоуровневых депозитов в сети Polygon, понес убытки в размере ~$12K. Первопричиной была несогласованность в логике расчетов депозитов и выводов: как вход, так и выход конвертировались по текущей спотовой цене CES, а внутренняя доля не содержала никакой записи о стоимости актива, по которой она была изначально выпущена. Атакующий воспользовался этим, завышая спотовую цену перед внесением депозита для получения непропорционально больших долей, а затем занижая цену перед выводом средств для выкупа большего количества CES за долю, повторяя этот цикл через вспомогательные контракты для извлечения прибыли.

Предыстория

Tactile — это протокол многоуровневых депозитов в сети Polygon, где пользователи вносят CES в платежный контракт согласно выбранному уровню. Требуемая сумма депозита вычисляется на основе текущей спотовой цены CES и конфигурации уровня, и пользователю зачисляется внутренняя учетная доля, представляющая его позицию. При выводе средств зафиксированная доля конвертируется обратно в CES по спотовой цене на момент выхода, а не путем расчета по первоначально внесенной сумме, поэтому балансы пользователей фактически отслеживаются как ценозависимые учетные единицы, а не фиксированные суммы активов.

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

Основной недостаток в платежном контракте (0x9153e1...09b654) заключается в том, что депозит и вывод рассчитываются по одному и тому же оракулу спотовой цены в два разных момента времени без какой-либо неизменной привязки, связывающей их. В момент депозита контракт считывает getActualPrice() и конвертирует внесенный CES во внутреннюю долю на основе текущей цены; в момент вывода та же доля конвертируется обратно в CES с использованием спотовой цены на момент выкупа.

Поскольку сама доля не содержит записи о цене или сумме актива, по которой она была выпущена, любое изменение спотовой цены между этими двумя моментами напрямую превращается в несоответствие между внесенным и выведенным CES, делая учет протокола полностью зависимым от траектории цены, а не от стоимости базового актива.

Анализ атаки

Следующий анализ основан на транзакции 0xc321...da74.

  • Шаг 1: Атакующий сначала занял 55,365e18 CES из флэш-пула Uniswap V3 и распределил средства по 5 вспомогательным контрактам. Каждый вспомогательный контракт сначала получил 6,426e18 CES, а затем вызвал deposit(12). В процессе каждый вспомогательный контракт сначала запрашивал getPriceForLevel(12), а затем подготавливал сумму CES, необходимую для этого депозита, на основе текущей цены.
  • Шаг 2: После того как все 5 вспомогательных контрактов завершили первый раунд deposit, атакующий выбросил 300,000 CES на DEX, снизив цену, используемую bank, с 1.067585 до 0.688542. Затем 5 вспомогательных контрактов по очереди выполнили withdraw, выкупая доли, созданные ранее по высокой цене, в CES по теперь более низкой цене. Каждый вспомогательный контракт получил 9,427e18 CES.
  • Шаг 3: После завершения первого раунда withdraw атакующий обменял полученный контрагентский актив обратно на CES, снова подтолкнув цену вверх. Затем атакующий повторил Шаги 2-3.

  • Шаг 4: Наконец, после нескольких циклов атаки, и после погашения флэш-займа плюс комиссии за флэш-займ в размере 166.097975017841805126 CES, у атакующего осталось 567,736e18 CES в качестве прибыли.

Заключение

Первопричина данного инцидента заключается в том, что Tactile рассчитывал как депозит, так и вывод по манипулируемой спотовой цене, не привязывая учетную долю к сумме актива или цене на момент депозита, оставляя свой внутренний учет полностью подверженным любому движению цены между входом и выходом.

Протоколам, выпускающим долеподобные позиции против волатильного актива, следует привязывать каждую долю к конкретной сумме актива или цене на момент выпуска, чтобы погашение воспроизводило первоначальную экономическую стоимость, а не переоценивалось по живому оракулу. Там, где функции расчета должны ссылаться на текущую цену, им следует использовать средневзвешенные по времени или иным образом устойчивые к манипуляциям источники и избегать считывания той же спотовой цены, которая может быть изменена сделками, выполненными в той же транзакции, что и вызов расчета.


7. Инцидент с токеном SAS

Краткое описание

2 апреля 2026 года токен SAS в сети BNB Chain был эксплуатирован на сумму ~$12K. Первопричиной был недостаток в пользовательской логике перевода токена: отправка SAS в LP-пул только увеличивала глобальный счетчик sellBurn, и любой последующий обычный перевод мог затем сжечь SAS непосредственно из пула и вызвать sync() для перезаписи его резервов, полностью минуя логику обмена AMM. Атакующий воспользовался этим, накапливая sellBurn через продажи, запуская несвязанный обычный перевод для сжигания SAS из пула и снижения его резерва до 1 вея, а затем совершая обратный обмен оставшегося SAS с прибылью.

Предыстория

SAS — это дефляционный токен в сети BNB Chain с пользовательской логикой перевода, построенной поверх пула PancakeSwap V2. Функция transfer() различает два пути: путь продажи, запускаемый, когда получателем перевода является LP-пул, который увеличивает глобальный аккумулятор sellBurn на переведенную сумму; и путь обычного перевода, который, когда sellBurn не равен нулю, сжигает SAS непосредственно из LP-пула, а затем вызывает sync() для обновления его резервов до нового текущего баланса. Эти два пути предназначены для совместной работы как дефляционный механизм, уменьшающий резерв SAS в пуле в ответ на накопленное давление продаж.

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

Основной недостаток в контракте токена SAS (0xbfa266...3d91c6) заключается в том, как дефляционный механизм встроен в transfer(). Когда SAS отправляется в LP-пул, контракт увеличивает глобальный аккумулятор sellBurn на переведенную сумму. Затем при любом последующем обычном переводе, если sellBurn не равен нулю, контракт вызывает _burnFromPair() для сжигания SAS непосредственно из LP-пула и следует за этим вызовом sync(), который перезаписывает резервы пула в соответствии с его текущим балансом.

Проблема заключается в том, что этот путь сжигания и синхронизации перезаписывает резервы пула, минуя логику обмена AMM. Как только sellBurn был повышен переводами в пул, несвязанный обычный перевод достаточен для запуска сжигания и синхронизации, вынуждая резерв SAS в пуле стремиться к нулю и создавая крупное ценовое искажение, которое затем может быть извлечено через обычный обмен.

Анализ атаки

Следующий анализ основан на транзакции 0x878e...adc5.

  • Шаг 1: Атакующий занял WBNB через флэш-займ.

  • Шаг 2: Атакующий обменял WBNB на SAS.

  • Шаг 3: Атакующий развернул контракт и выполнил логику атаки в constructor(). Это было использовано для обхода проверки is_contract() протокола, поскольку контракт токена требовал, чтобы отправитель transfer() был либо адресом из белого списка, либо EOA.

  • Шаг 4: Атакующий перевел SAS в пул, что запустило путь продажи и накопило sellBurn.
  • Шаг 5: Атакующий развернул второй контракт и снова, внутри его constructor(), инициировал обычный перевод. Поскольку sellBurn уже был не равен нулю после Шага 4, этот перевод запустил функцию _burnFromPair(), которая сожгла SAS непосредственно из LP-пула, а затем вызвала функцию sync(), уменьшив резерв SAS до 1 вея.
  • Шаг 6: Атакующий выполнил обратный обмен и продал оставшийся SAS с прибылью.

Заключение

Первопричина данного инцидента заключается в недостатке пользовательской логики перевода токена SAS: обычный перевод мог напрямую сжигать SAS из LP-пула и синхронизировать его резервы с уменьшенным балансом, позволяя превращать накопленную активность продаж в произвольное уменьшение резерва SAS в пуле, а оттуда — в крупное ценовое искажение, которое затем можно было извлечь через обычный обмен.

Токены не должны вмешиваться во внешний пул AMM и изменять его резервы вне обычных путей обмена. Если дефляционный дизайн действительно требует сжигания из пула, сжигание и сопутствующий вызов sync() должны быть привязаны к строго контролируемому внутреннему триггеру, например, доверенному хранителю или расписанию с ограниченной частотой, а не подключены к произвольным пользовательским переводам.


8. Инцидент Unknown-EIP-7702

Краткое описание

3 апреля 2026 года пользовательский аккаунт в сети BNB Chain, который включил делегированный код через EIP-7702, был опустошен на ~$17.2K. Делегированный код предоставлял функцию pancakeV3SwapCallback() без надлежащего контроля доступа. Атакующий напрямую вызвал этот колбэк с подготовленными данными вызова, вынудив аккаунт жертвы перевести свои токены на адрес, контролируемый атакующим.

Предыстория

EOA жертвы использовал транзакцию EIP-7702 типа 4 для установки делегированного кода, чтобы аккаунт мог выполнять логику, связанную с обменом. Однако делегированная реализация включала публичную функцию pancakeV3SwapCallback(), которая должна была вызываться только во время легитимного колбэка пула PancakeSwap V3.

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

Первопричина заключается в отсутствии контроля доступа в функции pancakeV3SwapCallback() делегированного контракта (0x02C809...aEDbAE).

В корректном дизайне колбэка UniswapV3/PancakeV3 колбэк должен проверять, что msg.sender является ожидаемым каноническим пулом (полученным из фабрики + пары токенов + комиссии, или проверенным против доверенного списка пулов). В данном случае эта проверка отсутствовала, поэтому любой внешний вызывающий мог вызвать колбэк напрямую.

Поскольку колбэк выполняет переводы токенов из аккаунта, в котором он размещен, отсутствие проверки msg.sender означает, что любой внешний вызов с положительными amount0Delta/amount1Delta попадает в путь оплаты внутри колбэка и выводит токены из аккаунта жертвы, без фактического совершения обмена.

Анализ атаки

Следующий анализ основан на транзакции 0x5b2c...4261.

  • Шаг 1: Атакующий напрямую вызвал pancakeV3SwapCallback() с подготовленными параметрами, запустив логику перевода в колбэке для вывода токенов жертвы на адреса, контролируемые атакующим.

Заключение

Данный инцидент был вызван развертыванием логики колбэка обмена на аккаунт EIP-7702 без строгой аутентификации колбэка. Поскольку функции pancakeV3SwapCallback() не хватало контроля доступа, колбэк мог быть вызван любым внешним вызывающим и использован для вывода токенов из аккаунта жертвы без фактического совершения легитимного обмена.

Для любого контракта или делегированного кода EIP-7702, реализующего колбэки в стиле V3, разработчики должны проверять, что msg.sender является каноническим пулом PancakeV3 (полученным из доверенной фабрики, пары токенов и уровня комиссии), прежде чем колбэк перейдет к какой-либо логике перевода.


9. Инцидент с Silo Finance

Краткое описание

3 апреля 2026 года хранилище soUSDC протокола Silo Finance в сети Arbitrum было эксплуатировано на сумму примерно $359K. Первопричиной стало совпадение трех дефектов: неизменяемого оракула wstUSR, который по-прежнему оценивал токен на уровне ~1.133 даже после того, как его рыночная цена обвалилась до ~0.12, механизма лимита предложения на soUSDC, который ограничивал только собственные депозиты хранилища, но не внешние, и недостатка учета totalAssets(), который учитывал внешне зачисленные доли bUSDC без выпуска соответствующих долей soUSDC. Внося USDC напрямую на рынок wstUSR с нулевым лимитом с параметром receiver=soUSDC, атакующий завысил цену доли хранилища, занял тот же USDC обратно под завышенное залоговое обеспечение wstUSR и выкупил ранее приобретенные доли soUSDC по завышенной оценке, а недостача была покрыта из других здоровых рынков в очереди на вывод.

Предыстория

Silo Finance — это протокол кредитования с изолированным риском в сети Arbitrum. Каждый рынок Silo представляет собой двустороннюю кредитную пару (например, wstUSR/USDC): заемщики вносят залог (wstUSR) и заимствуют кредитный актив (USDC), в то время как кредиторы вносят USDC и зарабатывают проценты. Когда кредитор вносит USDC на определенный рынок, он получает токен доли депозита этого рынка. Когда заемщик вносит залог, он получает токен доли залога (например, bwstUSR-149).

soUSDC — это SiloVault, который находится поверх нескольких рынков Silo для агрегации кредитования USDC. Пользователи вносят USDC в soUSDC и получают доли soUSDC. Затем хранилище направляет внесенный USDC на одобренные рынки Silo на основе лимитов предложения, установленных аллокатором, и само хранилище хранит доли bUSDC каждого рынка, в который оно внесло депозит. Когда пользователь выкупает доли soUSDC, хранилище рассчитывает, сколько USDC стоят эти доли, используя totalAssets(), которая перебирает каждый рынок в очереди на вывод и суммирует баланс долей bUSDC хранилища на каждом из них. Затем хранилище выводит USDC из своих базовых рынков для выплаты выкупающему.

wstUSR (Wrapped Staked USR) — это стейкинг-дериватив стейблкоина USR, выпущенного Resolv. После того как Resolv была эксплуатирована, USR потерял привязку, stUSR также потерял привязку, а вторичная рыночная цена wstUSR обвалилась до ~0.12. Однако Chainlink-фид для wstUSR отслеживал только обменный курс wstUSR/stUSR (~1.133), а протокол неявно предполагал, что 1 stUSR = 1 USD, поэтому оракул продолжал оценивать wstUSR на уровне ~1.133, что представляло собой разрыв примерно в 10 раз по сравнению с рыночной реальностью.

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

Адрес оракула рынка wstUSR/USDC жестко закодирован как неизменяемый в SiloConfig и не может быть заменен. Сам контракт оракула (0x836a1a...04425e) представляет собой ChainlinkV3Oracle, чей базовый Chainlink-фид (описание: «wstUSR / stUSR Exchange Rate») отслеживает только коэффициент обертывания wstUSR в stUSR (~1.133), а не цену на вторичном рынке. Протокол неявно предполагает, что 1 stUSR = 1 USD, поэтому он оценивает wstUSR на уровне ~1.133. После того как USR потерял привязку, stUSR также потерял привязку, и wstUSR обвалился до ~0.12 на открытом рынке, но оракул продолжал сообщать ~1.133, что представляло собой примерно 10-кратную переоценку.

Протокол частично осознавал риск: лимит предложения soUSDC для рынка wstUSR был установлен на 0, что означало, что хранилище никогда не направит USDC туда добровольно. Однако этот лимит регулирует только собственные исходящие вызовы deposit() хранилища. Поскольку wstUSR_Market.deposit() принимает произвольный параметр receiver, любой может внести USDC напрямую на рынок wstUSR и зачислить полученные доли bUSDC на адрес soUSDC, полностью обходя лимит предложения.

Это создает основной путь эксплуатации. Когда доли bUSDC попадают на баланс soUSDC через такой внешний депозит, totalAssets() учитывает их: она перебирает каждый рынок в очереди на вывод и считывает фактический баланс долей хранилища, без какой-либо проверки того, была ли позиция добровольно открыта. Между тем, для этих внешне зачисленных позиций не выпускаются новые доли soUSDC, поскольку собственная логика выпуска хранилища никогда не вызывалась. Результатом является то, что totalAssets увеличивается, а totalShares остается прежним, завышая цену доли soUSDC.

Анализ атаки

Следующий анализ основан на транзакции 0xf77a...f3e1.

Атакующий сначала купил wstUSR на вторичном рынке по цене ~0.12 за токен.

  • Шаг 1: Флэш-займ ~4,236,352 USDC от Morpho. Одной лишь неверной оценки оракула недостаточно — рынок wstUSR имел нулевую ликвидность USDC (лимит=0, soUSDC никогда туда не депонировал), поэтому не было ничего, под что можно было бы занять против завышенного залога. Флэш-займ предоставляет капитал, необходимый для последующих шагов депозита и «пожертвования».

  • Шаг 2: Внесение wstUSR на рынок wstUSR в качестве залога и получение bwstUSR-149. Это подготовка к заимствованию на Шаге 5 — оракул оценивает 13,797 wstUSR примерно в 15,633 (по 1.133 каждый), хотя атакующий заплатил лишь ~1,656.

  • Шаг 3: Внесение ~4,222,007 USDC в хранилище soUSDC, получение долей soUSDC (~91.5% от общего предложения). Хранилище направляет этот USDC на существующие здоровые рынки (не на рынок wstUSR, поскольку лимит=0). Эти доли soUSDC являются инструментом для извлечения прибыли на Шаге 6 — чем больше долей держит атакующий, тем больше он выигрывает при завышении цены доли.
  • Шаг 4: Внесение ~14,344 USDC напрямую на рынок wstUSR через wstUSR_Market.deposit(receiver=soUSDC) и выпуск bUSDC-149 на soUSDC. Полученные доли bUSDC зачисляются на адрес soUSDC, а не на адрес атакующего. Это ключевая манипуляция: totalAssets() soUSDC теперь включает эти доли bUSDC по номинальной стоимости (~14,344 USDC), но новые доли soUSDC не выпускаются, поскольку собственная логика депозита хранилища никогда не вызывалась — totalAssets растет, totalShares остается прежним, и цена доли soUSDC завышается. Одновременно это создает ликвидность USDC на ранее пустом рынке wstUSR, что необходимо для следующего шага.
  • Шаг 5: Заимствование ~14,344 USDC с рынка wstUSR с использованием залога, внесенного на Шаге 2. Оракул оценивает залог примерно в 15,633, поэтому при максимальном LTV 92% атакующий может занять ~14,344. Это возвращает USDC, «пожертвованный» на Шаге 4 — заимствование и «пожертвование» нейтральны по денежному потоку. Но рынок wstUSR теперь полностью истощен: весь USDC был заимствован, оставив лишь непогашенный кредит, обеспеченный почти бесценным залогом wstUSR. soUSDC по-прежнему держит доли bUSDC по номинальной стоимости в totalAssets().
  • Шаг 6: Выкуп всех долей soUSDC, приобретенных на Шаге 3. Цена доли теперь завышена после «пожертвования» на Шаге 4, поэтому атакующий получает ~4,235,143 USDC, что примерно на 13,136 больше, чем 4,222,007, внесенных на Шаге 3. Хранилище пытается вывести средства с рынка wstUSR, но обнаруживает нулевую ликвидность (заимствовано на Шаге 5), поэтому оно забирает недостачу с других здоровых рынков в очереди на вывод. Именно здесь материализуются убытки: реальный USDC с рынков других вкладчиков soUSDC переводится для покрытия завышенного выкупа.
  • Шаг 7: Погашение флэш-займа.

После 32 циклов soUSDC остается держателем позиций bUSDC на рынке wstUSR, номинально оцененных в ~359K, но обеспеченных залогом wstUSR, стоящим лишь малую долю от этой суммы — 100% использование, фактически невосстановимый плохой долг, ложащийся на оставшихся вкладчиков soUSDC.

Заключение

Данный инцидент был вызван совпадением оракула, отслеживающего курс стейкинг-обмена, а не рыночную цену обесценившегося актива, системы учета хранилища, которая учитывала внешне зачисленные позиции в totalAssets() без выпуска соответствующих долей, и механизма лимита предложения, который ограничивал только собственные депозиты хранилища, но не внешние. Неизменяемость адреса оракула в SiloConfig предотвратила любое экстренное исправление после того, как проблема стала очевидной.

Протоколам хранилищ, агрегирующим кредитные рынки, следует обеспечить, чтобы totalAssets() учитывала только позиции, в которые хранилище вошло через свои собственные операции депозита, а не внешне зачисленные балансы долей. Адреса оракулов не должны быть постоянно неизменяемыми; должны существовать механизмы экстренного управления для обновления ценовых фидов, когда базовые активы теряют привязку.


Начните работу с Phalcon Security

Обнаруживайте каждую угрозу, оповещайте о важном и блокируйте атаки.

Попробовать бесплатно

О BlockSec

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

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

Sign up for the latest updates
Мост Harmony Cross-Shard ONE Mint + потеря ключей на ~$47М | BlockSec
Security Insights

Мост Harmony Cross-Shard ONE Mint + потеря ключей на ~$47М | BlockSec

10-16 авг 2026: 5 инцидентов, ~$47М убытков. Анализ — уязвимость Harmony: replay чеков между шардами создал 3.01Т ONE (не учтено в убытках). $47М — кражи ключей (Whale ~$25М, Kite ~$14М, Coinsbuy ~$7.9М) и ошибка Fox (~$117K).

~$1.6M потеряно: эксплойты токена Moke и LpdFi | BlockSec Weekly
Security Insights

~$1.6M потеряно: эксплойты токена Moke и LpdFi | BlockSec Weekly

За неделю 3-9 августа 2026 года в BNB Chain произошло 2 инцидента с общими потерями ~$1,6 млн из-за манипуляций с ценами. LpdFi (~$697K): атакующий использовал резервы PancakeSwap для завышения позиции. Moke Token (~$906K): манипуляция ценой и дублирование дивидендов LP.

Инцидент с COLDCARD: когда «случайная» сид-фраза кошелька оказалась не случайной
Security Insights

Инцидент с COLDCARD: когда «случайная» сид-фраза кошелька оказалась не случайной

Ошибка в прошивке COLDCARD направляла генерацию seed на слабый программный ГСЧ, делая кошельки восстановимыми офлайн. Обновление не устраняет проблему. К 7 августа 2026 г. подтверждённые потери — 1 405 BTC (~$91 млн), оценки до 2 055 BTC.

Best Security Auditor for Web3

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

BlockSec Audit