30 Nisan 2022'de bir saldırgan, Nerve Bridge Olayı'nda aynı güvenlik açığını kullanarak Saddle Finance'e saldırdı. Toplamda 4.900 Ether saldırı altına girdi. Neyse ki bunların 1.360 Ether'i tarafımızca başarıyla kurtarıldı. Bu olayın ayrıntılı açıklaması resmi ölüm sonrası raporda bulunabilir.


Her ne kadar aynı güvenlik açığı kullanılmış olsa da saldırı yöntemi öncekinden farklıdır. Yeni saldırı yöntemi beklendiği kadar basit olmadığından, derinlemesine bir inceleme yapılmasının gerektiğine inanıyoruz. Bu raporda önce güvenlik açığını kısaca açıklıyor, ardından Nerve Bridge Olayı'nın orijinal saldırı yöntemini gözden geçiriyoruz. Daha sonra, yeni saldırı yöntemini açığa çıkarmak amacıyla saldırı sürecini parçalara ayırarak Saddle Finance Olayı'na odaklanıyoruz.
0x1. Dağıtılan Sözleşmeler Hakkında
İlgili sözleşme adresleri aşağıda listelenmiştir:
- Kurban MetaSwap sözleşmesi: 0x824dcd7b044d60df2e89b1bb888e66d8bcf41491
- Savunmasız MetaSwapUtils sözleşmesi: 0x88Cc4aA0dd6Cf126b00C012dDa9f6F4fd9388b17
Şunu belirtmekte fayda var: Doğrulanmış MetaSwap sözleşmesiyle ilişkili MetaSwapUtils sözleşmesinin gösterilen kodu, Settings bölümünde adresi belirtilen dağıtılmış MetaSwapUtils sözleşmesiyle EŞDEĞERLİ DEĞİLDİR:

Bu iki MetaSwapUtils sözleşmesini birbirine karıştırmayın :)
0x2. Güvenlik Açığı Analizi
Savunmasız sözleşme, önceki blog yazısında ayrıntılı olarak ele alınan MetaPool'a aittir. Kısaca, MetaPool başlangıçta Curve tarafından, tek bir coin'in likiditeyi seyreltmeden başka bir (temel) havuzdaki tüm coinlerle havuzlanabilmesi için tasarlandı. Temelde birkaç farklı stabil coin'den oluşan temel havuzun LP token'ı ile bir stabil coin'den oluşan bir havuzdur. MetaPool tasarımına ilişkin bir endişe mevcuttur: MetaPool, stabil coinler için fiyatları koruyan bir stabil coin havuzudur; ancak temel bir stabil coin havuzunun LP token'ı stabil coin değildir.
Aslında, temel bir stabil coin havuzunun LP token fiyatı, temel havuzun getVirtualPrice fonksiyonu çağrılarak elde edilebilir ve bu fiyat, temel havuz tarafından tahsil edilen ücretlerin birikmesiyle birlikte istikrarlı biçimde artar.
Bununla başa çıkmak için MetaPool, fiyatı hesaplamadan önce LP token rezervini ölçeklendirerek büyütür; aşağıda gösterildiği gibi.

Buna göre, bir kullanıcı LP token'ı stabil coin ile takas ederse, fiyat hesaplanmadan önce LP token miktarı ölçeklendirilerek büyütülür. Alternatif olarak, bir kullanıcı stabil coin'i LP token ile takas ederse, hesaplanan LP token miktarı transfer ve muhasebe işlemlerinden önce ölçeklendirilerek küçültülür.

Yukarıdaki swapUnderlying fonksiyonuna ait kod parçacığı, MetaPool'daki stabil coin ile temel havuzdaki stabil coinler arasında takas yapmak için kullanılır. İki kırmızı dikdörtgende gösterildiği üzere, fonksiyon gelen LP token miktarını ölçeklendirerek büyütmekte ve takas edilen LP token miktarını ölçeklendirerek küçültmektedir.
Ancak swap fonksiyonunun uygulaması, swapUnderlying fonksiyonununkiyle tutarsızdır. Özellikle, güvenlik açığının temel nedeni, LP token miktarını gereği gibi küçültmeyen ve büyütmeyen swap fonksiyonunda (yani _calculateSwap fonksiyonunda) uygulanan hatalı hesaplamadan kaynaklanmaktadır. Aşağıda gösterildiği gibi, sol taraf MetaPool'un savunmasız kodunu verirken, sağ taraf düzeltilmiş sürümü göstermektedir.

