Cross-chain, DeFi e smart contract · Lezione 4 di 6
Bridge, layer 2, sidechain e altri modelli di blockchain
15 min di lettura
I percorsi dei fondi raramente rimangono sulla mainnet di Bitcoin o Ethereum. I fondi sottratti vengono trasferiti tramite bridge verso rollup e sidechain, spostati sotto forma di stablecoin su Tron, instradati attraverso programmi Solana o trasferiti tra blockchain Cosmos. Ogni passaggio è il punto in cui una traccia si consolida oppure si interrompe. Un passaggio ben documentato lascia su entrambi i registri un identificativo che collega il deposito all'erogazione con la stessa solidità con cui un output speso collega due transazioni Bitcoin; uno scarsamente documentato lascia soltanto un'ipotesi basata su importo e tempo. L'esaminatore deve trovare tale identificativo, dimostrare la corrispondenza su entrambe le blockchain, spiegare ogni differenza di importo, sapere dove ciascuna blockchain conserva i propri dati e chi potrebbe riscriverli, e sapere quale operatore detiene ciò che le blockchain non mostrano. La lezione 5.3 tratta gli schemi di passaggio tra blockchain e la correlazione basata su importo e tempo; questa lezione tratta i meccanismi e gli elementi probatori lasciati da ciascuno.
Modelli di bridge e relative chiavi di collegamento
| Modello | Lato origine | Lato destinazione | Chi eroga i fondi | Chiave di collegamento tipica |
|---|---|---|---|---|
| Blocco e conio | Token bloccati in deposito vincolato; evento di deposito | Token wrapped coniato a favore del destinatario | Il soggetto che esegue il conio per il bridge | Nonce o ID del messaggio in entrambi gli eventi |
| Distruzione e rilascio (percorso di ritorno) | Token wrapped distrutto | Token originali rilasciati dal deposito vincolato | Il contratto di deposito vincolato | Stesso nonce o ID del messaggio |
| Distruzione e conio (nativo dell'emittente) | Token distrutto | Token dello stesso emittente coniato | I contratti dell'emittente | Nonce dell'emittente e dominio di origine |
| Bridge di liquidità o con relayer | Deposito in un pool o in un contratto spoke | Un relayer paga con fondi propri e viene successivamente rimborsato | Un relayer terzo | ID della blockchain di origine e ID del deposito ripetuti nell'esecuzione |
Tra i due lati si trova un livello di verifica: un insieme di validatori, un client leggero, una finestra di contestazione ottimistica o una prova a conoscenza zero. I bridge verso le sidechain si basano solitamente sulle firme di un piccolo insieme di validatori, quindi un collegamento «deterministico» in quel contesto è valido soltanto entro i limiti della fiducia riposta in tali validatori; la relazione dovrebbe precisarlo.
La maggior parte dei bridge utilizza un livello di messaggistica. Wormhole identifica ogni messaggio tramite blockchain dell'emittente, indirizzo dell'emittente e numero di sequenza; LayerZero assegna a ogni pacchetto un endpoint di origine, un mittente e un nonce, oltre a un identificativo globale di 32-byte (GUID). Le applicazioni ereditano questi identificativi, quindi occorre innanzitutto stabilire quale livello utilizza un bridge. Il Cross-Chain Transfer Protocol (CCTP) di Circle per USDC utilizza il modello di distruzione e conio: l'origine emette DepositForBurn (importo, depositante, destinatario del conio, dominio di destinazione), la destinazione MessageReceived (dominio di origine, nonce). Nella versione attuale, l'emittente assegna i nonce fuori dalla blockchain e il suo servizio di attestazione li restituisce a partire dall'hash di una transazione di origine. Una parte della chiave proviene quindi dall'operatore: tale risposta API va trattata come un reperto, corredato di richiesta, ora di acquisizione e hash della risposta.
I bridge numerano inoltre le blockchain secondo convenzioni proprie: Wormhole dispone di propri ID di blockchain a 16-bit, LayerZero di ID degli endpoint e CCTP di domini (Ethereum 0, Arbitrum 3, Solana 5, Base 6), mentre l'ID di blockchain EIP-155 di Arbitrum One è 42161. Interpretare destinationDomain = 3 come «blockchain 3» porta alla rete sbagliata. Registrare ogni corrispondenza e la relativa fonte, ossia la documentazione del bridge in una versione datata.
Associare un deposito al relativo rilascio
Una corrispondenza difendibile supera sette verifiche:
- Decodificare l'evento di origine dalla ricevuta, non dal riepilogo di un explorer: contratti, importo, depositante, destinatario, identificativo della destinazione, chiave di collegamento.
- Associare l'identificativo della destinazione a una rete e registrare la corrispondenza.
- Trovare l'evento di destinazione con la stessa chiave (e, sui livelli di messaggistica, lo stesso emittente o mittente).
- Verificare il destinatario rispetto a quello indicato nell'evento di origine; spiegare ogni differenza prima di procedere.
- Riconciliare l'importo: l'importo di destinazione è uguale a quello di origine meno la commissione dichiarata, verificando i decimali su entrambi i lati, poiché i token wrapped non mantengono sempre i decimali dell'originale.
- Verificare ordine e stato: il rilascio deve seguire il deposito; un deposito senza rilascio può essere in attesa, scaduto o rimborsato.
- Ripetere l'associazione utilizzando una seconda fonte di dati e registrarle entrambe.
Il superamento di tutte e sette le verifiche fornisce un collegamento di flusso di grado A secondo la scala della lezione 3.2; il mancato superamento della verifica del destinatario o dell'importo significa che non vi è corrispondenza finché la differenza non viene spiegata. In un data warehouse, l'associazione è un LEFT JOIN dei depositi con le esecuzioni basato sull'ID della blockchain di origine e sull'ID del deposito, non una ricerca per importo: conserva i depositi non eseguiti per la verifica dei rimborsi, calcola la commissione implicita e identifica il relayer affinché nessuno lo confonda con il soggetto esaminato. Le esecuzioni dei relayer possono avvenire pochi secondi dopo il deposito, prima che la blockchain di origine abbia raggiunto la finalità; se il blocco di origine venisse eliminato da una riorganizzazione, il relayer sopporterebbe solitamente la perdita, ma gli elementi probatori citerebbero una transazione che non esiste più. Registrare l'hash del blocco di origine e il suo stato di finalità (lezione 8.2).
Insidie che indeboliscono un collegamento:
- Relayer, esecutori e finalizzatori non sono proprietari. Un tracciamento ingenuo attraverso un bridge di liquidità passa ai fondi di un soggetto estraneo.
- Il destinatario non è il depositante. L'elemento probatorio è il campo del destinatario nell'evento di origine.
- Gli aggregatori possono figurare come depositanti; esaminare la traccia di esecuzione per individuare chi li ha chiamati.
- Stesso indirizzo, proprietario diverso. Un account a controllo esterno (EOA) ha lo stesso indirizzo su ogni blockchain EVM, ma un indirizzo di contratto può contenere altrove codice diverso, oppure nessun codice. Nel giugno 2022 circa 20 milioni di token OP sono stati inviati a un indirizzo Optimism per il quale il portafoglio multifirma previsto esisteva soltanto su Ethereum; un attaccante vi ha distribuito un diverso portafoglio multifirma e se ne è appropriato.
- Identificare i token tramite contratto, non tramite ticker: possono coesistere diverse versioni trasferite tramite bridge dello stesso asset.
Riconciliare deposito vincolato e offerta
L'invariante di un bridge di blocco e conio è il seguente: l'offerta di token wrapped sulla destinazione non supera mai il collaterale nel deposito vincolato sull'origine, a parte i depositi in transito. Confrontare il balanceOf del deposito vincolato con il totalSupply() del token wrapped in momenti corrispondenti, oppure mantenere totali cumulativi giornalieri delle unità nette bloccate e coniate. Un piccolo scarto positivo è normale; uno scarto negativo indica token privi di copertura. Gli exploit invertono il tracciamento: i fondi compaiono senza un deposito legittimo, quindi occorre partire dal conio o dal rilascio (le cause alla radice sono trattate nella lezione 5.5).
| Incidente | Che cosa è accaduto | Come appare sulla blockchain |
|---|---|---|
| Wormhole, 2 febbraio 2022 | Una falla nella verifica delle firme ha consentito all'attaccante di coniare 120.000 ETH wrapped su Solana senza deposito; 93.750 sono stati trasferiti indietro tramite bridge e riscattati | L'offerta aumenta bruscamente senza afflussi nel deposito vincolato, che viene poi svuotato; il percorso di ritorno ha lasciato trasferimenti collegati tramite messaggi |
| Ronin, 23 marzo 2022 | Cinque delle nove chiavi dei validatori hanno firmato prelievi di 173.600 ETH e circa 25,5 milioni di USDC; rilevato il 29 marzo | Rilasci senza distruzioni corrispondenti, rimasti inosservati per sei giorni |
| Nomad, 1 agosto 2022 | Un aggiornamento difettoso ha consentito il passaggio di messaggi non comprovati; circa 186 milioni di $ sono stati sottratti (i primi resoconti della stampa parlavano di circa 190 milioni di $) da centinaia di indirizzi, quasi il 90% dei quali ha imitato il primo exploit | Rilasci senza depositi di origine; ogni indirizzo costituisce un soggetto distinto, con le restituzioni tracciate e attribuite |
I sei giorni di Ronin dimostrano l'utilità del monitoraggio continuo. I protocolli di prestito richiedono la stessa verifica (token rappresentativi dell'offerta rispetto al sottostante detenuto più il debito), e i loro eventi distinguono chi ha agito da chi ha subito una modifica della propria posizione: un router compare come user, il proprietario come onBehalfOf. I saldi fruttiferi, come quelli degli aToken, crescono senza eventi Transfer, quindi vanno letti dallo stato. Il capitale di un prestito flash entra ed esce in un'unica transazione e deve essere escluso dal calcolo netto di qualsiasi perdita (lezione 5.5).
Gli operatori come fonti. La blockchain mostra il trasferimento; gli operatori possono rivelare la persona. L'operatore di un bridge o di un front-end può detenere log API e web (indirizzi IP, user agent, portafogli connessi), esecuzioni dei relayer, attestazioni, ticket di assistenza e log di screening; gli emittenti alla base dei bridge di distruzione e conio possono anche congelare i fondi (lezione 10.1). Un bridge completamente decentralizzato potrebbe non avere un operatore, quindi occorre rivolgersi al front-end utilizzato dal soggetto esaminato. Specificare blockchain, hash del deposito, depositante, destinatario, intervallo UTC e campi, chiedendo anzitutto la conservazione dei dati (lezione 1.4).
Rollup e sidechain
| Modello | Fonte della sicurezza | Dove risiedono i dati | Prelievo verso L1 |
|---|---|---|---|
| Rollup ottimistico (OP Mainnet, Base, Arbitrum One) | L1, tramite prove di frode in una finestra di contestazione | L1, batch compressi | Dopo la finestra, tipicamente circa una settimana |
| Rollup ZK (zkSync Era, Scroll, Linea, Starknet) | L1, tramite prove di validità | L1, transazioni o differenze di stato | Una volta verificata una prova, da alcune ore a un giorno |
| Validium o blockchain alt-DA | Prove, dati fuori da L1 | Un comitato o un altro livello di dati | Dipende dal modello |
| Sidechain (Polygon PoS, Gnosis Chain) | I propri validatori | Soltanto sulla propria blockchain | Bridge gestito dai validatori |
La cronologia di un rollup può in linea di principio essere ricostruita da L1; quella di una sidechain è affidabile soltanto quanto i suoi validatori. Per una sidechain, registrare le regole di consenso e finalità, l'insieme dei validatori se pubblicato, e se è stato utilizzato il suo unico explorer oppure un nodo proprio.
Sequencer e finalità a più livelli. La maggior parte dei rollup dispone di un unico sequencer che ordina le transazioni, imposta i timestamp L2 entro i limiti del protocollo e pubblica i batch su L1. I nodi OP Stack espongono le teste unsafe (solo sequencer, soggetta a riorganizzazione), safe (derivata dai dati L1) e finalized; costruire gli elementi probatori a partire da blocchi safe o finalized e registrare la transazione L1 di ancoraggio. Dall'aggiornamento Dencun (13 marzo 2024), la maggior parte dei rollup pubblica blob, che i nodi L1 eliminano dopo 4.096 epoche, circa 18 giorni, lasciando un hash con versione. Per dimostrare che la cronologia L2 può essere ricostruita in modo indipendente, conservare i dati dei blob entro tale intervallo oppure indicare l'archivio utilizzato. Gli operatori dei sequencer e i fornitori di RPC pubblici possono registrare metadati di invio e possono ricevere richieste precise.
Depositi. Sulle blockchain OP Stack, OptimismPortal su L1 emette TransactionDeposited e L2 crea una transazione di deposito non firmata di tipo 0x7E (126 come intero), il cui sourceHash, calcolato a partire dall'hash del blocco L1 e dall'indice del log, è una chiave di join esatta; il suo campo mint rappresenta ETH creati su L2, a cui corrispondono ETH bloccati su L1. In assenza di firma, l'autorizzazione e l'attribuzione derivano dal mittente L1. Su Arbitrum, un ticket ritentabile la cui esecuzione automatica non riesce rimane in attesa fino a una settimana, quindi l'effetto su L2 può verificarsi con giorni di ritardo. Entrambe le famiglie assegnano alias ai contratti L1 aggiungendo 0x1111000000000000000000000000000000001111: il contratto L1 0x5d3a…7c10 arriva su L2 come 0x6e4b…8d21. Agli EOA non vengono assegnati alias; cercare l'alias.
Prelievi. Un prelievo canonico OP Stack richiede tre passaggi collegati da un hash del prelievo: avvio su L2 (MessagePassed), prova su L1 (WithdrawalProven), finalizzazione dopo la finestra di contestazione (WithdrawalFinalized). Arbitrum non prevede il passaggio di prova (sendTxToL1, poi esecuzione Outbox circa una settimana dopo). Una volta visibile l'avvio, il destinatario L1 e il primo momento possibile di arrivo sono noti con giorni di anticipo, quindi è possibile avvisare un exchange prima che i fondi arrivino (lezione 10.1). I soggetti che presentano le prove e i finalizzatori sono spesso relayer, e le finestre differiscono tra blockchain e cambiano nel tempo, quindi occorre registrare il parametro in vigore. Gli autori di reati, pertanto, escono solitamente tramite bridge di liquidità.
Utilizzare ID della blockchain e indirizzo come chiave di ogni tabella: Ethereum 1, OP Mainnet 10, BNB Smart Chain 56, Polygon PoS 137, zkSync Era 324, Base 8453, Arbitrum One 42161, Linea 59144, Scroll 534352.
Altri modelli di blockchain
Tron è compatibile con EVM (TRC-20 emette l'evento Transfer di ERC-20), veicola un'ampia quota di USDT e produce blocchi circa ogni tre secondi. Gli indirizzi T… codificano un byte 0x41 più un corpo di 20-byte; convertirli in esadecimale per unirli ai dati EVM, mantenendo l'identificativo della blockchain in ogni riga. Le commissioni utilizzano bandwidth ed energy, che possono essere delegate o noleggiate, quindi l'account pagante può essere un servizio di noleggio. Un nuovo indirizzo si attiva solitamente alla prima ricezione di TRX, e il soggetto che lo attiva costituisce una pista investigativa. L'emittente di USDT può congelare un indirizzo (AddedBlackList) e distruggerne il saldo (DestroyedBlackFunds); verificare entrambi gli aspetti prima di dichiarare disponibili i fondi.
Solana conserva tutto in account (1 SOL = 1.000.000.000 lamports). I programmi non conservano stato; un account mint definisce un token e i saldi risiedono negli account di token, normalmente nell'account di token associato derivato da proprietario, programma del token e mint. I token si spostano tra account di token, quindi occorre associare ciascuno al relativo proprietario al momento del trasferimento. Registrare la prima firma (l'ID della transazione), lo slot e il blockTime stimato. Confrontare preTokenBalances e postTokenBalances è più efficace che decodificare le istruzioni interne: un account che scende da 900.000.000 a 650.000.000 unità di base con 6 decimali ha inviato 250 token. Molti nodi conservano soltanto la cronologia recente; indicare la fonte di archivio.
Cardano estende UTXO (eUTXO): gli output contengono ADA e token nativi; gli output di script contengono un datum e vengono spesi con un redeemer. Gli indirizzi di pagamento che condividono una stessa credenziale di delega appartengono nella maggior parte dei casi a un unico portafoglio: un forte segnale di raggruppamento, ma non una prova.
Le blockchain Cosmos utilizzano indirizzi Bech32 con prefisso (cosmos1…, osmo1…), e una stessa chiave genera spesso indirizzi corrispondenti su blockchain diverse. IBC blocca i fondi in deposito vincolato sull'origine e conia un voucher denominato ibc/ seguito da un hash SHA-256 del percorso e della denominazione di base; porta, canale e numero di sequenza del pacchetto compaiono in send_packet, in recv_packet e in acknowledge_packet, costituendo una chiave di join esatta. Uno stesso asset che arriva attraverso due percorsi ha due denominazioni diverse.
Monero e le transazioni schermate di Zcash nascondono soggetti e importi; l'analisi si concentra sui punti di ingresso e di uscita (lezione 6.4).
| Famiglia di blockchain | Chiave di collegamento tra blockchain | Tempi e finalità | Insidia principale |
|---|---|---|---|
| Rollup ottimistico | sourceHash in ingresso; hash del prelievo in uscita | Secondi su L2; uscita in circa una settimana | Il soggetto che presenta la prova o il finalizzatore è un relayer |
| Uscita tramite bridge di liquidità | Blockchain di origine e ID del deposito | Secondi, spesso prima della finalità | Erogazione con fondi del relayer |
| Sidechain | Nonce firmato dai validatori | Regole proprie | Piccolo insieme di validatori |
| Tron | Registri di bridge, swap o exchange | Blocchi ogni circa 3 secondi | Chi paga le commissioni o attiva l'indirizzo non è il proprietario |
| Solana | ID del messaggio del bridge | Slot e ora stimata | Account di token, non portafogli |
| Cosmos con IBC | Porta, canale, numero di sequenza | Finale una volta confermato dal consenso | La denominazione ibc/ varia in base al percorso |
Blockchain non supportate. Quando gli strumenti utilizzati non riescono a decodificare una blockchain: leggerne la documentazione in una versione datata; acquisire dati da due fonti, salvando le risposte grezze e calcolandone gli hash (lezione 8.3); validare su un caso noto, come un deposito di cui si possiedono i registri dell'exchange; riportare soltanto i campi validati; fare affidamento sui bridge e sugli exchange ai punti di ingresso e di uscita; e dichiarare ogni limitazione (lezione 3.6).
Focus sull'esame: i quattro modelli di bridge e ciò che ciascuno lascia su entrambe le blockchain; gli identificativi Wormhole, LayerZero e CCTP, i nonce CCTP assegnati dall'emittente e l'associazione degli identificativi dei bridge, come i domini CCTP, alle reti; l'associazione in sette passaggi; relayer, aggregatori e finalizzatori come soggetti non proprietari; l'invariante secondo cui l'offerta di token wrapped non supera mai il deposito vincolato e il modo in cui Wormhole, Ronin e Nomad vi si manifestano; indirizzo che agisce rispetto aonBehalfOf; rollup ottimistici e ZK rispetto alle sidechain; teste unsafe, safe e finalized ed eliminazione dei blob dopo circa 18 giorni;sourceHash, ticket ritentabili e assegnazione di alias; il prelievo in tre passaggi come tempo utile di preavviso; uso di ID della blockchain e indirizzo come chiave; risorse Tron, attivazione e congelamenti di USDT; account di token Solana e differenze dei saldi; credenziali di delega Cardano; chiavi dei pacchetti IBC.