Back to Blog

Haftalık Web3 Güvenlik Olayları Özeti | 9 Mart – 15 Mart 2026

March 18, 2026
22 min read

Geçen hafta boyunca (2026/03/09 - 2026/03/15) BlockSec, toplam tahmini zararı ~$1.66M olan sekiz saldırı olayını tespit etti ve analiz etti. Aşağıdaki tablo bu olayları özetlemekte olup her bir olay için ayrıntılı analizler aşağıdaki alt bölümlerde sunulmaktadır.

Tarih Olay Tür Tahmini Zarar
2026/03/09 EtherFreakers Olayı Hatalı iş mantığı ~$25K
2026/03/10 Alkemi Olayı Hatalı iş mantığı ~$89K
2026/03/10 MT Olayı Hatalı iş mantığı ~$242K
2026/03/11 AAVE Tasfiye Olayı Yanlış yapılandırma ~$1.01M
2026/03/11 Planet Finance Olayı Hatalı iş mantığı ~$10K
2026/03/12 AM Olayı Hatalı iş mantığı ~$131K
2026/03/12 DBXen Olayı Hatalı iş mantığı ~$149K
2026/03/15 Goose Finance Olayı Hatalı iş mantığı ~$8K

EtherFreakers Olayı

Kısa Özet

9 Mart 2026'da Ethereum üzerindeki bir NFT oyunu olan EtherFreakers, hatalı çift sayım nedeniyle istismar edildi ve yaklaşık $25K zarar oluştu. Oyundaki her NFT, çekilebilir bir ETH bakiyesine (adı "enerji") sahiptir. Bir oyun mekaniği olarak oyuncular, bir NFT'nin diğerini ele geçirmesi ve hedefin enerjisini talep etmesi için attack() fonksiyonunu kullanabilir. Ancak sözleşme, muhasebeyi kapatmadan önce hedefin bakiyesini öder ve NFT'yi transfer eder. Transfer kancası daha sonra güncel olmayan, ödeme öncesi verileri okur ve bunun bir kısmını global bir temettü havuzuna geri besleyerek yeni bir ETH desteği olmaksızın havuzu şişirir. Saldırgan, global indeksi şişirmek için bu ele geçirme mekaniğini döngüye aldı ve ardından bir grup NFT'den şişirilmiş bakiyeyi boşalttı.

Arka Plan

EtherFreakers, her NFT'nin ("Freaker" olarak adlandırılır) energy adı verilen çekilebilir bir ETH bakiyesine sahip olduğu, zincir üzerinde çalışan bir NFT oyunudur. Sistem bir temettü havuzu gibi çalışır: belirli eylemler gerçekleştiğinde, bir miktar ETH orantılı olarak tüm Freaker'lara dağıtılır. Her Freaker'ın talep edilebilir ETH'si, global bir akümülatör olan freakerIndex ve token başına hisse ağırlığı olan fortune ile takip edilir.

Somut olarak muhasebe formülü şudur: energyOf = basic + (freakerIndex - index) * fortune. freakerIndex, _dissipateEnergyIntoPool(amount) çalıştığında artar; amount'un %80'ini tüm Freaker'lara ve %20'sini oluşturuculara dağıtır. charge() aracılığıyla yapılan doğrudan mevduatlar yalnızca basic'i artırır, freakerIndex'i etkilemez. Bu nedenle, freakerIndex'teki artışlar her zaman sisteme giren gerçek Ether tarafından desteklenmelidir. freakerIndex karşılık gelen ETH girişi olmaksızın büyürse, Freaker'lar sözleşmenin gerçekte tuttuğundan daha fazla Ether kullanabilir.

Güvenlik Açığı Analizi

Temel neden, EtherFreak sözleşmesindeki (0x3A27...c0f33) hatalı yürütme sırasıdır. Bir ele geçirme başarılı olduğunda, attack() fonksiyonu şu adımları sırasıyla gerçekleştirir:

  1. 237. Satır: targetCharge'ı (hedef NFT'nin tam enerjisi) doğrudan ETH transferi olarak savunucuya öder. Enerji artık harcanmıştır.
  2. 240. Satır: NFT'yi taşımak için _transfer(defender, capturer, targetId) çağrısı yapar. Dahili olarak, _transfer(), _dissipateEnergyIntoPool() fonksiyonunu energyOf(targetId)'nin %0,1'i ile çağıran ERC-721 kancası _beforeTokenTransfer()'ı çağırır. Bu, _dissipateEnergyIntoPool() fonksiyonuna yapılan ilk çağrıdır ve 5. adım henüz gerçekleşmediği için güncel olmayan bir değer okur.
  3. 241. Satır: _dissipateEnergyIntoPool(sourceSpent) açıkça çağrılır. Bu, normal oyun mantığının bir parçası olan ikinci çağrıdır.
  4. 244-251. Satırlar: Hem sourceId hem de targetId için energyBalances güncellenir.

Hata 2. adımdadır: energyBalances[targetId] henüz güncellenmediği için kanca, ödeme öncesi bakiyeyi hâlâ görür ve halihazırda harcanmış enerjinin bir kısmını temettü havuzuna besler. 1. adımdaki doğrudan ETH ödemesi ve 2. adımdaki havuz girdisi aynı enerjiden beslenir; bu da yeni bir ETH desteği olmaksızın freakerIndex'i şişirir.

_dissipateEnergyIntoPool() her çağrıldığında freakerIndex büyür:

Saldırı Analizi

