Mono Audit logo

Список распространенных уязвимостей

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

  1. Reentrancy
  2. Unexpected Ether
  3. DoS
  4. Overflow
  5. tx.origin Authentication
  6. Access Control
  7. Weak Randomness
  8. Hash Collision
  9. Precision Loss
  10. msg.value in loop
  11. ecrecover
  12. Replay
  13. Inheritance Order
  14. MEV
Link

Reentrancy

Реентерабельность - одна из самых ранних и разрушительных уязвимостей смарт контрактов, ответственная за значительные исторические эксплойты, такие как взлом The DAO, который привел к хардфорку Ethereum. Она остается критической угрозой с потенциально ужасными последствиями, способной опустошить контракты, выведя все средства.

Уязвимость проистекает из распространенного антипаттерна кодирования, часто переносимого из привычек Web2: выполнение внешних взаимодействий (например, перевод Ether или вызов другого контракта) перед обновлением внутреннего состояния контракта (например, балансов пользователей). Когда контракт отправляет Ether или вызывает внешний контракт, он временно передает управление исполнением. Злоумышленник, контролирующий принимающий контракт, может воспользоваться этим, немедленно вызвав обратно исходный контракт, часто через функцию receive или fallback, срабатывающую при переводе Ether, или через хуки стандарта токенов.

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

Хотя классическая атака включает одну функцию, существуют более сложные варианты, такие как межфункциональная реентерабельность (использование общего состояния между функциями) и реентерабельность только для чтения (манипулирование чтением состояния через view-функции).

Основная защита - это паттерн CEI (Checks-Effects-Interactions): выполнить все необходимые проверки, затем обновить переменные состояния (эффекты), и только после этих обновлений взаимодействовать с внешними контрактами.

Link

Unexpected Ether

Уязвимость "Манипулирование балансом через неожиданное получение Эфира" возникает из-за того, что смарт контракты Solidity могут получать Эфир через механизмы, обходящие их определенные функции `receive` и `fallback`. Основными методами такого "неожиданного" поступления Эфира являются опкод `selfdestruct`, который принудительно переводит баланс уничтожаемого контракта на указанный адрес, и coinbase транзакции (награды за блок).

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

Контракты, которые некорректно используют `address(this).balance` для критически важных логических проверок, становятся уязвимыми. Например, контракты могут проверять, что `address(this).balance == expectedAmount`. Злоумышленник может воспользоваться этим, используя `selfdestruct` для отправки небольшой суммы Эфира, тем самым манипулируя балансом. Это может привести к:

Отказу в обслуживании (DoS): Строгие проверки равенства могут быть безвозвратно нарушены, делая функции непригодными для использования.

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

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

Основной метод защиты - никогда не полагаться на `address(this).balance` в логике контракта. Вместо этого контракты должны вести учет баланса во внутренних переменных, обновляя их только в рамках легитимных функций обработки средств. Все критические проверки и переходы состояний должны основываться на этих надежных внутренних переменных.

Link

DoS

Уязвимости типа "Отказ в обслуживании" (Denial of Service, DoS) в смарт контрактах Solidity направлены на нарушение или полную остановку предполагаемой функциональности контракта, не позволяя легитимным пользователям получать доступ к его услугам. "Услуга" в которой отказывают - это способность контракта выполнять свои функции так, как запрограммировано и ожидается его пользователями.

Злоумышленники достигают этого, используя недостатки в логике кода контракта, манипулируя ограничениями ресурсов (в первую очередь газом) или используя внешние зависимости.

Распространенные паттерны включают:

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

Неожиданные откаты (Unexpected Reverts): Вызов неожиданного отката (revert) критически важных функций. Это может быть спровоцировано принудительным сбоем внешних вызовов (например, отправкой средств контракту, который их отклоняет), манипулированием состоянием для нарушения условий `require` или другими необработанными исключениями. Если контракт зависит от внешнего вызова, который завершается сбоем (возможно, злонамеренно вызванного), вся операция может быть заблокирована.

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

Смягчение последствий основывается на практиках безопасного программирования: использование ограниченных операций вместо неограниченных циклов, предпочтение паттернов запроса платежей (pull-payment) перед отправкой средств пользователям (push-payment), что изолирует сбои при переводе, надежная обработка сбоев внешних вызовов (например, использование `try/catch` там, где это уместно) и тщательное управление газом.

