Звіт про аудит розумних контрактів для Dusa

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

Дуса зв’язався із Sayfer, щоб провести аудит безпеки їхніх смарт-контрактів. 

У цьому звіті задокументовано дослідження, проведене Sayfer, спрямоване на вибрані ресурси, визначені в рамках дослідження. Зокрема, у цьому звіті відображається перевірка стану безпеки для смарт-контрактів Dusa.

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

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

Підсумовуючи, слід зазначити, що після звіту слід внести кілька виправлень, але стан безпеки системи є компетентним.

Після перевірки командою Sayfer ми засвідчуємо, що всі проблеми безпеки, згадані в цьому звіті, були розглянуті або підтверджені командою Dusa.

Методологія ризиків

У Sayfer ми прагнемо надавати нашим клієнтам найвищу якість аудиту розумних контрактів. Ось чому ми запровадили комплексну модель оцінки ризиків, щоб оцінити серйозність наших висновків і надати нашим клієнтам найкращі рекомендації щодо пом’якшення.

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

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

Ризик визначається таким чином:

Уразливості за ризиком

Високий – Пряма загроза ключовим бізнес-процесам.
Medium – Непряма загроза ключовим бізнес-процесам або часткова загроза бізнес-процесам.
низький – Прямої загрози немає. Уразливість може бути використана за допомогою інших уразливостей.
Інформаційний – Цей висновок не вказує на вразливість, але містить коментар, який сповіщає про недоліки дизайну та неправильну реалізацію, які можуть спричинити проблему в довгостроковій перспективі.

Строгість
Кількість випусків
Високий
2
Medium
1
низький
8
Інформаційний
6
Критичний
0

Підхід

Вступ

Дуса зв’язався із Sayfer, щоб провести аудит безпеки їхніх смарт-контрактів.

У цьому звіті задокументовано дослідження, проведене Sayfer, спрямоване на вибрані ресурси, визначені в рамках дослідження. Зокрема, у цьому звіті відображається перевірка стану безпеки для вищезгаданих контрактів.

Огляд сфери застосування

Разом із командою клієнта ми визначили наступний контракт як обсяг проекту.

Контракт Ша-256
Завод.ц b86a4c350c37a0d8c62495bde0be2b0dca2c8a9f343149238548690df5104cee
main.ts d0073078a6ef26a402bcfb368e94dfb9dddc3f2a629eabc842e2b62d62772b6a
Пара.ц 186f3bd5fab92cb4e98ea5daef31f44d1889f28e683663d056ff6649685ce36c
Quoter.ts b51c762d8ebe50c6b966c9b52a33819a674fb7cf056062ebe34d8f425d879aad
Router.ts 038e32c21432ad173cf8f3b77a586f222a99a8d0f8e033e40145643671ff87ee
WMAS.ts bcef456ec5e27527ae560e21b00fb9f4c8300016aae584da3aa1e869c7018832

Наші тести проводилися з січня по лютий 2024 року.

Нехай не буде надто пізно!

Почніть свій аудит із Sayfer

Перевірка обсягу

Ми почали з того, що переконалися, що обсяг, визначений нам клієнтом, є технічно логічним. Вирішення того, яка область підходить для даної системи, є частиною початкового обговорення.

Модель загрози

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

Нехай не буде надто пізно!

Почніть свій аудит із Sayfer

Огляд протоколу

Вступ до протоколу

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

Огляд архітектури

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

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

Оцінка безпеки

Специфічні тести Dusa

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

Перевірки безпеки

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

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

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

Математика та обробка змінних

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

Екстрена позика та управління ліквідністю

  • Експертиза типових помилок, пов'язаних із флеш-кредитами, включаючи прорахунки та блокування коштів.
  • Проблеми, пов’язані зі створенням фабрик і пар, наприклад створення небезпечних пулів і управління ліквідністю.
  • Перевірка розрахунків виведення ліквідності з урахуванням комісії, отриманої при забезпеченні ліквідності.

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

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

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

  • Перевірте, чи правильно передаються контекстні дані до функцій, щоб уникнути вразливостей.

 

Загальні тести

