Noobing Security Research
192 subscribers
17 photos
2 files
42 links
Изучаю и пишу про безопасность смарт контрактов
Download Telegram
Череда случайностей (которые конечно не случайны) привела меня к погружению в Security Research в области смарт-контрактов на Solidity

Быстро стало понятно, что область достаточно обширная, и хорошо бы записывать и суммировать полученные знания не только в заметках/бумаге, но и делать обучающие посты, собирать где-то ссылки и прочее

Потому я завел этот канал, который точно будет полезен мне и, возможно, кому-то еще
10
Что вообще такое Security Research в web3?

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

В идеале Security Research - это итеративный процесс, который продолжается столько, сколько существует и изменяется контракт. Это, к сожалению, не 100% защита, но постоянная работа над безопасностью снижает вероятность ректа

Внешний аудитор/ресерчер лишь часть системы безопасности протокола и многое зависит от команды проекта

В отличие от веб2, где чаще всего атаки идут через инфраструктуру, в веб3 атаки осуществляются через баги в коде, нередко порождаемые бизнес-логикой

Типичные векторы атак хорошо известны на протяжении многих лет, но только в 2024 году из протоколов было похищено $2.2 МИЛЛИАРДА,
в 2023 - $1.8 миллиарда,
в 2022 - $3.8 миллиарда

Причина, кажется, кроется как в специфичности Solidity и блокчейна в целом, так и в недостатке специалистов
10
Please open Telegram to view this post
VIEW IN TELEGRAM
Какая база нужна и где учиться Security Research?

Сразу оговорюсь, что в мою область интересов пока входит только EVM, так что и говорить буду об этом

Минимальный багаж знаний выглядит так:
- Представление хотя бы в общих чертах как работает блокчейн
- Любой базовый курс по Solidity
- Любой базовый курс по Hardhat/Foundry

Если у вас это есть - поздравляю, можно начинать погружаться в безопасность, но по пути придется добирать знаний. Впрочем, придется в любом случае

В данный момент я прохожу курс от CYFRIN, который называется Smart Contract Security
На платформе 19 курсов разного уровня сложности:
- Basic
- Intermediate
- Advanced

Курсы там на очень разные темы, начинать можно с нуля. Два курса по безопасности и они оба считаются Advanced. Сам процесс и материал просто супер, всё на английском, но есть субтитры

Еще один англоязычный источник высокого качества это Alchemy University, предлагают 5 курсов (без регистрации видны только 3), отлично позволяют закрыть базу. Есть объемный классный курс по тому как работает Ethereum, рассчитанный на 7 недель

Из того, что я видел на русском языке могу рекомендовать только платное сообщество GUIDE DAO, сам в нем состою и до сих пор выплачиваю кредит за вступление 😭
В гайд дао есть неплохие курсы, которые пересекаются с источниками выше, но главная ценность там - люди, разнообразные стримы и конечно внутришкольные хакатоны, на которых можно получить первый опыт работы в команде.

Мы со своей командой так совпали по вайбу, что школьный проект у нас перерос в стартап и мы делаем свой DeFi протокол, что меня и привело к изучению аудита
Please open Telegram to view this post
VIEW IN TELEGRAM
6
Какие бывают аудиты

Продолжаю обозревать теорию, потому что практика должна иметь базис

Существует два вида аудита: приватный (private) и соревновательный (competitive). В определенных рамках делать придется одно и то же, но по разному будут расставлены акценты.

Для аудита конечная цель - сделать протокол более безопасным, это понятно.

В приватном вы оказываете услуги проекту/фирме/кто-там-вам-заказал-аудит и он, как правило, не публичный, то есть отчет вы если и сможете закинуть себе в портфолио, то с некоторой задержкой.

Соревновательный проходит на платформах типа codehawks, протоколы там выкладываются перед деплоем, а награда делится среди нашедших уязвимости. Сейчас на codehawks нет актуальных соревнований, но есть на code4rena. Там же через 9 дней стартует аудит для Chainlink с призовым пулом в $200k в USDC и продолжительностью в месяц

