Резюме управления
Команда ZenPool связалась с Sayfer Security, чтобы провести полную проверку безопасности всех своих контрактов.
Перед оценкой этих услуг мы провели стартовую встречу с технической командой ZenPool и получили обзор системы и целей этой оценки.
На следующий аудит ушло 20 человеко-дней, все ончейн-контракты были проверены построчно с участием как минимум 2 аудиторов на каждый контракт. Из-за нехватки времени со стороны клиента мы проверили компоненты вне сети и приложили все усилия, чтобы убедиться, что они не содержат критических уязвимостей.
Мы обнаружили в общей сложности 9 находок, 3 из которых были классифицированы как уязвимости «высокого риска» и могли быть использованы злоумышленниками, которые могли полностью опустошить средства пула.
Мы задокументировали наш процесс и наши предложения по устранению каждой уязвимости. Команда ZenPool внедрила исправления, которые были задокументированы в каждом разделе уязвимости.
Обзор системы
ZenPool — это протокол рынка токенов и займов с открытым исходным кодом, не связанный с хранением.
Пользователи могут вносить свои криптоактивы, чтобы получать проценты, или занимать другие токены, чтобы выплачивать проценты на рынке ZenPool. ZenPool имеет собственный токен под названием ZEN.
ZEN — это свободно плавающая валюта, обеспеченная казначейским предложением стабильной монеты BUSD. Токены ZEN могут чеканиться и сжигаться только протоколом, протокол делает это только в зависимости от цены. Каждый ZEN поддерживается как минимум одним BUSD.
Если цена ZEN падает ниже 1 BUSD, протокол покупает и сжигает ZEN, поднимая цену обратно до 1 BUSD.
ZenPool также поддерживает облигации, которые являются еще одним способом пополнить свою казну. Протокол продает облигации в обмен на различные активы, а взамен покупатель получает ZEN по значительно сниженной цене. Это пополняет казну и позволяет ZeenPool обеспечивать своим клиентам невероятную прибыль.
Наконец, часть всех комиссий за продукты ZenPool будет использоваться в качестве дополнительной поддержки, потенциально предоставляя токену ZenPool бесконечную взлетно-посадочную полосу для получения вознаграждений.
Уязвимости по рискам
High
- DoS транзакции
- прямая потеря средств
- перманентная заморозка средств
Medium
- Атаки на тонкие клиенты
- Частично DoS
- Газовые атаки
Низкий
- Лучшие практики
Информационный
- Не наносит вреда системе, и у нас недостаточно данных или знаний, чтобы доказать, что это когда-либо нанесет какой-либо вред, тем не менее важно поделиться нашим
Объем и контракты
В рамках определения масштаба проекта и для того, чтобы понять цели и потребности наших клиентов, мы определили контракты, которые мы должны протестировать в ходе этого аудита. Вместе мы нашли лучший баланс, который подходит для этого конкретного проекта.
Область действия является гибкой по определению, то есть мы можем протестировать в локальной среде другие контракты, которые могут взаимодействовать с контрактом, определенным в качестве области аудита. Это дает нам возможность находить проблемы безопасности, которые в противном случае могли бы остаться незамеченными.
Список контрактов и их коммит на Github:
Зафиксировать хеш
Зафиксировать хеш | контракт |
5d253cb3c544a17399e7d2f4c381a1065bcfa0a0 | https://github.com/zenpoolproject/zenpool/tree/master/contracts/createGovernor.sol |
3887cd307163d130477d4805e74ade11f84d7a4d | https://github.com/zenpoolproject/zenpool/tree/master/contracts/ZenPoolUserManager.sol |
a50062dfc63a0e82ec43de98865420193270236a | https://github.com/zenpoolproject/zenpool/tree/master/contracts/ZenPoolManager.sol |
c4d0db2f9fbfc3146a1a1a797e55c3f3d7a19899 | https://github.com/zenpoolproject/zenpool/tree/master/contracts/ZenTickets.sol |
844132ae5210cb27101bf4a415d9c16e201e1afc | https://github.com/zenpoolproject/zenpool/tree/master/contracts/ZenPoolFunds.sol |
a70146c5d276f933a79c567d2e96512302a6a940 | https://github.com/zenpoolproject/zenpool/tree/master/contracts/ZenGovernorAlpha.sol |
d476137af592fe71cae2578a62e2f8f92b335d8c | https://github.com/zenpoolproject/zenpool/tree/master/contracts/ZenLendingPool.sol |
8c5d858ad7fbfe856cd23160fd8810997f3fdf70 | https://github.com/zenpoolproject/zenpool/tree/master/contracts/ZenGovernorAlpha.sol |
Заказать аудит у Sayfer
Результаты аудита смарт-контрактов
Пользователи могут снимать средства с других балансов, пока пул не станет пустым
контракт | контракты/ZenPoolFunds.sol |
Снижение | High |
Исправлена | Да |
Найдено | Ручное тестирование |
Описание
Ассоциация withdrawFunds
Функция проверяет, что пользователь может вывести только максимальную сумму на своем балансе, проверяется по его адресу и позже сравнивается с пулом токенов.
Позже снятая сумма вычитается из текущего максимального заимствования пользователя по текущей цене. Если общая сумма заемных средств пользователя превышает новый максимальный размер займа, метод не работает, поскольку у пользователя больше нет достаточного залога для поддержки своей позиции по займу. Однако это требование проверяется только в том случае, если пользователь еще не перегружен:
Злоумышленник может использовать эту функцию для использования withdrawFunds
функция вывода средств, превышающих максимальную сумму займа.
Он мог это сделать, потому что getMaxBorrow
будет проверяться только в том случае, если пользователь занимает меньше максимальной суммы, которую ему разрешено, в различных сценариях злоумышленник может злоупотреблять потоком, чтобы пропустить этот конкретный require
, что позволяет ему вызывать withdrawFund
несколько раз, пока пул не опустеет.
риска
Изменить require
вызываться перед строкой 145, чтобы не зависеть от оператора if. Таким образом require
всегда будет выполняться.
Небезопасное самоуничтожение в прокси-контракте
контракт | контракты/ZenTickets.sol контракты/ZenPoolManager.sol |
Снижение | High |
Исправлена | Да |
Найдено | Ручное тестирование |
Описание
Когда главный ZenPoolManager
развертывается, он также развертывает несколько контрактов.
Одним из них является ZenTickets
контракт, который в основном обеспечен, за исключением destoryContract
функция, которая не имеет механизма ACL, как и остальные функции:
Используя эту функцию, злоумышленник, не прошедший проверку подлинности, может вызвать destoryContract
и выберите, куда будут переведены ETH контракта. Это легко использовать с точки зрения злоумышленника.
риска
Использовать onlyOwner
модификатор, как он используется в сбросе функций.
Другим более конкретным решением было бы использование специального механизма ACL, такого как ACL ролей openzeppelin, который позволит только определенным ролям получить доступ к destoryContract
Функции
Пользовательские пулы подвергаются атакам MEV
контракт | контракты/ZenPoolUserManager.sol |
Снижение | High |
Исправлена | Нет – риск принят |
Найдено | Ручное тестирование |
Описание
Основной ZenPoolUserManager
обрабатывает пользовательские пулы, созданные в системе. Пользователь может вызывать различные действия в этих пулах, если у него есть на это права. Пользователь также может предоставлять доступ через ролевой механизм на основе контрактов управления доступом OpenZeppelin.
Ассоциация ZenPoolUserManager
имеет правильный механизм ACL, но в то же время у него есть 2 функции, которые подвергаются фронтальному / обратному запуску или любым атакам MEV.
Хотя сама бизнес-логика верна и кажется, что она не может причинить большого вреда, поскольку у нее есть правильный ACL, пользователь с той же ролью может использовать ее с помощью атак MEV.
риска
Использовать onlyOwner
модификатор, как он используется в сбросе функций.
Другим более конкретным решением было бы использование специального механизма ACL, такого как ACL ролей openzeppelin, который позволит только определенным ролям получить доступ к destoryContract
функции.
Отсутствие защиты от стражей
контракт | контракты/ZenGovernorAlpha.sol |
Снижение | Medium |
Исправлена | Исправлена |
Найдено | Анализ устаревшего кода и ручное тестирование |
Описание
В ходе нашего аудита мы провели анализ исходного кода и сравнили текущую кодовую базу клиента с существующей.
проекты с открытым исходным кодом, которые клиент использовал для разработки кода. Если мы обнаруживали, что в код с открытым исходным кодом были внесены изменения, мы более тщательно изучали их, чтобы убедиться, что они были сделаны с умом.
Большинство клиентов считают сторонние проекты с открытым исходным кодом безопасными, поскольку они исходят от крупных поставщиков (например, пул Uniswap). Это предположение в основном верно. Однако серьезные ошибки безопасности возникают, когда клиенты вносят незначительные изменения в код и предполагают, что эти изменения не влияют на общую безопасность продукта.
Во время нашего анализа исходного кода мы обнаружили, что ZenPool использует код из протокола STRIKE для создания токена управления, исходный код из репозитория STRIKE:
В то время как код в ZenGovernorAlpha:
Следующее заявление было удалено msg.sender == guardian
, это означает, что опекун не может отменить заказы, если достигнуто пороговое значение. Устранение силы стражей может привести к очень опасным ситуациям. Например, если было выполнено скомпрометированное предложение, которое переводит все деньги контракта злоумышленнику (например, путем взлома закрытого ключа), механизм пороговой защиты является избыточным и не может помочь, потому что нет опекуна, который может остановить предложение. от происходящего.
риска
Добавить msg.sender == guardian
до require
.
Отсутствие защиты от повторного входа
контракт | контракты/ZenLendingPool.sol |
Снижение | Medium |
Исправлена | Исправлена |
Найдено | Слайдер и ручное тестирование |
Описание
Следующая функция заимствования не содержит ни защиты от повторного входа, ни шаблона проверки-эффекты-взаимодействия, в настоящее время это невозможно использовать, поскольку пул поддерживает только токены ERC20, но если в будущем будет добавлен новый ERC-777, может произойти эксплойт повторного входа и привести к полному освоению контрактных средств.
Кроме того, код не следует шаблону проверки-эффекты-взаимодействия. В данном конкретном случае require
проверяется после того, как некоторая бизнес-логика уже реализована, это может привести к ошибкам повторного входа, если побочные эффекты будут добавлены до того, как require
.
риска
Добавьте защиту от повторного входа для повторного входа одной и той же функции, а также используйте шаблон проверки-эффекты-взаимодействия для сложного повторного входа между функциями.
Запретить переводы с нулевой суммой
контракт | контракты/ZenPoolFunds.sol |
Снижение | Низкий |
Исправлена | Да |
Найдено | Ручное тестирование |
Описание
Ассоциация ZenPoolFunds.sol
контракт разрешает переводы нулевой суммы между пользователями. Хотя само по себе это не уязвимость в системе безопасности, это пример кода, который может расширить вектор атаки злоумышленника.
Уязвимость существует, потому что transfer
на ZenPool генерировать события, делая нулевое количество transfer
Злоумышленник может создать несколько событий, которые в некоторых сценариях могут инициировать бизнес-логику вне цепочки, даже не удерживая токены в пуле.
риска
Необходимо более глубокое понимание бизнеса. Если возможно, удалите эту функцию.
Если есть случаи использования, когда имеет смысл использовать переводы с нулевой суммой, внедрите еще один уровень проверок, чтобы ограничить использование пользователями, которые являются частью этой группы.
Недостаточное ведение журнала для привилегированных функций
контракт | контракты/ZenGovernorAlpha.sol |
Снижение | Инфо |
Исправлена | Да |
Найдено | Ручное тестирование |
Описание
Следующие привилегированные onlyOwner
функция не генерирует события.
События — это обычная практика для привилегированных функций, чтобы объявить публике о внесении изменений. Без событий изменения сложнее обнаружить, а поведение контракта удивляет пользователей.
Хозяин может позвонить chainId
путем выполнения setChainId()
и изменение chaindId
параметр без создания каких-либо событий в процессе.
риска
Добавьте код, который генерирует события.
Избыточная проверка состояния
контракт | контракты/createGovernor.sol |
Снижение | Инфо |
Исправлена | Да |
Найдено | Ручное тестирование |
Описание
При создании нового токена губернатора _timelockDelay
параметр проверяется дважды. один раз проверяет, когда функция запускается, а затем в составе другой require
, это лишнее и должно быть удалено.
Дублированный код требует больше газа для запуска и может привести к будущим ошибкам при изменении бизнес-логики.
риска
Убрать второй лишний require
.
Несоответствие имен
контракт | - Несколько - |
Снижение | Инфо |
Исправлена | Принятый риск |
Найдено | Слайдер и ручное тестирование |
Описание
Существует множество случаев использования разных стилей заглавных букв (нижний регистр верблюда, регистр змеи и т. д.).
риска
Просмотрите код для стиля кода.
Добавьте руководство по стилю кода и применяйте его с помощью задачи непрерывной интеграции.