Aşağıdaki analiz, 0x89e24d...9abd2942 işlemine dayanmaktadır.

  • Adım 1: 1.700 WETH ödünç alındı.

  • Adım 2: Saldırganın kontrolündeki adreslerde iki yeni Freaker, 590 ve 591 numaralı tokenlar, üretildi.

  • Adım 3: Oyunun attack(590, 591) fonksiyonu defalarca çağrıldı ve başarılı ele geçirme dalında yürütmeler sürdürüldü.

  • Adım 4: Her başarının ardından, aynı çiftin yeniden kullanılabilmesi için 591 numaralı token yardımcıya geri transfer edildi.

  • Adım 5: Her başarılı döngü, freakerIndex'i sistem tarafından gerçekte korunan Ether'in ötesinde şişirdi.

  • Adım 6: İndeks yeterince yükseldikten sonra, daha önce kontrol edilen Freaker'lardan oluşan bir grup boşaltıldı. 496'dan 520'ye kadar olan Token ID'lerin her biri 0.278052246002402082 Ether karşılığında boşaltıldı.

  • Adım 7: Boşaltılan Ether WETH'e dönüştürüldü, 1.700 WETH flash kredisi geri ödendi ve yaklaşık 7,498 WETH kâr olarak elde tutuldu.

Sonuç

Temel neden, attack() fonksiyonunun başarılı ele geçirme akışındadır: EtherFreakers, hedef tokenın enerji durumu düzeltilmeden önce targetCharge'ı öder. _transfer() ardından _beforeTokenTransfer() fonksiyonunu tetikler; bu da güncel olmayan ödeme öncesi energyOf(targetId) değerini okur ve bir kısmını havuza dağıtır. Bu durum, yeni bir Ether desteği olmaksızın freakerIndex'i artırır; böylece aynı hedef enerjisi hem ödeme hem de havuz girdisi olarak sayılır. Bu bir yeniden giriş hatası değil, iş mantığı şişirme hatasıdır.

Gelecekte benzer riskleri azaltmak için:

  • Aynı işlem hâlâ sonuçlanmaktayken transfer kancaları içinde değişebilir durumdan ekonomik değerlerin yeniden hesaplanmasından kaçının.

  • Transfer kancası bir durum değişkeni okuyorsa, yürütme sırasının sonucu etkilemediğinden emin olun (örneğin, kanca çalıştıktan sonra değil, çalışmadan önce durumu düzeltin).


Alkemi Olayı

Kısa Özet

10 Mart 2026'da Ethereum üzerindeki Alkemi protokolü istismar edildi ve yaklaşık $89K zarar oluştu. Temel neden, bir muhasebe hatası ve hatalı iş mantığıdır. Hatalı tasfiye mantığı, herhangi birinin aynı işlem içinde kendi pozisyonunu tasfiye etmesine ve bundan kâr etmesine olanak tanır. Ayrıca, bir muhasebe hatası nedeniyle tasfiye sırasında saldırganın kendi teminatından yapılan kesintinin üzerine yazılması, saldırganın amaçlanan maliyete katlanmadan tasfiye ödülleri almasına yol açar.

Arka Plan

Alkemi bir kredi protokolüdür. Bir borçlunun pozisyonu yetersiz teminatlı hale geldiğinde, herhangi biri borcun bir kısmını geri ödemek ve teminatı indirimli olarak ele geçirmek için liquidateBorrow() fonksiyonunu çağırabilir. Aşırı tasfiyeyi önlemek için protokol, işlem başına geri ödenebilir tutarı üç değerin minimumunda sınırlar:

  1. Borçlunun mevcut borç bakiyesi (currentBorrowBalance_TargetUnderwaterAsset).
  2. Borçlunun teminatının tasfiye indirimi uygulandıktan sonra karşılayabileceği maksimum geri ödeme (calculateDiscountedBorrowDenominatedCollateral()).
  3. Hesabı tasfiye sınırına geri getirmek için gereken geri ödeme miktarı (calculateDiscountedRepayToEvenAmount()), yalnızca piyasa isSupported (destekleniyor) olduğunda kontrol edilir.

Güvenlik Açığı Analizi

Temel neden, Alkemi protokolündeki (0x4822...a888) hatalı iş mantığı ve muhasebe hatasıdır. currentBorrowBalance_TargetUnderwaterAsset değeri, borçlunun ödenmemiş bir borcu olduğu sürece zorunlu olarak 0'dan büyük olduğundan ve calculateDiscountedBorrowDenominatedCollateral() tarafından döndürülen değer de borçlunun teminatı olduğu sürece zorunlu olarak 0'dan büyük olduğundan, AlkemiEarnPublic protokolü belirli bir kredinin tasfiye edilip edilemeyeceğini belirlemek için fiilen calculateDiscountedRepayToEvenAmount() fonksiyonuna dayanır. Bu fonksiyonda, tasfiye edilmesi gereken borç miktarı accountShortfall_TargetUser adlı bir değişkene göre hesaplanmalıdır.

Ancak gerçek uygulamada fonksiyon bunun yerine, geri ödenebilecek borç miktarına bir üst sınır hesaplamak için closeFactorMantissa adlı global bir değişken kullanır ve bu değeri döndürür. Sonuç olarak, bir saldırgan aynı işlem içinde borç alabilir ve hemen kendi pozisyonunu tasfiye edebilir.