В случае приватного аудита в процесс включается:
- работа с командой протокола, возможно придется учить людей лучшим практикам, например обращать внимание, что в коде не должно быть магических чисел и для storage переменных хорошо бы использовать префикс s_
- анализ полноты и содержания тестов
- отработка критических ситуаций, буквально команда может позвонить и сказать что-то в духе "нас ломают, помоги выбраться из собаки ситуации"
Фокус в приватном аудите стоит не сколько на поиске уязвимостей, сколько на повышении качества кодовой базы

Для соревновательного аудита главное - количество уязвимостей, которые вы обнаружили. Рассказать проекту как бы вы их убрали тоже надо, но поскольку обычно есть ограничение по времени (1-4 недели), то фокус стоит на количестве и тяжести найденного

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

Так, давайте последний кусочек теории перед разбором первой реальной уязвимости

Стандартно у аудита (или одной его итерации в случае приватного) есть 4 шага:

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

2. Reconnaissance/Разведка. Первое вдумчивое чтение кода. Раскидываем вопросительные знаки в комментариях, выписываем приглянувшиеся места, используем инструменты статического анализа, нейронки, в общем получаем первое детальное представление о том коде, который входит в область исследования.

3. Vulnerability Identification/Определение уязвимостей. После полного прохода по коду какие-то места перестанут вызывать вопросы, а те, что останутся должны быть тщательно изучены. На этом моменте происходит оценка уязвимостей, ресерчер пишет proof of code для каждой из них (если это требуется). Доказательство кодом демонстрирует как эксплуатировать уязвимость и показывает, что угроза реальна.

4. Reporting/Создание отчета. После того, как все уязвимости выявлены, необходимые тесты/атакующие скрипты написаны пора приступать к отчету (как правило промежуточно оформляется в md формате, который дальше преобразуется в pdf). Они несколько отличаются для private и competitive аудитов, но описание уязвимостей в них одинаковое, оно всегда должно следовать определенной структуре:

### \[S-#] TITLE (Root Cause + Impact)
[Критичность уязвимости-номер] Название должно содержать причину и влияние

Description: Более подробное описание того почему возникает уязвимость

Impact: Более подробное описание того как она влияет на контракт

Proof of Concept: Доказательство кодом. Считается хорошим тоном предоставлять.

Recommended Mitigation: Предложения по устранению
1
Уязвимость: Reentrancy

Первый тип уязвимости, который мы разберем, на русский можно перевести как повторный вход

Схема взлома надежна как швейцарские часы, если я всё правильно понял

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

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

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

Продолжаться это может до полного дрейна жертвы.

Как противостоять

1. Использовать принцип CEI - Check Effect Interactions:
- проверили сумму запроса
- изменили инфу о балансе пользователя
- отправили средства пользователю

2. У OpenZeppelin существует ReentrancyGuard класс, от которого можно наследоваться и вешать модификатор nonReentrant() на чувствительные функции

Ущерб

Казалось бы, такая простая ошибка, так легко исправляется и детектится даже статическими анализаторами кода, но такие взломы происходят до сих пор, а в 2024 таким образом было похищено $35.7M. На текущий момент уязвимость стоит на 5 месте рейтинга OWASP

Что почитать
Есть хороший материал у QuickNode с подробным объяснением и примерами кода

Схема к посту взята отсюда
1
РЕКТ ТЕСТ

На первой стадии аудита (Scoping) вам надо наладить контакт с командой проекта и получить максимум информации

Для этого существуют опросники, а так же rekt test, название которого говорит само за себя

