Списали 50 токенов, а долг уменьшили на 140 тыс: ошибка погашения в Zentra Finance

Введение
Zentra Finance — это протокол кредитования в сети Ethereum. Пользователи вносят криптовалюту как обеспечение и получают займы в стейблкоине ctUSD, который выпускает сам протокол.
Депозитные токены (zctUSD) — это внутренние токены Zentra, которые пользователь получает, когда вносит ctUSD обратно в протокол. Они подтверждают, что у него есть депозит, и могут использоваться для погашения долгов.
Мгновенный кредит (flash loan) — это кредит, который берётся и возвращается в рамках одной транзакции. Если в конце транзакции деньги не вернуты — вся операция отменяется.
Ход инцидента
-
Злоумышленник взял мгновенный кредит на примерно 200 тыс. USDC.e и внёс их в Zentra Finance как обеспечение.
-
Он занял под это обеспечение около 140 тыс. ctUSD. На этом этапе у него был долг перед протоколом.
-
Затем он внёс около 50 ctUSD в протокол и получил около 50 zctUSD — депозитных токенов.
-
Он вызвал функцию repayWithATokens, которая позволяет погашать долг депозитными токенами. В запросе он указал сумму погашения — около 140 тыс. ctUSD.
-
Система проверила баланс злоумышленника: у него было только около 50 zctUSD. Она корректно ограничила списание — сняла с него только 50 токенов.
-
Но из-за ошибки в коде сумма, на которую уменьшился долг, рассчитывалась не по реально списанным токенам, а по первоначально указанной в запросе сумме. Долг уменьшился на 140 тыс. ctUSD, хотя в резерв протокола вернулось лишь 50 ctUSD.
-
Система посчитала крупный долг погашенным. Злоумышленник забрал своё обеспечение — 200 тыс. USDC.e — обратно, вернул мгновенный кредит и остался с 140 тыс. ctUSD. Чистый ущерб для протокола составил около 140 тыс. ctUSD.
Почему это стало возможным
Детали расследования: движение средств
Похищенные 140 тыс. ctUSD поступили на адрес злоумышленника:
Оттуда средства были отправлены на адрес:
Заключение
Инцидент в Zentra Finance показал, что ошибка в логике погашения долга может привести к полному списанию задолженности без соответствующего возврата средств в резерв. Система корректно ограничила списание токенов балансом пользователя, но некорректно рассчитала сумму прощённого долга.