Наступні тестові приклади були орієнтиром під час аудиту системи. Цей контрольний список є модифікованою версією SCSVS 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 Атаки повторного входу пом’якшуються блокуванням рекурсивних викликів з інших контрактів і дотриманням шаблону перевірки-ефекти-взаємодії. Не використовуйте функцію надсилання, якщо це не обов’язково.
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 У контрактах не використовуються рядкові літерали як ключі для зіставлення. Замість цього використовуються глобальні константи, щоб запобігти атаці гомогліфів.
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 або токени, може бути викликана лише пулом і в рамках процесу, ініційованого власником контракту-одержувача або іншим надійним джерелом (наприклад, multisig).
G13.5 Розрахунок частки пулу ліквідності виконується з максимально можливою точністю (наприклад, якщо внесок розраховується для ETH, це має бути зроблено з точністю до 18 цифр – для Wei, а не для Ether). Ділене потрібно помножити на 10 у степені кількості десяткових цифр (наприклад, ділене * 10^18 / дільник).
G13.6 Винагороди не можна розрахувати та розподілити в межах того самого виклику функції, який депонує токени (його також слід визначити як без повторного входу). Це захищає від миттєвих коливань акцій.
G13.7 Управлінні контракти захищені від атак швидкої позики. Одним із можливих методів пом’якшення є вимога процесу депонування токенів управління та пропозиції змін, які мають бути виконані в різних транзакціях, включених до різних блоків.
G13.8 При використанні on-chain оракул контракти можуть призупиняти операції на основі результату оракула (у разі скомпрометованого оракула).
G13.9 Зовнішні контракти (навіть довірені), яким дозволено змінювати атрибути контракту проекту (наприклад, ціну токена), мають такі обмеження: порогові значення для зміни (наприклад, не більше/менше 5%) та обмеження оновлень (наприклад, одне оновлення на день).
G13.10 Атрибути контракту, які можуть бути оновлені зовнішніми контрактами (навіть надійними), відстежуються (наприклад, за допомогою подій), і реалізується процедура реагування на інцидент (наприклад, під час поточної атаки).
G13.11 Складні математичні операції, які складаються з операцій множення та ділення, спочатку виконують множення, а потім ділення.
G13.12 Під час розрахунку біржових цін (наприклад, ETH на токен або навпаки), чисельник і знаменник множаться на резерви (див. getInputPrice функція в UniswapExchange договір).

 