В нем 12 вопросов, звучат они так:
1. У вас задокументированы все роли и привилегии, используемые в контракте?
2. Вы ведёте документацию по всем внешним сервисам, контрактам и оракулам, на которые вы полагаетесь?
3. У вас есть письменный и протестированный план реагирования на инциденты?
4. Вы документируете наилучшие способы атаки на вашу систему?
5. Вы проводите проверку личности и биографии всех сотрудников?
6. Есть ли в вашей команде человек, в чьей роли явно указана ответственность за безопасность?
7. Вы требуете использования аппаратных ключей безопасности для доступа к продакшен-системам?
8. Требует ли ваша система управления ключами участия нескольких человек и физических шагов?
9. Вы определяете ключевые инварианты системы и проверяете их при каждом коммите?
10. Вы используете автоматизированные инструменты для обнаружения уязвимостей в коде?
11. Вы проходите внешние аудиты и программу раскрытия уязвимостей или баг-баунти?
12. Вы проверяете возможные способы злоупотребления вашим сервисом в отношении пользователей?

Думаю понятно, что каждый ответ "нет" значительно увеличивает шанс неудачи, подробнее про сам тест, что подразумевается под каждым из вопросов здесь
3
Вопросы для Scope стадии

Что касается опросников, то Cyfrin предлагает две формы: расширенную и минимальную, оставлю ссылки на гит
- extensive onboarding questions
- minimal onboarding questions

В расширенную версию входит и рект тест
2
2503.23718v1.pdf
1.7 MB
AI нам поможет?

Если коротко, то ситуация с AI такая же, как и в остальных сферах, т.е. не панацея, но инструмент

В этой области я решил опираться на научные статьи, коих к моему удивлению не прям много

Первой стала Demystifying exploitable bugs on smart contracts 2023 года выпуска, не очень свежо по меркам AI, но не так давно, если подумать

Не буду подробно на ней останавливаться, скажу только, что там коллектив авторов, написано хорошо, но главное - согласно исследованию агенты находили не более 20% уязвимостей!

Как так вышло авторы сказать не могут, но велика вероятность, что контракты, которые они проверяли еще при разработке подвергались анализу с помощью AI и потому «легкие» баги уже были вычищены.

Главная проблема была в том что для поиска уязвимостей требуется анализировать высокоуровневую логику вкупе с низкоуровневой имплементацией и в 2023 у LLM были с этим проблемки

В общем, в 2023 было прям не очень

Но!

31 марта 2025 года вышло продолжение (часть авторов та же), где они рассказывают о своем новом методе PromFuzz, который набирает 86.96% recall и 93.02% по f1!

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

Так, подводящую часть закончил 😂

В общем, я эту статью буду здесь разбирать, если владеете английским и хотите прочесть побыстрее, то скачивайте прикрепленный файл
Please open Telegram to view this post
VIEW IN TELEGRAM
1
Detecting Functional Bugs in Smart Contract through LLM-powered and Bug-Oriented Compose Analysis
Binbin Zhao, Xingshuang Lin, Yuan Tian, Saman Zonouz, Na Ruan, Jiliang Li, Raheem Beyah, Shouling Ji
2025

Разбор статьи ч.1

Авторы определяют три ключевые проблемы, которые надо решить для детекции функциональных багов в автоматическом режиме:
1) Определить бизнес логику. Требуется аккуратно извлечь высокоуровневую бизнес логику из кода.
2) Создать баг чекер. Бизнес логика - это очень абстрактная вещь, поэтому второй задачей становится её деконструкция и создание баг-чекеров.
3) Детектировать функциональные баги. Для этого авторы разработали методику применения баг чекеров для их эффективного использования.

Решение задачи началось с сборки фреймворка для работы с LLM. В корне этой сборки лежит идея использования промптов для двух агентов: аудитора и атакующего. Далее их ответы смешиваются по определенным правилам. Затем, полученный результат используется для создания чекера инвариантов (для этого есть 6 шаблонов). На третьей стадии через чекеры пропускают потенциально опасные функции. Схема работы фреймворка показана на втором изображении.

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

Авторы назвали свою систему PromFuzz и выложили датасет к ней и саму стратегию в открытый доступ

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

