Back to Blog

Убытки $16 млн: DxSale, SquidRouterModule и другие | Еженедельный обзор BlockSec

June 3, 2026
9 min read
Key Insights

За прошедшую неделю (27.05.2026 - 30.05.2026) компания BlockSec выявила многочисленные инциденты атак в различных блокчейн-экосистемах. В таблице ниже перечислены 5 значимых инцидентов с общим объемом предполагаемых убытков около 16 млн долларов США.

Дата Инцидент Тип Оценочный ущерб
27.05.2026 Контракт SquidRouterModule Ненадлежащая проверка входных данных ~$3,2 млн
29.05.2026 Stake DAO Компрометация закрытого ключа ~$91 тыс.*
29.05.2026 DxSale Ошибка бизнес-логики и компрометация ключа ~$7,3 млн
30.05.2026 Gravity Bridge Уязвимый процесс внесетевой подписи ~$5,4 млн
30.05.2026 Alephium Уязвимый процесс внесетевой подписи ~$300 тыс.*

*Дополнительные примечания:

  • В инциденте со Stake DAO злоумышленник скомпрометировал закрытый ключ развертывателя и использовал его для перенастройки контракта LayerZero v2 OFT для vsdCRV в сети Arbitrum, что позволило выпустить 5,4 триллиона токенов vsdCRV. Из-за ограниченной ликвидности на DEX удалось вывести только около 91 тыс. долларов США, после чего пулы были опустошены.
  • В инциденте с Alephium, помимо вывода активов из хранилища моста на сумму около 300 тыс. долларов США (USDT, USDC, WETH, WBTC в сети Ethereum и USDT, WBNB в сети BNB Chain), злоумышленник также выпустил 13,7 млн не обеспеченных токенов wALPH в сети Ethereum. Мост был отключен, что помешало атакующему выкупить или перевести эти токены обратно через мост Alephium.

Для углубленного анализа были выбраны два инцидента:

  • Контракт The SquidRouterModule: Как и в случае с эксплойтом CrossCurveFi, здесь был повторен тот же тип ошибки интеграции, демонстрируя, как перенос кроссчейн-логики без глубокого понимания и тщательной проверки безопасности может быстро превратить унаследованную сложность в унаследованный риск.
  • DxSale: Длительный период до реализации атаки показывает, что неиспользуемые устаревшие контракты не обязательно остаются безопасными, и что протоколы должны постоянно проводить аудит неактивной инфраструктуры, минимизировать привилегированный доступ и никогда не принимать годы тишины за доказательство безопасности.

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

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

Главное событие недели: DxSale

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

29 мая 2026 года платформа по продаже токенов и блокировке ликвидности DxSale в сети BNB Chain подверглась эксплойту [1] на сумму около 7,3 млн долларов США. Функция вывода токенов содержала три пропущенных обновления состояния, которые позволяли любому пользователю с валидной позицией блокировки неоднократно выполнять вывод и опустошить весь общий пул без необходимости обладания правами владельца. Отдельная компрометация ключа развертывателя DxSale через делегирование EIP-7702 не была обязательным условием для эксплойта, но повысила эффективность действий злоумышленника, позволив манипулировать комиссиями и блокировать создание новых локов другими пользователями.

Предыстория

DxSale — это платформа для продажи токенов и блокировки ликвидности в сети BNB Chain. Компонент DxLock позволяет разработчикам проектов блокировать LP-токены в хранилищах с временной блокировкой, что дает инвесторам гарантию того, что ликвидность не будет выведена мошенническим путем (rug-pull).

Основной механизм блокировки работает следующим образом: пользователь вносит токены в контракт-локер, создавая запись о блокировке, индексируемую комбинацией адреса вызывающего абонента и идентификатора токена (token ID). Каждая запись содержит информацию о том, существует ли блокировка, заблокированы ли токены в данный момент, количество заблокированных токенов, временную метку разблокировки и адрес токена. Когда период блокировки истекает, пользователь вызывает unlockToken(tokenId), чтобы вывести свои токены.

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

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

Функция unlockToken в проблемном контракте (0xeb3a...e449) содержала три комплексных дефекта — в каждом случае отсутствовало обновление состояния или проверка:

