Smart Contract Audits: What Auditors Check—and What an Audit Does Not Guarantee

Audyt smart kontraktu to niezależny przegląd kodu i architektury w określonym zakresie. Jego celem jest wykrycie podatności, błędów implementacji oraz rozbieżności między zamierzonym a rzeczywistym działaniem.

Audyt może zmniejszyć niepewność, ale nie sprawia, że kontrakt staje się pozbawiony ryzyka. Oficjalne wytyczne bezpieczeństwa Ethereum opisują audyt jako dodatkowy przegląd, a nie uniwersalne rozwiązanie wykrywające każdy błąd.

Ten artykuł ma wyłącznie charakter edukacyjny. Audyt nie gwarantuje bezpieczeństwa, odzyskania środków ani zwrotu.

Najpierw zakres

Przydatny raport dokładnie określa, co sprawdzono:

  • repozytorium i hash commita;
  • pliki i smart kontrakty;
  • wersję kompilatora i ustawienia kompilacji;
  • zależności;
  • architekturę i role uprzywilejowane;
  • gałąź lub wydanie;
  • wyłączenia, ograniczenia i założenia;
  • datę przeglądu.

To ważne, ponieważ prawdziwy audyt może obejmować starą wersję, inne wdrożenie lub tylko jedną część większego systemu.

Co zwykle sprawdzają audytorzy

1. Zamierzone działanie i niezmienniki

Audytorzy porównują kod z jego specyfikacją:

  • kto może wywoływać poszczególne funkcje;
  • jak obliczane są kwoty i opłaty;
  • kiedy następują zmiany statusu;
  • które właściwości muszą zawsze pozostawać prawdziwe;
  • jak obsługiwane są przypadki brzegowe i awarie.

Jeśli w specyfikacji pominięto ważny wymóg, technicznie poprawny kod może nadal realizować niebezpieczny lub niepożądany projekt.

2. Kontrola dostępu

Audytorzy sprawdzają role właściciela, administratora, operatora i inne role uprzywilejowane, w tym uprawnienia do:

  • nadawać lub cofać uprawnienia;
  • wstrzymywać system;
  • zmieniać opłaty i limity;
  • emitować tokeny;
  • wypłacać aktywa;
  • aktualizować implementację.

Sprawdzają również, czy jeden klucz może wprowadzić krytyczną zmianę oraz czy projekt obejmuje zabezpieczenia takie jak multisig lub timelock.

3. Wywołania zewnętrzne i ponowne wejście

Podczas wykonywania kontrakt może przekazać sterowanie innemu kontraktowi. Może to umożliwić ponowne wejście, gdy kontrakt zewnętrzny wywołuje funkcję zwrotną przed zakończeniem pierwotnej zmiany stanu. Oficjalne zalecenia Solidity wskazują, aby tam, gdzie jest to potrzebne, starannie ustalać kolejność kontroli, zmian stanu i interakcji zewnętrznych.

4. Obliczenia i jednostki

Audytorzy szukają:

  • zaokrąglenia i utratę precyzji;
  • niezgodną liczbę miejsc dziesiętnych tokena;
  • nieprawidłową kolejność operacji;
  • wartości graniczne;
  • dzielenie przez zero;
  • unsafe unchecked arithmetic;
  • rozbieżności między jednostkami wewnętrznymi i wyświetlanymi.

5. Odmowa usługi i gas

Nieograniczone pętle, rosnące tablice, nieudane wywołania zewnętrzne lub kosztowne operacje mogą sprawić, że wykonanie funkcji stanie się niepraktyczne. Audytorzy sprawdzają, czy projekt pozostaje użyteczny wraz ze wzrostem danych i przy nietypowych danych wejściowych.

6. Kontrakty proxy i aktualizacje

W systemach z możliwością aktualizacji przegląd powinien obejmować:

  • smart kontrakty proxy i implementacji;
  • uprawnienia upgrader lub admin;
  • inicjalizację;
  • zgodność układu pamięci;
  • nieautoryzowane ścieżki aktualizacji;
  • wpływ zmiany logiki po audycie.

Proxy może zachować ten sam adres widoczny dla użytkownika, przekazując wykonanie nowej logice. Stwierdzenie, że „kontraktu nie można zmienić”, należy więc sprawdzić w odniesieniu do rzeczywistej architektury.

7. Integracje

Kontrakty mogą zależeć od tokenów, wyroczni cenowych, mostów, DEX-ów, podpisów lub innych kontraktów. Audytorzy analizują założenia dotyczące tych zależności, nieaktualne dane, nietypowe zachowanie tokenów i zewnętrzne scenariusze awarii.

8. Zdarzenia i monitorowanie

Audytorzy mogą sprawdzić, czy zdarzenia prawidłowo ujawniają ważne działania, takie jak zmiany ról, aktualizacje, wstrzymania i transfery. Zdarzenia ułatwiają monitoring, ale nie zastępują kontroli stanu.

