Raporlama dönemi boyunca (2026/08/22 - 2026/08/30), toplam tahmini kaybı yaklaşık 22,7 milyon dolar olan 5 güvenlik olayı gözlemledik.
| Tarih | Olay | Tür | Tahmini Kayıp |
|---|---|---|---|
| 2026/08/20* | The Cosmos EVM Exploit Series (MANTRA, TAC, KiiChain, +3) | Aritmetik Underflow/Overflow | ~5,7M$* |
| 2026/08/27 | Moonwell | Fiyat Manipülasyonu | ~9,1M$ |
| 2026/08/28 | Ajna | Hatalı İş Mantığı | ~775K$ |
| 2026/08/28 | Rain Card Contract Exploit Series (Avici, Tria ve diğerleri) | İmza Doğrulama Atlatması | ~1,1M$† |
| 2026/08/30 | Tectonic | Fiyat Manipülasyonu | ~6M$‡ |
*Cosmos EVM serisi 08/20 tarihinde (MANTRA) başladı; bu, bu haftanın raporlama döneminden öncedir ve geçen haftaki raporda ele alınmamıştı; eksiksizlik açısından burada yer verilmiştir. ~5,7M$ tutarı, saldırganların etkilenen altı zincirde 19 Ağustos fiyatlarıyla elde ettiği miktardır (yaklaşık 2,87M'ı ise o zamandan beri dondurulmuş merkezi borsalar üzerinden), resmi Cosmos olay sonrası raporuna göre. Token miktarının bilindiği durumlarda nominal çekimler daha büyüktü (TAC ~3B TAC, ~7,5M; KiiChain 148,3M KII), ancak tokenlerin çoğu satılmadı, donduruldu veya zincir üzerinde geri kazanılabilir durumda kaldı.
†~1,1M$ tutarı, paylaşılan kontrat tarafından açığa çıkan Rain destekli programlar genelinde tahmini toplam tutardır; Avici ve Tria en büyük iki program olup, sırasıyla ~500.859$ (1.685 kullanıcı) ve ~431.945$ (636 kullanıcı) açıklamıştır.
‡~6M$ tutarı, geri alma (rollback) öncesinde Ethereum'a köprülenen gerçekleşmiş kayıptır. Toplam çekilen miktarın tahminleri, ~74M'a (brüt piyasa çıkışı) kadar değişmektedir; büyük kısmı Cronos'ta kaldı ve doğrulayıcılar zinciri exploit öncesi duruma geri aldığında silindi. Ne Tectonic ne de Cronos nihai bir kayıp rakamını doğrulamıştır.
Web3 İçin En İyi Güvenlik Denetçisi
Lansmandan önce tasarımı, kodu ve iş mantığını doğrulayın
Haftanın Öne Çıkanı: The Cosmos EVM Exploit Series (TAC Chain Üzerinde İzlendi)
Bu seri, paylaşılan altyapı açıklaması hakkında ortaya koyduğu unsurlar nedeniyle seçilmiştir: hata, ciddi bir güvenlik tehdidi olarak değerlendirilmediği için düzeltmesi, koordineli özel dağıtım yerine sessiz bir kamuya açık yama olarak yayınlandı ve üçüncü taraf bir fork daha sonra istismar yolunu açıkça tarif ederek, modülü hâlâ çalıştıran her yamasız zinciri açığa çıkardı.
2026/08/20 ile 08/25 tarihleri arasında, saldırganlar altı Cosmos EVM zincirinde paylaşılan cosmos/evm modülündeki iki güvenlik açığını birleştiren tek bir istismar zinciri çalıştırdı. Her iki hata da EVM durumunu Cosmos x/bank defteriyle uzlaştıran kodda yer alıyordu: bir bakiye underflow'u ve buna karşılık gelen bir overflow, tek bir arz-nötr işlem içinde zincirlenmiş halde.
Resmi Cosmos olay sonrası raporuna göre, hata Nisan ayında ödül (bounty) programı aracılığıyla bildirildi ve başlangıçta üretim fonlarını tehdit etmediği yönünde yanlış değerlendirildi, bu yüzden sessiz kamuya açık yama sürecinden geçti ve 08/19 tarihinde v0.6.2 ve v0.7.2 sürümlerinde yayınlandı. 08/20'de üçüncü taraf bir fork istismar yolunu kamuya açık şekilde tarif etti ve ilk çekimler saatler sonra başladı; önce MANTRA (08/20), ardından TAC ve KiiChain (08/22) vuruldu [1][2]. Altı zincirin tamamında saldırganlar, 19 Ağustos fiyatlarıyla yaklaşık 5,7M$ elde etti (yaklaşık 2,87M'ı o zamandan beri dondurulmuş merkezi borsalarda) [1].
Bu rapor, ayrıntılı bir çalışılmış örnek olarak TAC Chain'i analiz etmektedir; bu, seride en ağır vurulan zincirdi ve stake havuzunda nominal olarak ~7,5M$'lık bir kayıp yaşandı [3].
Arka Plan
TAC Chain hem Cosmos SDK'yı hem de EVM'yi çalıştırır. Bir tac1... adresi ve bir 0x... adresi aynı temel 20 baytı paylaşır, bu nedenle tek bir adres önce bir Cosmos vesting hesabı olarak oluşturulabilir ve daha sonra ona bir EVM kontratı dağıtılabilir. Bunlar iki ayrı hesap değildir: aynı adres, hem vesting durumunu hem de kontrat kodunu aynı anda taşır. İkisi yan yana çalışır ve TAC, staking gibi yerel Cosmos eylemlerini, sabit adreslerdeki önceden derlenmiş (precompiled) kontratlar aracılığıyla EVM çağıranlara sunar, böylece bir EVM kontratı bunları diğer herhangi bir çağrı gibi çağırabilir.
Bir vesting hesabının Bank toplam bakiyesi kilitli tokenleri de içerir. Kilitli kısım, hak edilmeden (vest olmadan) önce transfer edilemez, harcanabilir bakiye ise toplamdan kilitli miktar çıkarıldıktan sonra kalan kısımdır. EVM bir hesabı yüklediğinde, StateDB bakiyesini harcanabilir bakiyeden başlatır ve yürütme sırasındaki kontrat transferleri bu bakiye üzerinde işlem yapar.