-- Манипуляция ценой оракула. Самый "дорогой" вектор атаки, топ-1 из года в год
- Неавторизованное поведение
- Ненадежная логика расчетов
- Некорректный механизм контроля

Авторы отмечают, что они не первые, кто использует LLM для решения задачи, но первые, кто выработал стратегию, которая дает консистентный результат. В работе использовалась GPT-4-turbo.
1
Разбор статьи ч.1 продолжение

На скриншоте представлены промпты, используемые для двойной системы агентов, слева аудитор, справа атакующий.

Схема промпта проста: представь, что ты аудитор, есть ли в этом коде [вопрос1, вопрос2, ... вопросN]? Выполняется ли [сценарий1, сценарий2, ... сценарийN]?

Для атакующего спрашивают по списку возможностей (feature) и по списку присутствующих категорий багов.

Причем интересно, что модели просят отвечать на каждый вопрос исключительно да/нет, ограничивая тем самым пространство для галлюцинаций.

Для того чтобы составить этот опросник исследователи вручную перекопали широкий набор инцидентов из реального мира для каждой категории багов.
1
Detecting Functional Bugs in Smart Contract through LLM-powered and Bug-Oriented Compose Analysis
Binbin Zhao, Xingshuang Lin, Yuan Tian, Saman Zonouz, Na Ruan, Jiliang Li, Raheem Beyah, Shouling Ji
2025

Разбор статьи ч.2

Дальше происходит смешение ответов аудитора и атакующего

Для более точной оценки классификации багов по определенным правилам смешиваются ответы агентов. Грубо определенные атакующим первичные категории складываются с подкатегориями от аудитора по следующему алгоритму (рис. 1):
1) Если 𝑡 является подкатегорией 𝑇, подтверждается 𝑡 как тип-кандидат (строка 10-11).
2) В дополнение к подтверждению 𝑡, если 𝑡 принадлежит 𝑇, также включаются все другие подкатегории 𝑇 в качестве типов-кандидатов, чтобы устранить потенциальные дублирования или неоднозначности (строка 10-14).
3) Если 𝑡 не соответствует ни одной подкатегории 𝑇, или если 𝑇 не была идентифицирована, то 𝑡 исключается из числа типов-кандидатов. (строка 17)
4) Если 𝑡 не определен, но определен 𝑇, откладываем классификацию этого сегмента до получения дополнительной информации или проведения дополнительного анализа (строка 3).

Эти потенциальные уязвимости тем не менее нельзя считать точными, поскольку ответы нейросетей в определенной мере случайные.

Генерация чекера инваривантов

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

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

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


[Подробнее про извлечение переменных и логики]

Во-первых, производится анализ "в глубину" для каждой категории багов, чтобы пометить критичные переменные и действия (операторы, методы, места их первого появления и тд), без которых невозможно собрать бизнес логику. Для примера, если рассматривать манипуляцию ценой оракула, то критичной переменной будет та, которая содержит посчитанную цену LP токена. Характеристики и действия (в оригинале statement), представлены на рис.2

Во-вторых, для выявленных элементов формулируются специальные промпты, которые отправляются в GPT. На изображении 3 показан шаблон для извлечения критических переменных и statement из части кода, потенциально подверженной манипуляции ценой оракула.


[Подробнее про генерацию чекера с использованием шаблона]

Для каждого типа багов были спроектированы соответствующие шаблоны чекеров, которые ориентированы на уязвимые особенности каждого типа багов (рис. 2). Всего было спроектировано 6 видов шаблонов:
- PriceChange_Checker
- ExchangeRate_Checker
- TokenChange_Checker
- StatementOrder_Checker
- ShareSafety_Checker
- StateChange_Cheker

В каждом шаблоне определены условия, которые отслеживают изменения в состоянии контракта. Например в PriceChange_Checker, который создан для определения манипуляции ценой оракула АММ, отслеживается состояние переменной, которая хранит в себе цену LP токена. Если она становится меньше на 90% или больше на 110% старой цены, то это явно говорит о уязвимости.


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

