Niedawna luka w zabezpieczeniach puli Curve różni się od incydentów związanych z włamaniami do kryptowalut, które widzieliśmy wcześniej, ponieważ tym razem problem nie jest bezpośrednio związany z podatnością samego inteligentnego kontraktu, ale z podstawowym kompilatorem języka programowania używanego przez Vyper.

Vyper to inteligentny język programowania zorientowany na kontrakty, który przyjmuje styl podobny do Pythona i został specjalnie zaprojektowany do interakcji z maszyną wirtualną Ethereum (EVM).

Skutki tej luki są bardzo poważne, a wiadomości codziennie donoszą o ogromnych stratach. Sytuacja wydaje się być pod kontrolą, ale hakerzy ukradli ponad 70 milionów dolarów. Według oceny końcowej przeprowadzonej przez LlamaRisk hakerzy zaatakowali także niektóre pule projektów DeFi, w tym pulę pETH/ETH firmy PEGD, która straciła 11 mln dolarów, pulę msETH/ETH firmy Metronome, która straciła 3,4 mln dolarów, oraz pulę alETH/ETH firmy Alchemix, która straciła 11 dolarów. mln dolarów, podczas gdy pula Curve DAO straciła około 24,7 mln dolarów.

Luka ta nazywana jest błędem ponownego wejścia i występuje głównie w niektórych wersjach języka programowania Vyper, w szczególności v0.2.15, v0.2.16 i v0.3.0. Dlatego projekty korzystające z tych konkretnych wersji Vypera mogą stać się celem ataków.

Co to jest ponowne wejście?​

Aby zrozumieć, dlaczego pojawiła się ta luka, przyjrzyjmy się najpierw, czym jest ponowne wejście i jak działa.

Tak zwana reentrancy oznacza, że ​​funkcję można przerwać w trakcie wykonywania i bezpiecznie wywołać ponownie przed zakończeniem poprzedniego wywołania. Mechanizm ten jest często używany w zastosowaniach takich jak obsługa przerwań sprzętowych i rekurencja.

Aby funkcja mogła być współbieżna, musi spełniać kilka warunków:

Po pierwsze, nie może wykorzystywać danych globalnych i statycznych. Jest to konwencja, która oznacza, że ​​podczas wykonywania funkcji nie należy opierać się na danych globalnych ani zmiennych statycznych. Ponieważ jeśli funkcja zostanie przerwana podczas wykonywania, a następnie wywołana ponownie, dane globalne i statyczne mogą zostać uszkodzone lub informacje mogą zostać utracone.

Po drugie, nie może modyfikować własnego kodu. Bez względu na to, kiedy funkcja zostanie przerwana, powinna móc kontynuować wykonywanie w ten sam sposób. Jeśli funkcja zmodyfikuje swój własny kod podczas wykonywania, przy ponownym wywołaniu może wystąpić błąd.

Wreszcie nie może wywoływać innych funkcji, które nie są współbieżne. Oznacza to, że w ramach funkcji współbieżnej nie należy wywoływać innych funkcji, które mogą nie być współbieżne. Ponieważ jeśli to zrobisz, może to spowodować nieprzewidywalne skutki, powodując awarię programu lub błędy.

Jest to zbyt trudne do zrozumienia, więc nie będziemy wdawać się w szczegóły.

Jak został wykorzystany?

Wyjaśnijmy, w jaki sposób ataki polegające na ponownym wejściu doprowadziły do ​​kradzieży środków i utraty 70 milionów dolarów w wyniku ataku Curve.

Po pierwsze wiemy, że atak typu „reentrancy” odnosi się do metody, w której złośliwy kontrakt wielokrotnie wywołuje funkcję inteligentnego kontraktu. W ataku Curve funkcja ta służy do wycofania płynności użytkownika z puli. Ta funkcja ma wadę polegającą na tym, że nie przeprowadza wystarczającej kontroli przed aktualizacją kwoty.

Przyjrzyjmy się konkretnemu procesowi ataku:

  1. Załóżmy, że wrażliwy inteligentny kontrakt ma 10 eterów.

  2. Atakujący wywołuje funkcję depozytu i wpłaca 1 Ethereum.

  3. Następnie atakujący wywołuje funkcję wypłaty i przygotowuje się do wypłaty 1 Ethereum. W tej funkcji sprawdza, czy atakujący posiada na swoim koncie 1 Ethereum.

  4. Jednakże ta funkcja nie aktualizuje salda w kontrakcie przed przesłaniem 1 Etheru na konto atakującego. Oznacza to, że kontrakt nadal zakłada, że ​​w środku znajduje się 10 eterów.

  5. Atakujący ponownie wywołuje funkcję wypłaty (re-entry) i przygotowuje się do ponownej wypłaty 1 Ethereum.

  6. Ponieważ kontrakt nadal uważa, że ​​w środku znajduje się 10 eterów, ponownie przekaże 1 eter atakującemu.

  7. Proces ten powtarza się do momentu, gdy w kontrakcie nie będzie już płynności.

W ten sposób atakujący może wielokrotnie wywołać funkcję wypłaty i przenieść niemal całą płynność kontraktu na swoje własne konto, powodując kradzież środków znajdujących się w kontrakcie.

Luka ta jest bardzo korzystna dla atakującego, ponieważ kwota w umowie nie jest aktualizowana w czasie rzeczywistym, co pozwala atakującemu na powtarzanie ataku do czasu, aż zabraknie środków na wypłatę z umowy. #Crv