21 октября 2022

Итак, вы хотите использовать ценовой оракул…

Перевод

Это тоже — вольный перевод очень старого (2019-2020 гг.) материала, но актуальность его с каждым годом лишь возрастает: https://www.paradigm.xyz/2020/11/so-you-want-to-use-a-price-oracle

Введение

В конце 2019 года опубликовал пост под названием «Взятие кредитов под залог для развлечения и наживы». В нём описал экономическую атаку на Ethereum dApps, которые полагаются на точные данные о цене одного или нескольких токенов. Сейчас конец 2020 года, и, к сожалению, с тех пор множество проектов совершили очень похожие ошибки, а самым последним примером стал взлом Harvest Finance, в результате которого пользователи протокола потеряли 33 млн долларов США.

Хотя разработчики знакомы с такими уязвимостями, как reentrancy, манипуляции с ценовым оракулом явно не являются тем, что часто рассматривается. И наоборот, эксплойты, основанные на реентерабельности, с годами сократились, в то время как эксплойты, основанные на манипулировании ценовым оракулом, сейчас на подъёме. Поэтому решил, что пришло время опубликовать окончательный ресурс по манипулированию ценовым оракулом.

Эта статья состоит из трёх разделов. Для тех, кто не знаком с темой, здесь есть введение в оракулы и оракульные манипуляции. Те, кто хочет проверить свои знания, могут перейти к тематическим исследованиям, где рассмотрим прошлые уязвимости и эксплойты, связанные с оракулами. Наконец, в заключение привожу некоторые методы, которые разработчики могут применить для защиты своих проектов от манипуляций с оракулами.

Оракловые манипуляции в реальной жизни

Среда, 1 декабря 2015 года. Вас зовут Дэвид Спарго, и вы находитесь на концерте группы Peking Duk в Мельбурне, Австралия. Вы хотели бы лично встретиться с группой, но между вами и доступом за кулисы стоят два охранника, и они ни за что не позволят какому-то условному Джо пройти прямо внутрь.

Интересно, как бы отреагировали охранники, если бы вы просто вели себя как подобает. Членам семьи наверняка разрешат посещать группу за кулисами, так что всё, что вам нужно будет сделать, это убедить охранников, что вы — родственник. Вы немного подумали и придумали план, который можно назвать либо гениальным, либо абсолютно безумным.

Быстро все подготовив, вы уверенно подходите к охранникам. Вы представляетесь Дэвидом Спарго, семьёй Пекин Дук. Когда охранник просит предъявить доказательства, вы показываете ему неопровержимое доказательство — Википедию. 

Охранник пропускает вас вперёд и просит подождать. Проходит минута, потом две. Через пять минут вы задумываетесь, не сбежать ли вам, пока не появились правоохранительные органы. Когда вы уже собираетесь уходить, подходит Рубен Стайлз и представляется. Вы проходите с ним в зелёную комнату, где группа была настолько впечатлена вашей находчивостью, что в итоге вы вместе выпиваете несколько кружек пива. Позже они рассказали о случившемся на своей странице в Facebook.

Что такое ценовой оракул?

Ценовой оракул, говоря в общем, это всё, к чему обращаетесь за информацией о цене. Когда Пэм спрашивает Дуайта о денежной стоимости Schrute Buck, Дуайт выступает в роли ценового оракула.

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

Оба варианта имеют свои преимущества и недостатки. Данные оффчейн обычно медленнее реагируют на волатильность, что может быть хорошо или плохо в зависимости от того, для чего пытаетесь их использовать. Однако для передачи данных в чейн обычно требуется несколько привилегированных пользователей, поэтому вы должны быть уверены, что они не станут злоумышленниками и их нельзя будет принудить к передаче плохих обновлений. Данные ончейн не требуют привилегированного доступа и всегда актуальны, но это означает, что ими легко манипулируют злоумышленники, что может привести к катастрофическим сбоям.

Что может пойти не так?

Давайте рассмотрим несколько случаев, когда плохо интегрированный ценовой оракул привел к значительному финансовому ущербу для проекта DeFi.

Сбой в работе оракула Synthetix sKRW

Synthetix — платформа деривативов. Для облегчения этой задачи Synthetix (в то время) полагался на пользовательскую реализацию оффчейн ценового фида, в котором совокупная цена, рассчитанная из секретного набора ценовых фидов, публиковалась ончейн с фиксированным интервалом. Эти цены позволяли пользователям занимать длинные или короткие позиции против поддерживаемых активов.