Предложение их следующее: чекеры инвариантов надо встроить прямо в код, до и после опасных мест. Затем получившийся код предлагается прогнать через stateful fuzzing (авторы говорят, что их метод основан на ItyFuzz, гибридном фаззере, по которому есть отдельная статья в списке литературы, возможно что он отличается от традиционного стейтфул фаззинга)
1
Detecting Functional Bugs in Smart Contract through LLM-powered and Bug-Oriented Compose Analysis
Binbin Zhao, Xingshuang Lin, Yuan Tian, Saman Zonouz, Na Ruan, Jiliang Li, Raheem Beyah, Shouling Ji
2025

Разбор статьи ч.3

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

Погнали дальше

Оценка системы

Для оценки системы авторы отвечают на 4 ключевых вопроса:
1) Как двухагентная стратегия проектирования промптов влияет на производительность PromFuzz?
2) Какова точность PromFuzz в генерации инвариантных чекеров?
3) Насколько эффективен PromFuzz при обнаружении функциональных ошибок в смарт-контрактах?
4) Способен ли PromFuzz обнаружить функциональные ошибки нулевого дняв реальных смарт-контрактах?

Пару слов о датасете

Было создано 6 датасетов, которые покрывают разные категории багов. Источников послужил DeFiHackLabs, Web3bugs, GPTScan, а так же контракты реальных DeFi проектов.
1) Безбаговый датасет. Тут всё понятно, 303 контракта на 6 ЕВМ сетях
2) DeFi датасет с эксплойтами. 7 контрактов, которые подвергались реальным атакам и были успешно взломаны. 4 случая манипуляции ценой оракула, 2 неавторизованное поведение, 1 некорректный механизм контроля
3) Багованный датасет. 36 контрактов, где были найдены и подтверждены высокорисковые уязвимости на платформах типа Code4Arena, Immunefi. Содержат 10 функциональных багов, из которых 5 незащищенная логика рассчетов, 2 некорректный механизм контроля, 2 неавторизованное поведение, 1 манипуляция ценой оракула.
4) Синтетический с багами датасет. Специально добавлены баги в 44 контракта, всего 6 штук. 4 связаны с неавторизованным поведением, 2 с некорректным механизмом контроля
5) Датасет извлеченных критических переменных и ключевых операторов (те самые statement, которые я не понимаю как правильно перевести). 55 извлеченных переменных и ключевых операторов из 23 контрактов.
6) Датасет реальных DeFi проектов. 6 проектов, которые проходили публичный аудит во время написания статьи

Оценка двухагентной архитектуры
Велась по первому датасету. Сравнивалась с одноагентными архитектурами GPTScan и SMARTINV. Если коротко, то SMARTINV сильно проигрывает (построен на LLаMA-7b), а GPTScan держится по ложно-позитивным менее чем в проценте от PromFuzz архитектуры, оба построены на GPT-4-turbo.

Так же PromFuzz с двумя агентами сравнивали с PromFuzz где есть только аудитор. Аудитор в одиночку справился значительно хуже. В этом сравнении использовались датасеты 2, 3, 4.

Двухагентная версия достигает полноты (recall) 91.30% и F1 53.85%, обнаружив 21 верный баг и имея 34 ложных срабатывания при 2 пропущенных багах.

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

Оценка точности чекеров инвариантов
5й датасет.
Извлечение переменных - точность составила 100%.

Извлечение операторов — 83.33%, с одним ложным срабатыванием. Это ложное срабатывание связано со сложной бизнес-логикой в смарт-контрактах, где PromFuzz не смог различить несколько похожих действий в одном случае.

Эти критические переменные и операторы должны были бы дать 23 правильных проверяющих инварианта, но в итоге PromFuzz сгенерировал 22 верных, что соответствует точности 95.65%.