Bir işlemin sonunda, StateDB'deki bakiye değişiklikleri, yetkili defter olan x/bank'a geri yerleştirilir ve yalnızca orada yerleşen miktar gerçek, transfer edilebilir TAC'tir. TAC, bir EVM bakiyesini doğrudan x/bank'a yazan v0.7.x sürüm hattını çalıştırır, ancak bunu yalnızca değer bir uint256'dan int256'ya dönüşümden sağ çıkarsa yapar, dolayısıyla 2^256'ya yakın bir bakiye hiçbir şekilde yerleşemez.
Kilitli tokenler transfer edilemez, ancak yine de staking için delege edilebilir. Delegasyon, kilitli tokenleri de içeren Bank toplam bakiyesini kontrol eder ve ardından DelegatedVesting aracılığıyla vesting kısıtlamasını korur. total=1 olan tamamen kilitli bir hesap için, bu birimi delege etmek Bank toplam bakiyesini 0'a düşürür ve DelegatedVesting'i günceller, harcanabilir bakiye ise öncesinde ve sonrasında doğru şekilde 0 olarak kalır.
Güvenlik Açığı Analizi
Hatalı bileşen, her durum değiştirici (stateful) staking precompile çağrısında çalışan, paylaşılan cosmos/evm işleyicisindeki bakiye senkronizasyonudur; bu, 0x0000...0800 adresindeki staking precompile aracılığıyla açığa çıkar ve [4]'te uygulanır. EVM bakiyelerini kontrolsüz uint256 aritmetiği ile Cosmos defteriyle uzlaştırır ve bu, iki tamamlayıcı kusuru açığa çıkarır: staking geri-yazma (write-back) yolunda bir bakiye underflow'u ve normal toplama yolunda buna karşılık gelen bir overflow. Hiçbiri tek başına tehlikeli değildir; risk, bunların paylaşılan bir aritmetik yol üzerindeki birleşiminden gelir.
İlk kusur, bakiye geri-yazımında (write-back) bir underflow'dur. Durum değiştirici bir staking precompile çağrısı yürütüldüğünde, yerel Cosmos eylemi bir BeforeBalanceChange ile bir AfterBalanceChange kancası (hook) arasında çalışır ve AfterBalanceChange, yerel bakiye değişikliğini EVM StateDB'sine geri yansıtmaktan sorumludur.


Delegasyon, Bank toplam bakiyesine karşı doğrulama yapar, bu nedenle tamamen kilitli bir hesap, harcanabilir bakiyesi 0 kalırken delegasyon kontrolünden geçebilir. Yerel delegasyon, delege edilen miktarı Bank toplam bakiyesinden düşer ve bir coin_spent olayı yayınlar. Kusur, AfterBalanceChange'in bu olayı nasıl tükettiğindedir: hesabın mevcut harcanabilir bakiyesini yeniden yükleyip atamak yerine, coin_spent miktarını stateDB.SubBalance(spender, amount) olarak yeniden oynatır ve bunu mevcut EVM bakiyesinden düşer.

SubBalance, çıkarma işlemini kontrolsüz uint256 aritmetiğiyle gerçekleştirdiği için, EVM bakiyesi olay miktarından küçük olan herhangi bir hesap underflow'a uğrar. EVM bakiyesi 0 olan ve coin_spent miktarı 1 olan bir hesap için, 0 - 1 sarılarak MAX_UINT256 olur.

İkinci kusur, toplama yolunda buna karşılık gelen bir overflow'dur. Her bakiye transferi, gönderende SubBalance ve alıcıda AddBalance'ı aynı StateDB üzerinden çalıştırır, dolayısıyla her iki yön de tek bir aritmetik yolu paylaşır.

Her ikisi de aynı stateObject ilkellerine (primitives) çözümlenir; burada AddBalance ve SubBalance, aralık kontrolü olmaksızın new(uint256.Int).Add(s.Balance(), amount) ve .Sub(s.Balance(), amount) hesaplar. Tıpkı çıkarmanın 0'ın altına underflow olması gibi, yeterince büyük bir toplama da MAX_UINT256'ın üzerine overflow olur ve tekrar aşağı sarılır.

Bu iki kusur birbirini tamamlar. Tek başına underflow, hareketsiz bir MAX_UINT256 bakiyesi üretir, çünkü 2^256'ya yakın bir değer, x/bank'a yerleşimin gerektirdiği uint256'dan int256'ya dönüşümden sağ çıkamaz. Kontrolsüz toplama bunun tamamlayıcısıdır: bu büyüklükte aşırı bir bakiyeyi bu yerleşim tavanının altına geri getirebilecek tek yoldur.
Saldırı Analizi
Aşağıdaki analiz, 0xae4e9b...da46fc işlemine dayanmaktadır.
-
Adım 1: 0x4da591...df1af7 işleminde saldırgan,
0x5711...c978saldırı kontratı adresinin, kontrat dağıtılmadan önce hesaplanabilmesi için birCREATE2fabrikası dağıttı. -
Adım 2: 95F43742...6A885BA işleminde saldırgan, o gelecekteki kontrat adresinde bir temel birimi (
1utac) transfer edip kilitlemek içinMsgCreateVestingAccount'ı kullandı; bu, o adrese, harcanabilir bakiyesi0kalırken delegasyon kontrolünden geçebilecek bir Bank toplam bakiyesi kazandırdı.

- Adım 3: 0x2400f8...c57c81 işleminde saldırgan, saldırı kontratını aynı
0x5711...c978adresine dağıtmak içinCREATE2kullandı; bu, adresi hem bir Cosmos vesting hesabı hem de bir EVM kontratı yaptı, böylece harici bir hesap gaz ücretini öderken kontrat adresispendable=0olan delegatör olarak kaldı.