25 июня 2019 года один из ценовых фидов, на которые полагалась Synthetix, неверно указал цену корейской воны, в 1000 раз превышающую истинный курс. Из-за дополнительных ошибок в системе ценового оракула эта цена была принята системой и опубликована ончейн, где торговый бот быстро совершал сделки на рынке sKRW и вне его. 

В общей сложности бот смог получить прибыль в размере более 1 миллиарда долларов США, хотя команде Synthetix удалось договориться с трейдером о возврате средств в обмен на баунти за ошибку.

Synthetix правильно реализовал оракловый контракт и получил цены из нескольких источников, чтобы не дать трейдерам предсказать изменения цен до их публикации ончейн. Однако единичный случай сбоя в работе одного из восходящих ценовых каналов привёл к разрушительной атаке. Это иллюстрирует риск использования ценового оракула, который использует оффчейн-данные: вы не знаете, как рассчитывается цена, поэтому ваша система должна быть тщательно спроектирована, чтобы все возможные варианты отказа были обработаны должным образом.

Кредиты с недостаточным обеспечением

Как упоминалось ранее, в сентябре 2019 года я опубликовал пост, в котором описал риски, связанные с использованием ценовых оракулов, опирающихся на данные из сети. Хотя настоятельно рекомендую прочитать оригинальную статью, она довольно длинная и насыщена техническими деталями, что может затруднить восприятие. 

Поэтому здесь дам упрощённое объяснение.

Представьте, что хотите внедрить децентрализованное кредитование в блокчейн. Пользователям разрешено вносить активы в качестве залога и брать взаймы другие активы до определенной суммы, устанавливаемой через стоимость внесённых ими активов. Предположим, что пользователь хочет занять USD, используя ETH в качестве залога, что текущая цена ETH составляет 400 USD, а коэффициент залога равен 150%.

Если пользователь разместит 375 ETH, он внесёт 150 000 долларов США в качестве залога. За каждые 1,5 USD залога пользователь может взять 1 USD, таким образом, он сможет взять у системы максимум 100 000 USD.

Но, конечно, на блокчейне не так просто объявить, что 1 ETH стоит 400 долларов США, потому что злоумышленник может просто объявить, что 1 ETH стоит 1 000 долларов США, а затем забрать все деньги из системы. Поэтому для разработчиков заманчиво обратиться к ближайшему оракулу, например, к текущей спотовой цене на Uniswap, Kyber или другой децентрализованной бирже.

На первый взгляд, это правильное решение. Ведь цены Uniswap всегда примерно верны, когда хотите купить или продать ETH, так как любые отклонения быстро корректируются арбитражниками. Однако, как выясняется, спот-цена на децентрализованной бирже может быть дико неверной во время сделки, как показано на примере ниже.

Рассмотрим, как функционирует резерв Uniswap. 

Цена рассчитывается на основе количества активов, находящихся в резерве, но количество активов, находящихся в резерве, меняется по мере того, как пользователи торгуют между ETH и USD. Что если злоумышленник совершит сделку до и после получения займа на вашей платформе?

Перед тем как пользователь берёт кредит, он покупает 5 000 ETH за 2 000 000 долларов США. Теперь биржа Uniswap рассчитывает цену как 1 ETH = 1 733,33 USD. Теперь их 375 ETH могут выступать в качестве залога для активов стоимостью до 433 333,33 долларов США, которые они берут в кредит. Наконец, они обменивают 5 000 ETH на свои первоначальные 2 000 000 долларов США, что приводит к изменению цены. В итоге ваша кредитная платформа только что позволила пользователю занять ещё 333 333,33 доллара США без предоставления какого-либо залога.

Этот пример иллюстрирует наиболее распространённую ошибку при использовании децентрализованной биржи в качестве ценового оракула — злоумышленник имеет почти полный контроль над ценой во время транзакции, и пытаться точно узнать эту цену — всё равно что считывать вес на весах до того, как они закончат измерять вес. Скорее всего, вы получите неверное число, и в зависимости от ситуации это может стоить вам больших денег.

Манипуляция Synthetix MKR

В декабре 2019 года компания Synthetix подверглась ещё одной атаке в результате манипуляций с ценовым оракулом. Эта атака примечательна тем, что она преодолела барьер между данными о ценах ончейн и оффчейн.

Пользователь Reddit u/MusaTheRedGuard заметил, что злоумышленник совершает очень подозрительные сделки против sMKR и iMKR (инверсной MKR). Сначала злоумышленник приобрёл длинную позицию по MKR, купив sMKR, затем приобрел большое количество MKR в паре Uniswap ETH/MKR. Подождав некоторое время, злоумышленник продал свои sMKR за iMKR и продал свои MKR обратно в Uniswap. 