Оценка точности обнаружения функциональных багов
Сравнение PromFuzz с четырьмя готовыми инструментами: GPTScan, SMARTINV, ItyFuzz и SMARTIAN. Здесь проще посмотреть на рисунок 2. TP, FP, FN - это True Positive, False Positive и False Negative соответственно. PromFuzz достигает общей полноты (recall) 86.96% и F1 93.02%, обнаружив 20 верных багов, 0 ложных срабатываний и с 3 пропущенными багами.
1
Detecting Functional Bugs in Smart Contract through LLM-powered and Bug-Oriented Compose Analysis
Binbin Zhao, Xingshuang Lin, Yuan Tian, Saman Zonouz, Na Ruan, Jiliang Li, Raheem Beyah, Shouling Ji
2025

Разбор статьи ч.4

Оценка нахождения 0-day уязвимостей
6й датасет. Как показано в рисунке 1, PromFuzz успешно находит 30 багов нулевого дня в 6 DeFi-проектах. О них сообщили соответствующим разработчикам, и 24 из них уже получили CVE ID. Общая рыночная стоимость DeFi-проектов, затронутых этими багами, оценивается примерно в $18.2 миллиарда.

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

Послесловие

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

Во-первых, некоторые пропущенные баги (false negatives) возникают из-за неточностей при извлечении критических переменных и присущей случайности анализа на основе LLM. Несмотря на эти проблемы, PromFuzz всё равно превосходит существующие методы в выявлении более сложных функциональных багов.

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

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

Мои впечатления
В целом, это хорошая динамика для отрасли, такие исследования и разработки однозначно пойдут на пользу всему сообществу. На данный момент наверное немного замороченно ставить эту систему на свою машину (авторы об этом тоже пишут в начале), но сама структурированность подхода может только восхищать. Даже если не внедрять в свой рабочий процесс PromFuzz полностью, то использование отдельных частей может помочь, написание инвариантов на данный момент краеугольный камень в работе любого аудитора. Потому что это и непросто, и может давать потрясающие результаты одновременно. В любом случае, буду ждать продолжения
3
Взлом GMX, что это было?

TLDR; 9 июля 2025 года хакер обнаружил и использовал уязвимость в смарт-контракте GMX v1, что привело к краже около 42 миллионов долларов из пула ликвидности GLP на сети Arbitrum. Уязвимость типа reentrancy позволилa манипулировать шортами и завышать стоимость токена GLP. В данный момент хакер вернул 40.5 миллионов по соглашению с биржей, а GMX v1 остановлен.

Материал для поста взят из разборов от SlowMist, SolidityScan а так же из X GMX

Ключевые моменты

Атака стала возможной из-за наличия двух фундаментальных недостатков дизайна GMX v1.
1. Некорректная работа с globalShortAveragePrice. Система обновляла значение глобальной цены коротких позиций только при открытии шорт, а при закрытии - нет.
2. Мгновенный рост globalShortSizes. При открытии шорт глобальный размер коротких позиций возрастает немедленно, что оказывает влияние на расчет AUM (Assets Under Management) - средства под управлением и это позволяет манипулировать ценой токена GLP в GlpManager.sol (токен ликвидности пула GMX).

В атаке так же использовалась уязвимость в Timelock.enableLeverage механизме, который вызывался во время работы Keeper (это бот, через который происходит работа с ордерами). Глобально можно сказать, что проблема заключается в десинхронизации внутренних подсчетов механизма расчета цен GMX.

Подготовка к атаке

С атакующего контракта были исполнены две транзакции: открытие длинной позиции и ордер на уменьшение позиции, который позже должен был исполнить keeper.

Когда keeper получил ордер на уменьшение позиции, он вызвал PositionManager::executeDecreaseOrder, который в свою очередь сделал внутренний вызов Timelock.enableLeverage, который в свою очередь поставил флаг _isLeverageEnabled контракта Vault в позицию true (да, атака не самая простая). Постановка этого флага - ключевой момент.