-
Adım 4: Saldırı kontratı, staking precompile aracılığıyla kilitli temel birimi delege etti. Staking akışı, delegasyonu Bank toplam bakiyesine karşı kabul etti ve ardından bakiye geri-yazımı, kontratın EVM bakiyesini
MAX_UINT256'a sarmaladı. -
Adım 5: Sarmalanmış
MAX_UINT256bakiyesi olduğu haliyle Cosmos defterine geri yerleşemezdi, bu yüzden saldırı kontratı önce bunu yerleşebilir bir değere indirdi. Bakiyesinin neredeyse tamamını, zincirin en büyük hesabı ve tüm stake edilmiş TAC'yi tutan hesap olanbonded_tokens_pool'a gönderdi; miktarı, havuzun bakiyesinin toplama sırasında overflow olup0'a sarılacağı şekilde seçti. Bu miktar, saldırı kontratının kendiMAX_UINT256'sından düşüldüğü için, kontrat, yeni bir arz oluşturulmaksızın tam olarak havuzun eski bakiyesini elinde bırakmış oldu. Havuzu sıfırlamak, bu overflow'un sağlayabileceği en fazla miktar olan tüm bakiyesini alır; saldırganın öncelikle zincirin en büyük hesabını hedef almasının nedeni de budur. -
Adım 6: Ardından saldırı kontratı, bu bakiyeyi, 2.985.651.403,40 TAC'yi, saldırganın adresine transfer etti.

İşlem düzeyindeki analizimiz, iki zincirlenmiş güvenlik açığını tarif eden resmi Cosmos olay sonrası raporuyla eşleşmektedir: yukarıdaki underflow anormal bakiyeyi üretir ve Saldırı Analizi Adım 5'teki overflow bunu havuzun gerçek fonlarına dönüştürür [1]. O resmi rapordan önce yayınlanan daha erken bir KiiChain olay sonrası raporu, en az üç üst-akış (upstream) kusurunun söz konusu olduğunu ve yalnızca underflow'un yamalandığını öne sürmüştür [2]. Bağımsız basın haberleri, kaç üst-akış kusurunun hâlâ mevcut olduğuna dair aynı anlaşmazlığı özetlemiştir [5].
Sonuç
The Cosmos EVM Exploit Series'in temel nedeni, EVM ve Cosmos katmanlarının aynı bakiyeyi nasıl hesapladığındaki tutarsızlık ve hiçbir zaman sınır kontrolüne tabi tutulmamış aritmetikti. İki çalışma zamanı tek bir defteri paylaştığında, her bir bireysel hesaba kadar bakiye semantiği konusunda hemfikir olmalıdırlar ve her bakiye değişikliği overflow ve underflow açısından kontrol edilmelidir. Kusur, herhangi bir tek zincirin kodunda değil paylaşılan bir modülde yaşadığı için, tek bir kusur onu çalıştıran her zinciri açığa çıkardı; tek bir hatayı çok zincirli bir olaya dönüştüren de budur. Kodun ötesinde, bu olay önem derecesi değerlendirmesi açısından bir derstir. Güvenlik açığı başlangıçta üretim fonlarını tehdit etmediği şeklinde değerlendirildi, bu yüzden düzeltmesi sessiz bir kamuya açık yama olarak yayınlandı; bu değerlendirme düzeltildiğinde yama zaten kamuya açıktı ve üçüncü bir tarafın istismar yolunu açıklaması, bu yanlış değerlendirmeyi altı istismar edilmiş zincire dönüştürdü. Gerçek fonları hareket ettirebilen paylaşılan altyapı hatası, en baştan itibaren, herkesin çözebileceği sessiz bir kamuya açık yama değil, özel ve koordineli dağıtım gerektirir.
Phalcon Explorer ile Başlayın
Akıllıca Hareket Etmek İçin İşlemlerin Derinliklerine İnin
Şimdi ücretsiz deneyinBu Haftaki Diğer Olaylar
Moonwell
2026/08/27 tarihinde, Base üzerindeki Moonwell, teminat muhasebesi şişirmesini, Core Market'inde listelenen düşük likiditeli bir varlık olan MAMO'nun oracle fiyat manipülasyonuyla birleştirerek yaklaşık 9,1M$ değerinde istismar edildi. MAMO fiyatını yükseltmenin ötesinde, saldırgan, hisse (share) basmadan MAMO'yu doğrudan mMAMO piyasa kontratına transfer etti; bu, her hissenin destek oranını yükseltti ve fiyat hareketinin üzerine teminat değerini şişirdi. İki kat şişirilmiş teminata karşı saldırgan, cbBTC, WETH, USDC ve wstETH genelinde brüt olarak yaklaşık 11,03M$ borç aldı ve tasfiyelerden (liquidations) sonra yaklaşık 9,13M$'lık kalan yükümlülük bıraktı [6][7].
Güvenlik Açığı Analizi
Moonwell'in Core Market'i, Compound v2 kodu üzerinde çalışır; burada bir piyasa hissesinin (mMAMO) değeri (cash + totalBorrows - totalReserves) / totalSupply'dir. Burada iki zayıflık birleşir. Birincisi, MAMO arz üst sınırı yalnızca resmi mint yolunu kontrol eder, bu nedenle MAMO'nun mMAMO kontratına doğrudan transferi, hisse basmadan piyasanın nakit (cash) miktarına eklenir; bu, hesaplanan döviz kurunu (exchangeRateStored()) yükseltir ve üst sınırı tamamen atlarken mevcut her hissenin teminat değerini yükseltir. İkincisi, MAMO, düşük likiditesine rağmen %50 teminat faktörüyle teminat olarak listelenmişti, bu nedenle oracle fiyatı mütevazı bir sermayeyle hareket ettirilebilir. Teminat değeri, hisse çarpı döviz kuru çarpı oracle fiyatı olarak hesaplandığından, hem döviz kuru hem de fiyat manipüle edilebilir yüzeylerdir ve ikisini birlikte şişirmek, çok daha likit varlıklara karşı borçlanma gücünü katlar.
Saldırı Analizi
Aşağıdaki analiz, 0x09687d...395593e işlemine dayanmaktadır. Operasyon yaklaşık 1,947M$ (799 ETH, USDC'ye dönüştürülerek Base'e köprülendi) ile başlatıldı; borç alınan varlıklar yeniden döngüye sokulduğunda brüt MAMO satın alma hacmi yaklaşık 7,50M$'a ulaştı.
-
Adım 1: Saldırgan,
mMAMObasmak için resmi olarakMAMOtedarik etti, ardındanMintolayı yayınlamayan iki işlemde53.393.290 MAMO'yu doğrudanmMAMOkontratına transfer etti; bu, piyasanın hesaplanan döviz kurunu yaklaşık3,68 katyükseltti ve saldırganın az önce bastığımMAMOhisselerini diğer tüm sahiplerinkiyle birlikte yeniden değerledi. -
Adım 2: Saldırgan, likiditenin düşük olduğu bir sırada DEX havuzları genelinde
MAMOsatın aldı;MAMO/USDfeed'ini yaklaşık0,0106$'dan yaklaşık0,43$'a çıkardı.

