Отчет об аудите смарт-контрактов для Dusa

Резюме управления

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

В этом отчете документально подтверждено исследование, проведенное Sayfer с использованием выбранных ресурсов, определенных в рамках исследования. В частности, в этом отчете представлен обзор состояния безопасности смарт-контрактов Dusa.

За период исследования в 4 недели мы обнаружили 17 уязвимостей в контракте.

В целом, Dusa — это хорошо продуманный протокол. Тот факт, что он получен и транслирован из TraderJoe, делает его очень надежным протоколом с довольно распространенной архитектурой, но считающимся оптимальным. Однако у нас есть несколько рекомендаций, которые, по нашему мнению, могут улучшить качество и безопасность протокола. Эти рекомендации подробно описаны в разделе «Обзор архитектуры».

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

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

Методология риска

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

Наша модель оценки рисков основана на двух ключевых факторах: ВЛИЯНИЕ и ВЕРОЯТНОСТЬ. Под воздействием понимается потенциальный вред, который может возникнуть в результате проблемы, например финансовые потери, репутационный ущерб или неработоспособность системы. Вероятность означает вероятность возникновения проблемы с учетом таких факторов, как сложность контракта и количество потенциальных злоумышленников.

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

Риск определяется следующим образом:

Уязвимости по рискам

High – Прямая угроза ключевым бизнес-процессам.
Medium – Косвенная угроза ключевым бизнес-процессам или частичная угроза бизнес-процессам.
Низкий – Прямых угроз нет. Уязвимость может быть использована с использованием других уязвимостей.
Информационный - Этот вывод не указывает на уязвимость, но содержит комментарий, который уведомляет о недостатках дизайна и неправильной реализации, которые могут вызвать проблему в долгосрочной перспективе.

Строгость
# выпусков
High
2
Medium
1
Низкий
8
Информационный
6
критический
0

Подход

Введение

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

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

Обзор области применения

Вместе с командой клиента мы определили следующий контракт как объем проекта.

контракт Ша-256
Фабрика.ц b86a4c350c37a0d8c62495bde0be2b0dca2c8a9f343149238548690df5104cee
main.ts d0073078a6ef26a402bcfb368e94dfb9dddc3f2a629eabc842e2b62d62772b6a
Пара.ц 186f3bd5fab92cb4e98ea5daef31f44d1889f28e683663d056ff6649685ce36c
Цитата.ts b51c762d8ebe50c6b966c9b52a33819a674fb7cf056062ebe34d8f425d879aad
Маршрутизатор.ts 038e32c21432ad173cf8f3b77a586f222a99a8d0f8e033e40145643671ff87ee
WMAS.ts bcef456ec5e27527ae560e21b00fb9f4c8300016aae584da3aa1e869c7018832

Наши испытания проводились с января по февраль 2024 года.

Не позволяйте этому быть слишком поздно!

Начните свой аудит с Sayfer

Проверка области действия

Мы начали с того, что убедились, что объем, определенный нам клиентом, был технически логичным. Решение о том, какая область применения подходит для данной системы, является частью первоначального обсуждения.

Модель угрозы

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

Не позволяйте этому быть слишком поздно!

Начните свой аудит с Sayfer

Обзор протокола

Введение протокола

Dusa — это новаторский протокол децентрализованного финансирования (DeFi), представляющий полностью децентрализованный и продвинутый автоматизированный маркет-мейкер (AMM). Созданный на блокчейне Massa, Dusa подчеркивает такие ключевые принципы, как полная децентрализация, доступность для всех профилей пользователей, совместимость с будущими децентрализованными приложениями (DApps), а также твердая приверженность безопасности и устойчивости к цензуре. Его дорожная карта описывает поэтапный подход, включая исследования и разработки, тестирование, стимулирующие квесты и развертывание децентрализованной биржи (DEX). Уникальные функции Dusa включают в себя концентрированную ликвидность, переменные комиссии, автономную ликвидность и сложные торговые приказы — все они предназначены для улучшения пользовательского опыта и максимизации прибыли. Имея специальную команду, стратегических инвесторов и консультантов, Dusa стремится стать пионером внедрения автономных смарт-контрактов и распространить свои децентрализованные решения на другие экосистемы.