После этого метод OrderBook::executeDecreaseOrder приступает к уменьшению позиции. Позиция скорректирована, и collateral (токен залогa), в данном случае WETH, должен вернуться на атакующий контракт. Но WETH перед трансфером разворачивается в ETH и это вызывает fallback функцию атакующего контракта - здесь и начинается reentrancy

fallback функция отправляет 3001 USDC в Vault::increasePosition и открывает шорт с х30 плечом, и соответствующий ордер на закрытие летит в keeper

Как работает Vault::increasePosition
В функции increasePosition в первую очередь происходит вызов внутренней функции _validate, чтобы проверить разрешено ли использовать плечи (тот самый _isLeverageEnabled, который заранее переведен в true). Такая ситуация возможно только если операцию проводит keeper, то есть прямой вызов контракта приведет к ошибке.

Поэтому атакующий и создал заранее ордер на уменьшение позиции, который исполнит keeper, и так получил доступ к использованию плечей в своей fallback функции, с помощью которой в осуществил повторный вход (reentrancy) и вызвал Vault::increasePosition, напрямую создав короткую позицию.

Ко всему прочему, Vault::increasePosition обновляет значение globalShortAveragePrices, когда шорт позиция открывается, а вот Vault:: decreasePosition не обновляет, когда шорт закрывает.

Это позволило использовать эти 3к USDC многократно, чтобы повлиять на globalShortAveragePrices.

В итоге хакеру удалось уменьшить среднюю цену шорта примерно в 57 раз относительно настоящей цены по маркету WBTC. Все эти операции проводились пока keeper исполнял ордер по уменьшению позиции.

Что было дальше
После того как keeper получил финальный ордер на закрытие позиции, он вызвал OrderBook::executeDecreaseOrder. Затем возврат ETH на атакующий контракт снова запустил fallback функцию, но на этот раз она:
- Взяла flashloan на Uniswap в размере 7.538кк USDC
- Вызвала RewardRouterV2::mintAndStakeGlp, где сминтила и стейкнула 4.129кк GLP за 6кк USDC
3
Дальше атака развивается так:
- Происходит вызов Vault::increasePosition, через который открывается шортовая позиция размером 15.385кк USD в WBTC
- Открытие этой позиции обновляет значение globalShortSizes, которое вырастает мгновенно
- Контракт вызывает unstakeAndRedeemGlp, который должен анстейкнуть и вернуть GLP токены, купленные на flashloan

Здесь остановимся подробнее. Атакующему вернули только 386к токенов GLP, еще 9.731кк USDG были сожжены а 88 BTC отправились на атакующий контракт.

Чтобы понять почему так получилось, надо понимать как работает GlpManager:: _removeLiquidity. В этом методе есть формула подсчета того, сколько USDG должно быть сожжено, выглядит она так

usdgAmount = _glpAmount * aumInUsdg / glpSupply

Потом это подсчитанное количество USDG отправляется в Vault и обменивается на желаемый актив (WBTC), AUM (Assets Under Management - активы под управлением) считается так:

aum = ((totalPoolAmounts - totalReservedAmounts) * price)
+ totalGuaranteedUsd + GlobalShortLoss
- GlobalShortProfits - aumDeduction


Из-за того, что на предыдущем шаге была создана большая шорт позиция, globalShortSizes вырос. А getGlobalShortAveragePrice был уменьшен еще чуть раньше, это привело к тому, что эта шорт позиция считается убыточной. Из-за этого резко возрастает GlobalShortLoss, оказывая влияние на AUM (Он растет, значит GLP стал дороже, а значит за один GLP биржа отдаст больше средств), что позволяет в конечном итоге получать атакующему больше активов, чем положено.

Далее атакующий просто продолжает вызывать unstakeAndRedeemGlp, получая средства от манипуляции размером AUM

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

Единственный непонятный мне момент заключается в том, как именно происходила манипуляция с globalShortAveragePrices, что у нее так сильно снизилось значение. Если найду ответ, до дополню пост
4