Ayrıca liquidateBorrow() fonksiyonunda, tasfiye eden ve borçlu aynı adres olduğunda, supplyBalance_TargetCollateralAsset ve supplyBalance_LiquidatorCollateralAsset değişkenleri aynı depolama yuvasına işaret eder. Fonksiyon daha sonra aynı başlangıç bakiyesine göre ayrı ayrı bir "azaltılmış bakiye" ve bir "ödüllendirilen bakiye" hesaplar ve ardından bunları aynı depolama yuvasına sırayla geri yazar. Azaltılmış bakiye önce yazıldığı ve ödüllendirilen bakiye daha sonra yazıldığı için, azaltma etkisinin üzerine yazılır ve kaybolur; yalnızca ödüllendirilen sonuç kalır. Bu, saldırganın kârını daha da artırmasına olanak tanır.

Saldırı Analizi

Aşağıdaki analiz, 0xa170...6d9d işlemine dayanmaktadır.

  • Adım 1: Saldırgan, Balancer'dan 51e18 WETH flash kredisi aldı.

  • Adım 2: Saldırgan 51e18 WETH'i ETH'e dönüştürdü ve Alkemi protokolüne yatırdı.

  • Adım 3: Saldırgan Alkemi'den 39.5e18 ETH ödünç aldı.

  • Adım 4: Saldırgan 39.5395e18 ETH kullanarak kendi pozisyonunu tasfiye etti.

  • Adım 5: Saldırgan Alkemi'den 93.5e18 ETH çekti.

  • Adım 6: Saldırgan flash kredisini geri ödedi ve 43.4e18 ETH kâr elde etti.

Sonuç

Temel neden, hatalı tasfiye mantığının saldırganın aynı işlem içinde borç alarak kendi pozisyonunu tasfiye etmesine ve kâr etmesine izin vermesidir; hatalı muhasebe mantığı ise saldırganın kazancını daha da artırmaktadır.

Gelecekte benzer riskleri azaltmak için:

  • Borçlu ve tasfiye eden için bakiye güncellemelerinde protokol, bakiyeleri ayrı hesaplama ve geri yazma için geçici bellek değişkenlerine kopyalamak yerine doğrudan depolama değişkenleri üzerinde işlem yapmalıdır.

MT Olayı

Kısa Özet

10 Mart 2026'da BNB Chain üzerindeki deflasyonist bir token olan MT Token istismar edildi ve yaklaşık $242K zarar oluştu. Temel neden, hatalı işlem kısıtlama mantığı ile özel transfer koşullarının tutarsız biçimde ele alınmasının bir arada bulunmasıdır. Deflasyon aşamasında sözleşme, havuz rezervi sabit bir eşiği aştığında alım işlemlerini kısıtlar. Ancak sözleşme, tam miktardaki transferleri (örneğin 2e17 MT) referans bağlama eylemleri olarak değerlendirerek saldırganın alım kısıtlamasını aşmasına ve başlangıç tokenlarını edinmesine olanak tanır. Buna ek olarak, kısıtlama mantığı eksik yol tespitine (isBuy) dayanır ve Çift'ten Router'a gibi dolaylı takas rotalarını kapsamaz; beyaz liste kontrolleri ise kritik doğrulamaları devre dışı bırakır. Saldırgan, kısıtlamaları veya ücretleri tetiklemeden MT tokenları biriktirdi, kontrollü likidite işlemleri ve takaslara aracılığıyla pendingBurnAmount değerini manipüle etti ve token fiyatının yapay olarak şişirildiği anormal bir duruma havuzu zorladı.

Arka Plan

MT Token, yerleşik işlem kısıtlamalarına sahip BNB Chain üzerinde deflasyonist bir tokendir. Deflasyon aşamasında, havuzdaki MT rezervi 21.000e18'i aştığında sözleşme alım işlemlerini engeller. Rezerv bu eşiğin altına düştüğünde deflasyon aşaması sona erer ve alım yeniden etkinleştirilir. MT Token ayrıca bir referans mekanizması içerir: tam olarak 2e17 MT veya 1e17 MT transferi, normal bir işlem yerine referans bağlama eylemi olarak kabul edilir.

Güvenlik Açığı Analizi

Temel neden, MT sözleşmesindeki (0x037E...b449) hatalı alım kısıtlama tasarımıdır. Normal koşullar altında saldırganların kısıtlı aşamada başlangıç sermayesi olarak MT edinememesi gerekir. Ancak sözleşme, tam olarak 2e17 MT'lik bir transferi alım değil referans bağlama eylemi olarak değerlendirdiğinden, bir saldırganın alım kısıtlamasını aşarak 2e17 MT satın almasına olanak tanır.

Ayrıca işlem kısıtlaması, satın almaları engellemek için isBuy dalına dayanır; ancak "Çift'ten Router'a" yolunu kapsamaz. Hem Router hem de Çift beyaz liste adresleri olduğundan, bu tür transferler beyaz liste kontrolünde kısa devre yapar ve asla alım kısıtlama mantığına ulaşamaz; bu da saldırganın alımları Router'a yönlendirerek MT edinmesine ve ardından likidite kaldırarak tokenları kendine geri çıkarmasına olanak tanır.

Saldırı Analizi

