Credo che Uniswap v4 sarà presto disponibile per tutti!
Questa volta il team di Uniswap ha obiettivi ambiziosi e prevede di introdurre molte nuove funzionalità [1], incluso il supporto per un numero illimitato di pool di liquidità e commissioni dinamiche per ciascuna coppia di trading, design singleton, contabilità fulminea, Hooks e supporto per il token ERC1155 standard. Sfruttando lo storage transitorio introdotto da EIP-1153, si prevede che Uniswap v4 venga rilasciato dopo l'aggiornamento di Ethereum Cancun.
Tra le tante innovazioni, il meccanismo Hook ha attirato l'attenzione diffusa grazie al suo potente potenziale. Il meccanismo Hook supporta l'esecuzione di codice specifico in punti specifici del ciclo di vita del pool di liquidità, migliorando notevolmente la scalabilità e la flessibilità del pool.
Tuttavia, il meccanismo del gancio può anche essere un’arma a doppio taglio. Sebbene sia potente e flessibile, anche l'utilizzo sicuro di Hook rappresenta una grande sfida. La complessità degli hook porta inevitabilmente con sé nuovi potenziali vettori di attacco. Pertanto, speriamo di scrivere una serie di articoli per introdurre sistematicamente i problemi di sicurezza e i potenziali rischi legati al meccanismo Hook, in modo da promuovere lo sviluppo della sicurezza della comunità. Crediamo che queste intuizioni aiuteranno a costruire un Uniswap v4 Hook sicuro.
Come inizio di questa serie di articoli, questo articolo introduce concetti relativi al meccanismo Hook in Uniswap v4 e delinea i rischi per la sicurezza del meccanismo Hook.
Il meccanismo di Uniswap V4
Prima di approfondire, dobbiamo avere una conoscenza di base dei meccanismi di Uniswap v4. Secondo l'annuncio ufficiale [1] e il white paper [2], Hooks, architettura singleton e contabilità fulminea sono tre funzioni importanti per implementare pool di liquidità personalizzati e ottenere un routing efficiente su più pool.
1.1 Gancio
Gli Hooks si riferiscono a contratti che vengono eseguiti in diverse fasi del ciclo di vita del pool di liquidità. Il team di Uniswap spera di consentire a chiunque di prendere decisioni di trade-off introducendo gli Hooks. In questo modo, è possibile supportare nativamente commissioni dinamiche, aggiungere ordini con limite di prezzo sulla catena o distribuire ordini di grandi dimensioni attraverso un market maker medio ponderato nel tempo (TWAMM).
Attualmente ci sono otto callback Hook, divisi in quattro gruppi (ogni gruppo contiene una coppia di callback):
prima dell'inizializzazione/dopo l'inizializzazione
primaModificaPosizione/dopoModificaPosizione
prima dello scambio/dopo lo scambio
prima della donazione/dopo la donazione
Quello che segue è il processo di scambio degli Hooks introdotto nel white paper [2].
Figura 1: processo di Exchange Hook
Il team di Uniswap ha spiegato come farlo con alcuni esempi (come TWAMM Hook[3]), e anche i partecipanti alla comunità hanno dato alcuni contributi. La documentazione ufficiale[4] si collega anche al repository Awesome Uniswap v4 Hooks[5], che raccoglie più esempi di Hook.
1.2 Singleton, contabilità fulminea e meccanismo di blocco
L'architettura Singleton e la contabilità flash sono progettate per migliorare le prestazioni riducendo i costi e garantendo l'efficienza. Introduce un nuovo contratto singleton, in cui tutti i pool di liquidità sono mantenuti nello stesso contratto intelligente. Questo design singleton si basa su un PoolManager per archiviare e gestire lo stato di tutti i pool.
Nelle versioni precedenti del protocollo Uniswap, operazioni come lo scambio o l'aggiunta di liquidità comportavano trasferimenti diretti di token. La versione v4 è diversa in quanto introduce la contabilità lampo e un meccanismo di blocco.
Il meccanismo di bloccaggio funziona come segue:
1. Un contratto di armadietto richiede un blocco su PoolManager.
2. PoolManager aggiunge l'indirizzo del contratto dell'armadietto alla coda lockData e richiama il callback lockAcquired.
3. Il contratto locker esegue la sua logica nel callback. Durante l'esecuzione, l'interazione del contratto locker con il pool può comportare incrementi valutari diversi da zero. Tuttavia, al termine dell'esecuzione, tutti i delta devono assestarsi a zero. Inoltre, se la coda lockData non è vuota, solo l'ultimo contratto dell'armadietto può eseguire operazioni.
4. PoolManager controlla lo stato della coda lockData e l'incremento della valuta. Dopo la verifica, PoolManager cancellerà il contratto dell'armadietto.
In sintesi, il meccanismo di blocco impedisce l’accesso simultaneo e garantisce che tutte le transazioni possano essere cancellate. Il contratto locker si applica ai blocchi in sequenza e quindi esegue le transazioni tramite la richiamata lockAcquired. La richiamata Hook corrispondente verrà attivata prima e dopo ogni operazione del pool. Infine, il PoolManager controlla lo stato.
Questo approccio significa che l’operazione adegua il saldo netto interno (ovvero il delta) anziché eseguire un trasferimento istantaneo. Eventuali modifiche verranno registrate nel saldo interno del pool, e l'effettivo trasferimento verrà effettuato al termine dell'operazione (cioè blocco). Questo processo garantisce che non vi siano token in circolazione, mantenendo così l'integrità dei fondi.
A causa del meccanismo di blocco, gli account di proprietà esterna (EOA) non possono interagire direttamente con PoolManager. Invece, qualsiasi interazione deve avvenire attraverso un contratto. Questo contratto funge da armadietto intermedio e deve richiedere un blocco prima di eseguire qualsiasi operazione sul pool.
Esistono due principali scenari di interazione contrattuale:
Un determinato contratto di locker proviene dal codice base ufficiale o viene distribuito dagli utenti. In questo caso, possiamo pensare all'interazione come se passasse attraverso il router.
Un contratto locker e Hook sono integrati nello stesso contratto o controllati da un'entità terza. In questo caso, possiamo pensare all'interazione come se avvenisse attraverso gli Hooks. In questo caso, Hook svolge sia il ruolo del contratto di locker sia la responsabilità della gestione dei callback.
Modello di minaccia
Prima di discutere i problemi di sicurezza correlati, dobbiamo identificare il modello di minaccia. Consideriamo principalmente le seguenti due situazioni:
Modello di minaccia I: gli hook stessi sono benigni, ma presentano vulnerabilità.
Modello di minaccia II: gli hook sono intrinsecamente dannosi.
Nelle sezioni seguenti, discutiamo i potenziali problemi di sicurezza basati su questi due modelli di minaccia.
2.1 Problemi di sicurezza nel modello di minaccia I
Il Threat Model I si concentra sulle vulnerabilità legate all'Hook stesso. Questo modello di minaccia presuppone che gli sviluppatori e i loro Hook siano innocui. Tuttavia, le vulnerabilità note esistenti negli smart contract potrebbero comparire anche negli Hooks. Ad esempio, se un Hook viene implementato come contratto aggiornabile, potrebbe riscontrare problemi simili alla vulnerabilità UUPSUpgradeable di OpenZeppelin.
Alla luce dei fattori di cui sopra, abbiamo scelto di concentrarci sulle potenziali vulnerabilità uniche della versione v4. In Uniswap v4, gli Hooks sono contratti intelligenti in grado di eseguire logica personalizzata prima o dopo le operazioni del pool principale, tra cui l'inizializzazione, la modifica della posizione, lo scambio e la raccolta. Sebbene sia previsto che gli Hooks implementino interfacce standard, consentono anche l'inclusione di logica personalizzata. Pertanto, la nostra discussione sarà limitata alla logica che coinvolge l'interfaccia Hook standard. Cercheremo quindi di identificare possibili fonti di vulnerabilità, ad esempio, come gli Hooks potrebbero abusare di queste funzioni Hook standard.
Nello specifico, ci concentreremo sulle seguenti due tipologie di Hook:
Il primo gancio è trattenere i fondi degli utenti. In questo caso, un utente malintenzionato potrebbe attaccare questo hook per trasferire fondi, causando la perdita di risorse.
Il secondo tipo di hook memorizza i dati sullo stato chiave su cui fanno affidamento gli utenti o altri protocolli. In questo caso, l'aggressore potrebbe tentare di modificare lo stato critico. Possono sorgere rischi potenziali quando viene utilizzato uno stato errato da altri utenti o protocolli.
Tieni presente che gli hook al di fuori di questi due ambiti non rientrano nell'ambito della nostra discussione.
Poiché non esistono casi d'uso reali per gli Hooks al momento della stesura di questo articolo, estrarremo alcune informazioni dal repository Awesome Uniswap v4 Hooks.
Dopo un'analisi approfondita del repository Awesome Uniswap v4 Hooks (commit hash 3a0a444922f26605ec27a41929f3ced924af6075), abbiamo scoperto diverse vulnerabilità critiche. Queste vulnerabilità provengono principalmente da interazioni rischiose tra hook, PoolManager e terze parti esterne e possono essere principalmente suddivise in due categorie: problemi di controllo degli accessi e problemi di convalida dell'input. Si prega di consultare la tabella seguente per risultati specifici:
In totale, abbiamo trovato 22 progetti rilevanti (esclusi i progetti non correlati a Uniswap v4). Tra questi progetti, riteniamo che 8 (36%) siano vulnerabili. Degli otto progetti vulnerabili, sei presentavano problemi di controllo degli accessi e due erano vulnerabili a chiamate esterne non attendibili.
2.1.1 Problemi di controllo degli accessi
In questa parte della discussione, ci concentreremo principalmente sui problemi che potrebbero essere causati dalle funzioni di callback nella v4, inclusi 8 hook callback e lock callback. Naturalmente, esistono altre situazioni che devono essere verificate, ma queste situazioni variano in base alla progettazione e esulano dall'ambito della nostra discussione.
Queste funzioni dovrebbero essere chiamate solo da PoolManager e non possono essere chiamate da altri indirizzi (inclusi EOA e contratti). Ad esempio, nel caso in cui i premi vengano distribuiti tramite chiavi del pool, i premi potrebbero essere richiesti in modo errato se la funzione corrispondente può essere richiamata da qualsiasi account.
Pertanto, è fondamentale stabilire forti meccanismi di controllo degli accessi per gli hook, soprattutto perché possono essere chiamati da altre parti oltre al pool stesso. Gestendo rigorosamente i diritti di accesso, i pool di liquidità possono ridurre significativamente il rischio di interazioni non autorizzate o dannose con gli hook.
2.1.2 Problemi di verifica dell'input
In Uniswap v4, a causa del meccanismo di blocco, gli utenti devono ottenere un blocco tramite il contratto prima di eseguire qualsiasi operazione di pool di fondi. Ciò garantisce che il contratto attualmente partecipante all'interazione sia l'ultimo contratto dell'armadietto.
Tuttavia, esiste un possibile scenario di attacco, vale a dire chiamate esterne non attendibili dovute a una convalida errata dell'input in alcune implementazioni Hook vulnerabili:
Innanzitutto, l’hook non verifica il pool di fondi con cui l’utente intende interagire. Potrebbe trattarsi di un pool dannoso contenente token falsi ed esecuzione di logica dannosa.
In secondo luogo, alcune funzioni di hook dei tasti consentono chiamate esterne arbitrarie.
Le chiamate esterne non attendibili sono estremamente pericolose perché possono portare a vari tipi di attacchi, inclusi quelli che conosciamo come attacchi di rientro.
Per attaccare questi hook vulnerabili, un utente malintenzionato può registrare un pool di fondi dannoso per i propri token falsi e quindi richiamare l'hook per eseguire operazioni nel pool di fondi. Quando si interagisce con il pool, la logica del token dannoso dirotta il flusso di controllo per intraprendere comportamenti indesiderabili.
2.1.3 Misure preventive contro il modello di minaccia I
Per aggirare tali problemi di sicurezza legati agli hook, è fondamentale autenticare le interazioni applicando adeguatamente i necessari controlli di accesso alle funzioni sensibili esterne/pubbliche e convalidando i parametri di input. Inoltre, la protezione dalla rientranza può aiutare a garantire che l'hook non venga eseguito ripetutamente nel flusso logico standard. Implementando adeguate misure di sicurezza, i pool possono ridurre i rischi associati a tali minacce.
2.2 Problemi di sicurezza nel modello delle minacce II
In questo modello di minaccia, presupponiamo che lo sviluppatore e il suo hook siano dannosi. A causa dell'ampio ambito, ci concentriamo solo sui problemi di sicurezza relativi alla versione v4. Pertanto, la chiave è se l’hook fornito può gestire le risorse crittografiche trasferite o autorizzate dall’utente.
Poiché il metodo di accesso all'hook determina i permessi che possono essere concessi all'hook, dividiamo l'hook in due categorie:
Hook gestiti: gli hook non sono punti di ingresso. Gli utenti devono interagire con l'hook tramite un router (eventualmente fornito da Uniswap).
Hook autonomi: gli hook sono punti di ingresso che consentono agli utenti di interagire direttamente con essi.
Figura 2: Esempio di Hook dannoso
2.2.1 Hook gestito
In questo caso, le risorse crittografiche dell'utente (inclusi token nativi e altri token) vengono trasferite o autorizzate al router. Poiché PoolManager esegue controlli del saldo, non è facile per gli hook dannosi rubare direttamente queste risorse. Tuttavia, esiste ancora una potenziale superficie di attacco. Ad esempio, il meccanismo di gestione delle spese della versione v4 può essere manipolato dagli aggressori tramite hook.
2.2.2 Gancio Indipendente
La situazione è ancora più complicata quando gli Hooks vengono utilizzati come punti di ingresso. In questo caso, il gancio acquisisce maggiore potenza poiché l'utente può interagire direttamente con esso. In teoria, un hook può fare tutto ciò che vuole con questa interazione.
Nella versione v4, la verifica della logica del codice è molto critica. Il problema principale è se la logica del codice può essere manipolata. Se un hook è aggiornabile, ciò significa che un hook apparentemente sicuro potrebbe diventare dannoso dopo essere stato aggiornato, ponendo un rischio significativo. Questi rischi includono:
Agenti aggiornabili (possono essere attaccati direttamente);
Con logica di autodistruzione. Può essere attaccato quando selfdestruct e create2 vengono chiamati insieme.
2.2.3 Misure preventive contro il modello di minaccia II
È fondamentale valutare se l’hook è dannoso. Nello specifico, per gli hook gestiti, dovremmo concentrarci sul comportamento della gestione delle commissioni, mentre per gli hook autonomi, l'attenzione principale è se sono aggiornabili.
Insomma
In questo articolo, forniamo innanzitutto una breve panoramica dei meccanismi principali relativi ai problemi di sicurezza Hook di Uniswap v4. Successivamente, proponiamo due modelli di minaccia e delineamo brevemente i rischi per la sicurezza associati.
Negli articoli successivi condurremo un'analisi approfondita dei problemi di sicurezza relativi a ciascun modello di minaccia.