- Adım 3: Hem döviz kuru hem de fiyat şişirilmiş halde, saldırgan
cbBTC,WETH,USDCvewstETHgenelinde (brüt yaklaşık 11,03M$) 18 borçlanma tamamladı, ardından geliri dönüştürüp konsolide etti; yaklaşık8,729M USDC'yi CCTP aracılığıyla Ethereum'a köprüledi ve yaklaşık8,728M DAI'ye dönüştürdü.
Sonuç
Temel neden, Moonwell'in düşük likiditeli bir teminat varlığını aynı anda bağımsız olarak manipüle edilebilir iki yüzeyde değerlemesiydi: düşük likiditenin saldırganın mütevazı bir sermayeyle hareket ettirmesine izin verdiği oracle fiyatı ve arz üst sınırının yalnızca resmi mint yolunu koruduğu için altta yatan varlığın doğrudan transferinin şişirdiği makbuz-token döviz kuru. Teminat değeri ikisini çarptığından, ikisini birlikte şişirmek borçlanma gücünü çok daha likit varlıklara karşı katladı. Bir borç verme piyasası, hem teminatın fiyatını hem de hisse muhasebesini manipüle edilebilir olarak ele almalıdır: istenmeyen transferleri döviz kuru hesaplamasından hariç tutmalı ve muhafazakâr teminat faktörlerini, likidite açısından duyarlı fiyatlandırma ile düşük likiditeli varlıklar için sıkı arz ve borç üst sınırlarıyla eşleştirmelidir.
Ajna
2026/08/28 tarihinde, Ajna, tasfiye yolundaki bir iş mantığı kusuru aracılığıyla yedi Ethereum havuzu genelinde yaklaşık 775K$ değerinde istismar edildi. Ajna, harici bir oracle kullanmayan bir borç verme protokolüdür; pozisyonları, havuz likiditesinden türetilen LUP'a (En Düşük Kullanılan Fiyat) göre fiyatlandırır. Saldırgan önce ciddi şekilde ödeme gücü olmayan bir pozisyon oluşturmak için LUP'ı manipüle etti, ardından protokolün, kontrol ettiği bir pozisyonu, protokolün hâlâ piyasanın çok üzerinde tuttuğu bir Hollanda tipi açık artırma fiyatından tasfiye etmesini sağladı; böylece havuz mevduat talepleri, borcu geri ödemek için kotasyon token cinsinden nominal değerlerinden tüketilirken, saldırgan karşılığında gerçek teminat aldı [8].
Arka Plan
Ajna, herkesin bir Uniswap havuzuna benzer şekilde tedarik ve borçlanma için eşleştirilmiş tokenlerden oluşan bir havuz oluşturabildiği izinsiz (permissionless) bir protokoldür. Her havuz, Uniswap V3'teki fiyat aralıklarına (tick) benzer bucketlara bölünür; burada her tick, teminat birimi başına sabit bir kotasyon token miktarını temsil eder. Borç verenler tercih ettikleri kredi-değer oranına göre bir bucket seçer ve orada likidite sağlar, karşılığında o bucket'ın mevduatları üzerinde bir talep hakkı olan LP alırlar. Harici bir oracle olmadığından, LUP doğrudan bucket mevduat dağılımından ve toplam borçtan türetilir.
Bir pozisyonun eşik fiyatı (borcunun teminatına bölümü) LUP'ın üzerine çıktığında, o pozisyon tasfiye edilebilir hale gelir. Herkes bir bono göndererek onu tasfiyeye kick edebilir, bu da bir Hollanda tipi açık artırma açar. Açık artırma fiyatı spot piyasaya bağlı değildir: bir referans fiyatın 32 katından başlar ve her saat yarıya iner ve çürümeye başlamadan önce ilk saat boyunca (bir iyileşme dönemi) sabit tutulur.
Açık artırmaya çıkarılan teminat iki şekilde alınabilir. Bir çağıran, mevcut açık artırma fiyatından kotasyon token ödeyerek teminatı take() edebilir veya seçilen bir bucket'ın kotasyon mevduatlarını kullanarak açık artırmaya çıkarılan teminatı satın alan ve borçluyu geri ödeyen bucketTake()'i çağırabilir. Bir bucketTake()'de, teminat o bucket'a alacak kaydedilir, dolayısıyla onu edinenler o bucket'ın borç verenleridir; bir arbitraj bucket take için, çağırana ayrıca, tasfiyeyi tetiklemesi için teşvik olarak bucket fiyatı ile açık artırma fiyatı arasındaki fark üzerinden LP ödülleri (o bucket üzerinde bir talep hakkı) ödenir. Tasarım, bir alıcının (taker) yalnızca açık artırma fiyatı teminatın değerine eşit veya altına düştüğünde devreye girdiğini varsayar: oracle olmadan, bu azalan açık artırma, Ajna'nın adil bir fiyatı keşfetme yoludur ve bir bucket'ın borç verenleri, teminatı kendi bucket fiyatlarının altında edinerek kâr eder. Açık artırmanın kendisi yalnızca borçlunun borcu ödendiğinde veya kredi tekrar teminatlandırıldığında sona erer; ayrı bir yerleştirme (settlement) yolu, 72 saatlik bir ödeme süresi sonrasında veya daha önce hiç teminat kalmadığında bir açık artırmayı çözüme kavuşturur, kalan kötü borcu (bad debt) emer ve kalan teminatı borçluya iade eder.
Bu mekanizmanın üç uygulama ayrıntısı, bir take'in ürettiği rakamları belirler. Birincisi, açık artırma fiyatı piyasadan türetilmez; 32 * max(kickMomp, neutralPrice) * 2^(-max(elapsedHours - 1, 0)) olarak çürür, dolayısıyla ilk saatlik iyileşme dönemi boyunca sabit kalır ve ancak ondan sonra düşmeye başlar; o dönemden kısa süre sonra referans fiyatının yaklaşık 32 katına yakın kalır.

İkincisi, bir kick yalnızca borçlu ceza öncesi (pre-penalty) borcuyla zaten yetersiz teminatlandırılmışsa kabul edilir: _kick(), üç aylık faiz cezasını eklemeden önce _isCollateralized() kontrolünü çalıştırır ve BorrowerOk() ile geri döner (revert), böylece bu ceza, kaydedilen kick sonrası borcu, pozisyonun kabul edilmesine yardımcı olmadan yükseltir.

