İmza kimi söyler, neyi değil
İmzalanmış bir işlem kesin görünür. Oysa imza, geçerli bir şeyi kimin onayladığını kanıtlar — çalışan şeyin onayladıkları şey olduğunu değil. DeFiLoops bu boşluğa şunu koyar: bir içerik makbuzu ve bir işlemin gerçekte ne yaptığına bakan bir simülasyon.
İmzalanmış bir işlem hikâyenin sonu gibi hissettirir. Yetkili biri onayladı, imza doğrulanıyor, zincir buna uyacak. Bitti.
Ama onaylandı ile çalıştırıldı arasında bir boşluk var ve göründüğünden geniş. Bir ajanın imzaladığı an ile işlemin bir bloğa girdiği an arasında bir rota seçilir, calldata kurulur ve dakikalar geçer. İmza, kimin onayladığına dair bir ifadedir — sonunda neyin çalıştığı hakkında neredeyse hiçbir şey söylemez. O boşluğu kapatmak güvenlik işinin büyük kısmıdır ve hiçbiri imza değildir.
Ajan gerçekte neyi imzalar
Ajanımız hiçbir zaman ham bir işlem imzalamaz. Tipli bir niyet imzalar — bir tutar, listeden adı verilmiş bir mekân, bir aralık — ve adaptör çağrıyı bu parametrelerden kurar. Ele geçirilmiş bir ajanın bir çağrıyı saldırgana yöneltememesinin bütün sebebi budur: ona hedef verilmemiştir (bunu burada yazdık).
Ama tipli olsun ya da olmasın, bir imza yalnızca hash’lediği alanları kapsar. Ve bir EIP-712 mesajı bir alt kümeyi hash’ler.
Çatlak budur. İmzalama ile çalıştırma arasında bu kapsanmayan alanlardan birini değiştirebilen her şey, her imzayı doğrulanır bırakarak ne olduğunu değiştirir. Niyetin hâlâ geçerli olup olmadığını yeniden denetlemek işe yaramaz — değişmiş niyet de geçerlidir. İki denetim de hemfikirdir, farklı niyetler hakkında.
Dakikalar arayla iki onay
Bir adaptör planı bilerek iki kez yetkilendirilir, çünkü ilk onay anında calldata mevcut değildir.
- Grubu imzala ve bir makbuz bas
İmzalayan her adımı doğrular, her birinin EIP-712 mesajını imzalar ve bir doğrulama makbuzu basar — aynı anahtarla imzalanmış bir ifade: tam olarak şu içerik hash’lerine sahip niyetleri, tam olarak şu limitler altında, bu zincirdeki bu hesap için doğruladım. İçerik hash’i, imzalanan alt kümeyi değil, her alanı kapsar.
- Planın henüz bilemeyeceği rotayı kur
Ancak şimdi yönlendirme takasın havuzlarını seçer ve gerçek calldata’yı kurar. İkinci bir onayın bütün sebebi budur — baytlar az önce mevcut değildi.
- Tam baytları yetkilendir ve makbuzu denetle
İkinci durak, elindeki şeyin içerik hash’ini yeniden hesaplar ve makbuzla karşılaştırır. Aynı niyet, bit bit — zincirin asla görmeyeceği her alan dâhil. Kapsanmayan tek bir alan değiştiyse hash’ler uyuşmaz ve reddeder.
Makbuz tek bir kesin iş yapar: “bu geçerli mi?” sorusunun — ki birinci durak onu zaten yanıtladı ve ikincisi faydalı biçimde yeniden yanıtlayamaz — yerine gerçekten önemli olan “bu aynı mı?” sorusunu koyar. İkinci durağın yalnızca ikinci durakta öğrenebileceği şeyleri, örneğin rotanın iyi dolup dolmadığını, orada öğrenmeye devam eder. Tazelik makbuzdan asla güvenilerek alınmaz; 12:00’de basılmış bir makbuz 12:20 hakkında hiçbir şey söylemez, bu yüzden zamanlama her hâlükârda yeniden denetlenir.
Bir işlemin ne yaptığına bakan denetim
Yukarıdakilerin tamamı işlemin onaylanan işlem olduğunu kanıtlar. Güvenli olduğunu kanıtlamaz — doğru imzalanmış, doğru eşleşmiş bir niyet yine de berbat dolan bir havuzdan geçebilir veya arkasında bir onay bırakabilir. Bu yüzden herhangi bir şey yayınlanmadan önce onu çalıştırırız.
Simülatör işlemi gerçek ve güncel bir bloğa karşı yayınlamadan çalıştırır —
debug_traceCall — ve her çağrıyı, logu ve durum değişikliğini bildirir. Sonra tek bir kural
sonucu yargılar. Sistemdeki, ne istendiğine değil bir işlemin ne yaptığına bakan tek kuraldır.
- Planın beyan etmediği net bir kayıp
- Hesap yalnızca planın kaybettiğini söylediği kadarını kaybedebilir. Ötesindeki her şey reddedilir.
- Geriye kalan herhangi bir onay
- Her (sahip, harcayan) onayı sıfırda bitmelidir. Ayakta kalan bir onay, bir saldırganın geride bırakabileceği en değerli şeydir — işlemden sonra da yaşar ve başka hiçbir şey onu aramaz.
- Tabanın altında bir çıktı
- Planın satın aldığı şey, planın zaten imzaladığı tabanda ya da üstünde gelmelidir. Kötü dolan bir rota zincirde geri dönmek yerine burada, ucuza ve gazdan önce reddedilir.
- Hiçbir adımın taşımadığı bir NFT
- Planda bir adım taşımadıkça hiçbir pozisyon ya da token hareket etmez. Bir Uniswap pozisyonu bir NFT'dir ve id'si daha önce tutar sanılmış bir sayıdır.
Bunu mümkün kılan hile, simülasyonun gerçek sayıları döndürmesidir; böylece fiyat oracle’ına ihtiyacı olmaz — planın zaten taşıdığı tabanla karşılaştırır. Ve geri dönen bir çağrı, etrafından dolaşılacak bir hata değildir; bulgunun kendisidir. Paketteki herhangi bir çağrı geri dönerse işlemin hiçbir etkisi kalıcı olmaz, ve yayından önce reddetmek boşa gaz yakan bir zincir geri dönüşünü ucuz ve okunaklı bir hayır’a çevirir.
Boşluktaki her şey kapalı başarısız olur
Bunları yan yana dizin: her adımda biçim aynıdır — güvenli cevap hayır’dır ve varsayılan odur.
Sınırlandırılmamış bir koruma reddeder. Eksik bir makbuz reddeder. Uyuşmayan bir içerik hash’i reddeder. Planla uyuşmayan bir simülasyon reddeder — tek bir bayt yayınlanmadan önce. Bunların hiçbiri imza değildir. İmza hiçbir zaman zor kısım olmadı; yalnızca birinin bir şeyi onayladığını kanıtladı. Hat, bunun şu şey olduğunu ve şu şeyin planın dediğini yaptığını kanıtlamak için var.
Bunların herhangi biri nasıl değerlendirilir
Bu sayfaya güvenmeniz gerekmiyor. Gerçek bir yürütme hattını bir imza ve bir dualdan ayıran soru kısadır: onaylandığı an ile indiği an arasında ne denetleniyor?
Cevap “imza doğrulanıyor” ise, imzanın kapsamadığı her alan açıktır ve calldata’yı kuran her ne ise ona tamamen güvenilmektedir. Cevap bir içerik makbuzu ve bir etki simülasyonu adını veriyorsa, bir imzanın yapamadığı iki şey — aynılığı kanıtlamak ve gerçekte ne olduğunu yargılamak — bunu yapabilen bir şey tarafından yapılıyor demektir.