function unlockToken(uint256 tokenId) public nonPayable {
    require(_increaseLockTime[msg.sender][tokenId].field0_0_0);  // локер существует
    require(_increaseLockTime[msg.sender][tokenId].field0_1_1);  // токены заблокированы
    require(_increaseLockTime[msg.sender][tokenId].field2);       // сумма > 0

    if (block.timestamp > _increaseLockTime[msg.sender][tokenId].field3) {
        _increaseLockTime[msg.sender][tokenId].field0_1_1 = 0;
    }

    v0, v1 = _increaseLockTime[msg.sender][tokenId].field5_0_19.balanceOf(this);
    require(v1 >= _increaseLockTime[msg.sender][tokenId].field2);
    v2, v3 = _increaseLockTime[msg.sender][tokenId].field5_0_19.transfer(
        msg.sender, _increaseLockTime[msg.sender][tokenId].field2
    );
}
  1. Отсутствие принудительного соблюдения периода блокировки. Период блокировки охранялся оператором if, а не require. При вызове до наступления временной метки разблокировки функция просто пропускала очистку флага блокировки вместо выполнения revert. Это означало, что токены можно было вывести в любой момент, независимо от установленного периода блокировки.

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

  3. Проверка общего баланса вместо индивидуального распределения. Вызов balanceOf(this) проверял общий баланс токенов контракта, а не индивидуальную долю вызывающего абонента. Пользователь с небольшой позицией блокировки мог опустошить весь общий пул до тех пор, пока на контракте оставалось достаточно токенов.

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

Анализ атаки

Аккаунт развертывателя DxSale (0x47bacf93), работающий через делегирование EIP-7702, проявлял аномальную активность с 15.04.2026, включая массовые передачи прав собственности, изменение размера комиссий и операции разблокировки LP в нескольких контрактах DxSale. 26.05.2026 развертыватель передал право собственности на целевой локер (0xeb3a...e449) на контракт злоумышленника (0xc457...fa69). Два дня спустя злоумышленник выполнил вывод средств в пять шагов.

Следующий анализ основан на показательной транзакции 0x437b26...c1b303.

  • Шаг 1: Злоумышленник обменял BNB на токены BNBC на PancakeSwap и предоставил ликвидность для создания новой пары Cake-LP (BNBC/WBNB), получив примерно 0,323 LP-токена.

  • Шаг 2: Используя привилегии владельца, полученные в результате предыдущей передачи прав, злоумышленник вызвал changeFees(1), чтобы установить комиссию за создание блокировки в 1 вей, затем вызвал createLocker для депозита примерно 0,323 LP-токенов в новую позицию блокировки (tokenId=131). Сразу после этого злоумышленник вызвал changeFees(10^36), чтобы установить астрономически высокую комиссию, тем самым заблокировав другим пользователям возможность создания новых локов.

  • Шаг 3: Злоумышленник вызвал функцию эксплойта (0x11b432b4), которая организовала повторные вызовы unlockToken в рамках одной транзакции. Через множество транзакций злоумышленник систематически опустошал локер: 0x437b26...c1b303 вывел 161,4 LP-токена через tokenId=131, 0x82f541...a9fa73 и 0x5dd61f...4298aa вывели средства из дополнительных позиций блокировки, а 0xac8f5e...d36df9 вывел 260,3 LP-токена через tokenId=319 за 478 вызовов.

  • Шаг 4: Злоумышленник вызвал removeLiquidity на PancakeSwap, чтобы разбить выведенные LP-токены обратно на составляющие их базовые токены (BNBC и WBNB).

  • Шаг 5: Злоумышленник обменял базовые токены на WBNB и BUSD через PancakeSwap и перевел полученные средства на внешние адреса. BSCScan зафиксировал 123 447 транзакций за 4 дня (с 28.05.2026 по 31.05.2026) для этого контракта злоумышленника.

Заключение

Первопричиной этого инцидента являются три пропущенных обновления состояния в функции unlockToken. Каждое из них имеет прямое решение: применять период блокировки через require вместо if, обнулять заблокированную сумму после каждого вывода и проверять индивидуальную долю вызывающего абонента, а не общий баланс контракта. Одних этих дефектов было достаточно для осуществления эксплуатации; любой пользователь, создавший позицию блокировки, мог опустошить весь общий пул с помощью повторяющихся вызовов, при этом права владельца не требовались.

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

Ссылки

  • [1] Объявление DxSale

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

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

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

Другие инциденты на этой неделе

Контракт The SquidRouterModule

27 мая 2026 года неизвестный контракт под названием SquidRouterModule был взломан [1] в сети Ethereum из-за ненадлежащей проверки входных данных, что привело к убыткам в размере около 3,2 млн долларов США. Первопричиной стало неверное использование интеграции Axelar Bridge, аналогичное паттерну атаки на CrossCurveFi [2]. Контракт не обеспечил надлежащую проверку кроссчейн-сообщений через Axelar Gateway, что позволило злоумышленнику подделать полезные нагрузки (payloads), которые авторизовали и обменивали токены жертв в заранее созданных вредоносных пулах. Отдельный адрес злоумышленника, развернувший поддельный токен и пополнивший пулы, позже вывел ликвидность, чтобы присвоить настоящие активы. Эта атака затронула 86 кошельков Safe. Несмотря на название, SquidRouterModule не был создан, развернут или эксплуатировался командой протокола Squid [3].