Metody stosowane w audycie

Przegląd zazwyczaj łączy:

  • ręczna analiza kodu i architektury;
  • testy jednostkowe i integracyjne;
  • analizę statyczną i dynamiczną;
  • fuzzing z wygenerowanymi danymi wejściowymi;
  • testy oparte na właściwościach;
  • kontrole znanych klas podatności;
  • przegląd kompilacji i wdrożenia;
  • czasami formalną weryfikację wybranych właściwości.

Żadna pojedyncza metoda nie obejmuje wszystkiego. Formalna weryfikacja może dowieść, że kod spełnia formalną specyfikację, ale nie może potwierdzić właściwości, której specyfikacja nie uwzględnia.

Jak użytkownik powinien czytać audyt

1. Dopasuj sprawdzoną wersję

Znajdź hash commita i ustal:

  • czy bieżąca implementacja została zbudowana z tego kodu;
  • czy po dacie raportu przeprowadzono aktualizacje;
  • czy łańcuch i wdrożone adresy są zgodne;
  • czy krytyczne zależności były objęte zakresem.

Jeśli nie można tego ustalić, raport dostarcza jedynie ograniczonych dowodów dotyczących aktywnego wdrożenia.

2. Przeczytaj ustalenia, nie tylko podsumowanie

Dla każdego ustalenia sprawdź:

  • wagę i scenariusz;
  • kod objęty analizą;
  • zalecenie;
  • reakcję twórców;
  • bieżący status;
  • czy audytor ponownie przetestował poprawkę.

Fixed or Resolved is meaningful only when tied to a specific corrected version.

3. Przeczytaj ograniczenia

Raporty mogą nie obejmować:

  • systemy frontendu i backendu;
  • zarządzanie kluczami;
  • model ekonomiczny;
  • smart kontrakty zewnętrzne;
  • infrastrukturę wdrożeniową;
  • konfigurację produkcyjną;
  • kwestii prawnych i operacyjnych.

Użytkownicy korzystają z całego systemu, a nie tylko z jego plików Solidity.

4. Oceń ryzyko administracyjne

Zapytaj:

  • kto kontroluje aktualizacje;
  • czy operacje można wstrzymać;
  • czy opłaty lub powiązane adresy mogą się zmieniać;
  • czy istnieje timelock;
  • czy używany jest multisig;
  • jak użytkownicy dowiadują się o zmianach.

Są to kwestie zarządzania i zaufania, nawet jeśli w kodzie nie wykryto podatności.

5. Sprawdzaj bezpieczeństwo także po audycie

Przydatne bieżące wskaźniki obejmują:

  • testowanie każdego wydania;
  • przegląd ważnych aktualizacji;
  • program bug bounty;
  • monitorowanie ról i implementacji;
  • procedury reagowania na incydenty;
  • ograniczenia ilości narażonych aktywów.

What an audit does not guarantee

Audyt nie gwarantuje:

  • braku wszystkich błędów;
  • bezpieczeństwa kodu zmienionego po przeglądzie;
  • bezpieczeństwa witryny, portfela, DNS ani serwerów;
  • bezpieczeństwo kluczy uprzywilejowanych;
  • poprawności zewnętrznych tokenów, wyroczni i mostów;
  • odporności na każdy atak ekonomiczny;
  • rzetelności zespołu;
  • zgodność z prawem;
  • płynność tokena;
  • zwrot środków;
  • stałych ani żadnych innych zwrotów.

Pytania, które powinien zadać ostrożny użytkownik

Is an auditor’s logo enough?
No. Find the report from the auditor’s own source and check its scope, commit, date, and findings.

If every finding was fixed, is the contract safe?
It means the listed findings were addressed in a stated version. Unknown issues and out-of-scope risks remain.

Are several audits automatically better?
The count alone says little. Coverage, quality, independence, recency, and version matching matter more.

Does an audit still apply after a proxy upgrade?
Only if the new implementation and configuration are covered by the reviewed version.

Lista kontrolna raportu

  • Raport jest dostępny u audytora.
  • Wskazano repozytorium i hash commita.
  • Krytyczne kontrakty i zależności znajdują się w zakresie przeglądu.
  • Sprawdzona wersja odpowiada aktywnemu wdrożeniu.
  • Proxy, implementacja i administrator są objęte analizą.
  • Sposób ustalania statusu i ponownego testowania jest opisany w dokumentacji.
  • Założenia i wyłączenia zostały przeczytane.
  • Ryzyka poza kodem zostały ocenione osobno.

Źródła i dalsza lektura

  1. Ethereum.org — Bezpieczeństwo smart kontraktów
  2. Ethereum.org — Testowanie smart kontraktów
  3. Ethereum.org — Formalna weryfikacja smart kontraktów
  4. Solidity Documentation — Kwestie bezpieczeństwa
  5. OpenZeppelin Docs — Wzorzec aktualizacji proxy