Üçüncüsü, bir açık artırmadaki ilk take, take için geri ödeme ve teminat miktarları hesaplanmadan önce borçlunun borcuna %7'lik bir ceza ekler, dolayısıyla tek bir bucketTake()'in borcu kendi başına kapatması gerekmez.

Güvenlik Açığı Analizi
Hatalı kontrat, Ajna havuzudur (0xad24...178e); burada tarif edilen tasfiye mantığı bu doğrulanmış kaynaktan alınmıştır. bucketTake() içinde, protokol bir bucket'ın mevduat taleplerini kotasyon token cinsinden nominal değerlerinde kullanarak bir açık artırma borçlusunun borcunu geri öder ve bir arbitraj bucket take'de, alıcıya bucket fiyatı ile açık artırma fiyatı arasındaki fark temelinde LP ödülleri öder.
Bu mevduat taleplerinin gerçek geri kazanılabilir değerini veya açık artırma fiyatının ekonomik olarak makul olup olmadığını asla kontrol etmez; sadece taleplerin daha sonra nominal değerinden geri alınabileceğini varsayar. Dayandığı iki fiyat bağımsız olarak hesaplanır ve hiçbiri diğerine karşı doğrulanmaz: LUP, bucket mevduat dağılımını ve protokolün toplam borcunu takip ederken, açık artırma fiyatı yalnızca kick anında sabitlenen bir referans fiyattan geçen zamana göre çürür. Bir talebin zincir üzerindeki nominal değeri bu nedenle gerçekte geri kazanabileceğinden farklılaşabilir ve bucketTake() yine de borcu bu nominal değere göre yerleştirir (settle).
Dahili olarak, bucketTake(), _takeBucket() üzerinden _rewardBucketTake()'e yönlenir; burada bir arbitraj take'de, alıcının LP ödülü, alınan teminat çarpı bucket fiyatı ile açık artırma fiyatı arasındaki fark olarak hesaplanır.

Saldırı Analizi
Aşağıdaki analiz, etkilenen yedi havuzdan biri olan cbETH havuzunun zincir üzerindeki analizine dayanmaktadır; 0x8a8793...016e64 ve 0x12dfde...14e4f5 işlemleri kullanılmıştır.
- Adım 1: Kurulum işleminde saldırgan,
2000bucket indeksine, piyasanın çok üzerinde bir fiyat olan yaklaşık 49,343WETHkotasyon likiditesi ekledi. Bu şişirilmiş bucket'ın desteğiyle saldırgan, neredeyse teminatsız bir pozisyon açtı; yaklaşık 0,001cbETHteminat vererek yaklaşık 49,319WETHborçlandı. Bu pozisyon neredeyse hiç teminat tutmaz, dolayısıyla ödül değildir; iki kurulum amacına hizmet eder. Birincisi, ödeme gücü olmayan bir borç olarak, piyasa normale döndüğündeLUP'ı aşağı çeker. İkincisi,2000bucket'ına yatırılan 49,343WETH'in neredeyse tamamı artık geri borçlanıldığından, geriye yalnızca ufak (dust) bir miktar kaldığından,2000bucket'ı, nominal değeri (yaklaşık 49,343WETH) gerçekte geri kazanabileceğinden çok daha fazla olan bir mevduat talebiyle baş başa kalır; o zarar görmüş talep, saldırganın daha sonra Adım 4'te nominal değerinden harcadığı cephanedir.

-
Adım 2: Aynı kurulum işleminde saldırgan, normal fiyat seviyesinde bir borçlu pozisyonu açmak için ikinci bir kontrollü adres olan
0x02d329...6f5f'yi kullandı; buna karşı yaklaşık 48,128cbETHteminat vererek yaklaşık 49,319WETHborçlandı. Bu, piyasa fiyatını normal bir aralığa döndürdü; ilk pozisyonu ciddi şekilde ödeme gücünden yoksun bırakırken ikinci pozisyon sağlık eşiğinin hemen etrafında kaldı. Gerçek teminatı tutan bu ikinci pozisyon, saldırganın gerçekte boşaltmayı hedeflediği pozisyondur; ödeme gücü olmayan ilk pozisyon yalnızcaLUP'ı hareket ettiren kaldıraçtır. -
Adım 3: Saldırgan daha sonra ödeme gücü olmayan ilki yerine ikinci pozisyonu (yani
0x02d329...6f5ftarafından açılanı) açık artırmayakicketti. Bir kick yalnızca, pozisyon güncelLUP'a karşı ceza öncesi (pre-penalty) borcuyla zaten yetersiz teminatlandırılmışsa kabul edilir ve ödeme gücü olmayan ilk pozisyon artıkLUP'ı, ikinci pozisyonun tahakkuk eden borcunun bu barı karşılayacağı kadar düşürmüştü. Protokol, ancak uygunluk kontrolünden sonra üç aylık faiz kick cezasını ekler; kaydedilen kick sonrası borcun yaklaşık 49,362WETH'e ulaşmasının nedeni budur. Kick, pozisyonun Hollanda tipi açık artırmasını açtı.

- Adım 4: Saldırgan, bir saatlik iyileşme döneminin hemen ardına kadar bekledi; bu noktada açık artırma fiyatı henüz çürümeye başlamıştı ve hâlâ referans fiyatının 32 katına yakındı.
2000bucket'ında (şimdi zarar görmüş talebi tutan aynı bucket)bucketTake()'i çağırarak, onu hâlâ yüksek, piyasanın çok üzerindeki bu fiyattan tasfiye etti. Bu, açık artırmadaki ilk take olduğundan, protokol, take'in geri ödeme ve teminat miktarlarını hesaplamadan önce borçlunun borcuna%7'lik bir ceza ekledi. Teminat açık artırma fiyatından fiyatlandığından,2000bucket'ının mevduatından yaklaşık 49,34WETH'in tüketilmesi, bu borcun yalnızca bir kısmını ödedi ve teminatın yalnızca yaklaşık 1,51cbETH'ini kaldırdı; teminatın çoğu dokunulmamış kalırken çağıran, spread üzerinden büyük bir miktarLPödülü topladı.