Nerve Bridge Olayı'ndaki saldırgan, swap fonksiyonu ile swapUnderlying fonksiyonu arasındaki tutarsızlıktan yararlandı.
(Nerve Bridge'in Saddle Finance'in bir fork projesi olduğunu unutmayın.)
Bunun ardından Saddle Finance, güvenlik açığını giderdi ve MetaSwapUtils kütüphanesinin yeni sürümünü (yani V2) hemen yeniden dağıttı.
Ne yazık ki bilinmeyen bir nedenle, Ethereum üzerindeki sUSD V2 MetaPool hâlâ eski ve savunmasız MetaSwapUtils kütüphanesiyle dağıtılmıştı. Sonuç olarak bu güvenlik açığı, 30 Nisan'da bir saldırgan tarafından bir kez daha başarıyla istismar edildi. İlginç bir şekilde, Nerve Bridge Olayı'nda kullanılan saldırı yönteminden farklı olarak savunmasız MetaPool'a saldırmak için farklı bir yol benimsendi.
0x3. Nerve Bridge Olayı'nın Orijinal Saldırı Yöntemi
Orijinal saldırı yöntemini gözden geçirmek için aşağıdaki şekli (önceki blog yazısına bakın) yeniden kullanıyoruz.

Savunmasız swap fonksiyonu, takas edilen LP token (Nerve 3-LP) miktarını ölçeklendirerek küçültmediğinden, Adım 3'teki takas edilen miktar (36.959) normalden büyüktür.
Ardından saldırgan, 36.959 Nerve 3-LP'yi (Adım 4 ve 5'te) 51.494 fUSDT karşılığında satmak için swapUnderlying fonksiyonunu (güvenlik açığı olmadan) çağırarak 1.143 fUSDT kâr elde eder.
Makul bir şekilde, kâr şu şekilde açıklanabilir: Saldırgan Adım 3'te daha fazla Nerve 3-LP elde eder ve ardından swap fonksiyonu ile swapUnderlying fonksiyonu arasındaki tutarsızlıktan yararlanarak bunları "normal" bir fiyattan satar.
0x4. Saddle Finance Olayı'nın Yeni Saldırı Yöntemi
Son Saddle Finance Olayı'ndaki saldırgan, swapUnderlying fonksiyonunu dahil etmeden aynı savunmasız swap fonksiyonuna saldırmak için farklı bir yol kullandı.
Süreci somut olarak göstermek için bir saldırı işlemini örnek olarak alıyoruz.

Sezgisel olarak, Adım 3 ve Adım 4'ün herhangi bir etkisinin birbirini iptal edeceğinden, herhangi bir kâr elde edilmemesi gerektiği düşünülebilir.
Özellikle, Adım 3'te saldırgan, takas edilen LP token'ının (yani saddleUSD) ölçeklendirilerek küçültülmemesi nedeniyle daha fazla saddleUSD takas edebilir.
Ancak Adım 4'te saldırgan, savunmasız swap fonksiyonu fiyatı hesaplamadan önce gelen saddleUSD miktarını ölçeklendirerek büyütmediğinden kaçınılmaz olarak DAHA AZ sUSD takas edecektir.
Bununla birlikte, yukarıdaki şekilde gösterildiği gibi, saldırgan Adım 3 ve Adım 4'teki takas çifti aracılığıyla 2.059.771 sUSD kâr elde etti. Kârın nedenini anlamak için fiyatlandırma mekanizmasına derinlemesine dalmamız ve saldırı sürecini anlamak için kapsamlı bir araştırma yapmamız gerekmektedir.
0x4.1 Fiyatlandırma Mekanizması
Saddle Finance'in MetaPool'u, Curve'ün fiyatlandırma formülünü miras alır:

Fonksiyonun grafiği (n iki olduğunda) aşağıdaki şekilde mavi eğri olarak gösterilmiştir. (Formülün tasarımı Curve StableSwap Teknik Raporunda bulunabilir.)

İşte soru şu: MetaPool, bu formülü kullanarak her takas için fiyatı nasıl hesaplar?
n'nin 2 olduğunu ve bir kullanıcının dx0 token0 kullanarak dx1 token1 takas ettiğini varsayalım.
dx1 için hesaplama sürecini simüle edebiliriz.
Her takasta A bir sabit olarak ele alınabilir,
ve D, fiyat eğrisini etkileyebilecek tek değişkendir. Aslında
D, havuz tarafından tahsil edilen ücretlerin birikmesiyle artar.
Özellikle, hesaplama süreci aşağıdaki üç adımda özetlenebilir:
- Adım I: Mevcut
D'yi hesaplamak için havuzun mevcut rezervlerini (x0 ve x1) formüle koyun; bu, mevcut fiyat eğrisini belirler. - Adım II: x0'ı dx0 kadar artırın ve yeni x1'i hesaplamak için mevcut
Dve x0'ı formüle koyun. - Adım III: Ardından dx1, yeni x1 ile eski x1 arasındaki farktır.
token0 bir temel havuzun LP token'ı ise, Adım II şu hale gelir:

Burada baseVirtualPrice/1e18, saldırı sırasında yaklaşık 1,0033'tür. Alternatif olarak, token bir temel havuzun LP token'ı ise, Adım III şu hale gelir:

