
20 июня 2026 года автоматический торговый бот JaredFromSubway, который работает в сети Ethereum, растерял 4 424 $ETH (около $7,5 млн) из-за незащищенности, связанной с механизмом выдачи разрешений на внедрение цифровых активов. Злодей заблаговременно развернул поддельные пулы для обмена токенов и сделал липовые цифровые активы, выглядевш?? как симпатичные возможности для арбитражной торговли. В итоге автоматическая стратегия бота начала вести взаимодействие с вредоносными смарт-договорами и предоставила им разрешения на доступ к своим средствам.
Главная трудность заключалась в том, что после реализации операций эти разрешения не были всецело применены либо отозваны. с помощью данному злодей позднее сумел активировать приготовленные заблаговременно договоры и пользоваться оставшимися разрешениями, чтоб вывести принадлежащие боту припасы WETH, $USDC и $USDT. В GetBlock AML Research детально вернули метод нападения на MEV-бота JaredFromSubway.
Что необходимо знать о MEV-ботах
Jaredfromsubway.eth представляет из себя так называемого MEV-бота (Maximal Extractable Value) — автоматическую программку, которая повсевременно выслеживает еще не удостоверенные операции в блокчейне и изменяет порядок их выполнения, чтоб получить прибыль.
Главная специализация этого бота — так именуемая сэндвич-атака. Её сущность состоит в том, что бот располагает одну сделку конкретно перед операцией пользователя и еще одну сходу после нее, зарабатывая на изменении цены актива, вызывающее операция жертвы.
Когда пользователь посылает заявку на обмен цифровой валюты через децентрализованную биржу, эта операция некое время остается видимой в сети до её итогового включения в блокчейн. MEV-боты повсевременно анализируют подобные неподтвержденные операции, моделируют их воздействие на ликвидность торговых пулов и пробуют найти ситуации, в которых деяния пользователя способны поменять стоимость актива так, чтоб на данном можно было заработать.
Главные адреса
В процессе проведения следствия были выделены последующие адреса, принимавшие участие в нападении.
| Адреса, которые используются преступником для атаки |
| 0x3e37f4A10d771Ba9dE44b6d301410b1BEdeA65d0 |
| 0x74Dc5b93586D248D5Aec64b3586736FF0A0D0e65 |
| 0x71d4416A7A85e08a5Fe7227Ca3B44Fc639e94e97 |
| 0xd8C125efCBc99408eC8723E9BBd81d1E8D39D845 |
| 0xe3Da36E4bd1a5738fa5D6Ef4F0e4dF40bDeB5f17 |
| 0x139bE50D7c0829E0db6E9A444454517e24AbeE7a |
| 0x5aF38735B215b00aa7C9f93fEd7ee415CeCB36e1 |
| 0x19Ff2017803a832eE968454848DAb48fF39C881A |
| 0x7B4F24a4522bc2AEE9D1686FFB7d6c9dAC514e20 |
Вспомогательные договоры
0x81f248ff583d3f8592ea0354a7b8dbe66de40091 — договор для сотворения поддельных токенов.
0xEEE172A069f5171b407eBf47e8FCFB637E944ec2 — договор для управления липовой децентрализованной биржей.
Примеры использованных токенов
- Caps — пример поддельного токена.
- fCap — пример поддельного «обернутого» токена.
- Два разных договора fWETH — поддельные производные токены WETH, использовавшиеся как приманка для получения разрешений.
Кропотливая приготовление к атаке
Чтоб заинтриговать MEV-ботов, злодею требовалось сделать искусственную положение дел, выглядевш?? бы как удачная возможность для арбитражной торговли. С этой целью были развернуты несколько вспомогательных смарт-договоров.
Один договор отвечал за выпуск поддельных токенов. 2-ой употреблялся для координации их состояния и следующего извлечения дохода. 3-ий создавал фиктивные торговые пулы.
4-ый делал операции обмена снутри этих пулов. После чего злодей сделал 131 договор поддельных токенов, которые должны были выступать приманкой для автоматических торговых алгоритмов.
Снаружи эти токены смотрелись как аналоги известных «обернутых» активов WETH и $USDC. Их логика была построена таким образом, что пользователь получал один липовый токен за каждый внесенный WETH либо $USDC через функцию wrapTo().
Для реализации этой операции требовалось за ранее предоставить договору разрешение на внедрение средств пользователя. Конкретно вокруг этой процедуры и строилась вся схема.
Пока особый внутренний параметр owner_a_0_19 не был настроен, функция wrapTo() работала совсем приемлимо. Она вызывала внутреннюю функцию safeTransferFrom(), переводила средства и всецело употребляла выданное разрешение. Со стороны все смотрелось полностью нормально.
После изменения значения owner_a_0_19 управление переходило специальному организующему договору. При всем этом функция getStatus() начинала возвращать значение, которое соответствует текущему номеру блока в сети Ethereum.
Если возвращаемое значение прекращало совпадать с номером текущего блока, вызывалась особая функция, сигнализировавш?? злодею о необходимости обновить статус. Но если статус уже соответствовал текущему блоку и был равен единице, происходило самое принципиальное изменение.
Функция wrapTo() больше не вызывала transferFrom().
Иными словами, перевод средств практически не производился, а до этого выданное разрешение на внедрение токенов оставалось всецело реальным. Сразу организующий договор сохранял данные обо всех таковых неиспользованных разрешениях, равномерно формируя базу для грядущего вывода средств. После чего злодей сделал несколько поддельных пулов платежеспособности.
Часть из них содержала пары WETH–fCAP, а часть — fWETH–fCAP.
Потом через серию специально рассчитанных соглашений баланс активов снутри этих пулов был искусственно нарушен таким образом, чтоб со стороны они смотрелись как источник прибыльной арбитражной возможности.
Как была проведена атака
На блоке 25354425 автоматический бот jaredfromsubway.eth в первый раз вел взаимодействие с одним из приготовленных преступником поддельных пулов SwapV2Pair_0x0e97.
Исходя из убеждений торгового метода положение дел смотрелась очень симпатичной. Если думать, что один токен fWETH равнозначен одному истинному WETH, то распределение активов меж 2-мя поддельными пулами создавало явную возможность для арбитражной сделки по пути:
fWETH → fCAP → WETH
В одном пуле находилось:
- 0,1 fWETH;
- 0,1 fCAP.
Во 2-м:
- 0,086034434021378528 fCAP;
- 0,116281374898538093 WETH.
Автоматический метод оценил положение дел как возможность получить прибыль фактически без риска и начал реализации сделки.
С этой целью бот предоставил разрешение на внедрение 7 391 033 126 027 264 wei WETH и выполнил операцию «оборачивания» токенов через функцию wrapTo(). Поддельный договор выпустил равнозначное число липовых токенов и выслал их в приготовленный пул SwapV2Pair_0x0e97.
После чего бот поменял 6 863 125 844 328 448 wei fCAP и получил взамен 8 566 811 964 473 344 wei WETH. В итоге этой операции метод вправду заработал прибыль — около 0,002351557676892158 WETH.
Самое принципиальное заключалось в том, что на данном шаге все происходило полностью нормально. Так как особый параметр owner_a_0_19 еще не был активирован, выданное разрешение всецело расходовалось во время реализации операции. Для торгового бота это стало доказательством того, что сотрудничество с новыми договорами неопасно.
После чего злодей не решал никаких действий практически целые день. Он дал возможность боту не один раз совершать удачные сделки через приготовленную инфраструктуру, равномерно формируя у метода «доверие» к этим договорам. Для автоматизированной системы бессчетные выгодные операции смотрелись как подтверждение надежности новых торговых возможностей.
Только спустя практически день злодей активировал параметр owner_a_0_19, передав управление организующему договору. Начиная с блока 25360428, он стал часто вызывать функцию markStatusAndTip(), сразу выплачивая маленькое вознаграждение майнерам (либо валидаторам), чтоб его операции гарантированно исполнялись ранее операций MEV-бота.
Каждый этот вызов устанавливал значение _getStatus равным номеру текущего блока. Сейчас в процессе выполнения функции wrapTo() происходило принципно другое поведение. Договор больше не вызывал transferFrom(), а означает, не употреблял выданное до этого разрешение на доступ к средствам.
Со стороны торгового метода все смотрелось так же, по-прежнему. Сделки удачно заканчивались. Прибыль продолжала поступать. Никаких просчетов не появлялось.
Но каждое новое разрешение, которое бот выдавал договору, оставалось всецело реальным и не откликалось после окончания операции. Так злодей равномерно копил больше неиспользованных разрешений на управление активами жертвы. При этом процесс шел чрезвычайно стремительно.
После первых удачных соглашений MEV-бот начал фактически всецело доверять сделанной комплексу инфраструктурных объектов и стал делать через нее сотни операций в рамках одной операции, стремясь извлечь наивысшую прибыль.
При всем этом злодею пригодилось вызвать функцию обновления статуса всего около 10-ка раз, чтоб накопить необходимое число работающих разрешений. Когда подходящий размер доступа был получен, наступил финальная часть атаки.
На блоке 25360696 злодей сразу активировал 66 приготовленных договоров-приманок. Из них 60 уже владели действующими разрешениями, до этого выданными MEV-ботом. Эти договоры сразу пользовались сохраненными разрешениями и начали переводить цифровые активы с кошельков бота на адреса злодея.
В чем заключалась незащищенность
Арбитражный бот автоматом выдавал смарт-договорам разрешения на внедрение собственных токенов в процессе выполнения операций wrapTo(), думая, что во время каждой операции эти разрешения будут всецело потрачены.
Но метод никогда не инспектировал, вправду ли разрешение было применено, и не отзывал оставшиеся права доступа после окончания сделки. Если вредный договор преднамеренно не вызывал функцию transferFrom(), разрешение продолжало действовать пожизненно.
Это означало, что спустя хоть какое время злодей мог пользоваться до этого приобретенным доступом и без затруднений вывести принадлежащие боту средства. Эта самая логическая ошибка стала главной предпосылкой утраты миллионов долларов.
Движение похищенных средств
Главной адрес злодея 0x3e37f4A10d771Ba9dE44b6d301410b1BEdeA65d0 сумел вывести:
- 2 869 812,43 $USDC;
- 2 032 769,62 $USDT;
- 1 474 WETH (приблизительно $2,57 млн на момент атаки).
После чего все приобретенные стейблкоины были обменяны на $ETH. Потом средства были распределены меж пятью разными адресами:
| Адреса, которые используются для вывода похищенных активов |
| 0x5aF38735B215b00aa7C9f93fEd7ee415CeCB36e1 |
| 0x71d4416A7A85e08a5Fe7227Ca3B44Fc639e94e97 |
| 0x74Dc5b93586D248D5Aec64b3586736FF0A0D0e65 |
| 0xe3Da36E4bd1a5738fa5D6Ef4F0e4dF40bDeB5f17 |
| 0xd8C125efCBc99408eC8723E9BBd81d1E8D39D845 |

Схема распределения похищенных активов меж адресами. Визуализация: CertiK
На финальной части злодей выслал 3 000 $ETH в сервис Tornado Cash, созданный для сокрытия происхождения криптовалютных средств. А также, еще 1 422 $ETH были обменяны приблизительно на 2,44 млн DAI. На время опубликования статьи эти средства находятся на адресе 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2.