-
Adım 5: Saldırgan, bu
LPödülleriniremoveCollateral()aracılığıyla geri aldı; kârın bir kısmını teminat olarak çıkardı. -
Adım 6: İşlemi kapatmak için saldırgan bir Balancer flash loan aldı ve
bucketTake()'in bıraktığı kalan borcu ödemek için Ajna'nıntake()fonksiyonunu çağırdı; bu sefer gerçek kotasyon token ile, borçlunun borcu sıfıra ulaşana ve açık artırma çıkana kadar. Ardından son birrepayDebt()çağrısı, artık serbest kalan yaklaşık 46,51cbETHteminatı çekti;quoteRepaid=0ile: bunun karşılığında hiçbir kotasyon token iade edilmedi. Kazanç, havuzun pahasına geldi. Açık, kaybolmadı, yer değiştirdi: ikinci pozisyon kapatılınca, ilk pozisyonun hâlâ ödenmemiş, neredeyse desteksiz kredisi, diğer borç verenler tarafından taşınan kötü borç olarak havuzda kaldı.

Sonuç
Temel neden, Ajna'nın tasfiye yolunun, gerçek geri kazanılabilir değerini veya açık artırma fiyatının ekonomik olarak makul olup olmadığını kontrol etmeksizin bir açık artırma borçlusunun borcunu bir bucket'ın mevduat taleplerine karşı nominal değerinden yerleştirmesidir. Eksik olan bu kontrol, üretilmiş zarar görmüş bir talebin gerçek teminatı boşaltmak için nominal değerinden harcanmasına izin verdi ve açığı havuzda kötü borç olarak bıraktı. Tasfiye yolu, mevduat taleplerini nominal değer yerine gerçek geri kazanılabilir miktarlarına göre değerlemeli, bir take'i tamamlamadan önce açık artırma fiyatının ekonomik olarak makul olduğunu doğrulamalı ve bir havuzun mevcut kötü borcunun zaten zarar verdiği talepleri tüketmeye karşı korumalıdır. Etkilenen havuz kontratları değiştirilemez (immutable) ve idari bir duraklatma sunmamaktadır, dolayısıyla boşaltma başladığında onu durdurmanın bir yolu yoktu; kullanıcılar yalnızca kendi başlarına çıkış yapabildiler.
The Rain Card Contract Exploit Series (Avici Üzerinde İzlendi)
2026/08/28 tarihinde (UTC), Rain'in paylaşılan Solana kart-teminat programının eski bir sürümü, bir Ed25519 imza doğrulama atlatması aracılığıyla istismar edildi. Programın uydurma bir admin onayını kabul etmesini sağlayarak, saldırgan kullanıcı teminat hesaplarının kontrolünü ele geçirdi ve bunlarda tutulan token bakiyelerini boşalttı. Kusur, Rain destekli kart programları genelinde paylaşılan program kodunda yer aldığından, tek bir hata hepsini bir anda açığa çıkardı: istismar, toplamda tahmini ~1,1M$ boşalttı; Avici ve Tria en büyük iki program olarak, sırasıyla yaklaşık 500.859$ (1.685 kullanıcı) ve 431.945$ (636 kullanıcı) açıkladı [9].
Aşağıdaki analiz, çalışılmış örnek olarak Avici'yi kullanmaktadır.
Arka Plan
Solana'da imza kontrolleri, işlem işleme sürecinin bir parçası olarak yerel bir Ed25519 precompile tarafından yapılır: referans gösterilen bir imza geçersizse, işlemin tamamı başarısız olur. Bir iş programı bu sonucu doğrudan almaz; aynı işlemdeki diğer talimatları (Instructions sysvar aracılığıyla) inceler ve doğrulamanın geçtiğine güvenir. Bir kullanıcı Rain destekli bir kartı (Avici'de olduğu gibi) doldurduğunda, bakiye, paylaşılan Rain programı tarafından yönetilen kullanıcı başına bir teminat hesabında tutulur ve o hesabın token yetkisi programdan türetilir, dolayısıyla hesabın admini, o hesaptaki varlıkları programın transfer akışı aracılığıyla hareket ettirebilir.
Bir teminat hesabının adminini değiştirmek iki imza gerektirir. Biri protokol tarafından belirlenmiş adminden gelmelidir; diğer imzalayanın özel bir kimlik gereksinimi yoktur. Bu tasarım zincir dışı yetkilendirmeye dayanır: protokol admini admin-değiştirme mesajını imzaladıktan sonra, program bunu onaylanmış olarak kabul eder.
Bir Ed25519 doğrulama talimatı, kontrol edilecek imza sayısının tek bayt sayısı ve bir dolgu bayt ile başlar, ardından imza başına bir Ed25519SignatureOffsets yapısı gelir. Her yapı, yalnızca imzanın, genel anahtarın ve mesajın bayt ofsetlerini değil, aynı zamanda bunların her birinin okunması gereken talimat indeksini de belirtir [10]. Bu indeksler kasıtlı bir özelliktir: tek bir doğrulamanın, girdilerini işlemdeki indekslenmiş herhangi bir talimatın verisinden okumasına izin verirler, örneğin başka bir talimatın verisini kopyalamadan onun üzerindeki bir imzayı doğrulamak için. Yerel doğrulayıcı basitçe ofsetlerin ve talimat indekslerinin işaret ettiği her şeyi okur.

Güvenlik Açığı Analizi
Kusur, teminat programındadır (3zVB...yBzDuc): bu anahtarın doğrulayıcının aslında kontrol ettiği anahtar olduğunu doğrulamadan bir genel anahtara güvenir. Admin onaylayan imzalayanı kaydetmek için, incelediği Ed25519 doğrulama talimatı içindeki sabit bir konumdan bir genel anahtar okur, ardından geçen bir doğrulamanın salt varlığını, bu anahtarın sahibinin admin-değiştirme mesajını imzaladığının kanıtı olarak alır.
Hiçbir zaman doğrulamanın gerçekte nereye baktığını doğrulamaz. Bu talimat-indeksi alanları çağıran tarafından kontrol edildiğinden ve çalışma zamanı her talimatın verisini yerel doğrulayıcıya ilettiğinden, doğrulama talimatı kendi gövdesinde bir genel anahtarı tutabilirken talimat indeksleri, farklı bir genel anahtar altında ayrı kaynaklı bir mesaj üzerindeki bir imzayı doğrulamak için doğrulayıcıyı farklı bir talimata yönlendirebilir.