Затем они повторили этот процесс.

За кулисами сделки злоумышленников через Uniswap позволяли им произвольно изменять цену MKR на Synthetix. Вероятно, это произошло потому, что оффчейн ценовой канал, на который опиралась Synthetix, на самом деле опирался на ончейн цену MKR, и арбитражникам не хватало ликвидности, чтобы вернуть рынок к оптимальным условиям.

Этот инцидент иллюстрирует тот факт, что даже если вы думаете, что используете данные о ценах оффчейн, на самом деле вы можете использовать данные о ценах ончейн, и вы всё равно можете быть подвержены сложностям, связанным с использованием этих данных.

Взлом bZx

В феврале 2020 года компания bZx была дважды взломана в течение нескольких дней на сумму около 1 млн. долларов США. Вы можете найти отличный технический анализ обоих взломов, написанный palkeo, здесь, но мы рассмотрим только второй взлом.

Во втором взломе злоумышленник сначала купил почти все sUSD на Kyber, используя ETH. Затем злоумышленник приобрел вторую партию sUSD у самой Synthetix и разместил её на bZx. Используя sUSD в качестве залога, злоумышленник взял в долг максимальное количество ETH, которое ему было разрешено. Затем они продали sUSD обратно Kyber.

Если вы были внимательны, то узнаете, что это, по сути, та же атака на кредит под залог, но с использованием другого залога и другой децентрализованной биржи.

Ошибка yVault

25 июля 2020 года я сообщил компании yEarn об ошибке, связанной с запуском их новых контрактов yVault. Официальное сообщение об этой ошибке можно прочитать здесь, но вкратце расскажу о ней ниже.

Система yVault позволяет пользователям размещать токены и зарабатывать на них доходность без необходимости самостоятельно управлять ими. Внутри хранилища отслеживается общее количество выпущенных токенов yVault, а также общее количество депонированных токенов. Стоимость одного токена yVault определяется соотношением количества намайненных и депонированных токенов. Любая прибыль, которую получает хранилище, распределяется между всеми выпущенными токенами yVault (и, следовательно, между всеми держателями токенов yVault).

Первое yVault позволяло пользователям зарабатывать доходность на USDC, предоставляя ликвидность в пул Balancer MUSD/USDC. Когда пользователь предоставляет ликвидность пулу Balancer, он получает взамен BPT, которые можно обменять на часть пула. Таким образом, yVault рассчитывает стоимость своих авуаров на основе суммы MUSD/USDC, которая может быть выкуплена с помощью его BPT.

Это кажется правильной реализацией, но, к сожалению, действует тот же принцип, что и ранее — состояние пула Balancer во время транзакции не является стабильным и ему нельзя доверять. В данном случае, из-за кривой связывания, которую выбрал Balancer, пользователь, меняющий USDC на MUSD, не получит обменный курс 1:1, а фактически оставит в пуле некоторое количество MUSD. Это означает, что стоимость BPT может быть временно завышена, что позволяет злоумышленнику манипулировать ценой по своему усмотрению и впоследствии опустошить хранилище.

Этот инцидент показывает, что ценовые оракулы не всегда удобно маркировать как таковые, и что разработчики должны быть бдительными в отношении того, какие данные они получают, и учитывать, могут ли этими данными легко манипулировать непривилегированные пользователи.

Взлом финансовой компании Harvest

26 октября 2020 года неизвестный пользователь взломал пул Harvest Finance, используя технику, о которой вы, вероятно, уже догадались. Вы можете прочитать официальный постмортем здесь, но я еще раз подведу итог: злоумышленник сбил цену USDC в пуле Curve, совершив сделку, вошел в пул Harvest по сниженной цене, восстановил цену, отменив предыдущую сделку, и вышел из пула Harvest по более высокой цене. Это привело к убыткам на сумму более 33 млн. долларов США.

Как мне защитить себя?

Надеюсь, что к этому моменту вы научились распознавать общую черту — не всегда очевидно, что вы используете ценовой оракул, и если вы не будете соблюдать надлежащие меры предосторожности, злоумышленник может обмануть ваш протокол и переслать ему все ваши деньги. Хотя нет универсального решения, которое можно было бы предложить, вот несколько решений, которые сработали в других проектах в прошлом. Возможно, одно из них подойдет и вам.

Мелководные рынки, без погружения

