Vulnerabilitatea recentă a pool-ului Curve este diferită de incidentele de hacking de criptomonede pe care le-am mai văzut, deoarece de data aceasta problema nu este direct legată de vulnerabilitatea contractului inteligent în sine, ci de compilatorul de bază al limbajului de programare folosit de Vyper.
Vyper este un limbaj de programare inteligent, orientat spre contract, care adoptă un stil asemănător Python și este conceput special pentru a interacționa cu Ethereum Virtual Machine (EVM).
Impactul acestei vulnerabilități este foarte grav, iar în știri sunt raportate zilnic cantități uriașe de pierderi. Situația pare să fie sub control, dar nu înainte ca hackerii să fure mai mult de 70 de milioane de dolari. Conform evaluării ulterioare a LlamaRisk, unele pool-uri de proiecte DeFi au fost, de asemenea, atacate de hackeri, inclusiv pool-ul pETH/ETH al PEGD care a pierdut 11 milioane USD, pool-ul mETH/ETH al Metronome care a pierdut 3,4 milioane USD și pool-ul alETH/ETH al Alchemix care a pierdut 11 USD. 22,6 milioane de dolari SUA, în timp ce pool-ul Curve DAO a pierdut aproximativ 24,7 milioane de dolari.
Această vulnerabilitate se numește eroare de reintrare și apare în principal în unele versiuni ale limbajului de programare Vyper, în special v0.2.15, v0.2.16 și v0.3.0. Prin urmare, proiectele care utilizează aceste versiuni specifice de Vyper pot deveni ținta atacurilor.
Ce este reintrarea?
Pentru a înțelege de ce a apărut această vulnerabilitate, să înțelegem mai întâi ce este reintrarea și cum funcționează.
Așa-numita reintrare înseamnă că o funcție poate fi întreruptă în timpul execuției și apelată din nou în siguranță înainte de finalizarea apelului anterior. Acest mecanism este adesea folosit în aplicații precum manipularea întreruperilor hardware și recursiunea.
Pentru ca o funcție să fie reintrată, trebuie să îndeplinească câteva condiții:
În primul rând, nu poate folosi date globale și statice. Aceasta este o convenție, ceea ce înseamnă că atunci când funcția este executată, nu vă bazați pe date globale sau variabile statice. Pentru că dacă o funcție este întreruptă în timpul execuției și apoi apelată din nou, datele globale și statice pot fi corupte sau informațiile se pot pierde.
În al doilea rând, nu își poate modifica propriul cod. Indiferent când o funcție este întreruptă, aceasta ar trebui să poată continua execuția în același mod. Dacă o funcție își modifică propriul cod în timpul execuției, poate apărea o eroare atunci când este apelată din nou.
În cele din urmă, nu poate apela alte funcții care nu sunt reintrante. Adică, în cadrul unei funcții reintrante, nu ar trebui să apelați alte funcții care ar putea să nu fie reintrante. Pentru că dacă faceți acest lucru, poate provoca rezultate imprevizibile, provocând blocarea programului sau erori.
Este prea greu de înțeles, așa că nu vom intra în detalii.
Cum a fost exploatat?
Să explicăm cum atacurile de reintrare au dus la furtul de fonduri și la pierderea a 70 de milioane de dolari în atacul Curve.
În primul rând, știm că un atac de reintrare se referă la o metodă în care un contract rău intenționat apelează în mod repetat o funcție într-un contract inteligent. În atacul Curve, această funcție este folosită pentru a retrage lichiditatea utilizatorului din pool. Această funcție are un defect prin aceea că nu efectuează suficiente verificări înainte de a actualiza suma.
Să ne uităm la procesul specific al atacului:
Să presupunem că un contract inteligent vulnerabil are 10 eteri.
Atacatorul apelează funcția de depozit și depune 1 Ethereum.
Atacatorul apelează apoi funcția de retragere și se pregătește să retragă 1 Ethereum. În această funcție, verifică dacă atacatorul are 1 Ethereum în contul său.
Cu toate acestea, această funcție nu actualizează soldul din contract înainte de a transfera 1 Ether în contul atacatorului. Aceasta înseamnă că contractul încă crede că există 10 eteri înăuntru.
Atacatorul apelează din nou funcția de retragere (reintrare) și se pregătește să retragă din nou 1 Ethereum.
Deoarece contractul încă crede că există 10 eteri înăuntru, va transfera din nou 1 eter atacatorului.
Acest proces se repetă până când nu mai există lichiditate în contract.
În acest fel, atacatorul poate apela în mod repetat funcția de retragere și poate transfera aproape toată lichiditatea din contract în cont propriu, determinând furtul fondurilor din contract.
Această vulnerabilitate este foarte benefică pentru atacator deoarece suma din contract nu este actualizată în timp real, permițând atacatorului să repete atacul până când nu există fonduri disponibile pentru retragere în contract. #Crv