Предыстория

Контракт представляет собой модуль сервиса кроссчейн-обмена, разработанный для кошелька Safe на базе кроссчейн-протокола Axelar. Контракт предоставляет функцию expressExecuteWithToken, поддерживающую досрочное выполнение транзакций до подтверждения кроссчейн-сообщения. Перед использованием этого сервиса пользователи должны предварительно авторизовать разрешения APPROVE и SWAP контракта в своем кошельке Safe. При вызове expressExecuteWithToken контракт декодирует инструкции операции из полезной нагрузки и вызывает execTransactionFromModule кошелька Safe для выполнения авторизации и обмена токенов.

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

Функция _executeWithToken в уязвимом контракте (0x1f1d...23ca) проверяла только соответствовал ли srcAddress константе squidRouter. Однако srcAddress — это параметр, предоставляемый вызывающим абонентом, в то время как squidRouter — это неизменяемая строка, которую любой может прочесть из контракта. Это позволило злоумышленнику тривиально обойти проверку и выполнить функцию _processPayload с произвольным содержимым полезной нагрузки.

В отличие от него, функция executeWithToken легитимного Squid Router вызывает gateway.validateContractCallAndMint() и возвращает ошибку NotApprovedByGateway() в случае, если сеть валидаторов Axelar не подтвердила транзакцию.

Уязвимый контракт не требовал никакой подобной авторизации шлюза на пути expressExecuteWithToken. В сочетании с разрешениями APPROVE и SWAP, которые пользователи кошелька Safe предварительно передали модулю, подделанные полезные нагрузки могли напрямую воздействовать на средства жертв.

Анализ атаки

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

Перед атакой отдельный адрес злоумышленника развернул поддельный токен (0xe6Ff...3512) и создал несколько пулов Uniswap V3, каждый из которых связывал поддельный токен с различными ценными токенами (например, USDC, ENA, USDT), обеспечив пулы ликвидностью в виде поддельных токенов.

  • Шаг 1: Злоумышленник создал вредоносные calldata и вызвал функцию expressExecuteWithToken уязвимого контракта, используя известный адрес squidRouter в качестве sourceAddress, чтобы обойти проверку. Через ранее предоставленные жертвой разрешения APPROVE и SWAP, подделанная полезная нагрузка принудительно утвердила одобрение токенов из кошелька Safe жертвы в пользу пула Uniswap.

  • Шаг 2: Используя эти принудительные одобрения, полезная нагрузка обменяла токены жертвы на бесполезные поддельные токены через соответствующий вредоносный пул.

Злоумышленник повторял этот метод в ходе множества транзакций, нацелившись в общей сложности на 86 кошельков Safe, которые авторизовали уязвимый контракт. Отдельный адрес злоумышленника, развернувший поддельный токен и пополнивший пулы, впоследствии вывел ликвидность, чтобы извлечь реальные активы, получив в итоге прибыль около 3,2 млн долларов США.

Заключение

Этот инцидент был вызван ненадлежащей проверкой входных данных на пути обработки кроссчейн-сообщений. Единственная проверка безопасности опиралась на параметр, контролируемый вызывающим абонентом, в сравнении с общедоступной константой, что не обеспечивало реальной защиты. В сочетании с заранее авторизованными разрешениями APPROVE и SWAP от пользователей кошелька Safe, злоумышленник мог подделывать кроссчейн-сообщения и красть средства пользователей.

Инцидент схож с эксплойтом CrossCurveFi [2]: оба связаны с интеграцией Axelar Bridge, которая не смогла должным образом проверить входящие кроссчейн-сообщения. При интеграции инфраструктуры обмена кроссчейн-сообщениями целевой контракт должен независимо проверять подлинность сообщений через механизм авторизации моста. Пропуск этой проверки и опора на контролируемые злоумышленником входные данные превращают интеграцию в открытую поверхность для атаки.

Ссылки

  • [1] Phalcon Alert: эксплойт SquidRouterModule
  • [2] Phalcon Alert: паттерн атаки CrossCurveFi
  • [3] Разъяснения от Squid Router

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

Выявляйте любые угрозы, получайте уведомления о важном и блокируйте атаки.

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

О компании BlockSec

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

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