Как и ныряние в мелкий бассейн, ныряние в мелкий рынок болезненно и может привести к значительным расходам, которые навсегда изменят вашу жизнь. Прежде чем разбираться в тонкостях конкретного ценового оракула, который планируете использовать, подумайте, достаточно ли ликвиден токен, чтобы его можно было интегрировать в вашу платформу.

Птица в руке стоит двух в кустах

Можно завораживающе смотреть на потенциальный обменный курс на Uniswap, но ничто не является окончательным, пока вы не нажмете кнопку «торговля» и токены не окажутся в вашем кошельке. Аналогичным образом, лучший способ точно узнать курс обмена между двумя активами — просто обменять их напрямую. Этот подход хорош тем, что нет никаких обратных операций и никаких «что-если». Однако он может не подойти для таких протоколов, как кредитные платформы, которые обязаны хранить исходный актив.

Почти децентрализованные оракулы

Одним из способов резюмировать проблему с оракулами, которые полагаются на данные внутри сети, является то, что они слишком актуальны. Если это так, почему бы не ввести небольшую искусственную задержку? Напишите контракт, который обновляет себя последней ценой с децентрализованной биржи, такой как Uniswap, но только по запросу небольшой группы привилегированных пользователей. Теперь, даже если злоумышленник сможет манипулировать ценой, он не сможет заставить ваш протокол фактически использовать её.

Этот подход очень прост в реализации и является быстрой победой, но есть и несколько недостатков — во время перегруженности сети вы не сможете обновлять цену так быстро, как вам хотелось бы, и вы все еще уязвимы для сэндвич-атак. Кроме того, теперь ваши пользователи должны доверять тому, что вы действительно будете обновлять цену.

Ограничители скорости

Манипулирование ценовыми оракулами — операция, требующая времени, поскольку арбитражники всегда следят за ситуацией и с удовольствием воспользуются возможностью оптимизировать любые не-оптимальные рынки. 

Если злоумышленник хочет минимизировать риск, он захочет совершить две сделки, необходимые для манипулирования ценовым оракулом, в рамках одной транзакции, чтобы не было шансов, что арбитражник может подскочить (неожиданно) через MEV. Как разработчик протокола, если ваша система поддерживает это, может быть достаточно просто реализовать задержку в 1 блок между входом и выходом пользователя из вашей системы.

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

Средневзвешенная по времени цена (TWAP)

В Uniswap V2 появился оракул TWAP для разработчиков. В документации более подробно описаны [Прим. Menaskop: см. надо архивную версию или новую — с перенесёнными документами] точные гарантии безопасности, которые обеспечивает оракул, но в целом для больших пулов в течение длительного периода времени при отсутствии перегруженности цепи оракул TWAP очень устойчив к атакам манипулирования оракулом. Однако из-за особенностей своей реализации он может недостаточно быстро реагировать на моменты высокой волатильности рынка и работает только для тех активов, для которых уже есть ликвидный токен.

Репортёры M-of-N

Иногда говорят, что если вы хотите, чтобы что-то было сделано правильно, сделайте это сами. А что, если собрать N надёжных друзей и попросить их сообщить, какая, по их мнению, цена является правильной, а лучшие M ответов станут текущей ценой?

Такой подход сегодня используется во многих крупных проектах: Maker управляет набором ценовых каналов, управляемых доверенными лицами, Compound создал Open Oracle и включает таких репортеров, как Coinbase, а Chainlink агрегирует ценовые данные от операторов Chainlink и выставляет их на цепочке. Просто имейте в виду, что если вы решите использовать одно из этих решений, вы теперь делегируете доверие третьей стороне, и вашим пользователям придётся делать то же самое. Требование к репортёрам вручную публиковать обновления в сети также означает, что в периоды высокой волатильности рынка и перегруженности сети обновления цен могут не приходить вовремя.

Заключение

Ценовые оракулы являются важным, но часто упускаемым из виду компонентом безопасности DeFi. 

Безопасно использовать ценовые оракулы очень сложно, и существует множество способов подставить ногу как себе, так и своим пользователям. 

В этом посте мы с вами рассмотрели примеры манипуляций с ценовыми оракулами и установили, что считывание информации о цене в середине транзакции может быть небезопасным и привести к катастрофическому финансовому ущербу.

Мы также обсудили несколько методов, которые другие проекты использовали для борьбы с манипуляциями ценового оракула в прошлом. 

В конце концов, каждая ситуация уникальна, и вы можете обнаружить, что не уверены в том, правильно ли вы используете ценовой оракул. Если это так, не стесняйтесь обращаться за советом!

До!

Обсудить в Discord!