Böylece "admin anahtarı"nın iki okuması, ikisini birbirine bağlayan hiçbir şey olmadan var olur: program, incelediği talimatta oturan anahtara güvenirken, doğrulayıcı yalnızca indekslerin işaret ettiği her şeyi kontrol etmiştir. Admin'in anahtarı, bu anahtar altında hiçbir geçerli imza doğrulanmamış olsa bile, işlemde veri olarak mevcut olabilir. Bu ayrışma, güvenlik açığıdır ve eksik olan kontrol, doğrulayıcının gerçekte doğruladığı genel anahtarı ve mesajı, programın güvendiği aynı anahtar ve mesajla eşleştirecek bağlayıcıdır.
Saldırı Analizi
Aşağıdaki analiz, ZmpBgn...mqWL işlemine dayanmaktadır.
- Adım 1: Saldırgan, ardından
SubmitSignaturesgelen iki Ed25519 doğrulama talimatı içeren bir işlem inşa etti. Talimat0, saldırganın kendi genel anahtarını (cafa…53db) ve admin-değiştirme mesajı üzerinde gerçek bir imzayı taşıyor, işlemde gerçekten geçerli bir Ed25519 doğrulaması sağlıyordu.

-
Adım 2: Talimat
1, protokol adminin genel anahtarını (a2fc…959a) genel-anahtar yuvasına yerleştirdi ancak imza yuvasını sahte0x09baytlarıyla doldurdu, dolayısıyla bu talimat kendi verisi gerçekten doğrulansaydı başarısız olurdu. -
Adım 3: Saldırgan, talimat
1'in Ed25519 başlığını01003000000010000000700020000000olarak ayarladı. Yalnızca üç talimat-indeksi alanı yönlendirmeyi yapar ve çözüldüğünde bunların hepsi sıfırdır, dolayısıyla imza, genel anahtar ve mesaj talimat0'dan okunur (bayt ofsetleri hâlâ o talimatın verisi içinde işaret eder):num_signatures = 1, padding = 0 signature_offset = 48, signature_instruction_index = 0 public_key_offset = 16, public_key_instruction_index = 0 message_data_offset = 112, message_data_size = 32, message_instruction_index = 0Bu nedenle ikinci doğrulama talimat
0'ı yeniden okudu ve talimat1'deki geçersiz0x09yükü yerine saldırganın kendi geçerli imzasını yeniden doğruladı. -
Adım 4: Saldırgan
SubmitSignatures'ı çağırdı. Program iki başarılı Ed25519 doğrulaması gördü, ancak ikinci imzalayanı kaydederken talimat1içine gömülü protokol admin genel anahtarını okudu, dolayısıyla bu admin anahtarını onaylanmış ikinci bir imzalayan olarak kabul etti. -
Adım 5: Bu sahte onay kaydedildikten sonra, saldırgan, kurban teminat hesabının adminini saldırgan olarak ayarlamak için admin-değiştirme akışını kullandı; doğrulama atlatmasını o hesap üzerinde doğrudan kontrole dönüştürdü.

- Adım 6: Çağıranı teminat admini olarak doğruladıktan sonra, program, kendi program-türetilmiş adresini (PDA) o token hesabının yetkisi olarak kullanarak transferi çağırıp, kullanıcının kart-teminat token hesabından, transfer akışı aracılığıyla varlıkları taşıdı.

Sonuç
The Rain Card Contract Exploit Series'in temel nedeni, teminat programının yerel bir Ed25519 doğrulamasının çalıştığını doğrulaması ancak güvendiği genel anahtar ve mesajın doğrulayıcının aslında kontrol ettikleriyle aynı olduğunu asla doğrulamamasıydı. Yerel imza doğrulamasına dayanan bir program, tükettiği yetkilendirme verisini o doğrulamaya bağlamalıdır: ya girdilerini mevcut talimattan okuyan kendi kendine yeten bir Ed25519 düzeni gerektirmeli ya da referans gösterilen her talimatı çözerek doğrulanmış genel anahtarı ve mesajı, üzerinde işlem yaptığı verilerle bayt bayt karşılaştırmalıdır. Aynı kusurun, birçok Rain destekli kart programı genelinde yamalanmadan çalışıyor olması, tek bir hatayı çok programlı bir olaya dönüştüren şeydir.
Tectonic
2026/08/30 tarihinde, Cronos üzerinde Compound tarzı bir borç verme protokolü olan Tectonic, düşük likiditeli yönetişim tokeni TONIC'in %20 teminat faktörüyle teminat olarak kabul edilmesi nedeniyle istismar edildi. Saldırgan, TONIC cinsinden teminatı aynı anda iki yüzeyde şişirdi: tTONIC döviz kurunun doğrudan-transfer manipülasyonu, oracle fiyatını yukarı iten DEX satın alımlarıyla eşleştirilmiş halde. İki kat şişirilmiş teminata karşı, saldırgan birden fazla borç verme piyasası genelinde borçlandı. Yaklaşık 6,29M$ (2.592 ETH) Ethereum'a köprülendi ve gerçekleşmiş kayıp olarak durmaktadır; boşaltmanın büyük kısmı Cronos'ta kaldı ve doğrulayıcılar zinciri exploit öncesi bir duruma geri aldığında silindi. Ne Tectonic ne de Cronos nihai bir kayıp rakamını doğrulamıştır [11].
Güvenlik Açığı Analizi
Temel neden, düşük likiditeli bir yönetişim tokeni olan TONIC'in %20 teminat faktörüyle teminat olarak listelenmesiydi. Yönetişim rolüne rağmen TONIC, zincir üzerinde son derece düşük likiditeye sahipti, dolayısıyla değerlemesi sınırlı bir sermayeyle keskin bir şekilde hareket ettirilebilirdi. Moonwell istismarında olduğu gibi, aynı anda iki yüzey manipüle edilebilirdi: TONIC/USD oracle fiyatı ve piyasaya TONIC'in düz bir transferinin, eşleşen borcu iptal etmeden yükselttiği tTONIC makbuz-token döviz kuru [11]. Sıfırdan farklı herhangi bir teminat faktörü, bu şişirilmiş değerlemeyi çok daha likit varlıklara karşı borçlanma gücüne dönüştürdü.
Saldırı Analizi
Aşağıdaki saldırının yeniden inşası, zincir üzerindeki istihbarata ve ayrıntılı bir arşiv-düğüm (archive-node) yeniden inşasına dayanmaktadır [11][12].
-
Adım 1: Saldırgan, Tectonic'e teminat olarak yaklaşık 5M
USDCtedarik etti.TONIC/USDoracle'ı token'ı hâlâ yaklaşık1,06e-8$olarak değerlerken, kontrol edilen bir hesap yaklaşık 376,54TTONICborçlandı ve ikinci bir hesaba taşıdı. -
Adım 2: İkinci hesap normal şekilde yaklaşık 41,87T
TONICtedarik etti ve karşılığındatTONIC'i (piyasanın makbuz token'ı) aldı. -
Adım 3: Saldırgan, kalan borçlanılan
TONIC'in çoğunu, orijinalTONICborcunu ödemeden doğrudantTONICpiyasa kontratına transfer etti; bu,tTONICdöviz kurunu yükseltti ve ikinci hesabın tuttuğutTONIC'in teminat değerini yükseltti. -
Adım 4: Şişirilmiş
tTONICteminatını kullanarak, saldırgan 200.000USDCve yaklaşık 6,96MCROborçlandı, ardındanTONIC/USDC,TONIC/WCROveTONIC/VVShavuzları genelinde yaklaşık 16,23T daha fazlaTONICsatın aldı ve onu tekrar piyasaya yönlendirdi. Bu, döviz kurunu daha da yükseltti ve DEX spot fiyatını yukarı sürükledi; Tectonic'in zincir dışıTONIC/USDfeed'i, ardından hızla yükselen bir dizi kotasyonu kabul etti (12:19 UTC'de yaklaşık1,06e-8$'dan 12:49 UTC'ye kadar yaklaşık2,08e-6$'a). Bu, harici yüzeydir.

