Анализ смарт-контрактов
29.01.2024

Самостоятельный аудит смарт-контрактов с помощью ChatGPT

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

Если вы хотите самостоятельно изучить смарт-контракт на предмет уязвимостей и скрытых методов скама, то первым шагом будет корректно составленный запрос (prompt) в ChatGPT.

Полезным запросом для ChatGPT будет следующая команда:

Предоставь исчерпывающий список всех проблем и уязвимостей в следующем смарт-контракте. Подробно опиши проблемы и возможные уязвимости. Приведи по одному сценарию использования каждой уязвимости. Вывод сделай в виде корректной таблицы в формате markdown со списком объектов, каждый из которых имеет столбцы 'description', 'action', 'severity', 'actors', 'scenario', 'type' и 'line'. 'type' где может быть 'usability', 'vulnerability', 'optimization' или 'suggestion'. 'actors' - это список задействованных субъектов. 'серьезность' может быть "низкая", "средняя" или "высокая". 'строка' - это номер строки проблемы. Убедись, что все поля таблицы заполнены.

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

Сценарии использования:

  1. Кто является действующими лицами системы?

  2. Какими действиями обладает система?

  3. Какие ограничения существуют в системе?

  4. Какие существуют потенциальные способы сломать систему?

  5. Какая защита используется для противодействия атакам?

  6. Опиши, исходя из ограничений, изменения состояния каждой функции.

  7. Предоставь информацию об используемых шаблонах Solidity и DeFi.

  8. Напиши положительные и отрицательные аксиомы, основываясь на информации о системе.

  9. Перечисли способы оптимизации и изменения кода для повышения его надежности (с фрагментами кода).

  10. Перечисли скрытые методы скама, используемые в коде (с фрагментами кода).

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

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

Совет: Перед началом аудита предоставление чату документации по проверяемому протоколу может значительно повысить точность и релевантность ответов. Достаточно просто упомянуть: "Это документация, обеспечивающая лучший контекст для «название_протокола», который я проверяю", - и вставить документ.

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

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

common tips

Как провести углубленный аудит смарт-контракта? ТОП-100 запросов к ChatGPT

Выше мы рассмотрели общий запрос (prompt) к ChatGPT, с которого можно начать анализ смарт-контракта. Но, разумеется, подробный анализ не ограничивается вводным запросом.

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