Link

Overflow

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

Исторически, в версиях Solidity до 0.8.0, эти арифметические ошибки приводили к тихому "оборачиванию" значения (wrap around). Например, добавление 1 к максимальному значению uint8 (255) приводило к 0, а вычитание 1 из 0 — к 255. Это предсказуемое, но неконтролируемое поведение было основным источником эксплойтов, позволяя злоумышленникам манипулировать балансами токенов (например, выпускать огромные суммы или выводить средства, вызывая "оборачивание" балансов), обходить критические проверки безопасности, нарушать состояние контракта или вызывать блокировку контракта (denial-of-service).

В версии Solidity 0.8.0 было введено ключевое улучшение безопасности: стандартные арифметические операции (+, -, *, /) теперь по умолчанию выполняют проверки на переполнение. Если операция могла бы привести к "оборачиванию", транзакция вместо этого откатывается (revert), предотвращая тихое переполнение.

Однако риск не устранен полностью. Разработчики могут явно обходить эти проверки по умолчанию, используя блоки `unchecked`, часто для оптимизации расхода газа. Код внутри блока `unchecked` возвращается к опасному поведению тихого "оборачивания" версий до 0.8.0 и требует чрезвычайно тщательной проверки. Аналогично, низкоуровневый ассемблерный код EVM не использует проверки Solidity, требуя ручного управления безопасностью для арифметических операций. Кроме того, операции сдвига (<<, >>) остаются непроверенными даже в режиме по умолчанию >=0.8.0 и будут усекать результаты. Неправильное приведение типов (например, преобразование большого uint256 в меньший тип, такой как uint8) также может привести к усечению значения, потенциально вызывая неожиданное поведение в последующих вычислениях.

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

Link

tx.origin Authentication

Использование `tx.origin` для логики авторизации в смарт контрактах Solidity представляет собой критическую уязвимость безопасности. Она возникает из-за фундаментального непонимания его поведения по сравнению с `msg.sender`. В то время как `tx.origin` всегда идентифицирует EOA (внешне управляемую учетную запись), инициировавшую транзакцию, `msg.sender` идентифицирует непосредственного вызывающего. Использование `tx.origin` для проверки разрешений не позволяет проверить сущность, непосредственно взаимодействующую с контрактом.

Эта уязвимость открывает возможность для атак фишингового типа, где вредоносный контракт-посредник, вызванный привилегированным пользователем, может успешно вызывать защищенные функции целевого контракта. Проверка `tx.origin` ошибочно подтверждает подлинность первоначального пользователя, позволяя вредоносному контракту выполнять действия от имени пользователя. Последствия варьируются от прямой кражи Ether и токенов до несанкционированного изменения состояния контракта, что потенциально может привести к значительным финансовым потерям и непоправимому ущербу для целостности и репутации протокола.

Link

Access Control

Нарушенный контроль доступа - это критическая уязвимость в смарт контрактах Solidity, при которой ограничения на то, кто может выполнять какие функции, отсутствуют или реализованы неправильно. Поскольку в Solidity нет встроенных моделей доступа, разработчики должны вручную добавлять проверки, часто используя модификаторы, такие как onlyOwner, или реализуя управление доступом на основе ролей (RBAC). Неправильное выполнение этого создает дыры в безопасности.

Эта уязвимость обычно проявляется в виде незащищенных функций. Функции, предназначенные для административных или чувствительных операций, такие как передача владения контрактом (changeOwner), вывод средств (withdraw), приостановка контракта, выпуск токенов или даже уничтожение контракта (selfdestruct), могут остаться доступными для вызова любой внешней учетной записью. Часто это происходит из-за отсутствия модификаторов контроля доступа или неправильной видимости функций (например, функции по умолчанию являются public, если не указано иное). Открытые функции инициализации, которые должны выполняться только один раз, также могут стать вектором атаки, если они остаются доступными для вызова после развертывания, потенциально позволяя злоумышленникам сбросить админа или критические параметры.

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

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

Link

Weak Randomness

