Back to Blog

#6: Hundred Finance Olayı: Savunmasız Çatallanmış Protokollerde Hassasiyet Tabanlı Açıkların Dalgasını Tetiklemek

Code Auditing
February 16, 2024
6 min read

16 Nisan 2023'te, Compound V2'nin bir çatalı olan Hundred Finance saldırıya uğradı ve yaklaşık 7,4 milyon dolarlık kayba yol açtı. Saldırı iki temel sorunu içeriyordu:

  • Bir hassasiyet kaybı sorunu (yanlış yuvarlama sorunu);
  • Bilgisayar korsanının exchangeRate'i manipüle etmesine olanak tanıyan boş piyasalar.

DeFiLlama'ya göre en çok çatallanan borç verme protokolü olan Compound V2, 100'den fazla çatala sahiptir. OpenZeppelin tarafından denetlenmiş ve pratikte kanıtlanmış sözleşmeleri güvenli kabul edilmektedir. Ancak Hundred Finance saldırısı, özellikle düşük likidite ortamında hassasiyet kaybının DeFi protokol güvenliğini nasıl kritik ölçüde etkileyebileceğini ortaya koymuş ve Midas ile Radiant gibi önemli çatallarda benzer açıklardan yararlanma dalgasını tetiklemiştir.

Daha derin bir anlayış için tam analizin incelenmesi önerilir. Aşağıda, 2023'ün en önemli on güvenlik olayından biri olarak öne çıkan bu olaya kısa bir giriş sunulmaktadır.

Arka Plan

Hundred Finance'e Genel Bakış

Hundred Finance, Chainlink oracle'larını kullanan ve birden fazla ana ağda çalışan Compound v2'nin bir çatalıdır. Geleneksel finans borç verme uygulamalarının aksine, Compound ve Aave gibi DeFi borç verme protokolleri aşırı teminatlı borçlanmaya izin vermez. Basitçe söylemek gerekirse, 100 dolar değerinde Token A yatırırsanız, yalnızca 100 dolardan az değerde varlık ödünç alabilirsiniz. Çoğu protokolün risk kontrol katsayılarına göre bu oran genellikle %50 ile %80 arasında değişmektedir.

Borç verme protokolleri için yaygın saldırı yöntemleri arasında fiyat manipülasyonu ve yeniden giriş yer almaktadır. İlginç bir şekilde, Hundred Finance daha önce Mart 2022'de bir yeniden giriş saldırısı yaşamıştı, ancak bu olay yeni bir saldırı vektörü oluşturdu.

hToken

Compound ve Aave'den çatallanan borç verme protokolleri, her bir temel token (teminat) için karşılık gelen bir muhasebe token'ı oluşturur. Hundred Finance için:

  • USDC, hUSDC'ye karşılık gelir
  • WBTC, hWBTC'ye karşılık gelir

Temel token ile hToken arasındaki döviz kuru exchangeRate olarak adlandırılır.

  • Varlık yatırırken kullanıcılar hToken'ın mint() fonksiyonunu çağırmalıdır.
  • Varlık çekerken kullanıcı hToken'ın redeem() fonksiyonunu çağırmalıdır.

exchangeRate

Aşağıda exchangeRate hesaplama formülü verilmiştir: image

Burada:

  • getCash(): Bu hToken sözleşmesine ait temel token bakiye miktarı. Bu, manipüle edilebilen önemli bir parametredir. Lütfen bunu aklınızda tutun.
  • totalBorrows(): Piyasa tarafından şu anda borç olarak verilen temel token miktarı ve piyasa tedarikçilerine faiz biriktirilmekte olan tutar.
  • totalReserves(): Rezervler, protokolün yönetimi aracılığıyla çekilebilen veya transfer edilebilen nakit olarak bir kenara ayrılmış geçmiş faizin bir bölümünü temsil eden her hToken sözleşmesindeki bir muhasebe kaydıdır.
  • totalSupply(): Bu hToken piyasasında şu anda dolaşımda olan token sayısı.

Not: Bir hToken ile temel varlık arasındaki exchangeRate, örneğin (dai ile hDai veya eth ile hEth) 0,020'den başlar ve bileşik piyasa faiz oranına eşit bir hızda artar.

Tasfiye

Kötü borçları önlemek amacıyla borç verme protokolleri, herhangi bir kullanıcının başka bir kullanıcının borcunu tasfiye etmesine izin verir. Aşağıdaki örneği kullanarak açıklayalım:

  1. Alice, 100 dolar değerinde BTC yatırır ve 70 dolar değerinde ETH ödünç alır.
  2. ETH fiyatı yükselirse veya BTC fiyatı düşerse, Alice'in varlıkları tasfiye eşiğine ulaşabilir.
  3. Bob, Alice'in BTC'sini tasfiye etmek için belirli miktarda ETH kullanabilir; bu sayede Alice'in borcu protokol fonlarının güvenliğini sağlamak için sağlıklı bir seviyeye döner (protokol, tasfiyeyi başlatan kullanıcıları ödüllendirir).

Tasfiye bu saldırının odak noktası değildir, ancak saldırıda yer almıştır. Burada yalnızca herhangi bir kullanıcının bir tür Token ile başka bir kullanıcının borcunu tasfiye edebildiğini bilmemiz yeterlidir; bu işlem karşılık gelen hToken'ı azaltacaktır.

