Contratti verificati, proxy e la chiave di aggiornamento di cui nessuno parla

·7 min di lettura·Di SSP Editorial Team
Copertina SSP Academy: contratti intelligenti verificati, proxy e chiavi di aggiornamento

Contratti verificati, proxy e la chiave di aggiornamento di cui nessuno parla

Sull’esploratore di blocchi c’è un segno di spunta verde che dice Codice sorgente del contratto verificato, e un numero enorme di persone lo legge come «questo contratto è sicuro».

Non significa questo. Significa qualcosa di molto più ristretto e molto più utile, e confondere le due cose è il modo in cui persone attente finiscono per approvare cose che non avrebbero mai accettato.

Che cosa certifica davvero «verificato»

I contratti vengono distribuiti come bytecode: istruzioni macchina, in pratica illeggibili. La verifica è l’atto di caricare il codice sorgente originale e far confermare all’esploratore che compilandolo, con la versione e le impostazioni di compilatore dichiarate, si ottiene esattamente il bytecode che già vive a quell’indirizzo.

Questa è l’intera affermazione: il sorgente che stai leggendo è davvero il sorgente che viene eseguito.

È una garanzia reale e preziosa. Senza di essa non avresti modo di sapere se il codice dall’aspetto ordinato sul GitHub di un progetto abbia una qualche relazione con ciò che la tua transazione sta per toccare.

Ma nota tutto ciò che non dice. La verifica non è una revisione. Nessuno ha valutato se il codice sia corretto, se abbia difetti, o se faccia alcunché di simile a quanto suggeriscono i nomi delle sue funzioni. Un contratto con una funzione chiamata claimRewards che trasferisce tutto il tuo saldo a chi lo ha distribuito può essere verificato, e la verifica sarebbe del tutto onesta: attesterebbe fedelmente che il furto è esattamente ciò che il codice dichiara di fare.

Verificato significa leggibile, non affidabile. Sposta la domanda da «che cos’è questa cosa?» a «ho capito ciò che ho appena letto?», il che è un progresso, ma non risponde alla seconda al posto tuo.

Conta anche l’inverso. Un contratto non verificato non è prova di malizia: moltissime distribuzioni legittime non arrivano mai alla verifica. Significa però che nessuno — nessuno strumento che usi, nessun ricercatore che avrebbe potuto avvisarti — può leggere ciò con cui stai per interagire. È ragionevole esserne cauti.

E poi i proxy peggiorano le cose

Qui il terreno si sposta, ed è la parte che per lo più resta taciuta.

La maggior parte dei contratti non banali con cui interagirai non sono contratti singoli. Sono proxy. Il proxy è l’indirizzo che vedi, e contiene tutti i dati: saldi, permessi, stato. Ma non contiene quasi nessuna logica. Inoltra invece ogni chiamata a un contratto di implementazione separato, ed esegue semplicemente ciò che quel contratto dice.

La ragione è l’aggiornabilità. I contratti immutabili non si possono correggere, quindi un difetto è permanente e una funzione mancante lo è per sempre. Puntare un proxy a una nuova implementazione consente a un gruppo di correggere errori e pubblicare migliorie senza chiedere a ogni utente di migrare. Considerato quanto valore è andato perduto per difetti non correggibili, è una scelta ingegneristica difendibile.

Ha una conseguenza facile da mancare. Quando cerchi un proxy su un esploratore e lo vedi verificato, hai verificato la logica di inoltro, non il comportamento. Il codice che decide davvero che cosa accade al tuo denaro vive all’indirizzo di implementazione, che l’esploratore può mostrarti in evidenza oppure no, e che può essere sostituito.

Dunque la vera domanda non è mai stata «questo contratto è verificato?». È:

Chi può cambiare il comportamento di questo contratto, e con quanta rapidità?

La chiave di amministrazione è il vero modello di sicurezza

Ogni contratto aggiornabile ha qualcuno che può eseguire l’aggiornamento. Quell’autorità è il modello di sicurezza, per quanto buono sia il codice attuale.

La gamma va dall’allarmante al ragionevole:

Un singolo conto a proprietà esterna. Una chiave privata, sulla macchina di qualcuno, può sostituire la logica del contratto che custodisce i tuoi fondi. Se viene rubata con l’inganno, sottratta, o se il suo titolare è costretto, il contratto diventa ciò che l’attaccante vuole. Questa disposizione è più comune di quanto dovrebbe.

Un multifirma. Più firmatari devono concordare. Molto meglio — elimina il punto unico di guasto — anche se vale la pena sapere quanti firmatari sono e se siano davvero persone indipendenti o quattro portatili dello stesso gruppo.

Un multifirma dietro un blocco temporale. Un aggiornamento viene annunciato sulla catena e può essere eseguito solo dopo un ritardo fisso, spesso da 24 a 72 ore. È questo quello che conta, perché cambia del tutto la tua posizione: ricevi un preavviso del cambiamento e una finestra per ritirare prima che abbia effetto. Un blocco temporale non impedisce un aggiornamento malevolo. Lo rende sopravvivibile.