Замовити аудит у Сайфер





    Цей сайт захищено reCAPTCHA і Google Політика Конфіденційності та Умови обслуговування застосовувати.

    Висновки аудиту

    [H] Передній ризик під час створення нової пари

    ID СКАЖИ-01
    Статус Виправлено
    Risk Високий
    Business Impact У деяких випадках користувачі можуть втратити кошти, які вони внесли для фінансування створення пари. Або зловмисний фаворит може створити пару за рахунок іншого користувача, або кілька користувачів можуть спробувати створити пару одночасно, успішно або невдало випадковим чином.
    Місце розташування
    • Router.ts; createLBPair(StaticArray )
    • Factory.ts; createLBPair(StaticArray )

    Опис

    Щоб створити нову пару, користувач повинен зателефонувати Router::createLBPair(StaticArray ). Під капотом ця функція викликає Factory::createLBPair(StaticArray ), який у свою чергу називає Масса transferCoins(адреса, номер).

    • Завод.ц:264; createLBPair(StaticArray )

    transferCoins(_pair._origin, 200 * ONE_COIN);

    Згідно зі документація, ця функція просто переносить монети з поточної адреси на задану адресу. Це означає, що ці кошти потрібно попередньо надіслати завод. З іншого боку, користувачі мають можливість дзвонити createPair з маршрутизатора, який є точкою входу за замовчуванням для інших операцій. Однак, якщо вони внесені в будь-яку окрему транзакцію, існує ймовірність того, що хтось, навмисно чи інакше, також подзвонить createLBPair(StaticArray ).

    Коли блок із транзакціями буде завершено, вони будуть розміщені в невідомому порядку. Тоді, включаючи першу транзакцію, ці кошти будуть переведені з Factory до нової пари, тоді як транзакція другого користувача (останньої транзакції) буде скасовано через відсутність доступних коштів.

    Пом'якшення

    Фінансування створення пари має фактично відбуватися в одній транзакції, щоб уникнути проблем із зміною порядку транзакцій. 

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

    Механізм буде на місці в createLBPair функція (з завод), в конструктор, м'ята, горіти, збір зборів, збільшення довжини Oracle, safeTransferFrom & safeBatchTransferFrom (з пари). Це функції, які можуть витрачати Massa на зберігання, оскільки вони можуть створювати нові записи в сховищі (зміна сховища нічого не коштує). Функції, що взаємодіють з цими функціями, також повинні мати цей механізм. 

    Їх можна розділити на два різні види:

    • Функції, які взаємодіють із ними та не взаємодіють із WMAS (createLBPair від маршрутизатора та заводу + addLiquidity, removeLiquidity) передасть усі transferredCoins, зберегти баланс SC у константі, а після виклику SC передати назад абоненту різницю між новим балансом і збереженим балансом.
    • Функції, які взаємодіють із ними та які взаємодіють із WMAS (addLiquidityMAS, removeLiquidityMAS) знадобиться ще один параметр, щоб дізнатися кількість монет, які потрібно загорнути, ви надішлете різницю між transferredCoins і цей номер у дзвінку. Решта механізму в цих функціях буде такою ж, як і раніше.

     

    [H] Кошти, внесені на створення пари, можуть бути втрачені

    ID СКАЖИ-02
    Статус Виправлено
    Risk Високий
    Вплив на бізнес Користувачі, які вносять кошти на маршрутизатор для створення пари, можуть втратити свої гроші, не побачивши результату. Ми оцінили цю проблему як високу (а не критичну), оскільки існує альтернативний робочий процес – виклик factory::createLBPair(StaticArray ) безпосередньо з коштами.
    Місце розташування
    • Router.ts; createLBPair(StaticArray )
    • Завод.ц:264; createLBPair(StaticArray )

    Опис

    Ця проблема є результатом того, як розроблено створення пари. Користувач може подзвонити Router::createLBPair(StaticArray ) і оскільки для створення пари потрібен депозит, він може приєднати кошти до виклику функції, що звучить як інтуїтивно зрозуміле рішення.

    Однак, якщо користувач так зробить, кошти ніколи не досягнуть пари та будуть втрачені в контракті (хоча їх може врятувати власник). Це пояснюється тим, що вони застрягнуть у контракті Router, тоді як створення пари відбувається в контракті Factory, де замість нього використовується transferCoins(), який вираховує кошти з поточної (фабричної) адреси.

    • Завод.ц:264; createLBPair(StaticArray )

    transferCoins(_pair._origin, 200 * ONE_COIN);

    Оскільки це реалізовано на заводі, кошти, надіслані на маршрутизатор, не потраплять на завод, у якого також не буде коштів для створення пари та повернення.

    Пом'якшення

    Одним із варіантів є реалізація рішення, запропонованого в СКАЖИ-01.
    І навпаки, Завод.ц можна викликати безпосередньо для створення пар і вимагати від користувачів надіслати або точну необхідну суму разом із викликом функції, АБО принаймні необхідну суму з відшкодуванням надлишкових коштів.

     

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

    ID СКАЖИ-03
    Статус Виправлено
    Risk Medium
    Вплив на бізнес Якщо програма AMM дозволяє створювати кілька пулів з однаковими параметрами, ліквідність може бути розведена між цими пулами, а не зосереджена лише в одному. Це може негативно вплинути на користувачів і призвести до менш вигідних угод для користувачів протоколу.

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

    Місце розташування
    • Factory.ts; createLBPair(StaticArray )
    • Router.ts; createLBPair(StaticArray )

    Опис

    Під час створення нової пари перевірка на наявність точно такої пари не проводиться. Це може розпорошити ліквідність користувачів між кількома еквівалентними пулами. Пули з низькою ліквідністю більш схильні до маніпулювання цінами та пропонують менш вигідні операції, тому їх слід уникати.

    Пом'якшення

    Перевірте, чи вже існує пара певних параметрів під час створення пари, якщо так, скасуйте.

     

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

    ID СКАЖИ-04
    Статус Виправлено
    Risk низький
    Вплив на бізнес Одержувач флеш-позики може виконувати зовнішні виклики у зворотному виклику. Оскільки система вимагає, щоб баланс після термінової позики дорівнював рівному балансу до плюс комісії, ці зовнішні контракти можуть передати дуже невелику суму парі під час виконання, щоб гарантувати, що термінова позика не буде виконана (що може бути вигідним для них в певних ситуаціях).
    Місце розташування
    • Пар.ц:280; flashLoan(StaticArray )

    Опис

    Після термінової позики система вимагає, щоб баланс дорівнював балансу до моментальної позики плюс комісії.

    • flashLoan(StaticArray )

    assert(

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

      LBPair__FlashLoanInvalidBalance(),

    );

    Як правило, потрібно, щоб баланс був більшим, оскільки вимога точного збігу є обмеженням.

    Пом'якшення

    Лише перевіряйте, чи баланс перевищує баланс до моментальної позики плюс комісії. Це також логіка, яку використовує TraderJoe у своїй функції швидкої позики.

     

    [L] Ігнорування пари LB не створює події

    ID СКАЖИ-05
    Статус Виправлено
    Risk низький
    Business Impact Індексатори поза мережею можуть отримати невірну інформацію, що призведе до неправильних розрахунків.
    Місце розташування
    • Factory.ts; setLBPairInformation(StaticArray )

    Опис

    Функція setLBPairIgnored(StaticArray ) можна використовувати для керування тим, чи слід ігнорувати пару для маршрутизації чи ні. Будь-яка зміна прапора за допомогою цієї функції викликає подію SET_LBPAIR_IGNORED. Однак також можна змінити прапор за допомогою setLBPairInformation(StaticArray ), який не видає події.

    Пом'якшення

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

    [L] Непослідовне стягнення плати

    ID СКАЖИ-06
    Статус Визнаний
    Risk низький
    Business Impact Будь-який користувач може ініціювати стягнення плати для інших користувачів, тоді як стягнення плати за протокол може ініціювати лише власник.
    Місце розташування
    • Пара.ц; collectFees(StaticArray )
    • Пар.ц:723-726; collectProtocolFees(StaticArray )

    Опис

    Зателефонувати може кожен collectFees(StaticArray ) для будь-якої адреси для розподілу зборів на цю адресу. Це може бути небажаним для деяких користувачів, які хочуть контролювати, коли їм розподіляються комісії. 

    Це також суперечить collectProtocolFees(StaticArray ), яку може викликати тільки одержувач.

    • collectProtocolFees(StaticArray )

    assert(

      Context.caller().equals(_feeRecipient),

      LBPair__OnlyFeeRecipient(_feeRecipient, Context.caller()),

    );

    Пом'якшення

    Подумайте про зміну логіки collectFees(StaticArray ) щоб відповідати collectProtocolFees(StaticArray ), тобто дозволити лише одержувачу збирати свої збори.

    [L] Непослідовне використання SafeMath

    ID СКАЖИ-07
    Статус Виправлено
    Risk низький
    Business Impact Переповнення або недоповнення коду може призвести до неочікуваних повернення та/або прорахунків. 
    Місце розташування -

    Опис

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

    Пом'якшення

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

    [L] Неефективний перелік активів

    ID СКАЖИ-08
    Статус Виправлено
    Risk низький
    Business Impact Деякі заводські функції споживатимуть більше газу, ніж необхідно. У гіршому випадку, якщо власник зареєструє дуже велику кількість активів, це може призвести до 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
    Статус Виправлено
    Risk низький
    Business Impact Комісія за швидку позику може бути вищою, ніж MAX_FEE.
    Місце розташування
    • Завод.ц:80; конструктор (StaticArray )

    Опис

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

    Пом'якшення

    Перевірте комісію за флеш позику в конструкторі.

    [L] Неповний захист від прослизання – відсутність перевірки кінцевого терміну

    ID СКАЖИ-10
    Статус Виправлено
    Risk низький
    Business Impact Існує підвищена ймовірність того, що користувачі отримуватимуть менш вигідні угоди під час використання AMM.
    Місце розташування Router.ts

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

    Опис

    Пробуксовування є результатом нестабільності в рішеннях типу AMM і просто означає, що ціна під час запиту на зміну торгівлі/свопу/ліквідності відрізняється від ціни під час виконання транзакції. Щоб захистити користувачів від величезного прослизання, яке може бути природним або результатом навмисних атак, таких як сендвіч, існує два загальні типи захисту: мінімальна кількість, яка є, і перевірка терміну, якої немає.

    Ці перевірки слід застосовувати для будь-якого свопу, додавання та вилучення ліквідності, оскільки всі вони підлягають прослизанню.

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

    Пом'якшення

    Здійснювати  _esure(термін) таким же чином він уже присутній у всіх інших функціях, що мають справу з ліквідністю.

    [L] Передача права власності за один крок

    ID СКАЖИ-11
    Статус Виправлено
    Risk низький
    Business Impact Надання неправильної адреси може призвести до безповоротної втрати права власності на контракт.
    Місце розташування
    • Factory.ts; transferOwnership([u8])

    Опис

    In Завод.ц, зміна власника досягається шляхом покликання старого власника transferOwnership([u8]) з новим власником. Потім функція змінює ВЛАСНИК змінна стану.

    • transferOwnership([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
    Статус Виправлено
    Risk Інформаційний
    Business Impact Зменшення відстеження та видимості історичних змін стану ключів, що впливають на протокол.
    Місце розташування Завод.ц

    • setLBPairInformation(bs: StaticArray )
    • forceDecay(bs: StaticArray )
    • transferOwnership(bs: StaticArray )

    Опис

    Деякі зі змін стану ключів протоколу не видають пов’язаної події.

    Примітка: transferOwnership(bs: StaticArray ) створює подію, але лише для _setFeeRecipient.

    Пом'якшення

    Додайте випромінювання подій у вказаних місцях.

    [I] Геттери та сетери змішані із зовнішніми функціями

    ID СКАЖИ-13
    Статус Виправлено
    Risk Інформаційний
    Business Impact Змішування, геттери, сетери, точки входу та внутрішні функції роблять код менш читабельним.
    Місце розташування
    • Factory.ts:631, 639
    • Пар.ц:1031, 1227

    Опис

    Деякі контракти мають окремі розділи, що містять функції, які змінюють стан (сеттери), читають його (гетери) або є частиною дерева викликів функцій (внутрішні).

    Однак у деяких договорах цей порядок порушується – функції змішуються. Іноді експортовані функції (точки входу) також змішуються з внутрішніми.

    Пом'якшення

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

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

    ID СКАЖИ-14
    Статус Визнаний
    Risk Інформаційний
    Business Impact Тестові сценарії та модульні тести допомагають розробникам виявляти помилки та вразливості, які інакше проскочили б у простому статичному аналізі. Динамічне тестування має неоціненне значення для забезпечення якості готового продукту.
    Місце розташування -

    Опис

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

    Пом'якшення

    Вважається хорошою практикою гарантувати, що покриття коду для тестів є якомога вищим і що тестові сценарії включають як щасливі, так і невдалі шляхи.

    [I] Непотрібний код

    ID СКАЖИ-15
    Статус Виправлено
    Risk Інформаційний
    Business Impact Ця проблема не має прямого впливу на код чи протокол, тому її оцінили як інформаційну.
    Місце розташування Router.ts:770-772; _getAmountsIn(u64[], адреса[], IERC20[], u256)

    Опис

    Функція _getAmountsIn() приймає кроки bin як аргумент і виконує таку перевірку:

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

    if (_binStep == 0) {

      // means TraderJoe V1 swap

    } else {

      ...

    }

    Однак це непотрібно. Система не підтримує обміни у стилі V1, а решта функції не враховує кроки bin, оскільки вона отримує пари (що відповідають крокам bin) як додатковий аргумент.

    Пом'якшення

    Подумайте про видалення аргументу _pairBinSteps і непотрібної пропозиції if.

    [I] Невикористаний імпорт

    ID СКАЖИ-16
    Статус Виправлено
    Risk Інформаційний
    Business Impact Ця проблема не має прямого впливу на код чи протокол, тому її оцінили як інформаційну.
    Місце розташування
    • Пар.ц:35,
    • Router.ts:4,
    • WMAS.ts:5,6,
    • інтерфейси/IPair.ts:5

    Опис

    Схоже, що вказаний імпорт ніколи не використовувався у відповідних контрактах. Їх можна було видалити.

    Пом'якшення

    Видаліть невикористаний імпорт.

    [I] Використання «магічних чисел»

    ID СКАЖИ-17
    Статус Визнаний
    Risk Інформаційний
    Business Impact Це може ускладнити розбір коду для незнайомих читачів.
    Місце розташування
    • Пара.ц:113
    • Factory.ts:264, 735

    Опис

    У кількох місцях контракт використовує числові значення, які недостатньо задокументовані, описані чи прокоментовані.

    Пом'якшення

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

    Ви можете знайти більше інформації про це в нашому блозі

    Блог Sayfer зосереджений на web3, безпеці та дослідженні вразливостей. Ми вважаємо, що в індустрії кібербезпеки вкрай важливо бути в курсі останніх тенденцій і досягнень. Наразі наша команда досвідчених дослідників із задоволенням вивчає передові технології блокчейн і web3.
    Зв'яжіться з нами

    Підтримувати зв'язок

    Телефони
    Місце розташування
    Тель-Авів, Ізраїль
    Електронна адреса
    Месенджери:
    Будь ласка, не соромтеся звертатися до нас, ми будемо раді відповісти!





      Цей сайт захищено reCAPTCHA і Google Політика Конфіденційності та Умови обслуговування застосовувати.
      Перейти до вмісту