Aşağıdaki analiz, 0xfb57...fca6 işlemine dayanmaktadır.

  • Adım 1: Saldırgan ~358.681e18 WBNB flash kredisi aldı.

  • Adım 2: Saldırgan 2e17 MT satın alarak alım kısıtlamasını aştı.

  • Adım 3: Saldırgan likidite eklemek için Çift'e 4e12 WBNB ve 2e17 MT sağladı. Bu transfer, yukarıdakiyle aynı nedenle ücret uygulama mantığını atladı.

  • Adım 4: Saldırgan, Çift'ten Router'a ~10.000.000e18 MT tokeni satın alarak hem alım kısıtlamasını hem de ücret uygulama mantığını atladı.

  • Adım 5: Saldırgan likidite pozisyonunun yarısını kaldırdı, bu süreçte Router'ın elindeki tüm MT tokenlerini çıkardı ve ardından geri kazanılan MT'yi WBNB karşılığında sattı. Bu adımda pendingBurnAmount yaklaşık 9.000.000e18'e manipüle edildi.

  • Adım 6: Saldırgan yeniden ~10.000.000e18 MT tokeni satın aldı ve havuzun MT rezervini pendingBurnAmount'tan düşük olan ~6.756.516e18'e indirdi.

  • Adım 7: Saldırgan kalan likidite pozisyonunun tamamını kaldırdı, satın aldığı MT tokenlerini çekti ve ardından MT'yi havuzdan yakmak için distributeDailyRewards() fonksiyonunu çağırdı. Sonuç olarak MT rezervi 21.000e18'e düştü.

  • Adım 8: Saldırgan tüm MT'yi ~1.198e18 WBNB'ye geri takas etti, flash kredisini geri ödedi ve kârı kesinleştirdi.

Sonuç

Bu istismar, saldırganın tam olarak BINDING_AMOUNT kadar MT tokeni satın alarak alım yasağını atlamasına olanak tanıyan hatalı işlem kısıtlamalarından kaynaklandı. MT tokenlarını edindikten sonra saldırgan, önce likidite ekleyerek, ardından MT'yi Router'a satın alarak ve son olarak tokenları geri almak için likiditeyi kaldırarak hem ücret uygulama mantığını hem de alım kısıtlamasını atlatabildi. Saldırgan daha sonra satış işlemleriyle pendingBurnAmount'u biriktirdi ve yakma işlemini gerçekleştirerek havuz rezervlerini anormal bir duruma itti; bu sayede MT'yi yapay olarak şişirilmiş bir fiyattan satarak kâr etti.

Gelecekte benzer riskleri azaltmak için:

  • Transfer semantiği ile işlem mantığı arasında katı bir ayrım uygulayın.

AAVE Tasfiye Olayı

Kısa Özet

11 Mart 2026'da AAVE, Ethereum üzerinde $21M tutarında hatalı tasfiyeye maruz kaldı ve yaklaşık $1.01M zarar oluştu. Temel neden, wstETH için yanlış oracle fiyatıydı; bu durum, başlangıçta sağlıklı olan pozisyonların yetersiz teminatlı hale gelmesine yol açtı. Sonuç olarak kullanıcıların pozisyonları tasfiye edildi ve mali kayıplar yaşandı.

Arka Plan

AAVE, wstETH gibi sarılmış varlıkları fiyatlamak için oracle adaptörleri kullanır. CAPO (Üst Sınırlı Fiyat Oracle'ı) adlı adaptör, wstETH fiyatını temel ETH/USD fiyatını bir dönüşüm oranıyla (getRatio(), yani bir wstETH'in kaç ETH ettiği) çarparak türetir. Oran manipülasyonunu önlemek için CAPO, anlık görüntü tabanlı bir büyüme üst sınırı uygular:

maxRatio = snapshotRatio + maxGrowthPerSecond x (currentTime - snapshotTimestamp)

ve fiyatlandırma sırasında getRatio() çıktısını sınırlar (currentRatio > maxRatio ise maxRatio kullanır). Bu mekanizma, oranın ve ortaya çıkan fiyatın maksimum yukarı yönlü sapmasını etkin biçimde sınırlar.

Güvenlik Açığı Analizi

Temel neden, CAPO oracle anchor yapılandırmasındaki (0xe1D9...61Ef) zaman-oran uyuşmazlığıydı: anlık görüntü zaman damgası ve anlık görüntü oranı belirlenmişti, ancak anlık görüntü oranı gerçek wstETH/ETH oranının altında yapılandırılmıştı. Sonuç olarak, adaptörün hesapladığı maxRatio değeri canlı oranın altında kaldı ve getRatio() fonksiyonunu aşağı yönde sınırlandırarak wstETH/USD oracle fiyatını sistematik olarak düşük değerledi. Bu durum teminat değerlemesini baskıladı; wstETH'i teminat olarak kullanan pozisyonların sağlık faktörünü düşürerek sağlıklı hesapların yanlış biçimde sağlıksız olarak sınıflandırılmasına ve tasfiye edilmesine neden oldu.

Saldırı Analizi

Aşağıdaki analiz, 0x9064...8a9c işlemine dayanmaktadır.

  • Adım 1: Tasfiye eden ~6304e18 WETH flash kredisi aldı ve borçluyu tasfiye etti.

  • Adım 2: Tasfiye eden flash kredisini geri ödeyerek tasfiyeyi tamamladı.

Sonuç

Bu tasfiye, yanlış oracle fiyat yapılandırmasından kaynaklandı; bu durum, sağlıklı kalması gereken borçluları yanlış biçimde sağlıksız konuma itti ve böylece pozisyonlarının tasfiyesini tetikledi.

Gelecekte benzer riskleri azaltmak için:

  • Her güncellemeden önce kritik parametrelerin doğruluğunun doğrulandığından emin olun.

  • Yanlış parametreleri reddetmek ve hatalı yapılandırmaların başarıyla uygulanmasını önlemek için uygulamaya doğrulama kontrolleri ekleyin.


Planet Finance Olayı

Kısa Özet