Обзор архитектуры

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

  • С точки зрения передового опыта мы рекомендуем рассмотреть возможность внедрения мультиподписного кошелька для управления привилегированными ролями в будущем. Хотя мы признаем недавний выпуск кода мультиподписи Massa (https://github.com/massalabs/massa-standards/tree/feature/multisig-sc/smart-contracts/assembly/contracts/multisig), мы советуем проявлять осторожность и считаем использование стандартного закрытого ключа жизнеспособным вариантом на данный момент.
  • Другая содержательная рекомендация предлагает принять единую модель ликвидности, предусмотрев глобальное хранилище/PoolManager вместо отдельных контрактов для каждого пула. Этот стратегический сдвиг, вдохновленный недавними достижениями в области AMM, такими как Uniswap V4 и Balancer, обещает значительные преимущества. К ним относятся экономически эффективные многоступенчатые свопы и расширенные возможности флэш-кредитования, обусловленные оптимизированным доступом ко всему пулу ликвидности.

Оценка безопасности

Специфические тесты для Дусы

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

Проверки безопасности

  • Проверки переполнения/недополнения, особенно из-за изменения в кодовой базе языка с проверками по умолчанию на язык, где требуются явные проверки.
  • Использование безопасных библиотек (отмечено_*).
  • Согласованность между контрактами относительно движения средств и звонков.
  • Видимость функций для обеспечения экспорта правильных функций.
  • Реализация контроля доступа и защита чувствительных функций.
  • Защита свопа для защиты взаимодействия с ликвидностью от проскальзывания.

Аутентификация и авторизация

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

Математика и обработка переменных

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

Срочный кредит и управление ликвидностью

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

Функциональность и реализация

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

Обработка контекстных данных

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

 

Общие тесты

Следующие тестовые случаи были руководством при аудите системы. Этот контрольный список представляет собой модифицированную версию СКСВС v1.2, с улучшенной грамматикой, ясностью, краткостью и дополнительными критериями. При наличии пробела в нумерации первоначальный критерий удалялся. Критерии, отмеченные звездочкой, добавлены нами.

Архитектура, дизайн и моделирование угроз

Архитектура, дизайн и моделирование угроз Название теста
G1.2 Каждому вносимому изменению конструкции предшествует моделирование угроз.
G1.3 Документация четко и точно определяет все границы доверия в контракте (доверительные отношения с другими контрактами и значимыми потоками данных).
G1.4 SCSVS, требования безопасности или политика доступны для всех разработчиков и тестировщиков.
G1.5 Определены события для операций (изменение состояния/критические для бизнеса).
G1.6 Проект включает в себя механизм, который может временно остановить важные функции в случае атаки. Этот механизм не должен блокировать доступ пользователей к их активам (например, токенам).
G1.7 Количество неиспользованных криптовалют, хранящихся в контракте, контролируется и находится на минимально допустимом уровне, чтобы не стать потенциальной целью атаки.
G1.8 Если резервную функцию может вызвать кто угодно, она включается в модель угроз.
G1.9 Бизнес-логика последовательна. Важные изменения в логике должны применяться во всех контрактах.
G1.10 Для обнаружения уязвимостей используются инструменты автоматического анализа кода.
G1.11 Используется последняя основная версия Solidity.
G1.12 При использовании внешней реализации контракта используется самая последняя версия.
G1.13 Когда функции переопределяются для расширения функциональности, ключевое слово super используется для сохранения предыдущей функциональности.
G1.14 Порядок наследования тщательно определен.
G1.15 Есть компонент, который отслеживает активность контракта с помощью событий.
G1.16 Модель угроз включает в себя китовые транзакции.
G1.17 Утечка одного приватного ключа не ставит под угрозу безопасность всего проекта.

Политика и процедуры

Политика и процедуры Название теста
G2.2 Безопасность системы находится под постоянным контролем (например, ожидаемый уровень средств).
G2.3 Существует политика отслеживания новых уязвимостей в системе безопасности и обновления библиотек до последней защищенной версии.
G2.4 С отделом безопасности можно связаться публично, и процедура обработки сообщений об ошибках (например, тщательное вознаграждение за обнаружение ошибок) четко определена.
G2.5 Процесс добавления новых компонентов в систему четко определен.
G2.6 Процесс крупных системных изменений включает моделирование угроз сторонней компанией.
G2.7 Процесс добавления и обновления компонентов системы включает в себя аудит безопасности внешней компанией.
G2.8 В случае взлома существует четкая и хорошо известная процедура смягчения последствий.
G2.9 Процедура в случае взлома четко определяет, какие лица должны выполнять требуемые действия.
G2.10 Процедура включает оповещение других проектов о взломе по доверенным каналам.
G2.11 Определена процедура предотвращения утечки закрытого ключа.

Возможность обновления

Возможность обновления Название теста
G3.2 Перед обновлением делается эмуляция в форке основной сети и на локальной копии все работает как положено.
G3.3 Процесс обновления выполняется с помощью мультиподписного контракта, в котором операцию должны одобрить несколько человек.
G3.4 Временные блокировки используются для важных операций, чтобы у пользователей было время наблюдать за предстоящими изменениями (обратите внимание, что устранение потенциальных уязвимостей в этом случае может быть более сложным).
G3.5 инициализировать () можно вызвать только один раз.
G3.6 инициализировать () может вызываться только авторизованной ролью через соответствующие модификаторы (например, инициализатор, только владелец).
G3.7 Процесс обновления выполняется в одной транзакции, поэтому никто не может запустить его заранее.
G3.8 В обновляемых контрактах зарезервированы пробелы в слотах, чтобы предотвратить перезапись.
G3.9 Количество зарезервированных (в качестве промежутка) слотов было уменьшено соответствующим образом, если были добавлены новые переменные.
G3.10 Порядок объявления переменных состояния контракта и их типы не изменились.
G3.11 Новые значения, возвращаемые функциями, такие же, как и в предыдущих версиях контракта (например, владелец (), баланс (адрес)).
G3.12 Реализация инициализирована.
G3.13 Реализация не может быть уничтожена.

 

Бизнес-логика

Бизнес-логика Название теста
G4.2 Реализация логики контракта и параметров протокола соответствует документации.
G4.3 Бизнес-логика выполняется в последовательном порядке шагов, и невозможно пропустить шаги или выполнить их в порядке, отличном от запланированного.
G4.4 В договоре правильно установлены бизнес-лимиты.
G4.5 Бизнес-логика не полагается на значения, полученные из ненадежных контрактов (особенно при наличии нескольких вызовов одного и того же контракта в одном потоке).
G4.6 Бизнес-логика не зависит от баланса контракта (например, баланс == 0).
G4.7 Конфиденциальные операции не зависят от данных блока (например, хэш блока, метка времени).
G4.8 Контракт использует механизмы, которые смягчают атаки упорядочения транзакций (упреждающие) (например, схемы предварительной фиксации).
G4.9 Контракт не отправляет средства автоматически, а вместо этого позволяет пользователям снимать средства отдельными транзакциями.

Контроль доступа

Контроль доступа Название теста
G5.2 Соблюдается принцип наименьших привилегий. Другие контракты должны иметь доступ только к функциям и данным, для которых у них есть специальное разрешение.
G5.3 Новые контракты с доступом к проверенному контракту по умолчанию придерживаются принципа минимальных прав. Контракты должны иметь минимальные разрешения или вообще не иметь их до тех пор, пока доступ к новым функциям не будет предоставлен явным образом.
G5.4 Создатель контракта соблюдает принцип наименьших привилегий, и его права строго следуют изложенным в документации.
G5.5 Контракт применяет правила контроля доступа, указанные в доверенном контракте, особенно если присутствует контроль доступа на стороне клиента dApp, который можно обойти.
G5.6 Вызовы внешних контрактов разрешены только в случае необходимости.
G5.7 Код модификатора понятен и прост. Логика не должна содержать внешних вызовов недоверенных контрактов.
G5.8 Все атрибуты пользователей и данных, используемые элементами управления доступом, хранятся в доверенных контрактах, и другие контракты не могут ими манипулировать, если только это не разрешено специально.
G5.9 Элементы управления доступом дают сбой безопасно, в том числе при возврате.
G5.10 Если входные данные (параметры функции) проверены, по возможности используется метод положительной проверки (внесение в белый список).

Связь

Связь Название теста
G6.2 Выявляются библиотеки, которые не являются частью приложения (но от которых зависит работа смарт-контракта).
G6.3 Вызов делегата не используется с недоверенными контрактами.
G6.4 Контракты с третьими сторонами не затмевают специальные функции (например, возврат).
G6.5 Контракт не проверяет, является ли адрес контрактом, используя код операции extcodesize.
G6.6 Атаки с повторным входом смягчаются путем блокировки рекурсивных вызовов из других контрактов и следования шаблону Check-Effects-Interactions. Не используйте функцию отправки, если это не является обязательным.
G6.7 Результат низкоуровневых вызовов функций (например, отправить, делегировать вызов, позвонить) из других договоров проверяется.
G6.8 Контракт основывается на данных, предоставленных правильным отправителем, и не зависит от значения tx.origin.

Арифметический

Арифметический Название теста
G7.2 Значения и математические операции устойчивы к целочисленным переполнениям. Используйте библиотеку SafeMath для арифметических операций до Solidity 0.8.*.
G7.3 Непроверенные фрагменты кода из Solidity ≥ 0.8.* не вводят целочисленное недополнение/переполнение.
G7.4 Экстремальные значения (например, максимальные и минимальные значения типа переменной) учитываются и не меняют логическую схему контракта.
G7.5 Нестрогое неравенство используется для балансового равенства.
G7.6 В расчетах используются правильные порядки величин.
G7.7 В расчетах умножение выполняется перед делением для точности.
G7.8 Контракт не предполагает точности с фиксированной точкой и использует множитель или сохраняет как числитель, так и знаменатель.

Отказ в обслуживании

Отказ в обслуживании Название теста
G8.2 Контракт не повторяется по несвязанным циклам.
G8.3 Функция самоуничтожения используется только в случае необходимости. Если это включено в контракт, это должно быть четко описано в документации.
G8.4 Бизнес-логика не блокируется, если субъект (например, контракт, учетная запись, оракул) отсутствует.
G8.5 Бизнес-логика не мешает пользователям использовать контракты (например, стоимость транзакции выше, чем прибыль).
G8.6 Выражения функций assert или require имеют проходной вариант.
G8.7 Если резервную функцию никто не вызывает, она не блокирует функции контракта.
G8.8 В цикле нет затратных операций.
G8.9 В цикле нет обращений к недоверенным контрактам.
G8.10 Если есть возможность приостановить действие договора, возможно и его возобновление.
G8.11 Если используются белые и черные списки, они не мешают нормальной работе системы.
G8.12 Отсутствует DoS, вызванный переполнением и недополнением.

Данные блокчейна

Данные блокчейна Название теста
G9.2 Любые сохраненные данные в контрактах не считаются безопасными или частными (даже частные переменные).
G9.3 В блокчейне не хранятся конфиденциальные данные (пароли, персональные данные, токены и т. д.).
G9.4 Контракты не используют строковые литералы в качестве ключей для отображений. Вместо этого используются глобальные константы для предотвращения атаки Homoglyph.
G9.5 Контракт не тривиально генерирует псевдослучайные числа на основе информации из блокчейна (например, заполнение номером блока).

Использование газа и ограничения

Использование газа и ограничения Название теста
G10.1 Использование газа предполагается, определяется и имеет четкие ограничения, которые нельзя превышать. Ни структура кода, ни злонамеренный ввод не должны вызывать газового истощения.
G10.2 Выполнение функций и функциональность не зависят от жестко запрограммированных сборов за газ (они могут меняться).

Ясность и читабельность

Ясность и читабельность Название теста
G11.2 Логика понятна и разделена на несколько простых контрактов и функций.
G11.3 Каждый контракт имеет короткий комментарий из 1-2 предложений, объясняющий его назначение и функциональность.
G11.4 Используются готовые реализации, это поясняется в комментарии. Если эти реализации были изменены, изменения отмечаются по всему контракту.
G11.5 Порядок наследования учитывается в контрактах, использующих множественное наследование и теневые функции.
G11.6 Там, где это возможно, контракты используют существующий проверенный код (например, контракты токенов или такие механизмы, как принадлежащий) вместо реализации своих собственных.
G11.7 Последовательные шаблоны именования соблюдаются на протяжении всего проекта.
G11.8 Переменные имеют отличительные имена.
G11.9 Все переменные хранения инициализируются.
G11.10 Функции с указанным типом возвращаемого значения возвращают значение этого типа.
G11.11 Используются все функции и переменные.
G11.12 требовать используется вместо возвращаться in if заявления.
G11.13 Ассоциация утверждать используется для проверки внутренних ошибок и требовать Функция используется для обеспечения действительного условия ввода от пользователей и внешних контрактов.
G11.14 Ассемблерный код используется только в случае необходимости.

Покрытие тестов

Покрытие тестов Название теста
G12.2 Нарративы злоупотреблений, подробно описанные в модели угроз, покрываются модульными тестами.
G12.3 Чувствительные функции в проверенных контрактах покрываются тестами на этапе разработки.
G12.4 Реализация проверенных контрактов была проверена на наличие уязвимостей безопасности с использованием как статического, так и динамического анализа.
G12.5 Спецификация контракта была официально проверена
G12.6 Спецификация и результаты формальной проверки включены в документацию.

Децентрализованные финансы

Децентрализованные финансы Название теста
G13.1 Договор кредитора не предполагает изменения его баланса (используемого для подтверждения погашения кредита) только со своими собственными функциями.
G13.2 Функции, которые изменяют баланс кредиторов и/или предоставляют криптовалюту, не подлежат повторному входу, если смарт-контракт позволяет заимствовать криптовалюту основной платформы (например, Ethereum). Он блокирует атаки, которые обновляют баланс заемщика во время оформления срочного кредита.
G13.3 Функции быстрой ссуды могут вызывать только предопределенные функции в контракте-получателе. Если возможно, определите доверенное подмножество вызываемых контрактов. Обычно отзывается контракт на отправку (заимствование).
G13.4 Если он включает потенциально опасные операции (например, отправка большего количества ETH/токенов, чем заимствовано), функция получателя, которая обрабатывает заимствованные ETH или токены, может быть вызвана только пулом и в рамках процесса, инициированного владельцем принимающего контракта или другим доверенным источником (например, мультиподпись).
G13.5 Расчеты доли пула ликвидности выполняются с максимально возможной точностью (например, если вклад рассчитывается для ETH, это должно быть сделано с точностью до 18 знаков — для Wei, а не для Ether). Делимое должно быть умножено на 10 в степени количества десятичных цифр (например, делимое * 10^18 / делитель).
G13.6 Вознаграждения не могут быть рассчитаны и распределены в рамках того же вызова функции, который вносит токены (он также должен быть определен как невозвратный). Это защищает от сиюминутных колебаний акций.
G13.7 Контракты на управление защищены от атак мгновенных кредитов. Одним из возможных методов смягчения последствий является требование процесса депонирования токенов управления и предложения изменений для выполнения в разных транзакциях, включенных в разные блоки.
G13.8 При использовании оракулов в сети контракты могут приостанавливать операции на основе результатов оракулов (в случае взлома оракула).
G13.9 Внешние контракты (даже доверенные), которым разрешено изменять атрибуты контракта проекта (например, цену токена), имеют следующие ограничения: пороги для изменения (например, не более/менее 5%) и лимит обновлений (например, одно обновление в день).
G13.10 Атрибуты контракта, которые могут обновляться внешними контрактами (даже доверенными), отслеживаются (например, с помощью событий) и реализуется процедура реагирования на инциденты (например, во время продолжающейся атаки).
G13.11 Сложные математические операции, состоящие из операций умножения и деления, сначала выполняют умножение, а затем деление.
G13.12 При расчете биржевых цен (например, ETH в токен или наоборот) числитель и знаменатель умножаются на резервы (см. получитьInputPrice функции в UniswapExchange договор).

 

Заказать аудит у Sayfer





    Этот сайт защищен reCAPTCHA и Google Персональные данные и Условия Предоставления Услуг подать заявление.

    Выводы аудита

    [H] Риск опережения при создании новой пары

    ID САЙ-01
    Статус: Исправлена
    Снижение High
    Бизнес Влияние В некоторых случаях пользователи могут потерять средства, которые они внесли для создания пары. Либо злонамеренный лидер может создать пару за счет другого пользователя, либо несколько пользователей могут попытаться создать пару одновременно, успешно или неудачно в случайном порядке.
    Адрес
    • Роутер.ц; createLBPair(StaticArray )
    • Фабрика.ц; createLBPair(StaticArray )

    Описание

    Чтобы создать новую пару, пользователю необходимо позвонить Router::createLBPair(StaticArray ). Под капотом эта функция вызывает Factory::createLBPair(StaticArray ), что, в свою очередь, вызывает Массу TransferCoins(Адрес, номер).

    • Фабрика.ц:264; createLBPair(StaticArray )

    transferCoins(_pair._origin, 200 * ONE_COIN);

    Согласно документации, эта функция просто переводит монеты с текущего адреса на заданный адрес. Это означает, что эти средства должны быть предварительно отправлены на Производство. С другой стороны, пользователи имеют возможность звонить создать пару от Router, который является точкой входа по умолчанию для других операций. Однако, если они вносятся в какую-либо отдельную транзакцию, существует вероятность того, что кто-то, намеренно или иным образом, также вызовет createLBPair(StaticArray ).

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

    риска

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

    Например, одним из способов достижения этого может быть механизм проверки заводского баланса и баланса пула в конце функции и отправки излишка обратно, аналогично этому https://github.com/massalabs/coin-vester/blob/master/smart-contract/assembly/contracts/main.ts#L34

    Механизм будет действовать в создатьLBPair функция (из Производство), в конструктор, мята, гореть, собирать сборы, Увеличение OracleLength, SafeTransferFrom & SafeBatchTransferОт (из пары). Это функции, которые могут использовать Massa для хранения, поскольку они могут создавать новые записи в хранилище (изменение хранилища ничего не стоит). Функции, взаимодействующие с этими функциями, также должны иметь этот механизм. 

    Их можно разделить на два разных вида:

    • Функции, взаимодействующие с ними и не взаимодействующие с WMAS (создатьLBPair от маршрутизатора и завода + добавитьЛиквидность, удалитьЛиквидность) перенесет все переданные монеты, сохранить баланс СЦ в константе, а после звонка СЦ передать обратно звонящему разницу между новым балансом и сохраненным балансом.
    • Функции, взаимодействующие с ними и взаимодействующие с WMAS (добавитьЛиквидитиМАС, удалитьLiquidityMAS) понадобится еще один параметр, чтобы узнать количество монет, которые нужно обернуть, вы отправите разницу между переданные монеты и этот номер в звонке. Остальной механизм этих функций будет таким же, как и предыдущий.

     

    [H] Средства, внесенные на создание пары, могут быть потеряны

    ID САЙ-02
    Статус: Исправлена
    Снижение High
    Влияние на бизнес Пользователи, вносящие средства на роутер для создания пары, могут потерять свои деньги, не увидев результата. Мы оценили эту проблему как высокую (а не критическую), поскольку существует альтернативный рабочий процесс — вызов фабрика::createLBPair(StaticArray ) непосредственно с фондами.
    Адрес
    • Роутер.ц; createLBPair(StaticArray )
    • Фабрика.ц:264; createLBPair(StaticArray )

    Описание

    Эта проблема связана с тем, как устроено создание пар. Пользователь может позвонить Router::createLBPair(StaticArray ) а поскольку для создания пары требуется депозит, он может прикрепить средства к вызову функции, что звучит как интуитивное решение.

    Однако, если пользователь сделает это, средства никогда не дойдут до пары и будут потеряны в контракте (хотя могут быть восстановлены владельцем). Это связано с тем, что они застрянут в контракте Router, а создание пары происходит в контракте Factory, где вместо этого используется метод TransferCoins(), списывающий средства с текущего адреса (фабрики).

    • Фабрика.ц:264; createLBPair(StaticArray )

    transferCoins(_pair._origin, 200 * ONE_COIN);

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

    риска

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

     

    [M] Несколько пар одного и того же типа могут снизить ликвидность

    ID САЙ-03
    Статус: Исправлена
    Снижение Medium
    Влияние на бизнес Если приложение AMM позволяет создавать несколько пулов с одинаковыми параметрами, ликвидность может быть разбавлена ​​по этим пулам, а не сконцентрирована только в одном. Это может негативно повлиять на пользователей и привести к менее выгодным сделкам для пользователей протокола.

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

    Адрес
    • Фабрика.ц; createLBPair(StaticArray )
    • Роутер.ц; createLBPair(StaticArray )

    Описание

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

    риска

    Проверьте, существует ли уже пара определенных параметров при создании пары, если да, вернитесь.

     

    [L] Точная проверка баланса после возможного злоупотребления срочной ссудой

    ID САЙ-04
    Статус: Исправлена
    Снижение Низкий
    Влияние на бизнес Получатель срочного кредита может выполнять внешние вызовы в обратном вызове. Поскольку система требует, чтобы баланс после срочного кредита был точно таким же, как и до, плюс комиссионные, эти внешние контракты могут передавать очень небольшую сумму паре во время исполнения, чтобы гарантировать, что мгновенный кредит не удастся (что может быть выгодно для них). в определенных ситуациях).
    Адрес
    • Пара.ц:280; flashLoan(StaticArray )

    Описание

    После срочного кредита система требует, чтобы баланс был точно таким же, как до момента срочного кредита плюс комиссионные.

    • flashLoan(StaticArray )

    assert(

      _balanceAfter == SafeMath256.add(_balanceBefore, _fees.total),

      LBPair__FlashLoanInvalidBalance(),

    );

    Обычно требуется, чтобы баланс был больше, поскольку требование точного соответствия является ограничительным.

    риска

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

     

    [L] Игнорирование пары LB не генерирует событие

    ID САЙ-05
    Статус: Исправлена
    Снижение Низкий
    Бизнес Влияние Индексаторы вне цепочки могут получать неверную информацию, что приводит к неверным расчетам.
    Адрес
    • Фабрика.ц; setLBPairInformation(StaticArray )

    Описание

    Функция setLBPairIgnored(StaticArray ) может использоваться для управления тем, следует ли игнорировать пару при маршрутизации или нет. Любое изменение флага с помощью этой функции генерирует событие SET_LBPAIR_IGNORED. Однако также возможно изменить флаг с помощью setLBPairInformation(StaticArray ), который не генерирует событие.

    риска

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

    [L] Непоследовательный сбор платежей

    ID САЙ-06
    Статус: Признанный
    Снижение Низкий
    Бизнес Влияние Любой пользователь может инициировать сбор платы для других пользователей, тогда как сбор платы за протокол может быть инициирован только владельцем.
    Адрес
    • Пара.ц; собирать сборы(StaticArray )
    • Пара.ц:723-726; CollectProtocolFees(StaticArray )

    Описание

    Любой может позвонить собирать сборы(StaticArray ) для любого адреса, чтобы распределить сборы по этому адресу. Это может быть нежелательно для некоторых пользователей, которые хотят контролировать, когда им будут выплачиваться сборы. 

    Это дополнительно противоречит CollectProtocolFees(StaticArray ), который может вызвать только получатель.

    • CollectProtocolFees(StaticArray )

    assert(

      Context.caller().equals(_feeRecipient),

      LBPair__OnlyFeeRecipient(_feeRecipient, Context.caller()),

    );

    риска

    Рассмотрите возможность изменения логики в собирать сборы(StaticArray ) чтобы соответствовать CollectProtocolFees(StaticArray ), т.е. позволяя получателю получать только свои сборы.

    [L] Непоследовательное использование SafeMath

    ID САЙ-07
    Статус: Исправлена
    Снижение Низкий
    Бизнес Влияние Переполнение или опустошение кода может привести к неожиданным откатам и/или просчетам. 
    Адрес -

    Описание

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

    риска

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

    [L] Перечисление неэффективных активов

    ID САЙ-08
    Статус: Исправлена
    Снижение Низкий
    Бизнес Влияние Некоторые заводские функции потребляют больше газа, чем необходимо. В худшем случае, если владелец зарегистрирует очень большое количество активов, это может привести к DoS. Но это маловероятно.
    Адрес
    • Завод.ц:102-106; isQuoteAsset (Адрес)

    Описание

    вот две проблемы с этой функцией: 

    1. Цикл не прерывается после обнаружения актива и без необходимости перебирает остальную часть массива. Таким образом, каждый случай is худший случай.
    2. В этом случае сопоставление было бы более эффективным, поскольку оно имеет постоянный поиск по времени.
    • isQuoteAsset (Адрес)

    for (let i = 0; i < quoteAssets.length; i++) {

      if (quoteAssets[i].equals(_token)) {

        isQuoteAsset = true;

      }

    }

    риска

    Здесь есть два решения:

    1. Сохраните текущий алгоритм линейного поиска и просто добавьте разрыв в if блокировка после установки isQuoteAsset к истине.
    2. Лучшим решением было бы переключиться на картографирование. Когда в систему добавляется новый токен, quoteAssets[токен] должно быть установлено значение true. Отныне к нему можно будет получить доступ при необходимости – не нужно его искать. Возможно, всю функцию можно просто отрефакторить.

    [L] Максимальная комиссия за мгновенный кредит не устанавливается после развертывания

    ID САЙ-09
    Статус: Исправлена
    Снижение Низкий
    Бизнес Влияние Комиссия за флэш-кредит может быть выше, чем MAX_FEE.
    Адрес
    • Фабрика.ц:80; конструктор(StaticArray )

    Описание

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

    риска

    Проверьте комиссию за флэш-кредит в конструкторе.

    [L] Неполная защита от проскальзывания – отсутствует проверка срока

    ID САЙ-10
    Статус: Исправлена
    Снижение Низкий
    Бизнес Влияние Существует повышенная вероятность того, что пользователи получат менее выгодные сделки при использовании AMM.
    Адрес Маршрутизатор.ts

    • addLiquidity(bs: StaticArray )
    • addLiquidityMAS(bs: StaticArray )

    Описание

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

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

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

    риска

    Осуществлять  _ensure(срок) точно так же он уже присутствует во всех других функциях, связанных с ликвидностью.

    [L] Одноэтапная передача права собственности

    ID САЙ-11
    Статус: Исправлена
    Снижение Низкий
    Бизнес Влияние Предоставление неправильного адреса может привести к безвозвратной потере права собственности на контракт.
    Адрес
    • Фабрика.ц; передачавладения([u8])

    Описание

    In Фабрика.ц, смена владельца достигается путем вызова старого владельца передачавладения([u8]) с новым владельцем. Затем функция изменяет ВЛАДЕЛЕЦ переменная состояния.

    • передачавладения([u8])

    export function transferOwnership(bs: StaticArray<u8>): void {

      _onlyOwner();

      const _newOwner = new Address(new Args(bs).nextString().unwrap());

      _setFeeRecipient(_newOwner);

      Storage.set(OWNER, _newOwner.toString());

    }

    риска

    Мы рекомендуем реализовать двухэтапный процесс передачи права собственности. Это соответствует широко признанной передовой практике и может предотвратить случайные передачи. Для иллюстрации мы будем использовать реализацию OpenZepplin.

    Двухэтапная передача права собственности требует, чтобы текущий владелец инициировал передачу.

    function transferOwnership(address newOwner) public virtual override onlyOwner {

     _pendingOwner = newOwner;

     emit OwnershipTransferStarted(owner(), newOwner);

    }

    Но для завершения процесса новый владелец должен одобрить передачу.

    function acceptOwnership() public virtual {

     address sender = _msgSender();

     if (pendingOwner() != sender) {

         revert OwnableUnauthorizedAccount(sender);

     }

     _transferOwnership(sender);

    }

    Это гарантирует, что новый владелец является целевой целью.

    [I] Недостаточная эмиссия событий

    ID САЙ-12
    Статус: Исправлена
    Снижение Информационный
    Бизнес Влияние Снижение отслеживаемости и видимости исторических изменений состояния ключей, влияющих на протокол.
    Адрес Фабрика.ц

    • setLBPairInformation(bs: StaticArray )
    • ForceDecay(bs: StaticArray )
    • TransferOwnership(bs: StaticArray )

    Описание

    Некоторые ключевые изменения состояния протокола не вызывают соответствующего события.

    Примечание: TransferOwnership(bs: StaticArray ) генерирует событие, но только для _setFeeRecipient.

    риска

    Добавьте эмиссию событий в указанных местах.

    [I] Геттеры и сеттеры перепутаны с внешними функциями

    ID САЙ-13
    Статус: Исправлена
    Снижение Информационный
    Бизнес Влияние Смешение, геттеры, сеттеры, точки входа и внутренние функции делают код менее читабельным.
    Адрес
    • Фабрика.ц:631, 639
    • Пара.ц:1031, 1227

    Описание

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

    Однако в некоторых контрактах этот порядок нарушается — функции перепутаны. Иногда экспортированные функции (точки входа) также путают с внутренними.

    риска

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

    [I] Отсутствие модульных тестов

    ID САЙ-14
    Статус: Признанный
    Снижение Информационный
    Бизнес Влияние Сценарии тестирования и модульные тесты помогают разработчикам обнаруживать ошибки и уязвимости, которые в противном случае ускользнули бы от простого статического анализа. Динамическое тестирование имеет неоценимое значение для обеспечения качества готового продукта.
    Адрес -

    Описание

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

    риска

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

    [I] Ненужный код

    ID САЙ-15
    Статус: Исправлена
    Снижение Информационный
    Бизнес Влияние Эта проблема не оказывает прямого влияния на код или протокол, поэтому ей был присвоен информационный статус.
    Адрес Роутер.ц:770-772; _getAmountsIn(u64[], Адрес[], IERC20[], u256)

    Описание

    Функция _getAmountsIn() принимает шаги бункера в качестве аргумента и выполняет следующую проверку:

    • _getAmountsIn(u64[], Адрес[], IERC20[], u256)

    if (_binStep == 0) {

      // means TraderJoe V1 swap

    } else {

      ...

    }

    Однако в этом нет необходимости. Система не поддерживает обмены в стиле V1, а остальная часть функции не учитывает шаги интервала, поскольку получает пары (соответствующие шагам интервала) в качестве дополнительного аргумента.

    риска

    Рассмотрите возможность удаления аргумента _pairBinSteps и ненужного предложения if.

    [I] Неиспользованный импорт

    ID САЙ-16
    Статус: Исправлена
    Снижение Информационный
    Бизнес Влияние Эта проблема не оказывает прямого влияния на код или протокол, поэтому ей был присвоен информационный статус.
    Адрес
    • Пара.ц:35,
    • Роутер.ц:4,
    • WMAS.ts:5,6,
    • интерфейсы/IPair.ts:5

    Описание

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

    риска

    Удалите неиспользуемый импорт.

    [I] Использование «магических чисел»

    ID САЙ-17
    Статус: Признанный
    Снижение Информационный
    Бизнес Влияние Это может усложнить анализ кода для незнакомых читателей.
    Адрес
    • Пара.ts:113
    • Фабрика.ц:264, 735

    Описание

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

    риска

    Добавьте комментарии, поясняющие выбор констант.

    Вы можете найти больше информации об этом в нашем блоге

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

    Держите в курсе

    Телефон
    Адрес
    Тель-Авив, Израиль
    Вестники:
    Пожалуйста, не стесняйтесь обращаться к нам, мы будем рады ответить!





      Этот сайт защищен reCAPTCHA и Google Персональные данные и Условия Предоставления Услуг подать заявление.
      перейти к содержанию