fluxswap

Un protocollo di exchange decentralizzato (DEX) in Solidity, costruito con Foundry. Pool di liquidità, router, staking e timelock - con invarianti e copertura di test completa.

fluxswap
TL;DR

Un protocollo di exchange decentralizzato (DEX) in Solidity: pool di liquidità, un router, staking e un timelock. Il contratto muove fondi reali, quindi un bug non è una correzione per la prossima release, sono soldi persi. Per questo contano gli invarianti e una copertura di test completa in Foundry, non il dire che sembra funzionare.

Introduzione

La maggior parte del software vive sul fatto che i bug si possono correggere. Un contratto on-chain ti toglie questo comfort: è immutabile e custodisce il denaro altrui. Questo capovolge il modo in cui scrivi il codice, perché non verifichi più che il percorso felice funzioni, verifichi che una regola che deve valere sempre non possa essere infranta.

fluxswap è costruito attorno a questa differenza. I pool di liquidità, un router, lo staking e un timelock sono funzionalità, ma il vero lavoro sta negli invarianti che devono valere dopo ogni possibile sequenza di operazioni, compresa quella che nessuno ha previsto.

Codice che non puoi aggiornare a posteriori

Un'app ordinaria ha un bug, rilasci una correzione, si va avanti. Un contratto on-chain è immutabile e custodisce il denaro altrui, quindi un bug nella logica del pool di liquidità non è un difetto, è un vettore attraverso cui qualcuno drena fondi. Non c'è una release numero due in cui lo correggi.

Questa unica proprietà cambia tutto. Scrivi partendo dal presupposto che chiunque guardi il contratto stia cercando un modo per infrangere le sue regole, e che l'unica difesa sia dimostrare che non possono essere infrante.

Pool.sol · bash
uint256 kBefore = reserveX * reserveY;
_swap(amountIn, amountOut);
require(reserveX * reserveY >= kBefore, "K");

I test singoli verificano input specifici che inventi tu stesso, quindi verificano solo ciò che hai già previsto. I test di invarianti in Foundry fanno qualcosa di più forte: bombardano a caso il contratto con migliaia di sequenze di operazioni e dopo ciascuna verificano che la regola valga ancora.

Le somme dei token tornano, il prodotto delle riserve non cala, nessuno ha prelevato più di quanto ha versato. La differenza è fondamentale, perché è il fuzzer, non tu, a inventare lo scenario che infrange il contratto, e lo fa migliaia di volte di fila.

1000+
sequenze casuali per invariante
0
scenari che infrangono la regola del prodotto costante

Il timelock, ovvero il tempo per reagire

!
Attenzione

Il timelock sulle operazioni sensibili esiste perché un cambio di parametri non possa essere introdotto da un minuto all'altro. Anche il proprietario aspetta, e la comunità vede cosa sta arrivando prima che accada, con il tempo di reagire se il cambiamento è ostile.

Questa salvaguardia non protegge da un bug nel codice ma dall'abuso di privilegi. Senza timelock il proprietario potrebbe reimpostare in silenzio i parametri del protocollo poco prima di un attacco. Con esso, ogni cambiamento del genere è visibile e ritardato, il che gli toglie l'effetto sorpresa.

La prova invece della speranza

Il risultato è un protocollo la cui sicurezza poggia su una prova, non sulla convinzione di aver testato i casi più importanti. Gli invarianti reggono attraverso migliaia di sequenze casuali, i cambiamenti sensibili sono ritardati dal timelock, e le regole più pericolose, come il prodotto costante delle riserve, sono imposte direttamente nel codice del contratto.

Gli invarianti e cosa garantiscono

InvarianteCosa garantisce
Prodotto costanteil prodotto delle riserve non cala dopo uno swap
Somma dei tokeni depositi eguagliano i prelievi più il saldo
Prelievonessuno prende più di quanto ha messo
Timelocki cambiamenti dei parametri sono ritardati e pubblici

Altri progetti

Altri lavori della stessa categoria - scopri come affrontiamo sfide simili.

Hai un progetto simile?

Contattaci - il preventivo è gratuito e arriva entro un'ora.