11 Mart 2026'da Planet Finance, BNB Chain üzerinde istismar edildi ve tahmini ~$10K zarar oluştu. Temel neden, protokolün bir borçlunun kayıtlı borç bakiyesindeki artışı yanlışlıkla tahakkuk eden faiz olarak değerlendirmesiydi; bu da saldırganın kayıtlı borcunu düşürmek için defalarca borç almasına ve indirim ödemesini tetiklemesine olanak tanıdı.

Arka Plan

Planet Finance, borçluların faiz indirimi ile geri ödeme yapmasına olanak tanıyan bir kredi protokolüdür. İndirim kademeli olup kullanıcının stake edilmiş GAMMA değeri ile diğer varlıklardaki stake değeri arasındaki orana göre belirlenir: bu oran ne kadar yüksekse geri ödeme indirimi de o kadar yüksek olur. İndirim takvimi, %0 (minimum) ile %50 (maksimum) arasında değişen üç kademeden oluşur.

Güvenlik Açığı Analizi

Temel neden, changeUserBorrowDiscount() fonksiyonunda bir borçlunun indirimini öderken protokolün (0x4c9E...F467) borçlunun kayıtlı borç bakiyesindeki artışı yanlışlıkla yeni tahakkuk eden faiz olarak değerlendirmesiydi. Sonuç olarak, yalnızca tahakkuk eden faize uygulanması gereken indirim, yanlış biçimde yeni borçlanılan anaparaya uygulandı ve borçlunun kayıtlı borcunu haksız yere azalttı. Bir saldırgan, aşırı indirim biriktirmek için borrow ve ardından changeUserBorrowDiscount döngüsünü tekrar tekrar gerçekleştirebilir; bu durum zincir üzerindeki kayıtlı yükümlülüğün gerçek borçlanılan miktardan sürekli olarak düşük kalmasına ve nihayetinde bu farklılıktan kâr elde edilmesine yol açar.

Saldırı Analizi

Aşağıdaki analiz, 0x5f45...5ec9 işlemine dayanmaktadır.

  • Adım 1: Saldırgan 200.000e18 USDT flash kredisi aldı.

  • Adım 2: Saldırgan 5.000e18 USDT ile WBNB satın aldı ve ardından edinilen WBNB ile ~8.726.524e18 GAMMA satın aldı.

  • Adım 3: Saldırgan önce edindiği tüm GAMMA'yı gGAMMA piyasasına stake etti, ardından kalan USDT'yi teminat olarak sağladı; bu işlem geri ödeme indirimini %5'e yükseltti ve sonraki borçlanmayı mümkün kıldı.

  • Adım 4: Saldırgan, kayıtlı borcunu sürekli olarak azaltmak için borrow ve ardından updateUserDiscount çağrısını tekrar tekrar yaptı.

  • Adım 5: Saldırgan nihayetinde borcu geri ödedi, teminatı geri aldı ve kârı gerçekleştirdi.

Sonuç

Bu olay, Planet Finance'ın changeUserBorrowDiscount() fonksiyonundaki hatalı indirim ödeme mantığından kaynaklandı; söz konusu mantık, borçlunun kayıtlı borç bakiyesindeki artışı yanlışlıkla yeni tahakkuk eden faiz olarak değerlendiriyor ve bu deltaya faiz indirimi uyguluyor. Bir saldırgan, kayıtlı borcunu düşürmek ve nihayetinde gerçek yükümlülükten daha az geri ödeyerek kâr elde etmek için borrow ve ardından updateUserDiscount çağrısını tekrar tekrar yapabilir.

Gelecekte benzer riskleri azaltmak için:

  • Kredi protokolünde faiz ile yeni borçlanmaları birbirinden ayırt edin.

AM Olayı

Kısa Özet

12 Mart 2026'da BNB Chain üzerindeki deflasyonist bir token olan AM Token, tahmini ~$131K zarar ile istismar edildi. AM Token, her satışın likidite havuzundan ek bir yakma tetikleyerek tokenları kalıcı olarak kaldırdığı ve toplam arzı azalttığı deflasyonist bir mekanizma uygular. Ancak yakma hemen gerçekleştirilmez; bunun yerine, tam satış miktarı toBurnAmount olarak kaydedilir ve gerçek yakma bir sonraki satışa ertelenir. Bu gecikme, kayıt ve yürütme arasında saldırganın havuzun AM rezervini toBurnAmount değerine kadar küçülterek geri alım yapabildiği bir pencere oluşturur. Bir sonraki satış ertelenmiş yakımı tetiklediğinde, tüm AM rezervi silinir; bu da fiyatı aşırı bir düzeye çıkarır ve saldırganın AM'yi kâr amacıyla satmasına olanak tanır.

Arka Plan

AM Token, BNB Chain üzerinde deflasyonist bir tokendir. Her satışta sözleşme, takasta yer alan AM miktarını toBurnAmount olarak kaydeder ve bir sonraki satışta bu kaydedilen miktarı likidite havuzundan yakar. Pratikte satışlar, havuzun AM rezervini küçülten gecikmeli bir yakımı tetikler. Ayrıca protokol, yakımı gerçekleştirmeden önce birikmiş totalTokenFee'yi USDT'ye takas eder ve ücret tahsis mantığına göre dağıtır.

Güvenlik Açığı Analizi

Temel neden, tokenın (0x27f9...213f) satış mantığının, takas edilen tam AM miktarını toBurnAmount olarak biriktirmesi ve yakımı yalnızca bir sonraki satışta AM/USDT çiftinden tokenları kaldırıp rezervleri güncellemek için pair.sync() çağrısı yaparak gerçekleştirmesidir. Bu tasarım, bir saldırganın havuzun AM rezervlerini manipüle etmesine, zincir üzerindeki fiyatı bozmasına ve arbitraj yoluyla kâr etmesine olanak tanır.