Nessuna via di aggiornamento. Il contratto è immutabile. Massima prevedibilità, nessun rimedio se salta fuori un difetto. Scelta legittima, di solito compiuta da protocolli collaudati abbastanza a lungo da scommetterci.

Nessuna di queste è automaticamente giusta. Ma la differenza tra «una chiave» e «multifirma più due giorni di ritardo» è la differenza tra sperare che nessuno sbagli e avere il tempo di reagire quando accade.

Perché questo morde proprio sulle approvazioni

Questa è la parte che si collega a qualcosa che fai davvero con regolarità.

Quando concedi un’approvazione di token, stai autorizzando un indirizzo a muovere i tuoi token. Non un pezzo di codice: un indirizzo. L’approvazione risiede nella memoria del contratto del token e permane a tempo indeterminato.

Se quell’indirizzo è un proxy aggiornabile, allora la logica autorizzata a muovere i tuoi token può essere sostituita dopo che l’hai approvata, senza il tuo coinvolgimento e senza alcuna nuova firma da parte tua. Hai esaminato una cosa e resti esposto a un’altra.

Ecco perché il consiglio perenne di revocare le approvazioni che non usi più pesa più di quanto sembri all’inizio. Non riguarda soltanto un contratto che si riveli difettoso. Riguarda il fatto che un permesso illimitato a un contratto aggiornabile è un permesso concesso a chiunque controlli la chiave di aggiornamento, per tutto il tempo in cui lo lasci aperto.

È anche il limite più netto della simulazione delle transazioni. Simulare prima di firmare ti dice che cosa fa una transazione rispetto allo stato attuale e all’implementazione attuale. È davvero utile e non può dirti che cosa permetterà quella stessa approvazione il mese prossimo.

Che cosa ti mostra SSP e dove si ferma

Quando SSP Key presenta un’approvazione, decodifica i dati della chiamata anziché mostrarti esadecimale grezzo. Riconosce i selettori ERC-20 standard — approve, transfer, transferFrom, increaseAllowance, setApprovalForAll — e li rende in linguaggio piano, segnalando anche i permessi illimitati, definiti nel codice come qualsiasi importo pari o superiore a 2^255.

Il decodificatore è deliberatamente prudente. La sua stessa intestazione lo descrive come di solo livello di presentazione: non altera mai ciò che viene firmato e fallisce in chiusura. Un selettore sconosciuto, una lunghezza errata, esadecimale malformato o un riempimento di indirizzo non standard lo portano a non restituire nulla e a ripiegare su un’azione generica con l’esadecimale grezzo dietro una vista «Avanzate». Preferisce ammettere di non sapere piuttosto che tirare a indovinare con sicurezza e sbagliare. Simboli e decimali dei token vengono allegati solo quando noti dal registro presente sul dispositivo, mai dedotti.

Ora il confine onesto. Il decodificatore non ha alcuna nozione di proxy. Non vi compare da nessuna parte l’idea di un contratto di implementazione. Può dirti, correttamente e con chiarezza, «stai concedendo un permesso USDC illimitato a 0xABC…» — e non può dirti che 0xABC è un proxy, chi ne detiene la chiave di aggiornamento, o che il suo comportamento potrebbe essere del tutto diverso la settimana prossima.

Non è tanto una svista quanto un confine che nessun decodificatore di portafoglio può oltrepassare. Decodificare descrive la chiamata che hai davanti. Se la controparte sia aggiornabile, e chi la governi, è una proprietà del mondo più ampio che va verificata a parte. Preferiamo enunciare il confine piuttosto che lasciare che una schermata di approvazione dall’aria sicura lasci intendere una completezza che non ha.

Una verifica pratica prima di approvare qualcosa di rilevante

È verificato? In caso contrario, sappi che ti stai affidando alla sola reputazione.

È un proxy? Gli esploratori lo segnalano: cerca un avviso di proxy, o un’opzione «Read as Proxy». Se c’è, l’implementazione è il codice che conta.

Chi può aggiornarlo, e c’è un ritardo? È la domanda di maggior valore dell’elenco e quella che quasi nessuno pone. Un progetto che ci ha pensato lo documenterà. Uno che non l’ha fatto, o non lo dice, ti ha già detto qualcosa.

L’approvazione deve essere illimitata? Di solito no. Approvare l’importo che intendi davvero spendere limita la tua esposizione esattamente a quello, qualunque cosa il contratto diventi in seguito.

Revoca quando hai finito. Un permesso aperto è un’autorizzazione permanente, e sopravvive alla tua attenzione.

L’aggiustamento mentale che vale la pena fare è piccolo ma cambia molto. La verifica ti dice quale codice è in esecuzione proprio adesso. L’aggiornabilità ti dice chi decide che cosa verrà eseguito domani. Quasi tutto il rischio abita nella seconda domanda, e quasi tutta la rassicurazione in offerta si rivolge solo alla prima.

Condividi questo articolo

Articoli correlati