Pull to refresh

MEV: DeFi transaction ordering for profit and fun

Reading time12 min
Views5.2K

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

Сейчас объем операций в Ethereum каждые сутки измеряется миллиардами долларов, и конкуренция за место в блоке выросла до огромных значений. В “газовых аукционах” можно найти транзакции, где комиссии измеряются десятками тысяч долларов, а количество автоматических средств для торговли увеличивается с каждым днем. 

Что-то здесь интересное кроется, предлагаю рассмотреть этот вопрос поближе...

Введение

Рассматриваемые в статье проблемы с ордерингом транзакций в полной мере демонстрируют концепцию "тёмного леса" - этот термин озвучен в книге Лю Цысиня "Задача Трех Тел", поклонником которой я являюсь, и которая очень точно упомянута в отличной статье ("Ethereum is a Dark Forest”), которая и вдохновила меня на написание этого текста. В этой книге основной идеей является то, что мы не видим миллионы развитых цивилизаций во Вселенной не потому что их нет, а потому что как только цивилизация раскрывает свое существование, она мгновенно уничтожается более развитыми. В “темном лесу” достаточно один раз вскрикнуть или включить фонарик и страшные монстры мгновенно накинутся на беззащитного путника. 

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

Статья требует от читателя понимания функционирования сети Ethereum и смарт-контрактов.

Frontrunning и MEV

Представим такой несложный кусок кода на Solidity (подобные которому точно не стоит делать):

pragma solidity >=0.7.0 <0.9.0;

contract Test {

    bytes32 private hash_of_secret;

    constructor (bytes32 _hash_of_secret) {

        hash_of_secret = _hash_of_secret;

    }

    receive() external payable {

        // эта функция принимает ETH

        // на баланс контракта

    }

 

    function claim_eth_by_secret(bytes memory secret) public {

     // При условии если прислан

     // прообраз ранее сохраненного хеша

     // отправляет весь баланс отправителю

     // транзакции и уничтожает контракт. 

     require (keccak256(secret) == hash_of_secret);

     selfdestruct(payable(address(msg.sender)));

    }

}

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

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

  • транзакция, содержащая secret будет опубликована в mempool, и распространена по всей сети через p2p сеть

  • транзакция будет проанализирована автоанализатором, который определит “можно ли выполнить точно такую же транзакцию, но со своего адреса и получить профит?”. Для нашей транзакции ответ - “да”. "secret" теперь известен и любой отправивший его раньше нас, получит эфир с контракта

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

  • имея прямой доступ к майнинговым пулам атакующий гарантированно поместит ее выше в блоке чем наша

Несмотря на простоту проверки в примере, вы можете легко представить на ее месте любой proof, позволяющий одному, “удачливому”, адресу получить эфир (например: “каждая сотая транзакция - выигрышная”, или “последний участник закрывает контракт и за эту операцию получает вознаграждение”).

Получается, как только в сети появляется транзакция, выполнив которую можно получить профит, ее сразу же “подметают”, и эти идеи бродят довольно давно, когда то я даже писал статью про “Ether janitors”( https://medium.com/mixbytes/ether-janitors-and-greed-powered-garbage-collection-bd511e173aae) - про эксплойтинг ботов, которые мгновенно забирают любые токены или эфир, оказавшиеся на “слабых” адресах.

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

Например, арбитражный бот увидел, что на DEX1 и DEX2 сильно отличаются курсы некоторого SHITCOIN и хочет провести обмен сразу на двух DEX-ах взяв за небольшую комиссию flashloan на 100ETH (он позволит сделать обмен на большую сумму и получить больший профит). Для подобных операций используется специальный заранее выложенный ботом контракт, принимающий от него сразу пачку операций, и выполняющий их все в одной транзакции, примерно так:

function perform_trade(bytes[] operations) {

// в operations лежат сериализованные

// вызовы к нескольким DEX-ам,

// swap-ам, flashloan-ам, и т.д., например:

//

// 1. получить flashloan на 100 ETH

// 2. обменять 100 ETH на 100к SHITCOINS на DEX1

// 3. обменять 100k SHITCOINS на 120 ETH на DEX2

// 4. проверить slippage (что 120 ETH > 100 ETH)

// 5. вернуть flashloan 100 ETH (profit: 20 ETH)

// 6. transfer оставшихся 20 ETH на адрес бота

}

Особенно важным является п.4. ("slippage" в терминах биржевой торговли). Так трейдер страхуется от того, что пока транзакция дойдет, цена вдруг изменится и получить профит не получится. Если эта проверка не проходит, вся транзакция целиком откатывается. 

После того, как будет проведены операции 2 и 3, на DEX1 курс SHITCOIN вырастет, а на DEX2 - уменьшится, т.к. swap пулы в DeFi при покупке одного из токенов алгоритмически увеличивают его цену, а при продаже - уменьшают. Разница цен между двумя пулами уменьшится, и возможный заработок на арбитраже также уменьшится (или вообще исчезнет). Поэтому, если кто-то выполнит подобную транзакцию раньше (возможно с другими суммами), то последующие операции будут выполнены уже по другой цене и могут не пройти по slippage. А без использования slippage есть даже возможность потерять средства на сделке, если цены перебалансируются в обратную сторону.

Чем более продвинутым является анализатор транзакций, тем большее количество потенциально профитных транзакций он может детектировать. Для использования появившегося “profit opportunity”, можно просто повторить ту же операцию (буквально скопировав байткод вызовов), но заменив адреса и подписи на свои. И, чем больше вероятность разместить свою транзакцию выше искомой, тем больше вероятность забрать профит от транзакции себе.

Этот софт с одной стороны "ворует" “profit opportuninties” у трейдеров, а с другой является просто развитием арбитража - таким образом в DeFi появляется еще один “слой” на котором арбитражники могут торговаться за ordering транзакций. Основными выгодоприобретателями являются, конечно, майнеры - для них это совершенно новый рынок и заработок, параллельный майнингу, иногда приносящий огромный доход. 

Из за подобной активности на рынке появился термин MEV, который расшифровывается как “Miner Extractable Value” или, если рассматривается более общие механизмы, “Maximum Extractable Value”. Это число означает объем средств, которые можно получить за счет манипуляций порядком транзакций в блоках. Другими словами - это прибыль, которую может получить майнер блока, если максимально использует свои возможности по реордерингу транзакций.

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

[block begins] 

...previous transactions...

tx_orig: profit = 10 ETH, slippage = 3%, gasprice = 20Gwei, result=Success

...next transactions...

[block ends]

, тогда:

Вариант 1: destructive frontrun.

[block begins] 

...previous transactions…

tx_mev: profit = 10 ETH, slippage = 3%, gasprice = 20Gwei, result=Success

tx_orig: profit = 0 ETH, slippage = 3%, gasprice = 20Gwei, result=Failure

…next transactions...

[block ends]

Пользователь хотел выполнить транзакцию со slippage в 3%, а в случае невыполнения этого условия транзакция падает. Фронтраннер выполнил такую же транзакцию, поставив свою транзакцию выше. Это можно сделать поставив более высокую цену газа, и таким образом в Ethereum фронтраннить транзакции и без доступа к машинам майнеров. Но, внимательный читатель увидит, что в нашем примере gasprice не менялся. Почему тогда позже сгенерированная транзакция встала в блоке выше оригинальной? Это специально, чтобы показать, что майнер может менять порядок транзакций самостоятельно, не обращая внимание на цены транзакций, если доход от таких транзакций выше чем обычные майнерские награды.

Этот подход назван destructive, т.к. пользователь пострадал, и его транзакция была откачена (хотя комиссию он заплатил). Это сильно демотивирует market-maker-ов, поэтому сообщество активно ищет пути борьбы с destructive MEV. Но об этом позже…

Вариант 2: cooperative frontrun

[block begins] 

...previous transactions…

tx_mev: profit = 5 ETH, slippage = 3%, gasprice = 20Gwei, result=Success

tx_orig: profit = 5 ETH, slippage = 3%, gasprice = 20Gwei, result=Success

…next transactions...

[block ends]

В этом случае транзакция пользователя прошла. Пользователь не заработал планируемых 10 ETH, но все таки сумел выполнить свою транзакцию в пределах slippage, получив 5 ETH. Другая часть профита (5ETH) ушла фронтраннеру, который подобрал параметры своей транзакции так, чтобы не “сломать” сделку “следующему”. Например, оперировал небольшими суммами токенов, ровно такими, чтобы не сломать критерии slippage для следующей транзакции. Это подход “средней паршивости”, который намного лучше для пользователя, чем предыдущий вариант. Используя desctructive MEV майнеры рискуют остаться на рынке без активных маркет-мейкеров, что нанесет вред всем без разбора, поэтому вариант с cooperative MEV кажется более предпочтительным для всех нас в долгосрочной преспективе.

Вариант 3: backrun

[block begins] 

...previous transactions…

tx_orig: profit = 10 ETH, slippage = 3%, gasprice = 20Gwei, result=Success

tx_mev: profit = 1 ETH, slippage = 3%, gasprice = 20Gwei, result=Success

…next transactions...

[block ends]

В данном случае пользователь провел свою транзакцию и получил прибыль, но после эмуляции его транзакции, оказалось что можно “подобрать крохи”. Например пользователь не имел нужной суммы, чтобы на 100% выровнять цены в двух пулах, и после его транзакции еще осталась возможность повторить ту же операция с гарантированным профитом. Это наиболее хороший метод из всех, т.к. не оказывает никакого влияния на транзакцию пользователя, все довольны. В этом случае MEV работает как “усилитель” арбитража в сети.

В других статьях типы эксплуатации ордеринга разные - кто-то отдельно выделяет "сэндвичи", кто-то не разделяет cooperative-destructive, но всё это - атаки на ordering, я привел лишь показательные примеры.

Anti-MEV

Бороться с MEV хотят все. Трейдеры обижаются за воровство новых “profit opportunities” и отнятую прибыль. Пользователи обижаются за транзакции, которые у них отнимают, если они не предусмотрели в коде контрактов выдачу наград заданным адресам. Многие майнеры понимают, что избыток MEV будет способствовать оттоку пользователей из DeFi, что приведет к потерям на комиссиях. Не последнее место занимает и эксплойтинг ошибок пользователей - если юзер случайно ввел сумму с лишним нулем, а фронтраннер мгновенно использовал ее для получения выгоды, лишив пользователя даже малейшей возможности исправить ошибку. 

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

Именно эти идеи заложены в проектах, приванных решать проблемы MEV и обеспечивать честный ордеринг транзакций. Наиболее значимые шаги в этом направлении делаются в рамках проекта Flashbots, на их GitHub вы найдете множество полезных материалов, аналитику по MEV-транзакциям, модифицированный клиент geth, позволяющий майнерам принимать заранее выстроенные bundle-ы транзакций, за использование которых они получают дополнительное вознаграждение и многое другое.

Идея flashbots такова - вместо того, чтобы заниматься MEV, майнерам предлагается гарантированно получать дополнительный доход с помощью прямых выплат от трейдеров, а ордеринг транзакций происходит на отдельных сервисах - relays, где трейдеры торгуются за порядок транзакций, не видя других транзакций, используя помимо gasprice прямые выплаты майнеру (bribes). После окончания торгов транзакции упаковываются в единый bundle, который майнер обязан включить в блок как можно раньше, не меняя порядка ни одной транзакции. Очень важным требованием является то, что транзакции в bundle не должны revert-иться, это означает что трейдер не будет зря терять деньги на комиссиях за сломанные транзакции, когда не смог выиграть аукцион по ордерингу - из за этих комиссий очень страдают начинающие алготрейдеры.

Dark-Dark Forest

Алчные майнеры, умные хакеры, хитрые алготрейдеры, все эти монстры ордеринга в DeFI ужасны. Они сожрут всё и не дадут никому спокойно жить в мире децентрализованных финансов. Неужели все так ужасно и нет никакой надежды? Конечно есть! Описывая способы борьбы с destructive MEV часто забывают, что это - всего лишь алгоритмы, которые должны быстро и предсказуемо реагировать на определённые условия, а значит, в обратную сторону их тоже можно атаковать. Так что берегитесь, монстры, на охоту могут выйти ребята и пострашнее, и не каждый светящийся фонарик в тёмном лесу - это жертва!

Любое алгоритмически предсказуемое поведение в финансах - это уязвимость, которую можно эксплуатировать. Зная, что на определённый стимул фронтраннеры будут действовать одним и тем же способом, можно их обмануть. Один из показательных примеров - проект salmonella. Эта техника, которую автор довольно точно назвал “poisonous token”, может быть использована и для других атак на алгоритмы DeFi. Основная идея - в создании токена, операции с которым работают по-разному, в зависимости от того, кто вызывает его функции. В salmonella “отравлена” функция transfer():

// ...

  if (sender == ownerA || sender == ownerB) {

    _balances[sender] = senderBalance - amount;

    _balances[recipient] += amount;

  } else {

    _balances[sender] = senderBalance - amount;

    uint256 trapAmount = (amount * 10) / 100;

    _balances[recipient] += trapAmount;

  }

// ...

Т.е. правильно токен работает только с адресами автора, а для всех остальных передаёт на баланс получателя лишь 10% токенов, при этом эмитируя Event с правильной суммой. Транзакции с этим токеном MEV-анализатор считал профитными, т.к. полагался на данные из event-ов (это намного удобнее, чем читать балансы). Далее с этим токеном были созданы swap пулы в Uniswap и на других проектах и сбалансированы так, чтобы создать “profit opportunity” для MEV-анализатора. В итоге, транзакции автора вызвали реакцию MEV-фронтраннера, который оставил в пуле крупные суммы в ETH, которые и были забраны атакующим. Достойный заработок для whitehat.

Конечно, фронтраннеры доработают свои анализаторы, и постараются разобраться с такими атаками, но алгоритмы в DeFi развиваются, и токены и DEX-ы, только первые примеры, ведь есть еще огромный сектор NFT, где так же проводятся финансовые операции и тоже есть место для MEV. 

Каждое новое усложнение в логике открывает новые возможности для эксплойтинга уязвимостей с обеих сторон - поэтому мы будем наблюдать постоянную борьбу “снаряда и брони”, как это бывает в любой технологической отрасли. В отличие от централизованного мира бирж, здесь нет сторон с привилегированным доступом, посредников и механизмов “на бумаге”. А значит нет ограничений, и любой атакующий может оказаться атакуемым в любой момент. Каждая новая атака в DeFi публична и рождает все больше методов защиты, таких как появление flashbots, privacy-preserving алгоритмов, репутационных систем и т.п. - так что не всё так плохо. 

Заключение

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

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

Нигде так серьезно не отнсятся к безопасности кода, как в DeFi. В тех условиях, в которых работают DeFi по другому быть не может, это полностью открытая среда, где нет никаких доверенных сторон, где невозможно скрыть ни бита информации. Большое число взломов в DeFi? Это естественно - у атакующих есть огромные преимущества - они видят 100% кода и могут с огромной точностью сэмулировать любую атаку, а остановить их невозможно. Атакующему достаточно найти лишь одну уязвимость, а разработчиками и аудиторам нужно предусмотреть все. Любой плохой код сразу атакуется, любая ошибка - фатальна. Воистину - “сode is the law”. 

Но при этом, только в условиях “тёмного леса” будут рождаться по настоящему стойкие финансовые протоколы, здесь они будут проходить жестокий естественный отбор без читерской помощи в виде “SEC запретил”, “биржа оперативно отключила”, “в пресс-релизе кратко упомянули...”. Увы, выживут среди DeFi механизмов немногие. Зато выжившие точно будут достойны того, чтобы оперировать финансами в век информационных технологий.

Tags:
Hubs:
Total votes 13: ↑13 and ↓0+13
Comments7

Articles