Saldırı Analizi

Aşağıdaki analiz, 0xd0d1...f859 işlemine dayanmaktadır.

  • Adım 1: Saldırgan ~27.265.119e18 USDC ve ~361.710e18 WBNB flash kredisi aldı, ardından bunları ~100.423.811e18 USDT'ye takas etti.

  • Adım 2: Saldırgan ~5.062e18 AM tokenini USDT karşılığında takas etti; bu işlem, sözleşmenin kayıtlı toBurnAmount değerini ~4.303e18'e manipüle etti.

  • Adım 3: Saldırgan USDT'yi AM Token ile takas etti ve havuzun AM rezervini ~4.303e18'e düşürdü.

  • Adım 4: Saldırgan havuza 6 wei AM transfer ederek satış yolu yakma mantığını tetikledi. Sonuç olarak sözleşme, tüm AM bakiyesini havuzdan yaktı ve AM rezervini 0'a düşürdü. Not: protokol yakımdan önce birikmiş ücretleri USDT'ye takas etmeye çalışır. Bu ücret dönüşümü yolu da satış dalı yakma mantığını tetikler. Yakma gerçekleştikten ve AM rezervi 0'a ulaştıktan sonra ücret takası başarısız olur. try/catch içinde sarılı olduğundan, bu başarısızlık işlemi geri almaz. Bunun yerine yürütme devam eder ve ücret biriktiricisi 0'a sıfırlanır.

  • Adım 5: Saldırgan pool.sync() çağrısı yaptı ve kalan USDT ile 1 wei AM'yi havuza transfer etti. Her iki token aynı anda transfer edildiğinden, sözleşme bunu addLiquidity (likidite ekleme) olarak değerlendirdi; bu nedenle toBurnAmount biriktirilmedi. AM rezervi 7 olarak güncellendi.

  • Adım 6: Saldırgan kalan AM tokenlerini USDT karşılığında takas etti. Bu takas sırasında Çift'e AM transferi satış yolu yakma mantığını tetikledi ve AM rezervini 1'e düşürdü. Ayrıca, totalFeeAmount Adım 4'te 0'a sıfırlandığından, USDT'ye ücret dönüşümü artık gerçekleştirilmedi; bu da saldırganın AM'yi yapay olarak şişirilmiş bir fiyattan satmasına olanak tanıdı.

  • Adım 7: Saldırgan flash kredisini geri ödedi ve kalan kârı gerçekleştirdi.

Sonuç

Bu olay, AM Token'ın hatalı yakma mekanizmasından kaynaklandı; söz konusu mekanizma, her satışın takas içerdiği AM miktarını toBurnAmount olarak biriktirir ve ardından bir sonraki satışta pair.sync() çağrısı yaparak AM/USDT Çiftinden o miktarı yakar. Bu durum, bir saldırganın Çiftin AM rezervlerini aşırı bir düzeye manipüle etmesine ve USDT'yi boşaltmak için AM'yi yapay olarak şişirilmiş bir fiyattan satmasına olanak tanır.

Gelecekte benzer riskleri azaltmak için:

  • İşlem başına maksimum yakma miktarını sınırlandırın ve yakmanın ne sıklıkla tetiklenebileceğini hız sınırlayın; böylece saldırganların kısa bir süre içinde havuzun token rezervlerinin büyük bir kısmını tüketmesi engellenir.

DBXen Olayı

Kısa Özet

12 Mart 2026'da Ethereum ve BNB Chain üzerindeki bir yakma-kazan protokolü olan DBXen, toplam ~$149K kayıpla istismar edildi. Temel neden, _msgSender() ve msg.sender arasındaki tutarsızlıktı. burnBatch() fonksiyonu forwarder aracılığıyla çağrıldığında, yakılan XEN miktarı _msgSender() (saldırgan kontrolünde) altında kaydedilirken döngü kayıtları msg.sender (forwarder) üzerinde güncellenir. Bu bölünme, saldırganın bayat döngü kayıtlarına karşı ödüller ve ücretler talep etmesine olanak tanıyarak anormal derecede büyük ödemelere yol açar.

Arka Plan

DBXen bir yakma-kazan protokolüdür: kullanıcılar DXN ödülleri ve birikmiş protokol ücretlerinden pay almak karşılığında XEN tokenları yakar. Temel mekanizma döngüler halinde çalışır. Bir kullanıcı burnBatch() fonksiyonunu çağırdığında iki şey gerçekleşir: (1) yakılan XEN miktarı arayanın adresi altında kaydedilir (_msgSender() ile belirlenir) ve (2) XEN sözleşmesi, arayanın döngü kayıtlarını (yakma döngüsü ve lastFeeUpdateCycle) mevcut döngüye güncellemek için onTokenBurned() aracılığıyla DBXen'e geri çağrı yapar.

Ödüller ve ücretler updateStats() aracılığıyla ödenir. Ödül, kullanıcının yakma döngüsünde yakılan toplam XEN içindeki payıyla orantılıdır. Ücret, kullanıcının son kayıtlı döngüsünden bu yana biriken kümülatif protokol ücretlerine dayanır. Her iki hesaplama da kullanıcının döngü kayıtlarının güncel olmasına bağlıdır.

Güvenlik Açığı Analizi

