fluxswap

Protokół zdecentralizowanej giełdy (DEX) w Solidity, budowany w Foundry. Pule płynności, router, staking i timelock - z inwariantami i pełnym pokryciem testami.

fluxswap
TL;DR

Protokół zdecentralizowanej giełdy (DEX) w Solidity: pule płynności, router, staking i timelock. Kontrakt obraca realnymi środkami, więc bug to nie poprawka na kolejne wydanie, tylko utracone pieniądze. Dlatego liczą się inwarianty i pełne pokrycie testami w Foundry, a nie stwierdzenie, że wygląda, iż działa.

Wprowadzenie

Większe oprogramowanie żyje z tego, że błędy da się poprawić. Kontrakt na łańcuchu odbiera ci ten komfort: jest niezmienny i trzyma cudze pieniądze. To odwraca sposób pisania kodu, bo nie sprawdzasz już, czy ścieżka szczęścia działa, tylko czy nie da się złamać zasady, która ma trzymać zawsze.

fluxswap jest zbudowany wokół tej różnicy. Pule płynności, router, staking i timelock to funkcje, ale prawdziwa robota siedzi w inwariantach, które muszą obowiązywać po każdej możliwej sekwencji operacji, także tej, której nikt nie przewidział.

Kod, którego nie da się zaktualizować po fakcie

Zwykła aplikacja ma bug, wypuszczasz poprawkę, idzie dalej. Kontrakt na łańcuchu jest niezmienny i trzyma cudze pieniądze, więc błąd w logice puli płynności to nie usterka, to wektor, którym ktoś wyprowadza środki. Nie ma tu wydania numer dwa, w którym to naprawisz.

Ta jedna własność zmienia wszystko. Piszesz z założeniem, że każdy, kto patrzy na kontrakt, szuka sposobu, żeby złamać jego reguły, i że jedyną obroną jest udowodnienie, że złamać się ich nie da.

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

Pojedyncze testy sprawdzają konkretne wejścia, które sam wymyślisz, więc sprawdzają tylko to, co już przewidziałeś. Testy inwariantowe w Foundry robią coś mocniejszego: losowo bombardują kontrakt tysiącami sekwencji operacji i po każdej sprawdzają, że reguła wciąż zachodzi.

Suma tokenów się zgadza, iloczyn rezerw nie spada, nikt nie wypłacił więcej niż wpłacił. Różnica jest zasadnicza, bo to fuzzer, a nie ty, wymyśla scenariusz, który łamie kontrakt, i robi to tysiące razy pod rząd.

1000+
losowych sekwencji na inwariant
0
scenariuszy łamiących regułę stałego iloczynu

Timelock, czyli czas na reakcję

!
Ostrzeżenie

Timelock na wrażliwych operacjach jest po to, żeby zmiana parametrów nie mogła zostać wprowadzona z minuty na minutę. Nawet właściciel czeka, a społeczność widzi, co nadchodzi, zanim to się stanie, i ma czas zareagować, jeśli zmiana jest wroga.

To zabezpieczenie nie chroni przed bugiem w kodzie, tylko przed nadużyciem uprawnień. Bez timelocka właściciel mógłby po cichu przestawić parametry protokołu tuż przed atakiem. Z nim każda taka zmiana jest widoczna i opóźniona, co odbiera jej element zaskoczenia.

Dowód zamiast nadziei

Efektem jest protokół, którego bezpieczeństwo opiera się na dowodzie, a nie na przekonaniu, że przetestowaliśmy najważniejsze przypadki. Inwarianty trzymają po tysiącach losowych sekwencji, wrażliwe zmiany są opóźnione timelockiem, a najgroźniejsze reguły, jak stały iloczyn rezerw, są egzekwowane wprost w kodzie kontraktu.

Inwarianty i co gwarantują

InwariantCo gwarantuje
Stały iloczyniloczyn rezerw nie spada po swapie
Suma tokenówwpłaty równają się wypłatom plus saldo
Wypłatanikt nie bierze więcej niż włożył
Timelockzmiany parametrów są opóźnione i jawne

Więcej projektów

Inne realizacje z tej samej kategorii - zobacz, jak podchodzimy do podobnych wyzwań.

Masz podobny projekt?

Napisz do nas - wycena jest bezpłatna i wraca w godzinę.