D'nin fiyat eğrisini nasıl etkilediğini anlamak için bir örnek daha kullanıyoruz.
Bir kullanıcının önce dx0 token0'ı dx1 token1 ile takas ettiğini, ardından dx1 token1'i dx0' token0 ile takas ettiğini varsayalım.

Yukarıdaki şekilde gösterildiği gibi, ② adımı ilk takas için ücret tahsil ettiğinden D, fiyat eğrisini yukarı kaydırmak için artar (siyah eğriden mavi eğriye).
Ayrıca şekil, dx0'ın neden dx0'dan küçük olduğunun nedenini açıkça ortaya koymaktadır.
0x4.2 Saldırı Analizi
Kârın nedenini analiz etmek için, savunmasız ve düzeltilmiş MetaSwapUtils kütüphanelerini yerel olarak dağıttık ve saldırıyı simüle etmek için kurban havuzun o anki durumunu kullandık.
Ayrıca bu simülasyon sırasında saldırı sürecini anlamaya yardımcı olacak birkaç değer de kaydettik: A 10.000, x_sUSD 8.130.463, x_saddleUSD 9.688.608
ve o anki D 17.818.392'dir.

Yukarıdaki şekil, kârlı takas çiftinin sürecini açıklamaktadır:
- Takas-I: 14.800.272 sUSD'yi 9.657.586 saddleUSD ile takas edin
- Takas-II: 9.657.586 saddleUSD'yi 16.860.043 sUSD ile takas edin
Özellikle, Takas-I aşağıdaki iki adıma bölünebilir:
- ①: 14.800.272 sUSD'yi 9.625.654 saddleUSD ile takas edin. Şimdi
D, (tahsil edilen ücretler nedeniyle) 17.931.435 olarak artar. - ②: Savunmasız MetaPool, takas edilen saddleUSD miktarını ölçeklendirerek küçültmediğinden havuz 31.932 saddleUSD kaybeder. Bu kayıplar
D'yi 15.736.195'e düşürür, bu da fiyat eğrisini aşağı kaydırır (siyah eğriden gri eğriye).
Benzer şekilde, Takas-II de iki adıma bölünebilir:
- ③: Fiyat eğrisi aşağı kaydırıldığından, aynı 9.625.654 saddleUSD, maliyet olan 14.800.272 sUSD'nin çok üzerinde 16.891.906 sUSD takas edebilir.
- ④: Savunmasız MetaPool, fiyatı hesaplamadan önce gelen saddleUSD miktarını ölçeklendirerek büyütmediğinden MetaPool'da 31.863 sUSD kalır ve bu durum fiyat eğrisini yukarı kaydırır (gri eğriden mavi eğriye). Bununla birlikte, takas çifti yine de 2.059.771 sUSD kâr sağlar.
Açıkça, yukarıdaki analiz, saldırganın yeni saldırı yöntemini kullanarak neden kâr elde edebildiğini açıkça ortaya koymaktadır. Ayrıca, Takas-II'deki MetaPool'da kalan sUSD nedeniyle orijinal saldırı yönteminin yenisinden daha verimli göründüğü de anlaşılmaktadır. Elbette saldırgan havuzu boşaltmak için birden fazla saldırı başlatabilir; bu durum pratikte de gözlemlenmiştir.
0x5. Çıkarımlar
Araştırma, iki olayda kârların temel nedeninin aynı olduğunu göstermektedir. Özellikle, ilk takas (LP token için yapılan takas), savunmasız MetaPool'un D değerini düşürerek fiyat eğrisini aşağı kaydırır. Bu kayma, sonraki fiyatlandırmayı büyük ölçüde etkiler ve sonraki kârın ana nedenidir.
BlockSec Hakkında
BlockSec, 2021 yılında küresel alanda tanınan güvenlik uzmanlarından oluşan bir grup tarafından kurulmuş öncü bir blok zinciri güvenlik şirketidir. Şirket, kitlesel benimsemeyi kolaylaştırmak amacıyla gelişmekte olan Web3 dünyasının güvenliğini ve kullanılabilirliğini artırmayı taahhüt etmektedir. Bu amaçla BlockSec, akıllı sözleşme ve EVM zinciri güvenlik denetim hizmetleri, güvenlik geliştirme ve tehditleri proaktif olarak engellemeye yönelik Phalcon platformu, fon takibi ve araştırması için MetaSleuth platformu ve kripto dünyasında verimli gezinen Web3 geliştiricileri için MetaDock eklentisi sunmaktadır.
Bugüne kadar şirket, MetaMask, Uniswap Foundation, Compound, Forta ve PancakeSwap gibi 300'den fazla saygın müşteriye hizmet vermiş; Matrix Partners, Vitalbridge Capital ve Fenbushi Capital gibi önde gelen yatırımcılardan iki finansman turundan on milyonlarca ABD doları almıştır.
Resmi web sitesi: https://blocksec.com/
Resmi Twitter hesabı: https://twitter.com/BlockSecTeam