Генерация случайного значения в Виртуальной Машине Ethereum (EVM) сложна из-за ее детерминированной природы, необходимой для консенсуса сети. Это создает "иллюзию энтропии", когда кажущиеся случайными значения, полученные исключительно из данных в блокчейне, на самом деле предсказуемы.

Разработчики часто неправильно используют легкодоступные переменные блока, такие как block.timestamp, blockhash и prevrandao (доступный через block.difficulty), в качестве источников псевдослучайности. Эти переменные небезопасны, поскольку их можно предсказать или повлиять на них.

Майнеры (в Proof-of-Work) или валидаторы (в Proof-of-Stake) могут в некоторой степени манипулировать этими значениями для получения нечестного преимущества, часто в рамках стратегий MEV. Важно отметить, что даже обычные пользователи или контракты злоумышленников часто могут предсказывать результаты, если логика случайности опирается только на входные данные, известные до или во время выполнения транзакции, что позволяет использовать эксплойты, такие как перехват транзакции (front-running). Эта предсказуемость подрывает справедливость таких приложений, как лотереи, игры и минтинг NFT.

Link

Hash Collision

Коллизия хешей при использовании `abi.encodePacked` с несколькими динамическими типами возникает не из-за уязвимостей лежащей в основе Keccak-256 хеш-функции, а из-за способа упаковки данных перед хешированием, в частности, при использовании функции `abi.encodePacked` в Solidity. В отличие от стандартной функции `abi.encode`, которая выравнивает (дополняет) аргументы до 32 байт и включает префиксы длины для динамических типов, `abi.encodePacked` создает компактное, нестандартное кодирование путем конкатенации аргументов с использованием минимально необходимого количества байт, опуская выравнивание для небольших статических типов и, что особенно важно, опуская информацию о длине для динамических типов, таких как `string`, `bytes` или динамические массивы.

Основная проблема возникает, когда `abi.encodePacked` используется с двумя или более аргументами динамического типа. Поскольку длина каждого динамического аргумента не кодируется, граница между ними в итоговой последовательности байтов становится неоднозначной. Эта неоднозначность позволяет, зачастую тривиально, подобрать различные наборы логических входных данных, которые приводят к абсолютно одинаковой упакованной последовательности байтов. Например, `abi.encodePacked("a", "bc")` дает тот же байтовый результат, что и `abi.encodePacked("ab", "c")`.

Когда эта идентичная последовательность байтов впоследствии хешируется (например, с помощью `keccak256(abi.encodePacked(...))`), результатом будет одно и то же хеш-значение, так и возникнет хеш-коллизия, вызванная особенностями кодирования.

Эта уязвимость, связанная с коллизией при кодировании, может быть использована несколькими способами, если полученный хеш используется в критичном с точки зрения безопасности контексте:

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

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

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

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

Link

Precision Loss

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

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

Деление перед умножением: Вычисление (a / b) * c вместо (a * c) / b усекает промежуточный результат a / b, вызывая потерю точности.

Округление вниз до нуля: Если числитель A меньше знаменателя B (и оба положительны), результат A / B всегда равен 0. Это рискованно для вычислений, включающих небольшие комиссии, вознаграждения или конвертацию токенов.

Злоумышленники используют эти математические свойства для манипулирования логикой контракта с целью финансовой выгоды. Распространенные стратегии включают:

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

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

Успешные атаки, связанные с потерей точности, могут привести к значительным негативным последствиям:

Снижение расходов: Злоумышленники платят меньшие или нулевые комиссии.

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

Возможности для арбитража: Создание искусственных ценовых различий внутри протокола.

Обход механизмов контроля риска: Обход ликвидаций или других проверок безопасности из-за неточных вычислений.

Постепенное истощение средств: Выкачивание ценности через повторяющиеся транзакции, использующие крошечные ошибки округления ("атаки 1 wei").

Методы защиты включают осторожное обращение с арифметикой, например, выполнение умножения перед делением, использование масштабирования чисел (имитация математики с фиксированной запятой), применение специализированных математических библиотек и реализацию соответствующей логики округления. Стандартные проверки на переполнение (например, SafeMath или Solidity >=0.8) не предотвращают потерю точности при делении.

Link

msg.value in loop

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

