Звіт про аудит смарт-контракту для 1inch

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

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

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

За період дослідження тривалістю 15 днів аудиту ми виявили 3 уразливості та 1 інформаційну примітку в перевіреному договорі.
Жодне з цих знахідок не вважається критичним, контракт можна розгорнути як є. Усі знахідки були адресовані та виправлені командою 1inch.

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

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

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

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

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

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

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

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

Підхід

Вступ

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

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

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

Разом із командою 1inch ми визначили наступний контракт як обсяг проекту. Хеш фіксації: 81e1f5190c391fbb929aa74a67d43245f3f662dc

Контракт Ша-256
DecompressorExtension.sol bc852b286a487711699128f1124beb69a37a75658730486ce681b5cef1e5ba11

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

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

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

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

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

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

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

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

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

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

1inch підвищення ефективності операцій у середовищі блокчейну рівня 2. З огляду на те, що операції з більшими даними викликів, як правило, дорожчі на Рівні 2, основна увага полягає в зменшенні розміру даних викликів. Щоб досягти цього, використовується стратегія стиснення даних викликів, ця стратегія в основному передбачає операції поза ланцюгом і використовує механізм, званий DecompressorExtension, який дозволяє відновлювати стиснуті дані викликів.

Для стиснення даних виклику використовується кілька ключових методів:

  1. Стиснення послідовних нульових байтів: ця техніка зменшує загальний розмір даних виклику шляхом консолідації послідовних нульових байтів у більш компактний формат.
  2. Копіювання послідовних байтів: у деяких випадках реплікація послідовних байтів використовується як стратегія стиснення даних.
  3. Заміна на основі словника: два різні методи використовуються для заміни сегмента даних виклику індексом із попередньо визначеного словника, що забезпечує більш ефективне представлення даних.

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

Наступні тестові приклади були орієнтиром під час аудиту системи. Цей контрольний список є модифікованою версією 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 Політика Конфіденційності та Умови обслуговування застосовувати.

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

    Ризик централізації

    ID СКАЖИ-01
    Статус Виправлено
    Risk Medium
    Місце розташування DecompressorExtension.sol
    Tools Ручне тестування

    Опис

    Якщо _setData функція надається власнику контракту, що, здається, є запланованим способом використання контракту відповідно до README, це створює ризик централізації для кожного проекту, який використовує DecompressorExtension.

    function _setData(uint256 offset, bytes32 data) internal
    validDictAccess(offset) {
        unchecked {
            _dict[offset] = data;
        }
    }

    Власник може передати виклик від користувача та змінити відповідний ключ dict перед виконанням виклику, що дозволяє йому довільно змінювати дані виклику. Таким чином, користувачеві стає неможливо перевірити (розпаковані) дані виклику перед викликом.

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

    Пом'якшення

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

     

    Немає власної реалізації

    ID СКАЖИ-02
    Статус Виправлено
    Risk Medium
    Місце розташування DecompressorExtension.sol
    Tools Ручне тестування

    Опис

    У README кілька разів зазначено про впровадження Власна форма OpenZeppelin. Насправді контракт не реалізує та не розширює Owneable, що може заплутати та ввести в оману власників проекту.

    З README:

    This contract provides a `DecompressorExtension` abstract
    contract that extends `Ownable` from the OpenZeppelin
    library.

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

    Пом'якшення

    Реалізуйте функцію власності, успадкувавши від Ownable, або оновіть README, щоб указати, що користувач – це той, хто має піклуватися про контроль доступу

     

    Газова DoS-атака

    ID СКАЖИ-03
    Статус Виправлено
    Risk низький
    Місце розташування DecompressorExtension.sol
    Tools Ручне тестування

    Опис

    Дуже легко подати (короткий) вхід decompress що призводить до величезних розпакованих даних виклику, тобто еквівалента a zip бомба.

    Наприклад, багато 00111111 байтів, за якими слідують інші дані, можна надіслати за допомогою case 0, що призводить до величезних витрат на розширення пам’яті:

    case 0 {
        let size := add(byte(0, data), 1)
        calldatacopy(outptr, calldatasize(), size)
        inptr := add(inptr, 1)
        outptr := add(outptr, size)
        continue
    }

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

    Однак є деякі сценарії, коли це може призвести до атаки. Наприклад, у нас може бути контракт ретранслятора, який викликає смарт-контракт, де розробники подбали про те, щоб використання газу для кожної функції було обмеженим. Якщо цей смарт-контракт тепер починає використовувати розширення, використання газу стає необмеженим, як data змінна є введенням, керованим користувачем.

    Пом'якшення

    Уникнути цієї вразливості буде важко, необхідно краще розуміти потреби бізнесу.

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

     

    Несумісність з ERC-2771/мета-транзакціями

    ID СКАЖИ-04
    Статус Виправлено
    Risk Інформаційний
    Місце розташування DecompressorExtension.sol
    Tools Ручне тестування

    Опис

    Розширення несумісне зі стандартом ERC-2771, де ретранслятор додає вихідного відправника до даних виклику (оскільки це призведе до помилок стиснення).

    Це не повинно бути великою проблемою, оскільки контракти все ще підтримують звичайні (нестиснені) виклики, але це означає, що стиснення не можна використовувати разом із мета-транзакціями.

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

    Пом'якшення

    Якщо це актуально, запровадьте ERC-2771

    Зв'яжіться з нами

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

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





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