X100 governance flaws trigger $6M loss due to a flash loan
Краткое изложение
- Злоумышленник, атаковавший X100, получил два места в Сенате и погасил флэш-кредит, при этом приобретенная доля оставалась заблокированной в течение года.
- В голосовании, проводившемся на платформе Arkadiko в течение примерно пяти дней, допускалась поздняя покупка токенов, а затем был активирован вредоносный контракт без дополнительной задержки исполнения.
- 27 октября Arkadiko восстановила легитимную запись в контракте, но одного этого изменения недостаточно для подтверждения возврата залога или компенсации.
Злоумышленник все еще получил два места в системе управления X100, токеновом проекте с казначейством, управляемым Сенатом, одобрил транзакцию казначейства и погасил флэш-кредит в одной транзакции блокчейна 24 октября.
На платформе Arkadiko, протоколе кредитования, где пользователи берут кредиты под залог, голосование, которое должно было длиться около пяти дней, завершилось на два дня раньше, предоставив вредоносному контракту контроль над активами. Пользователи приобретали токены для голосования незадолго до решающего голосования, и предложение вступило в силу после завершения голосования.
Эти инциденты выявляют различные несоответствия между выделением средств, получением права голоса и выполнением утвержденного действия. Токены X100 должны быть заблокированы на год, поэтому длительная блокировка токенов может повлечь за собой определенные издержки, не задерживая при этом процесс принятия решений.
В то же время длительное голосование может служить предупреждением, при этом все еще допускается поздняя покупка токенов. Ни то, ни другое автоматически не создает времени для реагирования после того, как решение становится применимым.
Заблокированная доля X100 обеспечила немедленный контроль
Контракт Freezer от X100 хранит замороженные токены X и предоставляет долю, используемую для определения кандидатов в Сенат. Срок блокировки составляет один, три или пять лет, но для определения права на участие в Сенате используется текущее количество замороженных токенов, без минимального срока владения долей.
В первой атаке, произошедшей 24 октября, два вспомогательных контракта заморозили по 19 000,000001 X на срок в один год. Они зарегистрировались, вошли в рейтинг и предоставили два голоса, необходимые для выполнения предложения 7. Они завершили процесс распределения долей, голосования и исполнения в одной транзакции.
Срок действия системы управления не предусматривал обязательного периода ожидания. Пока предложение оставалось открытым, большинство мест в Сенате, занимающих лидирующие позиции, могли санкционировать его выполнение. Владение двумя из трех мест дало вспомогательным контрактам достаточно власти для немедленных действий.
Одобренная сделка отправила 400 000 токенов X из казначейства в пул, созданный злоумышленником. Freezer получил всего 35,675313 USDT, после чего злоумышленник извлек токены из этого пула и продал X, чтобы получить средства для погашения.
Доля оставалась заблокированной, а средства, полученные от изъятия средств из казначейства и продажи токенов, были использованы для погашения, поэтому злоумышленнику не нужно было сначала возвращать приобретенную долю.
В ходе атаки было заимствовано около 1,94 миллиона USDT, после чего сумма была возвращена с процентами. После погашения около 4,75 миллиона USDT поступило первому конечному получателю.
Участник ChainBounty, Филиппарк, подтвердил выплату 4,848 миллиона USDT трем выбранным получателям. Эта промежуточная сумма не включает нераспроданные токены X и их изменяющуюся стоимость, учитывая только выбранные платежи.
The Freezer также сохранил важное ограничение: после выполнения операции баланс токенов X должен был покрывать общую сумму, которую пользователи заблокировали. Защита этого количества заблокированных средств не защищала ликвидность внешнего пула или рыночную стоимость токена.
В голосовании Arkadiko были приняты средства, поступившие с опозданием
Предложение 12 от Arkadiko было представлено 17 октября в 20:35 UTC и выполнено 22 октября в 16:04 UTC. Его контракт управления предоставил внешнему инициатору интервал голосования в 720 блоков Bitcoin, что обычно соответствует пяти дням.
Правила требовали, чтобы для внесения предложения было использовано 0,25% от общего количества токенов DIKO, для достижения кворума необходимо было участие 5%, и количество голосов «за» должно было превышать количество голосов «против». При расчете общего количества токенов DIKO исключались токены, хранящиеся в контракте первоначального распределения.
Эти пороговые значения и правила голосования не требовали, чтобы владельцы токенов владели ими до внесения предложения. Кошелек, внесший предложение, совершил обмен 22 октября в 15:03:46 UTC и проголосовал в 15:06:47. Было выделено около 4,573 миллиона DIKO. Предложение завершилось с тем же количеством голосов «за» и нулевым количеством голосов «против».
Bitquery оценивает стоимость приобретенных токенов для голосования примерно в 51 000 долларов США. Их отслеживание также показывает, что 77% STX, отправленных в кошелек для голосования, поступили от предыдущей операции StackSwap.
Злоумышленник перевел средства в ходе нескольких транзакций и в разные даты, поэтому случай с Arkadiko существенно отличается от единичной транзакции заимствования и возврата средств в X100. Поздняя покупка имела решающее значение, поскольку она стала полезной силой для голосования во время уже открытого голосования.
Когда голосование завершилось, изменения вступили в силу. Между этим решением и получением контрактом необходимых полномочий не было отдельного периода ожидания.
Одобренный вредоносный контракт не имел авторизации вызывающей стороны в функциях вывода средств и выпуска USDA. В предложении 12 он был зарегистрирован как контракт для управления хранилищами с разрешением на выпуск. Успешные вызовы привели к выводу sBTC в 16:06 UTC и stSTX в 16:09, через несколько минут после активации.
По оценкам Bitquery, убытки Arkadiko составили около 1,09 миллиона долларов: примерно 780 000 долларов в stSTX, 135 000 долларов в sBTC и 173 000 долларов в STX, полученных от продажи не обеспеченного USDA.
Злоумышленник X100 действовал в рамках одной транзакции, несмотря на годичный период блокировки токенов, в то время как Arkadiko выполнил операцию после голосования, без дополнительной задержки.
В своем ответе от 22 октября Arkadiko заявила, что отключила вредоносный контракт и приостановила управление, погашение и ликвидацию хранилищ. В нем говорится, что измененные хранилища stSTX и sBTC не могут быть изменены, поскольку их обеспечение недоступно.
В 07:57 UTC 27 октября было выполнено предложение 14 «AIP 32.2 – Восстановление операций с хранилищами», в результате чего запись для управления хранилищами была установлена на легитимный контракт v1-3 Arkadiko.
Для выхода необходим период ожидания
Требование более старой доли или использование голосующей силы из более раннего снимка могло бы предотвратить немедленное включение вновь приобретенных токенов, а задержка выполнения отделила бы одобрение от перемещения активов.
Если бы каждое соответствующее действие должно было проходить через эту задержку, точная последовательность действий X100 не смогла бы профинансировать себя и погасить свой кредит в одной транзакции.
Злоумышленник, использующий долгосрочный капитал, мог бы подождать, но ограничения на то, что могут делать одобренные контракты, остаются отдельным вопросом.
Документация OpenZeppelin по управлению описывает историческую голосующую силу и временные ограничения на выполнение как отдельные механизмы.
Применение этого различия к этим инцидентам превращает задачу в вопрос о том, когда вновь приобретенный капитал получает полномочия, какие активы эти полномочия могут перемещать и сколько времени остается до выполнения.
Замороженные токены X100 обычно не могут быть разморожены до истечения срока их блокировки, поэтому задержка выполнения не устранит это ограничение на вывод средств.
Легитимная функция закрытия хранилища Arkadiko обеспечивает условный выход: активный владелец погашает долг, выплачивает комиссии за стабильность и выводит обеспечение, когда операции включены. Для этого требуются необходимые средства и доступное обеспечение.
Предложенный срок для подачи заявок, составлявший примерно пять дней, предусматривал заблаговременное уведомление об планируемых изменениях. Окончательное голосование состоялось значительно позже, и после его завершения контракт немедленно вступил в силу. Если рассматривать весь период голосования как гарантированный срок, в течение которого можно отказаться от соглашения после его утверждения, это может запутать и затруднить определение момента, когда риск станет реальной угрозой.
Контекст статьи