Давайте рассмотрим список ТОП-100 запросов, которые позволят вам профессионально подойти к аудиту смарт-контракта:

  1. Успешно ли компилируется код?
  2. Какая версия Solidity используется в коде? Это актуальная стабильная версия?
  3. Присутствуют ли понятные комментарии, объясняющие назначение функций и переменных?
  4. Используется ли в контракте схема "Ownable"? Если да, то для каких функций?
  5. Корректно ли распределены переменные состояния (state variables) с помощью модификаторов видимости?
  6. Используются ли события (events) для правильного логирования?
  7. Предоставляются ли удобные для пользователя сообщения об ошибках?
  8. Проверяется ли возвращаемое значение низкоуровневых вызовов (low-level calls)?
  9. Существуют ли сценарии, в которых владелец может авторизовать себя, что может привести к rug-pulling?
  10. Кто имеет контроль над привилегированными учетными записями и каковы механизмы контроля?
  11. Какие механизмы управления (governance mechanisms) существуют в контракте, и является ли управление полностью открытым или ограниченным?
  12. Используются ли в системе другие контракты и какие роли они выполняют (например, proxy-контракт)?
  13. Существует ли механизм блокировки по времени, и можно ли его обойти?
  14. Существует ли адекватная документация?
  15. Существуют ли в коде потенциальные уязвимости к атакам DoS или реентерабельности (reentrancy)?
  16. Все функции являются внутренними (internal), за исключением тех, которые явно должны быть общедоступными/внешними (public/external)?
  17. В математических операциях нет арифметических переполнений/недополнений (overflows/underflows)?
  18. Используется ли безопасная библиотека OpenZeppelin?
  19. Эфир или токены не могут быть случайно отправлены нуль-адресу (0x0)?
  20. Условия проверяются с помощью require перед операциями и изменением состояния?
  21. Состояние (state) устанавливается до и во время выполнения действий?
  22. Используется ли защита от атак повторного входа (reentry) (A вызывает B вызывает A)?
  23. Правильно ли реализован интерфейс ERC20?
  24. Используется ли модификатор в нескольких местах только, если это действительно необходимо?
  25. Все типы задаются явно (например, используется uint256 вместо uint)?
  26. Все методы и циклы находятся в пределах максимально допустимого лимита газа?
  27. В конструкторе отсутствуют лишние инициализации (помните, что значения по умолчанию заданы)?
  28. Имеется полное покрытие тестами: тестируется каждый метод смарт-контракта и все возможные типы входных данных?
  29. Проведено fuzz-тестирование с использованием случайных входов?
  30. Протестированы ли все возможные состояния, в которых может находиться контракт?
  31. Суммы эфира и токенов по умолчанию указываются в единицах wei?
  32. Блок/время окончания краудсейла (crowdsale) наступает после блока/времени начала (start / enable trading)?
  33. Курс обмена/конвертации токенов краудсейла установлен корректно?
  34. Установлен ли мягкий/жесткий лимит краудсейла?
  35. Минимальный/максимальный допустимый вклад в краудсейл установлен и протестирован?
  36. Функциональность белых списков краудсейла протестирована?
  37. Проверена логика возврата средств с краудсейла?
  38. Участники краудсейла получают пропорциональное количество токенов или могут заявить о своем вкладе?
  39. Правильно ли настроена продолжительность каждого этапа краудсейла (например, предпродажа, публичная продажа)?
  40. Указано ли, какие функции должны контролироваться только владельцем (например, приостановка краудсейла, переход на другую стадию краудсейла, включение распределения токенов и т. д.)?
  41. Логика наделения краудсейла правами (vesting) проверена?
  42. Краудсейл имеет режим отказоустойчивости, который при включении владельцем ограничивает вызовы функции и включает функцию возврата средств?
  43. В краудсейле предусмотрена функция отката, если она имеет разумный смысл.
  44. Импортируемые библиотеки были предварительно проверены и не содержат нежелательных частей, которые могут быть заменены в будущих версиях и могут быть использованы для вредоносных целей?
  45. Методы передачи токенов (transfer) обернуты в require?
  46. Корректно ли используются require и assert? Метод assert используется только для того, что никогда не должно происходить, обычно он используется для проверки состояния после внесения изменений.
  47. Существует ли защита от атак рекурсивных вызовов (recursive call)?
  48. Ограничиваются ли длины произвольных строк на входе?
  49. По возможности избегается использование массивов (array) и вместо них маппинги (mappings)?
  50. Не используются ли хэши блоков для работы со случайными величинами (майнеры могут влиять на это)?
  51. Нигде не использует tx.origin?
  52. Элементы массива сдвигаются вниз при удалении элемента, чтобы не оставлять пробелов?
  53. Используется ли revert вместо throw?
  54. Функции немедленно завершаются, если условия не выполняются?
  55. Устранены ли предупреждения (warnings) компилятора?
  56. Используется ли библиотека SafeMath при вычислениях?
  57. Считываются ли какие-либо слоты памяти (storage slots) несколько раз?
  58. Используются ли какие-либо неограниченные циклы/массивы, которые могут вызвать DoS?
  59. Используется ли block.timestamp только для длинных интервалов?
  60. Не используется block.number для расчета прошедшего времени?
  61. Избегается ли вызов delegatecall, особенно для внешних (пусть даже и доверенных) контрактов?
  62. Не обновляется ли длина массива во время итерации по нему?
  63. Защищены ли подписи от повторного воспроизведения с помощью nonce и block.chainid?
  64. Убедитесь, что все ли подписи используют EIP-712?
  65. Вывод abi.encodePacked() не должен хэшироваться, если используется более 2 динамических типов. В общем случае предпочтительнее использовать abi.encode().
  66. Внимательно проверяйте assembly-вставки кода.
  67. Избегайте недостаточного расхода газа (gas griefing).
  68. Являются ли все приватные данные действительно приватными?
  69. Обновление структуры/массива в памяти (memory) не изменит его в хранилище (stage)?
  70. Затеняются (overshadow) ли переменные состояния (stage variables)?
  71. Вычисление значения переменно на лету дешевле, чем его хранение?
  72. Все ли переменные состояния считываются из правильного контракта (мастер против клона)?
  73. Правильно ли используются операторы сравнения (>, <, >=, <=), особенно для предотвращения ошибок off-by-one?
  74. Правильно ли используются логические операторы (==, !=, &&, ||, !), особенно для предотвращения ошибок off-by-one?
  75. Всегда ли умножение выполняется перед делением (если только умножение не может переполниться)?
  76. Заменяются ли магические числа (magic numbers) константой с интуитивно понятным именем?
  77. Если у получателя ETH есть обратная (fallback ) функция, которая может быть отменена (reverted), то может ли это привести к DoS?
  78. Используется ли стандарт SafeERC20 и проверяются ли возвращаемые значения безопасным способом?
  79. Предполагается ли, что отправитель msg.sender всегда является релевантным пользователем?
  80. Не используется ли tx.origin для авторизации?
  81. Не используется ли address.transfer() или address.send() вместо .call.value()?
  82. При использовании низкоуровневых вызовов (low-level calls) убедитесь, что контракт существует до вызова.
  83. Используется ли assembly-код для доступа к chainid или коду/размеру/хэшу контракта вместо синтаксиса Solidity?
  84. Используется ли ключевое слово delete при установке переменной в нулевое значение (0, false, "" и т. д.)?
  85. Выражения, передаваемые логическим операторам/сравнениям (&&/||/>=/==/etc), не должны иметь побочных эффектов.
  86. При работе с несколькими адресами спросите себя, что произойдет, если они будут одинаковыми?
  87. Насколько хорошо документирован код? Приводятся ли комментарии и примеры везде, где используется нестандартный код?
  88. Если используется External Call, убедитесь действительно ли необходим вызов внешнего контракта?
  89. Проверяется ли результат External Call и обрабатываются ли ошибки?
  90. Что произойдет, если при External Call будет использован весь предоставленный газ?
  91. Если External Call вызывает определенную функцию, убедитесь, что функция реально существует (фантомные функции).
  92. Убедитесь, что в модификаторах (modifiers) не используются внешние вызовы (external calls)
  93. Выдаются ли события (event) для каждой функции, изменяющей хранилище (storage)?
  94. Проверьте свои предположения о том, что делают и возвращают внешние контракты, используемые в основном.
  95. Следите за токенами, в которых используется слишком много или слишком мало десятичных дробей. Убедитесь, что максимальное и минимальное поддерживаемые значения документированы.
  96. Документированы ли полномочия, связанные с ролями?
  97. Каковы риски при нарушении прав доступа и как это может повлиять на различные компоненты системы?
  98. Может ли владелец манипулировать токенами и ETH в рамках контракта?
  99. Как устанавливается адрес оракула (Oracle) и какой процесс за этим стоит? Существуют ли запасные оракулы для подстраховки?
  100. Как в других проектах реализованы аналогичные функции, учитывались ли лучшие практики?

common tips

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

 

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

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

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

С уважением, команда Lotus Market.

All posts

Connect to a wallet

Metamask