Blacksmith, в котором была обнаружена уязвимость. Если вы знаете точное имя затронутого протокола или уязвимого контракта, можно также искать его напрямую.



Blacksmith: pool does not exist.
Pool memory pool = pools[_lpToken]; в функции deposit, где данные кешируются, а позже, на строке 125, обновляются — там мы видим _claimCoverRewards(pool, miner);
Контракт использовал закешированные данные, потому что сами данные оставались в памяти; поэтому контракт позже рассчитывал функцию, используя эти данные. Кеш не обновлялся, что и привело к этому взлому:
example.sol
example.sol
example.sol
- Новый пул был одобрен для liquidity mining буквально за несколько часов до взлома. Этот пул был абсолютно нормальным, но, поскольку он был новым, в контракте blacksmith не было LP-токенов этого пула.
- Атакующий внёс некоторое количество токенов этого пула в контракт Blacksmith.
- Контракт Blacksmith ведёт учёт наград на попер-токен-основе. Если заблокировано много токенов, награда на токен будет мала. Если заблокировано мало токенов, награда на токен будет велика. Соответствующая переменная называется
accRewardsPerTokenи вычисляется какtotalPoolRewards / totalTokenBalance. - Затем атакующий вывел почти все LP-токены из контракта Blacksmith, уменьшив значение
totalTokenBalanceпрактически до нуля. - Затем атакующий снова внёс некоторое количество токенов этого пула в контракт Blacksmith. Именно здесь баг проявил себя во всей красе. Поскольку
totalTokenBalanceв предыдущей транзакции сильно уменьшился, вновь рассчитанныйaccRewardsPerTokenподскочил вверх. Контракт используетrewardWriteoff, чтобы держать под контролем эффектaccRewardsPerToken. Однако из-за бага при расчёте значенияrewardWriteoffиспользовалось старое (маленькое) значениеaccRewardsPerToken. Из-за этого большое значениеaccRewardsPerTokenосталось без контроля. - Затем атакующий вывел свои награды. Поскольку в
accRewardsPerTokenбыло большое неконтролируемое значение, общая награда, выплаченная системой, оказалась завышенной, и в итоге контракт заминтил 40 796 131 214 802 500 000 токенов COVER.
Спасибо Mudit Gupta за последнюю часть разбора этого взлома — подробнее об этом в его блоге :)