Účel a kontext: proč řešit bezpečnost chytrých kontraktů
Chytré kontrakty představují programovatelnou vrstvu decentralizovaných systémů (DeFi, NFT, DAO, hry). Na rozdíl od tradičního softwaru je jejich nasazení často nevratné, kód je veřejně auditovatelný a aktiva spravovaná kontrakty jsou okamžitě likvidní. Každá chyba má bezprostřední finanční dopady. Cílem tohoto článku je systematicky shrnout klíčová bezpečnostní rizika, útočné vektory a ověřená protiopatření pro návrh, vývoj a provoz chytrých kontraktů, zejména v ekosystémech EVM (Solidity/Vyper), ale obecně i na jiných platformách.
Model hrozeb: aktéři, povrchy útoku a předpoklady
- Externí útočník: neprivilegovaný účastník s možností volat veřejné funkce, manipulovat mempoolem a využívat MEV.
- Privilegovaný insider: držitel administrátorských klíčů, účastník multisigu, správce upgrade proxy nebo operátor oraclu.
- Ekonomický útočník: využívá racionálního chování protistran, neefektivních incentiv a tržních neefektivit (flash půjčky, manipulace cen).
- Povrchy útoku: veřejná rozhraní kontraktů, hooky (fallback/receive), externí volání (call, delegatecall), oracly, cross-chain mosty, zprávy L2 a front-running na úrovni mempoolu.
- Předpoklady: plná transparentnost kódu a stavu, deterministické vykonávání v rámci bloku, nedeterministické pořadí transakcí z pohledu uživatele.
Reentrancy a interakční vzory
- Popis: zneužití externího volání k opětovnému vstupu do kontraktu před aktualizací jeho stavu, typicky při výplatách.
- Zasažené vzory: push platby, callbacky, přijímače ERC-777/ETH, onERC721Received.
- Mitigace: vzor checks-effects-interactions, ReentrancyGuard, pull platby (vzor withdraw), minimalizace externích volání, limity výplat a vědomé a bezpečné použití call s nulovým limitem gasu.
Matematické chyby: přetečení, podtečení a zaokrouhlování
- Popis: aritmetické chyby vedoucí k neúmyslným hodnotám. V Solidity 0.8+ je aritmetika ve výchozím nastavení kontrolovaná (checked); rizikový je starší kód či inline assembly.
- Mitigace: používat moderní kompilátor, bezpečnostní knihovny pro přesné mulDiv, vyhýbat se dělení před násobením, validovat invarianty (např. x*y=k u AMM).
Autorizace a řízení přístupu
- Chyby: nechtěně veřejné funkce, spoléhání na tx.origin, chybějící ekvivalent onlyOwner, nesprávné pořadí modifier.
- Mitigace: explicitní role (RBAC) prostřednictvím knihoven typu AccessControl, rozdělení povinností (SoD), časové zámky (Timelock) pro administrativní akce, přepínač pozastavení (Pausable) pro reakci na incidenty.
Front-running, MEV a manipulace pořadí
- Popis: útočník přeuspořádá transakce, vloží svou transakci (sandwich) nebo zkopíruje transakci oběti a předřadí jí svou.
- Mitigace: protokoly commit–reveal, podepisování off-chain a meta-transactions s relayerem, limity skluzu a parametry deadline, dávkové aukce, využití soukromých transakčních kanálů (tam, kde to dává smysl).
Rizika oraclů a manipulace s cenou
- Popis: zneužití slabých cenových zdrojů (jednoduché spotové ceny při nízké likviditě) ke změně poměru kolaterálu či k likvidacím.
- Mitigace: časově vážené průměry (TWAP), kombinované zdroje (medianizéry), oracly s ekonomickými zárukami, zpožděná finalizace, limity jednorázových změn.
Flash půjčky a ekonomické útoky
- Popis: bleskově vypůjčená likvidita k manipulaci se stavem, cenami a invarianty během jediného bloku.
- Mitigace: navrhovat invarianty odolné vůči atomickým změnám, používat oracly odolné vůči jednorázovým výkyvům, v kritických funkcích vyžadovat více než jedno blokové potvrzení stavu (je-li to přijatelné).
Delegatecall a knihovní vzory
- Rizika: delegatecall spouští kód v kontextu volajícího, a může tak měnit jeho úložiště. Chyby ve směrování nebo chybně vytvořené knihovny mohou vést k převzetí stavu.
- Mitigace: přísný whitelist cílových implementací, kontrola slotu implementation podle EIP-1967, neměnné (immutable) adresy knihoven, audit inicializátorů.
Upgradovatelnost: proxy, inicializace a kolize úložiště
- Chyby: nevolaný initializer umožňující převzetí vlastnictví, kolize rozložení úložiště (storage layout) mezi verzemi, nedostatečně zabezpečený proces upgradeTo.
- Mitigace: standardy (Transparent/UUPS proxy), initializer s modifikátorem initializer, storage gaps, timelock a multisig pro upgrade, formální kontrola rozložení úložiště a testování migrací.
DoS a griefing: gas, smyčky, nepředvídatelné externí závislosti
- Chyby: neomezené iterace přes uživatelské seznamy, pevná závislost na externích voláních, selfdestruct a blokování cest pro vracení prostředků.
- Mitigace: navrhovat operace jako individuální pro každého uživatele (pull model), používat stránkování, limity, vzory umožňující vrácení prostředků a ochranu proti gas griefing.
Náhodnost, čas a zdroje entropie
- Chyby: používání block.timestamp, blockhash a dalších manipulovatelných zdrojů jako zdroje náhodnosti.
- Mitigace: commit–reveal s více účastníky, oracly VRF, odhalování v několika blocích, omezení závislosti logiky na čase a čísle bloku.
Podpisy, replay a EIP-712
- Rizika: podpisy bez domény a nonce umožňují opakované použití, hrozí také záměna řetězců.
- Mitigace: strukturované podpisy EIP-712, nonce pro každého uživatele, expirace a kontrola chain-id, oddělení oprávnění pro permit/schvalování.
Standardy tokenů a hooky
- ERC-20/721/1155: rozdíly v implementacích (vrácená hodnota bool, revert versus návratové kódy); bezpečné převody s hooky mohou spustit reentrancy.
- Mitigace: používat prověřené knihovny, bezpečné (safe) funkce, ochrany nonReentrant, minimalizovat logiku v hoocích.
Cross-chain a mosty
- Rizika: neautentizované zprávy, slabé ověřování light klientů, chybné relaye, rozdílná finalita.
- Mitigace: kryptografické ověřování (light klienti), důkazy založené na zk, limity rychlosti (rate limits), pojistné mechanismy (circuit breakers), schvalování více operátory.
Specifika L2 a rollupů
- Rizika: časová okna pro výběry, dostupnost sequenceru, odlišné limity gasu a předkompilované kontrakty, odlišný model mempoolu/MEV.
- Mitigace: návrh kompatibilní s cílovým L2, zohlednění finality a challenge period, testování na daném L2.
Bezpečnostní osvědčené postupy při návrhu
- Minimalistický povrch: veřejné jsou jen nezbytné funkce, rozhraní jsou stabilní, explicitní receive/fallback s omezeními.
- Návrh založený na invariancích: definovat a testovat invarianty (např. zachování hodnoty, nepřekročitelnost limitů).
- Bezpečný režim při selhání: Pausable, CircuitBreaker, RateLimiter pro nouzové stavy.
- Oddělené vrstvy: moduly pro matematiku, přístup a oracly; minimalizovat inline assembly.
Bezpečný vývojový proces
- Statická analýza: Slither, Mythril; pravidla v CI.
- Fuzzing a testy invariantů: Echidna, fuzzing ve Foundry, testy property-based s formálními vlastnostmi.
- Symbolické vykonávání: Manticore/Harvey pro kritické cesty.
- Formální verifikace: pro protokoly spravující vysoké hodnoty (např. specifikace v Scribble/Certora/Isabelle/HOL podle potřeby).
- Recenze kolegů a externí audit: vícestupňová revize kódu, nezávislý auditní tým, vypořádání připomínek před nasazením.
Provoz, monitoring a reakce na incident
- Upozorňování on-chain: sledování událostí, anomálií v tocích, neobvyklých volání administrátorských funkcí a změn implementace proxy.
- Provozní příručky: přesné postupy pro pause, blokaci výběrů, upgrade s timelockem a komunikaci s komunitou.
- Bug bounty: program s jasně vymezeným rozsahem, responsible disclosure a odměnami odpovídajícími riziku.
Role klíčů, multisig a governance
- Správa klíčů: multisig (≥2 ze 3, lépe 3 z 5), hardwarové peněženky, obezřetná rotace, oddělení pravomocí (upgrade, parametry, pozastavení).
- Governance: on-chain návrhy, kvórum, timelock, nouzové mechanismy a pravidla vymahatelná programově.
Tabulka: typické zranitelnosti a mitigace
| Zranitelnost | Projev | Mitigace |
|---|---|---|
| Reentrancy | Opakované výběry před aktualizací stavu | Checks–Effects–Interactions, ReentrancyGuard, pull pattern |
| Manipulace s oraclem | Falešná cena, likvidace, vyprazdňování poolu | TWAP/medianizér, více zdrojů, limity změny |
| Zneužití delegatecall | Útok na úložiště volajícího | Whitelist implementací, EIP-1967, audit knihoven |
| Front-running/MEV | Sandwich, kopírování obchodů | Commit–reveal, limity skluzu, deadline |
| Neověřená aritmetika | Přetečení/podtečení | Solidity 0.8+, bezpečné knihovny, testování invariantů |
| Chybná autorizace | Neoprávněné volání funkcí | RBAC, timelock, audit modifierů |
| Převzetí při upgradu | Převzetí prostřednictvím inicializátoru | Ochrana inicializátoru, multisig+timelock, storage gap |
| DoS způsobený smyčkami | Vyčerpání gasu, zablokování stavu | Stránkování, limity, operace pro jednotlivé uživatele |
Testovací strategie a pokrytí
- Jednotkové testy: ověřování běžných i okrajových hodnot parametrů, návratových hodnot a událostí.
- Integrační testy: interakce s oracly, tokeny, proxy a externími protokoly.
- Scénářové testy: flash půjčka + obchod + likvidace, manipulace mempoolu, reentrancy prostřednictvím hooků.
- Nasazení na testnetu a canary nasazení: postupné zvyšování limitů, monitorované nasazení s omezenou správou prostředků.
Dokumentace a transparentnost
- Specifikace: formální popis rozhraní, stavových proměnných a invariantů.
- Auditní zprávy: zveřejněné závěry, reakce a ověření oprav.
- Komunikace o rizicích: limity protokolu, administrátorská oprávnění, procesy pro nouzové zásahy.
Kontrolní seznam před nasazením
- Aktuální verze Solidity/Vyper, optimalizační přepínače a via-IR podle doporučení.
- RBAC a timelocky pro všechny privilegované funkce; Pausable pro kritické cesty.
- Proxy jsou inicializovány, initializer je uzamčen, rozložení úložiště je zdokumentováno.
- Oracly odolné vůči manipulaci; TWAP/medián, limity odchylek.
- Fuzzing a testy invariantů běží v CI; statická a symbolická analýza bez kritických nálezů.
- Program Bug Bounty je spuštěn, provozní příručka pro incidenty je připravena, upozornění jsou nasazena.
Závěr
Bezpečnost chytrých kontraktů je multidisciplinární obor kombinující formální metody, bezpečné programování, ekonomické modelování a provozní připravenost. Nejlepší obranou je minimalistický návrh, explicitní řízení přístupu, důsledné testování a monitorování a procesy pro reakci na incidenty. Protože útoky často zneužívají ekonomické slabiny stejně jako technické chyby, musí být bezpečnost a ekonomika protokolu navrženy společně a ověřeny v praxi i nezávislým auditem.
