Злоумышленник опустошил 299 кошельков The Red Village

21 сентября 2026 года злоумышленник не взламывал кошельки игроков и не крал приватные ключи. Он воспользовался тем, что один из контрактов The Red Village можно было попросить сделать что угодно.
Введение
The Red Village — блокчейн-игра на Polygon, в которой игроки участвуют в турнирах с ставками в WETH (это обёрнутый эфир — стандартная версия ETH для использования в смарт-контрактах). Для работы игры и турниров игроки заранее выдавали специальному контракту TRVZooKeeper разрешение — approve — распоряжаться их WETH. Это стандартная практика: один раз выдал разрешение, и игра сама списывает и возвращает ставки без лишних подтверждений.
В системе было несколько контрактов с разными ролями:
- PolygonTRVRouter — маршрутизатор, посредник между пользователем и другими контрактами игры.
- SeasonService — контракт, управляющий игровыми сезонами и имеющий права на работу со средствами через TRVZooKeeper.
- TRVZooKeeper — контракт-«хранитель», который принимает и выдаёт WETH игроков.
Все три части работали вместе — и именно неправильная настройка связей между ними открыла дверь для атаки.
Ход инцидента
- Обнаружение открытой функции. В PolygonTRVRouter существовала публичная функция
forwardRequest(). Публичная — значит, вызвать её мог любой адрес без какой-либо проверки прав. Функция позволяла пользователю указать, к какому сервису обратиться и с какими данными — и Router добросовестно выполнял эту инструкцию. - Замена кода SeasonService. Проблема в том, что сам Router обладал административными правами: в частности, он мог авторизовать обновление контракта SeasonService — то есть заменить его внутренний код на новый. Злоумышленник воспользовался
forwardRequest()и через Router отдал команду заменить реализацию SeasonService на собственный вредоносный контракт.
Это как если бы охранник на входе (Router) имел право менять инструкции кассира (SeasonService) — и при этом выполнял любые указания с улицы, не проверяя, кто их даёт.
- Получение прав на средства игроков. После подмены вредоносный контракт занял место SeasonService — и вместе с ним получил все его привилегии в системе TRVZooKeeper. Это означало право принимать и выводить WETH игроков.
- Списание средств с 299 кошельков. Через несколько минут после подмены злоумышленник воспользовался полученными правами: через функцию
transferERC20InWETH был списан примерно с 299 кошельков, которые ранее выдали TRVZooKeeper разрешение работать с их токенами. Затем черезtransferERC20Outвесь собранный баланс — около 31,43 WETH — был отправлен на адрес атакующего.
Почему это стало возможным
Корень проблемы — в неправильно настроенном контроле доступа. Функция forwardRequest() была публичной без каких-либо ограничений, но при этом Router обладал привилегированными правами. Любой пользователь мог «попросить» Router сделать то, что обычному пользователю было бы недоступно напрямую — в том числе авторизовать замену кода другого контракта.
Это типичная ошибка, при которой доверенный посредник становится точкой обхода системы безопасности: прямо к SeasonService злоумышленник не имел доступа, но через Router — имел.
Вторая часть проблемы: разрешения approve, которые игроки ранее выдали TRVZooKeeper, оставались действующими. После подмены SeasonService новый вредоносный контракт просто воспользовался ими — совершенно законно с точки зрения блокчейна.
Детали расследования: движение средств
После списания с 299 кошельков около 31,43 WETH поступили на контракт злоумышленника 0x426d2719... в сети Polygon, а затем на адрес 0xa566592CB94475BaF5B46Ce373A260dfC9d0dF3F.
Оттуда средства были переправлены через протокол LiFi — сервис для перевода активов между разными блокчейнами — на тот же адрес злоумышленника, но уже в сети Ethereum. Там 32,42 ETH были обменяны на около 86 175 DAI.
На момент расследования средства остаются на адресе злоумышленника в сети Ethereum без движения.
Заключение
Атака на The Red Village показывает, насколько важно правильно выстраивать цепочку доверия между контрактами. Злоумышленник не получил ни одного приватного ключа и не взламывал ни одного кошелька напрямую. Он просто воспользовался открытой функцией в доверенном посреднике — и тот сделал всё остальное.
299 игроков лишились WETH, которые были заблокированы как ставки или разрешения для игровых операций. Средства в размере ~86 тыс. DAI остаются на известном адресе без движения.