Злоумышленник может использовать это, отправив определенное количество Ether для вызова уязвимой функции. Внутри цикла проверки вроде require(msg.value >= amount_per_item) могут успешно проходить несколько раз, или обновления состояния могут некорректно использовать полное начальное значение msg.value многократно. Это происходит потому, что логика контракта не учитывает стоимость, фактически 'потраченную' или распределенную в предыдущих итерациях того же цикла.

Этот недостаток позволяет злоумышленнику инициировать действия (например, переводы Ether или зачисление на внутренний баланс), общая стоимость которых значительно превышает количество Ether, фактически отправленное им с транзакцией.

Link

ecrecover

ecrecover позволяет смарт контрактам восстанавливать адрес подписанта из хеша сообщения и подписи ECDSA (v, r, s). Это обеспечивает ключевые функциональные возможности, такие как проверка сообщений, подписанных вне блокчейна, для мета-транзакций или функций разрешений (permit functions). Однако его прямое использование сопряжено со значительными, часто недооцениваемыми, рисками безопасности, если не обращаться с ним осторожно.

Нулевой адрес вместо ошибки: Критическая проблема связана со стратегией обработки ошибок `ecrecover`. При получении недействительной или математически невозможной подписи он не отменяет транзакцию. Вместо этого он тихо завершается с ошибкой и возвращает нулевой адрес (`address(0)`). Контракты, которые вызывают `ecrecover`, но не содержат проверку на нулевой адрес, очень уязвимы. Злоумышленник может намеренно отправить недействительные данные подписи, заставляя `ecrecover` вернуть `address(0)`. Если этот результат явно не проверяется и не отклоняется, контракт может ошибочно продолжить выполнение, рассматривая `address(0)` как легитимного подписанта. Это может привести к серьезным последствиям, таким как несанкционированные изменения состояния, неверная публикация эвентов или предоставление разрешений, особенно если нулевой адрес имеет особые привилегии или значимое состояние в конкретной логике контракта. Надежный код всегда должен проверять `recoveredAddress != address(0)` сразу после вызова `ecrecover`.

Уязвимость зеркальной подписи: Второй основной риск связан с неотъемлемым свойством самого алгоритма ECDSA: зеркальность подписи. Для любого заданного сообщения и приватного ключа может существовать несколько различных, но криптографически действительных представлений подписи (в частности, подпись, использующая компонент `s`, часто может быть преобразована в действительную подпись с использованием `n-s`, где `n` - порядок кривой). Это становится уязвимостью, если контракты ошибочно предполагают, что подпись для сообщения уникальна. Злоумышленники могут использовать это для обхода проверок уникальности. Например, если контракт использует хеш самой подписи в качестве nonce для предотвращения повторов, злоумышленник может взять действительную подпись, вычислить ее зеркальный аналог и отправить его для повторного выполнения действия, поскольку хеши подписей будут отличаться. Это также может вызвать неожиданное поведение или повторное воспроизведение в системах, ожидающих определенную форму подписи, если внешние системы или части логики контракта не были разработаны для обработки обеих действительных форм подписи. Стратегия защиты включает принудительную канонизацию подписи - проверку, надежно реализованную в стандартных библиотеках, таких как ECDSA от OpenZeppelin, которым следует отдавать предпочтение перед прямым использованием `ecrecover`.

Link

Replay

Воспроизведение транзакции в другой сети (CCRA: Cross-Chain Replay Attack): Транзакция, успешно выполненная в одной сети EVM, перехватывается и успешно повторно отправляется в другую сеть EVM. Это использует сходства в форматах транзакций и подписях между сетями, особенно когда транзакциям не хватает уникальных идентификаторов сети (Chain ID). Хардфорк Ethereum/Ethereum Classic - классический пример, где этот риск материализовался. EIP-155 был введен для смягчения этого риска путем встраивания Chain ID в стандартные подписи транзакций, делая их специфичными для конкретной сети. Однако смарт-контракты, использующие пользовательскую проверку подписи, также должны явно проверять Chain ID. Эксплойт Optimism на 20 миллионов долларов против Wintermute стал результатом отсутствия такой проверки Chain ID в межсетевом контракте.