Temel neden, DBXen protokolündeki (0xf5c8...2abd) hatalı iş mantığıdır. _msgSender() fonksiyonu, msg.sender'ın forwarder olup olmadığını kontrol eder. Öyleyse, calldata'nın son 20 baytını döndürür ve bu döndürülen değer forwarder bağlamında keyfi olarak kontrol edilebilir. Ancak burnBatch(), msg.sender tarafından tutulan XEN'i doğrudan yakar. Sonuç olarak, bir saldırgan burnBatch() fonksiyonunu forwarder aracılığıyla çağırarak protokolün forwarder'ın tuttuğu XEN'i yakmasına ve hem forwarder'ın yakma-döngüsü kaydını hem de ücret güncelleme döngüsü kaydını mevcut döngüye güncellemesine neden olabilir. Aynı zamanda protokol, yakılan XEN miktarını _msgSender()'a karşılık gelen adres altında kaydeder.

Bunun ardından saldırgan claimFees() fonksiyonunu çağırır; bu da updateStats()'ı çağırır. _msgSender() adresinin döngü kayıtları hiçbir zaman güncellenmediğinden (hem yakma döngüsü hem de lastFeeUpdateCycle 0'da kalır), updateStats() mevcut döngüdeki ödülleri hesaplar ve döngü 0'dan bu yana biriken ücretleri hesaplar; bu da protokolün tüm ücret geçmişini kapsar. Saldırgan ardından claimFees() ve claimRewards() fonksiyonlarını çağırarak kâr eder.

Saldırı Analizi

Aşağıdaki analiz, 0x914a5a...b808bc37 işlemine dayanmaktadır.

  • Adım 1: Saldırgan önce Forwarder sözleşmesinin registerDomainSeparator() fonksiyonunu çağırdı; bu sayede sonraki Forwarder.execute() çağrıları etkinleştirildi.

  • Adım 2: Saldırgan bir Uniswap V2 havuzunda 0.14e18 ETH'i 13.900.000.000e18 XEN ile takas etti.

  • Adım 3: Saldırgan 13.900.000.000e18 XEN'i Forwarder sözleşmesine transfer etti.

  • Adım 4: Saldırgan, DBXen'in Forwarder tarafından tutulan 13.900.000.000e18 XEN'i harcamasını onaylamak için Forwarder.execute() fonksiyonunu kullandı.

  • Adım 5: Saldırgan, DBXen.burnBatch() fonksiyonunu çağırmak ve 13.900.000.000e18 XEN yakmak için Forwarder.execute() fonksiyonunu kullandı. Yakma miktarı 0x425D3eC2DCeBE2c04bA1687504D43AFC6be7328d adresi altında kaydedilirken, yakma yürütmesi sırasında XEN, onTokenBurned() aracılığıyla DBXen'e geri çağrı yaptı ve ilgili döngü kayıtlarını Forwarder üzerinde güncelledi.

  • Adım 6: Saldırgan, DBXen.claimFees() fonksiyonunu çağırmak için Forwarder.execute() fonksiyonunu kullandı ve 65.36e18 ETH elde etti.

  • Adım 7: Saldırgan, DBXen.claimRewards() fonksiyonunu çağırmak için Forwarder.execute() fonksiyonunu kullandı ve 2.305.4e18 DXN üretildi.

Sonuç

Bu olayın temel nedeni, DBXen protokolünün _msgSender() ve msg.sender değerlerini tutarsız biçimde kullanmasıydı. Bu iki değer birbirinden farklı olabileceğinden, protokolün iç muhasebesi tutarsız hale geldi ve saldırganın bu tutarsızlıktan kâr elde etmesine olanak tanıdı.

Gelecekte benzer riskleri azaltmak için:

  • _msgSender() fonksiyonunu tüm mantık yollarında tutarlı biçimde kullanın ya da msg.sender'a bağlı işlemler ile _msgSender()'a bağlı muhasebenin her zaman aynı adrese başvurduğundan emin olun.

Goose Finance Olayı

Kısa Özet

15 Mart 2026'da BNB Chain üzerindeki bir getiri tarım protokolü olan Goose Finance, yaklaşık $8K tutarında istismar edildi. Temel neden, StrategyGooseEgg'deki pay fiyatlama sırası hatasıydı: deposit() fonksiyonu, hasatlanmış ödülleri muhasebeye dahil etmeden önce pay üretir; bu nedenle pay fiyatlamasında payda olarak kullanılan toplam varlık değeri bu ödülleri kapsamaz ve gerçek değerin altında kalır. Bu durum, yatırımcıların alması gerekenden daha fazla pay alması anlamına gelir. withdraw() çağrıldığında, toplam varlıkları artıran bir ödül hasadı tetiklenir ve her payın değeri daha yüksek olur. Saldırgan tek bir işlemde yatırma ve çekme işlemini döngüye alarak defalarca aşırı fiyatlanmış pay üretip bunları düzeltilmiş (daha yüksek) değerinden kullandı ve farkı kâr olarak elde etti.

Arka Plan

Goose Finance, kullanıcı fonlarının bir vault'tan EGG ödülleri kazanmak için varlıkları MasterChef'e stake eden bir stratejiye aktığı, BNB Chain üzerinde bir getiri tarım protokolüdür.

Bu olayla ilgili bileşenler şunlardır:

  • VaultChef (0x3f64...): kullanıcı pozisyonlarını takip eder ve sermayeyi StrategyGooseEgg'e iletir.

  • StrategyGooseEgg (0x0980...): sharesTotal ve wantLockedTotal ile strateji düzeyinde muhasebeyi yönetir.

  • MasterChef (0xe70e...): stake edilmiş varlıkları alır ve EGG ödüllerini öder.

  • WrappedEgg (0xb815...): EGG'i stake için 1:1 oranında WEGG'e sarar.

