15 мая 2024 года Sonne Finance подверглась атаке на сеть Optimism, в результате чего убытки составили до 20 миллионов долларов.

После атаки пользователь @tonyke_bot на

(https://twitter.com/tonyke_bot/status/1790547461611860182)

После того, как проект Sonne Finance обнаружил атаку, он быстро приостановил работу всех рынков на Optimism и заявил, что рынки на Base безопасны.

(https://twitter.com/SonneFinance/status/1790535383005966554)

Краткое описание атаки

Sonne Finance — это децентрализованный протокол кредитования, который является ответвлением Compound V2 on Optimism, предоставляя отдельным лицам, учреждениям и протоколам доступ к финансовым услугам. Протокол Sonne Finance объединяет токены пользователей для формирования пула кредитной ликвидности, предоставляя пользователям кредитный бизнес, подобный банковскому. Как и Compound, участники протокола могут заложить свои токены в пул кредитной ликвидности Sonne Finance и получить сертификат soToken (тот же, что и cToken). SoToken — это сертификат актива, приносящий проценты, который будет приносить определенную сумму дохода по мере продвижения блока, а также будет получать стимулы в виде токенов SONE. Участники также могут заимствовать другие токены из пула кредитных активов Sonne, имея в своих руках soToken. Например, участники могут заложить определенную сумму USDC для получения сертификатов soUSDC, а затем предоставить WETH для дальнейшего обращения. Ипотечное кредитование в протоколе Sonne Finance может представлять собой отношение активов «многие ко многим». В процессе ипотечного кредитования протокол автоматически рассчитывает фактор здоровья (фактор здоровья) адреса участника. Когда коэффициент здоровья ниже 1, залог адреса Продукты будут поддерживать ликвидацию, и ликвидаторы также могут получать определенные вознаграждения за ликвидацию.

Взаимосвязь между количеством базовых токенов, депонированных пользователями, и отчеканенными soTokens в основном связана с переменной под названием ExchangeRate. Эту переменную можно грубо использовать для указания того, сколько базового токена стоит каждый soToken. Формула расчета ExchangeRate выглядит следующим образом:

В приведенной выше формуле TotalCash относится к количеству базовых токенов, принадлежащих soToken, TotalBorrows относится к количеству базовых токенов, предоставленных в аренду на определенном рынке, TotalReserves относится к общей сумме резерва (включая проценты, выплачиваемые заемщиком), TotalSupply Относится к количеству выпущенных soToken.

При погашении пользователи могут указать количество базовых токенов, которые они хотят выкупить, redeemAmount, чтобы рассчитать количество soTokens, которые необходимо уничтожить, redeemTokens. Метод расчета примерно такой: «redeemTokens = redeemAmount / ExchangeRat». потеря точности здесь.

Суть этой атаки заключается в том, что при создании рынка (soToken) злоумышленник выполнил первую операцию приведения ипотеки и выпустил очень мало soToken с небольшим количеством базовых токенов, в результате чего значение soToken «totalSupply» оказалось слишком маленьким. Затем злоумышленник воспользовался уязвимостью потери точности контракта Solidity, а затем отправил базовый токен непосредственно в контракт soToken (soToken не будет чеканиться, что означает, что «totalSupply» остается неизменным, а «totalCash» становится больше) вместо размещения ставок + кастинга. . метод внесения базового токена. Такая операция приводит к тому, что переменная «totalCash» в контракте становится больше, но «totalSupply» остается неизменной, в результате чего обменный курс становится больше. В конце концов, когда злоумышленник выкупает базовый токен, soToken, который необходимо уничтожить, меньше, чем soToken, отчеканенный во время ипотеки. Злоумышленник использует заработанный soToken для предоставления базового токена WETH и USDC другим soTokens (например, soWETH). , soUSDC), и, наконец, прибыль достигла 20 миллионов долларов США.

Ключевые адреса, вовлеченные в атаку

Транзакции подготовки атаки:

https://optimistic.etherscan.io/tx/0x45c0ccfd3ca1b4a937feebcb0f5a166c409c9e403070808835d41da40732db96

Атакуйте прибыльные сделки:

https://optimistic.etherscan.io/tx/0x9312ae377d7ebdf3c7c3a86f80514878deb5df51aad38b6191d55db53e42b7f0

Атаковать адреса, связанные с EOA:

0x5d0d99e9886581ff8fcb01f35804317f5ed80bbb

0xae4a7cde7c99fb98b0d5fa414aa40f0300531f43

Адрес, связанный с злоумышленником (контрактом):

0xa78aefd483ce3919c0ad55c8a2e5c97cbac1caf8

0x02fa2625825917e9b1f8346a465de1bbc150c5b9

базовый токен (VELO Token V2):

0x9560e827af36c94d2ac33a39bce1fe78631088db

Контракт на уязвимость (soVELO, аналог cToken Compound):

0xe3b81318b1b6776f0877c3770afddff97b9f5fe5

Транзакция @tonyke_bot по спасению пользователя на X:

https://optimistic.etherscan.io/tx/0x816f9e289d8b9dee9a94086c200c0470c6456603c967f82ab559a5931fd181c2

Анализ процесса атаки

Резюме

Команда проекта Sonne Finance недавно приняла предложение добавить рынок VELO к Sonne Finance (https://twitter.com/SonneFinance/status/1786871066075206044) и организовала пять транзакций через кошелек с мультиподписью, которые будут выполнены через два дня ( https://optimistic.etherscan.io/tx/0x18ebeb958b50579ce76528ed812025949dfcff8c2673eb0c8bc78b12ba6377b7), эти пять транзакций используются для создания рынка VELO (контракта soVELO) и установки некоторых ключевых конфигураций рынка, таких как установка модели процентных ставок, установка ценового оракула. и установка ипотечных коэффициентов и т. д. После создания рынка VELO пользователи могут вносить токены VELO для чеканки токенов soVELO, которые, в свою очередь, можно использовать для заимствования других токенов soToken.

подготовка атаки

Фаза подготовки атаки в основном предназначена для того, чтобы злоумышленник создал рынок VELO (контракт soVELO) на основе информации в проектном предложении Sonne Finance после истечения двухдневного периода блокировки предложения, установил ключевые конфигурации и выпустил Токены VELO в контракт soVELO, закладывая их токены soVELO, а также отправляя имеющиеся у него токены VELO непосредственно в контракт soVELO для увеличения обменного курса и подготовки к получению прибыли от последующих атак.

Конкретные шаги заключаются в следующем:

  1. По истечении двухдневного периода блокировки злоумышленник сначала упаковал операции первых четырех транзакций, организованных в предложении, в одну транзакцию (транзакция 0x45c0cc), использовал ее для создания рынка VELO (контракт soVELO) и настроил ключевые конфигурации. . При инициализации рынка VELO для параметра ExchangeRate установлено значение «200 000 000 000 000 000 000 000 000».

  2. Злоумышленник вызывает функцию «mint» контракта soVELO для внесения токенов VELO и выпуска токенов soVELO. Злоумышленник указывает «mintAmount» как «400 000 001» (количество токенов VELO). Как видно из функции «exchangeRateStoredInternal», поскольку «_totalSuppl» токена soVELO в данный момент равен 0, ExchangeRate — это значение, установленное на шаге 1. По формуле «mintTokens = factMintAmount/exchangeRate» расчетное количество токенов soVELO, которые следует отчеканить в данный момент, равно 2. Короче говоря, на этом этапе злоумышленник вносит токены VELO на сумму «400 000 001» в контракт soVELO и получает токены soVELO на сумму 2.

    soVELO.mint:

  3. Злоумышленник отправил токены VELO на сумму «2 552 964 259 704 265 837 526» в контракт soVELO, напрямую отправив токены VELO в контракт soVELO. В это время количество токенов VELO, хранящихся в контракте soVELO, увеличилось, но поскольку новых токенов soVELO не было. Приведение, поэтому totalSupply остается неизменным, а это означает, что значение ExchangeRate, рассчитанное в соответствии с формулой расчета ExchangeRate, в это время станет больше.

  4. Злоумышленник несколько раз передавал свои запасы токенов soVELO, в конечном итоге другому злоумышленнику, EOA 0xae4a.

Атака ради прибыли

Фаза получения прибыли от атаки в основном включает в себя выполнение злоумышленником пятой транзакции предложения и предоставление токенов VELO непосредственно в контракт soVELO посредством срочных кредитов для дальнейшего увеличения обменного курса. Затем злоумышленник использует токен soVELO со значением 2 в своей руке для заимствования базовых токенов, таких как WETH и USDC, из других контрактов soToken (таких как soWETH, soUSDC и т. д.), и эти части становятся прибылью злоумышленника. Затем злоумышленник пошел выкупить свой базовый токен в контракте soVELO. Из-за увеличения обменного курса и потери точности расчета токенов soVELO, которые необходимо уничтожить для выкупа, злоумышленник в конечном итоге использовал только токен soVELO со значением. 1. Почти все ранее внесенные токены VELO были погашены, что можно понимать как использование злоумышленником дополнительных токенов soVELO со значением 1 для получения базовых токенов, таких как WETH и USDC, путем заимствования у других токенов soToken. Злоумышленник использовал одну и ту же технику, чтобы повторить атаку много раз и в конечном итоге получил огромную прибыль.

Конкретные шаги заключаются в следующем:

  1. Злоумышленник выполняет пятую транзакцию в предложении и устанавливает коэффициент кредитования, указанный в предложении.

  2. Злоумышленник предоставил взаймы токены VELO на сумму «35 469 150 965 253 049 864 450 449» из пула VolatileV2 AMM — USDC/VELO, что активировало функцию перехвата злоумышленника. В функции перехвата злоумышленник продолжает выполнять операцию атаки.

  3. Злоумышленник отправляет свои собственные токены VELO в контракт soVELO для дальнейшего повышения обменного курса. В настоящее время в контракте soVELO имеется общее количество токенов VELO на сумму «35 471 703 929 512 754 530 287 976» (сумма токенов VELO, переданных злоумышленником три раза).

  4. Злоумышленник создает новый контракт 0xa16388a6210545b27f669d5189648c1722300b8b. В конструкторе он переносит 2 имеющихся у него токена soVELO во вновь созданный контракт 0xa163 (далее — атакующий 0xa163).

  5. Злоумышленник 0xa163 использовал имеющиеся у него токены soVETH, чтобы одолжить WETH на сумму «265 842 857 910 985 546 929» у soWETH.

  6. Злоумышленник 0xa163 вызывает функцию soVELO «redeemUnderlying», указывая стоимость выкупленных токенов VELO как «35 471 603 929 512 754 530 287 976» (почти количество токенов VELO, которые злоумышленник ранее передал или заложил в контракт soVELO). В настоящее время формула «redeemTokens =» redeemAmountIn/exchangeRate» для расчета количества токенов soVELO, которые необходимо уничтожить для погашения.

    Как видно из функции "exchangeRateStoredInternal", поскольку _totalSupply равен 2 вместо 0, то значение ExchangeRate необходимо рассчитать по формуле "exchangeRate = (totalCash + totalBorrows - totalReserves)/totalSupply", текущий обменный курс равен. «17 735 851 964 756 377 265 143 988 000, 000 000 000 000 000», это значение намного больше, чем исходное значение ExchangeRate, установленное «200 000 000 000 000 000 000 000,00».

    Значение «redeemTokens», рассчитанное на основе нового обменного курса, составляет «1,99». Из-за особенностей округления в сторону уменьшения в Solidity значение «redeemTokens» в конечном итоге становится равным 1. Это означает, что злоумышленник 0xa163 использовал токены soVELO со значением 1, чтобы выкупить почти все ранее внесенные токены VELO. В то же время злоумышленник 0xa163 также заработал WETH со значением «265 842 857 910 985 546 929», заимствованным у soWETH.

    soVELO.redeemБазовый:

     

    soVELO.exchangeRateStoredInternal:

  7. Злоумышленник 0xa163 передал все заимствованные токены WETH и выкупленные токены VELO злоумышленнику верхнего уровня, а затем самоуничтожился.

  8. Злоумышленник вызывает функцию «liquidateBorrow» soWETH, чтобы ликвидировать некоторые активы, заимствованные из вновь созданного контракта 0xa163, чтобы вернуть заблокированные токены soVELO со значением 1. В настоящее время злоумышленник владеет только токенами soVELO со значением 1.

  9. Злоумышленник вызывает функцию «mint» soVELO для повторного закладывания и чеканки токенов soVELO с целью сбора токенов soVELO со стоимостью 2, а затем снова выполняет шаги 3–8, описанные выше, чтобы получить прибыль от других ненадежных токенов.

  10. Злоумышленник выполняет шаг 9 несколько раз, погашает флэш-кредит и уходит с прибылью.

Как 100 долларов привлекают 6,5 миллионов долларов

После атаки пользователь @tonyke_bot на X отчеканил 0,00000011 soVELO, разместив 1144 токена VELO в контракте soVELO в транзакции 0x0a284cd. Причина, по которой эта операция может предотвратить дальнейшие атаки злоумышленника, заключается в том, что эта транзакция изменяет размер totalSupply в soVELO и количество удерживаемых токенов VELO totalCash, а влияние роста totalSupply на расчет ExchangeRate больше, чем влияние Таким образом, обменный курс становится меньше, в результате чего злоумышленник больше не сможет использовать потерю точности, чтобы заработать soVELO при проведении атаки, что делает атаку более невозможной.

Отслеживание денег

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

  1. 0x4ab93fc50b82d4dc457db85888dfdae28d29b98d

Злоумышленник перевел 198 WETH на этот адрес, а затем адрес использовал тот же метод атаки для получения незаконной прибыли в следующих транзакциях:

После атаки адрес перенес вышеупомянутую незаконную прибыль на 0x5d0d99e9886581ff8fcb01f35804317f5ed80bbb.

  1. 0x5d0d99e9886581ff8fcb01f35804317f5ed80bbb

Злоумышленник перевел на этот адрес 724277 USDC и 2353 VELO и обменял USDC на Ether. Часть средств была немедленно переведена на перекрестный мост Звездных врат, а большая часть нелегальных средств осталась по этому адресу:

  1. 0xbd18100a168321701955e348f03d0df4f517c13b 

Злоумышленник перевел 33 WETH на этот адрес и использовал цепочку пилинга, чтобы попытаться отмыть деньги. Ссылка на отмывание денег следующая:

0xbd18100a168321701955e348f03d0df4f517c13b -> 0x7e97b74252b6df53caf386fb4c54d4fb59cb6928 -> 0xc521bde5e53f537ff208970152b75a0 03093c2b4 -> 0x9f09ec563222fe52712dc413d0b7b66cb5c7c795。

  1. 0x4fac0651bcc837bf889f6a7d79c1908419fe1770

Злоумышленник перевел 563 WETH на этот адрес, а затем на 0x1915F77A116dcE7E9b8F4C4E43CDF81e2aCf9C68. Никаких дальнейших действий пока не предпринято.

Методы отмывания денег злоумышленников на этот раз относительно профессиональные, и методы демонстрируют тенденцию к разнообразию. Поэтому мы, участники Web3, должны продолжать совершенствовать наши возможности по борьбе с отмыванием денег с точки зрения безопасности, а также повышать безопасность проектов Defi с помощью KYT, AML и других связанных продуктов безопасности блокчейн-транзакций.

Советы по безопасности

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

  2. Рекомендуется, чтобы создание рынка, аналогичного cToken в Compound, и первая операция по кастингу ипотеки выполнялись привилегированными пользователями, чтобы избежать манипуляций со стороны злоумышленников и тем самым манипулирования обменным курсом.

  3. При наличии в контракте ключевых переменных, зависящих от значения «this.balance» или «token.balanceOf()», необходимо внимательно продумать условия изменения ключевой переменной, например, разрешено ли ее изменение. напрямую переносить нативную валюту или токены в контракт. Изменить значение переменной, либо значение переменной можно изменить только вызовом определенной функции.

Эту статью написали Кара (аккаунт X @Cara6289) и XiG (аккаунт X @SHXiGi) из команды ZAN.