Повтор на уровне смарт контракта (в той же сети): Подписанное сообщение или транзакция повторяется для того же смарт контракта или потенциально для другого контракта в той же сети. Обычно это эксплуатирует уязвимости в собственной логике контракта, особенно в нестандартных схемах проверки подписей, используемых для таких функций, как метатранзакции или функции разрешений ERC-20 (permit). Наиболее распространенным недостатком является отсутствие или неправильная реализация nonce на уровне приложения. Nonce («одноразовое число») - это уникальный счетчик, связанный с подписывающей стороной, который должен быть включен в хеш подписываемого сообщения и отслеживаться контрактом в сети (on-chain), чтобы гарантировать, что каждая конкретная подпись авторизует только одно действие.

Link

Inheritance Order

Поддержка множественного наследования в Solidity позволяет контракту одновременно наследовать свойства от нескольких родительских контрактов. Хотя это мощный инструмент для повторного использования кода, он создает потенциальную неоднозначность, известную как «проблема ромба» (Diamond Problem): когда два или более базовых контракта определяют функцию с одинаковым именем и параметрами.

Для решения этой проблемы Solidity использует алгоритм линеаризации C3 для установления единого, детерминированного порядка разрешения методов (Method Resolution Order, MRO) для каждого контракта. Этот MRO определяет точную последовательность, в которой проверяются базовые контракты при разрешении вызовов функций.

Уязвимость возникает непосредственно из-за того, как определяется этот MRO. Решающим фактором является порядок, в котором разработчик перечисляет базовые контракты в операторе `is`. Solidity требует перечислять контракты от «наиболее базового» к «наиболее конкретному». Этот указанный порядок напрямую влияет на конечный MRO, генерируемый алгоритмом C3.

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

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

Link

MEV

Максимально извлекаемая ценность (Maximal Extractable Value - MEV) представляет собой прибыль, которую производители блоков и специализированные искатели (searchers) могут получить, манипулируя включением и порядком транзакций в блоке, сверх стандартных вознаграждений за блок и комиссий за газ. Первоначально этот термин назывался "Извлекаемая ценность майнеров" (Miner Extractable Value), но затем название изменилось на "Максимальная", чтобы отразить жажду вознаграждения.

MEV возникает из-за того, что ожидающие транзакции часто находятся в общедоступной зоне ожидания, называемой мемпулом (mempool), видимой для всех. Производители блоков имеют право решать окончательный порядок транзакций в блоке. Автоматизированные боты, управляемые "искателями" (searchers), постоянно отслеживают мемпул, моделируют возможные исходы и используют выгодные возможности, стратегически упорядочивая транзакции, часто используя торги за газ (Аукционы приоритетного газа - PGA), чтобы обеспечить предпочтительное размещение.

Распространенные стратегии MEV, часто рассматриваемые как атаки, включают:

Фронтраннинг (Front-Running): Размещение транзакции атакующего перед транзакцией жертвы (например, крупной сделки на DEX), чтобы получить прибыль от ожидаемого влияния на цену.

Сэндвич-атаки (Sandwich Attacks): Комбинация фронтраннинга и бэкраннинга (следования за) транзакции жертвы на DEX для получения разницы в цене (проскальзывания), вызванной манипуляцией.

JIT-ликвидность (JIT Liquidity): Временное добавление и удаление ликвидности вокруг крупного обмена на DEX с концентрированной ликвидностью для получения комиссий.

Манипулирование оракулом (Oracle Manipulation): Использование обновлений или неточностей ценовых оракулов для получения прибыли, что часто влияет на протоколы кредитования.

Другие типы включают снайпинг NFT (NFT sniping) и пылевые атаки (dust attacks).

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

Стратегии смягчения последствий направлены на уменьшение негативного влияния MEV. Отправка транзакций через частные мемпулы или ретрансляторы (такие как Flashbots Protect или MEV Blocker) скрывает их от публичного просмотра. Дизайн на уровне приложений, такой как схемы Commit-Reveal (фиксация-раскрытие), скрывает детали транзакции до тех пор, пока порядок не будет зафиксирован, а использование средневзвешенных по времени цен (TWAP) для оракулов может снизить риски манипулирования.

Консультации по безопасности смарт контрактов

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