İşleyiş olarak, mevduatlar VaultChef'ten StrategyGooseEgg'e yönlendirilir, ardından MasterChef'e stake edilir. Çekimler VaultChef'ten başlatılır ve strateji tarafından gerçekleştirilir.

Temel muhasebe beklentisi, pay fiyatlamasının fiyatlama anındaki toplam strateji varlıklarını (stake edilen anapara artı stratejinin halihazırda elinde bulundurduğu boştaki ödüller) yansıtması gerektiğidir. Ancak StrategyGooseEgg'de deposit(), _farm() boştaki varlıkları wantLockedTotal'e dahil etmeden önce pay üretirken, withdraw() MasterChef'ten ödül hasadı tetikleyebilir. Bu sıralama, aşağıda analiz edilen güvenlik açığının temelidir.

Güvenlik Açığı Analizi

Temel neden, StrategyGooseEgg'deki (0x0980...b26b) ödül hasadı ile pay fiyatlaması arasındaki muhasebe uyumsuzluğudur.

StrategyGooseEgg'de pay fiyatlaması, payda olarak wantLockedTotal değerini kullanır: shares = deposit * sharesTotal / wantLockedTotal. Bunun adil olabilmesi için wantLockedTotal'ın, sözleşmede bulunan boştaki EGG ödülleri de dahil olmak üzere stratejinin gerçekte tuttuğu tüm varlıkları yansıtması gerekir. Ancak deposit(), _farm() boştaki ödülleri wantLockedTotal'e dahil etmeden önce pay üretir. Bu durum, paydanın hesaplanmamış ödülleri dışarda bıraktığı ve gerçek toplam varlıkların altında kaldığı anlamına gelir; yatırımcının alması gerekenden daha fazla pay almasına neden olur.

Ayrıca withdraw(), stake edilmiş anaparayı artı bekleyen EGG ödüllerini stratejiye geri döndüren MasterChef.withdraw() fonksiyonunu çağırır. Stratejinin muhasebesi yalnızca istenen _wantAmt değerini wantLockedTotal'dan çıkarır; bu nedenle hasatlanmış ödüller, wantLockedTotal'a yansıtılmadan stratejinin bakiyesinde kalır. Bu durum, gerçekte tutulan varlıklar ile kayıtlı wantLockedTotal arasındaki farkı genişleterek sonraki deposit() pay fiyatlamasını daha da hatalı hale getirir.

Saldırı Analizi

Aşağıdaki analiz, 0x86efdf...ce316223 işlemine dayanmaktadır.

  • Adım 1: Saldırgan iki Pancake çiftinden EGG flash ödünç aldı.

  • Adım 2: VaultChef/StrategyGooseEgg'e ilk yatırma (10.170.000e18 EGG).

  • Adım 3: İlk çekim (12.593.884e18 EGG), MasterChef'ten ödül hasadı yapar; 359.561e18 EGG, StrategyGooseEgg'e transfer edilir ve boşta/hesaplanmamış değer olarak kalır (R > 0).

  • Adım 4: İkinci yatırma, çekilen sermayeyi yeniden kullanır (12.593.884e18 EGG). Paylar, boştaki değer dahil edilmeden önce fiyatlandırıldığından, bu aşırı üretim adımıdır.

  • Adım 5: İkinci çekim (12.826.027e18 EGG), aşırı üretilen paylardan kâr gerçekleştirir (yani 4. adım yatırma girdisinin 232.143 EGG üzerinde).

  • Adım 6: Saldırgan flash takasları geri öder ve net farkı elde tutar.

Sonuç

İstismar, StrategyGooseEgg'deki pay fiyatlama sırası hatasından kaynaklanmaktadır: deposit(), _farm() wantLockedTotal'ı güncellemeden önce pay üretirken, withdraw() MasterChef'ten geçici olarak boşta ve hesaplanmamış kalan ödülleri hasat edebilir. Bu durum, mevduatların bayat bir paydaya karşı pay üretmesine ve daha sonra güncellenmiş varlıklara karşı çekim yapmasına olanak tanır.

Gelecekte benzer riskleri azaltmak için:

  • Hem pay üretimi hem de pay yakma hesaplamalarından önce ödülleri ödeyin ve muhasebeyi güncelleyin.

  • Payları, tam hesaplama noktasında tek bir totalAssets (stake edilmiş + boştaki) değerine göre fiyatlandırın.

  • Sıfırdan farklı boşta ödül koşulları altında shares_minted <= D * S / (A + R) için değişmez testler ekleyin.


BlockSec Hakkında

BlockSec, tam yığın bir blok zinciri güvenliği ve kripto uyum sağlayıcısıdır. Müşterilerin kod denetimi gerçekleştirmesine (akıllı sözleşmeler, blok zinciri ve cüzdanlar dahil), saldırıları gerçek zamanlı olarak engellemesine, olayları analiz etmesine, yasadışı fonları takip etmesine ve protokollerin ve platformların tüm yaşam döngüsü boyunca AML/CFT yükümlülüklerini yerine getirmesine yardımcı olan ürünler ve hizmetler geliştiriyoruz.

BlockSec, saygın konferanslarda birçok blok zinciri güvenlik makalesi yayımlamış, DeFi uygulamalarında çeşitli sıfır gün saldırıları bildirmiş, 20 milyon doların üzerinde varlığı kurtarmak için birden fazla saldırıyı engellemiş ve milyarlarca dolar değerinde kripto parayı güvence altına almıştır.