-
Adım 5: Yaklaşık 3,31M
USDCve 21,21MCRO'nun daha fazla borçlanılması, tekrar piyasaya yönlendirilen 7,68T daha fazlaTONICsatın aldı; bu, hem şişirilmiş döviz kurunu hem de çekim işleminden hemen önce manipüle edilen fiyatı güçlendirdi. -
Adım 6: Son işlemde saldırgan, birden fazla borç verme piyasası genelinde iki kat şişirilmiş teminata karşı çekim yaptı; yaklaşık 55,24M
USDC, 45,65MUSDT, 98WBTC, 1.895WETH, 16,75MCROve diğer varlıkları çıkardı. Doğrulayıcılar zinciri durdurmadan önce yaklaşık 6,29M$ Ethereum'a köprülendi (~2.592 ETH). Blok üretimi, doğrulayıcılar durumu exploit öncesi bir bloğa geri aldıktan sonra 2026/08/30 23:49 UTC'de (08/31'de duyuruldu) yeniden başladı; bu, Cronos üzerindeki bakiyeyi sildi; yalnızca köprülenen ~6,29M$ gerçekleşmiş kayıp olarak durmaktadır.
Sonuç
Bu haftanın başındaki Moonwell istismarı gibi, bu da düşük likiditeli bir token'ı teminat olarak kabul eden Compound tarzı bir piyasaya karşı düzenlenmiş bir fiyat manipülasyonu saldırısıydı; teminatın değeri aynı anda iki yüzeyde şişirildi: oracle fiyatı ve makbuz-token döviz kuru. Borç verme protokolleri, düşük likiditeli varlıkları teminat olarak listelemekten kaçınmalı, desteklenmeleri gerektiğinde sıkı arz ve borç üst sınırları uygulamalı ve düşük bir spot piyasanın oracle'ı hareket ettirememesi için zaman-ağırlıklı veya likidite açısından duyarlı fiyatlandırma kullanmalıdır. Döviz kuru yüzeyi kendi korumasına ihtiyaç duyar: bir piyasanın teminat muhasebesi, altta yatan varlığın istenmeyen transferlerini hariç tutmalıdır, böylece doğrudan bir transfer, eşleşen borç ödenmemiş kalırken makbuz-token döviz kurunu şişiremez. Anormal fiyat ve borçlanma aktivitesinin zincir üzerinde izlenmesi, değer köprülenip çıkarılmadan önceki yanıt penceresini daha da kısaltabilir.
Referanslar
- [1] Cosmos EVM GHSA-7g4w-cg88-2cq2 Olay Sonrası Raporu
- [2] KiiChain olay açıklaması
- [3] TAC Chain olay açıklaması
- [4] cosmos/evm bakiye işleyici commit'i
- [5] crypto.news: Cosmos EVM güvenlik açığı MANTRA, TAC ve KiiChain'i boşaltıyor
- [6] Moonwell istismarı hakkında Blockaid uyarısı
- [7] Moonwell: Post-Mortem, MAMO Market Incident on Base
- [8] Ajna istismarı hakkında Defimon uyarısı
- [9] crypto.news: Rain kontratı istismarı kart kullanıcılarından 1,1M$ boşaltıyor
- [10] Solana Belgeleri: Ed25519 programı
- [11] The Defiant: Cronos, Tectonic istismarından sonra zinciri geri alıyor
- [12] MASTR: Tectonic arşiv-düğüm yeniden inşası
BlockSec Hakkında
BlockSec, tam yığın (full-stack) bir blockchain güvenliği ve kripto uyumluluk sağlayıcısıdır. Müşterilerin kod denetimi (akıllı kontratlar, blockchain ve cüzdanlar dahil) gerçekleştirmelerine, saldırıları gerçek zamanlı olarak engellemelerine, olayları analiz etmelerine, yasa dışı fonları izlemelerine ve protokollerin ve platformların tüm yaşam döngüsü boyunca AML/CFT yükümlülüklerini karşılamalarına yardımcı olan ürünler ve hizmetler geliştiriyoruz.
BlockSec, saygın konferanslarda birden fazla blockchain güvenliği bildirisi yayınlamış, DeFi uygulamalarına yönelik birçok sıfırıncı gün (zero-day) saldırısını bildirmiş, 20 milyon doların üzerinde bir tutarı kurtarmak için birden fazla saldırıyı engellemiş ve milyarlarca dolarlık kripto para birimini güvence altına almıştır.
-
Resmi web sitesi: https://blocksec.com/
-
Resmi Twitter hesabı: https://twitter.com/BlockSecTeam