Güvenlik Açığı

Hassasiyet Kaybı Sorunu

Bilgisayar korsanı, redeem() aracılığıyla teminat çekildiğinde, düşülecek hToken miktarının hesaplamasının 1,99999992 (2'ye çok yakın ancak 2'den küçük) sonucunu vermesini sağlar. truncate() fonksiyonunda tam sayıya dönüştürülürken aşağı yuvarlama kullanımı, nihai sonucun 1 olmasına yol açar.

exchangeRate

Daha önce tanıtıldığı üzere exchangeRate hesaplaması, hToken sözleşmesine ait temel bakiye miktarını ifade eden getCash() fonksiyonunu içermektedir. Temel token'ları doğrudan sözleşmeye transfer ederek (mint kullanmadan, yalnızca transfer ederek), bilgisayar korsanı exchangeRate'i manipüle edebilir. Ancak şunu belirtmek önemlidir: Bu exchangeRate sorununun tek başına protokolün güvenliğini tehlikeye atmadığını unutmamak gerekir; bilgisayar korsanları bu sorundan yalnız başlarına kazanç sağlayamaz. Bu saldırı bağlamında, söz konusu sorun öncelikle bilgisayar korsanının kazançlarını büyütmek amacıyla kullanılmış ve havuzu hızla tüketmelerine olanak tanımıştır. Aksi takdirde saldırı, tek bir kesin darbeden çok sayıda küçük hamleye dönüşür ve kayda değer bir etki yaratmak için çok sayıda tekrar gerektirir.

Özetle, bu saldırıdaki temel sorun hassasiyet kaybıdır.

Saldırı Süreci

İşte saldırı işlemi; şimdi bu karmaşık işlemi analiz etmek için Phalcon Explorer'ı kullanacağız.

İşlem: 0x6e9ebcdebbabda04fa9f2e3bc21ea8b2e4fb4bf4f4670cb8483e2f0b2604f451

  1. Flashloan aracılığıyla Aave V3'ten 500 WBTC ödünç alın.

  2. Daha önce edinilen tüm hWBTC'yi Redeem edin, hWBTC'nin totalSupply değerini 0'a sıfırlayın.

Öncesindeki amaç, bir flashloan kullanarak rezerv fon hazırlamak ve hWBTC'yi yeni bir piyasa olarak sıfırlamaktır.

  1. İkinci saldırı sözleşmesini (Create) oluşturun (bundan böyle Saldırı Sözleşmesi 2 olarak anılacaktır) ve tüm WBTC'yi (500,30063816 WBTC) Saldırı Sözleşmesi 2'ye transfer edin.

  2. 200 hWBTC üretmek için 4 WBTC kullanarak hWBTC Mint() edin.

  3. 199,99999998 hWBTC Redeem() edin; hWBTC toplamını 0,00000002 (2 wei hWBTC) olarak bırakın.

  4. Tüm WBTC'yi (500,30063816 WBTC) hWBTC'ye transfer edin. Doğrudan transferlerin hWBTC'yi artırmadığını unutmayın; bu işlem WBTC'yi havuza bağışlamak olarak görülebilir. Bu adımın temel amacı, daha önce bahsedilen exchangeRate'i manipüle etmektir. Bu noktada hWBTC'nin totalSupply değeri 2 wei hWBTC'de kalırken artık 500,30064194 WBTC bulunmaktadır; bu durum exchangeRate'i orijinalinin yüzlerce katına çıkarmaktadır.

  5. hETH piyasasından 1021 Ether ödünç alın.

  6. 50030063815 WBTC Redeem() edin; burada hesaplamaya göre 1,9999992 hBTC düşülmesi gerekirken, hassasiyet kaybı nedeniyle yalnızca 1 hBTC düşülür ve bu durum önemli bir hassasiyet kaybı (%50'ye yakın) yaratır. Bu noktada bilgisayar korsanının elinde 500 WBTC + 1021 Ether bulunmakta olup 1021 Ether kazanç elde etmiştir.

  7. Saldırgan kalan hWBTC'yi liquidate() eder, totalSupply değerini 0'a sıfırlayarak diğer piyasalara yönelik saldırılara devam etmeye hazırlanır. hWBTC içindeki neredeyse tüm WBTC çekildiğinden, bilgisayar korsanı bunu yalnızca 0,000002 Ether ile gerçekleştirir.

  8. Diğer piyasalara saldırmaya devam ederek tüm protokolü tüketin.

  9. Flashloan'ı Aave'ye geri ödeyin.

Güvenlik Önerileri

Borç Verme Protokolü için Azaltma Önlemleri

Bu sorun, özellikle Compound ve Aave çatalları için yaygındır. Proaktif bir yaklaşım olarak, yeni piyasalar başlatılırken totalSupply'ın hiçbir zaman 0'a düşmemesini sağlamak amacıyla bir miktar muhasebe token'ı mint edilmesi önerilir.

Hassasiyet Kaybı Sorunu için Azaltma Önlemleri

Hassasiyet kaybından kaynaklanan bir dizi sorunu daha iyi önlemek için minimum bir değer belirlenmesi pratikte etkili bir yöntemdir. Bu strateji, çok küçük değerlerle uğraşırken hassasiyet kaybının neden olduğu önemli etkilerden kaçınılmasına yardımcı olur.

Bu serideki diğer makaleleri okuyun:

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit