13 Ağustos 2026 itibarıyla, HKDAP'ın (Anchorpoint) BlockSec tarafından yapılan bir güvenlik ve uyumluluk incelemesi.
Özet. Hong Kong'da ihraç edilen ilk düzenlenmiş stablecoin olan HKDAP'ın, Ethereum ana ağında canlı olarak çalışan dağıtılmış kontratını inceledik ve üretime hazır değil. KYC ve iptal kontrolleri yazıldığı gibi çalışmıyor, yönetişimi tek bir anahtarın basabileceği, yakabileceği veya dondurabileceği kadar merkezileşmiş durumda ve zincir üzerindeki birçok özelliği HKMA'nın kendi yönergesiyle çelişiyor. Altta ortak bir tema var: kontrat, ekosistemin zaten sağladığı ve ölçekte denetlediği ilkelleri (bir multisig, bir erişim kontrolü katmanı, bir zaman kilidi, ERC-20'nin kendisi) sıfırdan yeniden icat ediyor ve aşağıdaki kusurların çoğu, standart bileşenleri yeniden kullanan kısımlarda değil, bu özel yapıda yaşıyor. "Beta Erişim" etiketi bu boşluğu kapatmıyor.
12 Ağustos 2026'da Anchorpoint, bir Hong Kong doları stablecoin'i olan HKDAP'ın ilk aşamasını başlattı. Bu önemli bir lansman. Standard Chartered Bank (Hong Kong) liderliğinde, HKT ve Animoca Brands'in de dahil olduğu bir ortak girişim olan Anchorpoint, 36 başvuru sahibi arasından HKMA'nın verdiği sadece iki stablecoin ihraççı lisansından birine sahip ve HKDAP, Hong Kong'un Stablecoin Yönetmeliği kapsamında ihraç edilen ilk stablecoin'ler arasında.
Düzenlenmiş bir bankanın çoğu ürününden farklı olarak, HKDAP doğrudan incelenebilir durumda. Ethereum ana ağında çalışıyor ve kontrat kaynak kodu Etherscan'de doğrulanmış. Bu yararlı bir özellik: bu şekilde ihraç edilen bir stablecoin için, ihraç, transfer ve dondurma kurallarını yöneten kurallar bir belgede tarif edilmiyor, herkesin okuyabileceği ve yazıldığı şekilde çalışan kodda uygulanıyor. Bir lisans bir iddiadır; dağıtılmış kontrat ise bu iddianın uygulamasıdır ve kamuya açıktır.
Bu durum somut bir incelemeyi mümkün kılıyor ve biz de bunu yaptık. Dağıtılmış kontratı iki eksen üzerinden inceledik. Birincisi, yazılım olarak: doğru ve üretim seviyesinde mi? İkincisi, düzenlenmiş bir stablecoin olarak: zincir üzerindeki davranışı HKMA'nın Lisanslı Stablecoin İhraççılarının Denetimine İlişkin Yönergesi ile eşleşiyor mu?
Bulgular her iki eksende de tutarlı. Kontrat, yazıldığı gibi çalışmayan uyumluluk kontrolleri de dahil olmak üzere birden fazla işlevsel kusur içeriyor. Yönetişimi son derece merkezileşmiş durumda ve birkaç yüksek riskli işlem tek bir anahtarla yürütülebiliyor. Ve zincir üzerindeki bazı özellikleri HKMA yönergesinin belirli maddeleriyle çelişiyor. Değerlendirmemiz, kontratın beta aşamasında olsa bile, ticari bir stablecoin'in gerektirdiği kalite çubuğunu karşılamadığı yönünde.
Bu makalenin kalanı, 13 Ağustos 2026 tarihi itibarıyla geçerli olan bu incelemeyi sunuyor. İncelememiz kamuya açık olarak dağıtılmış kod ve gözlemlenebilir zincir üzerindeki gerçeklere dayanmaktadır. Rezerv desteği veya zincir dışı anahtar saklama gibi blok zincirin belirleyemeyeceği konularda hiçbir iddiada bulunmuyoruz.
Kontratı nasıl bulduk
Bir token listesinden değil, ihraççıdan başladık. Anchorpoint'in şirket varlığı, anchorpoint.hk adresindeki sitesine bağlantı veriyor. Beta Erişim sayfası dağıtımı belirtiyor: Ethereum ana ağı, proxy 0x87622385F960fcCB3121d6D0A9513bd1D9Bed6cA, kaynağı Etherscan'de doğrulanmış.
Buradan yola çıkarak tüm sistemi zincir üzerinde haritaladık: token proxy'si ve uygulaması (ControllableAHKD, 0xe42d38b05d7ff702193ac5ccedb411b7298ffbfc), onu yöneten yönetişim kontratı (0x47dd47a776902bee03abdd5aeff43f41b0ffbc2b), en üst düzey rol kayıt defteri (0xa7287701f7ab8f38ef57cdb2a2a69a40128ec89c) ve her biri kendi yönetişim kontratına sahip beş uyumluluk modülü. Aşağıdaki her ilişki, yalnızca kaynak koddan çıkarılmadı, ana ağda depolama slotlarını okuyup görüntüleme fonksiyonlarını çağırarak doğrulandı.
Kontrat nasıl görünüyor
HKDAP'ın üç katmanı: bir yönetişim kontrol düzlemi token'ı yönetiyor ve token, her transferde beş uyumluluk modülünü sorguluyor.

HKDAP'ın token'ı OpenZeppelin'in standart ERC-20 referans uygulamasını kullanmıyor; ERC-20 mantığı sıfırdan yazılmış (aşağıdaki bazı hataların kaynağı da burası). Sistem üç katmandan oluşuyor:
- Token. Yükseltilebilir bir proxy'nin arkasında
ControllableAHKD. Basma, yakma, duraklatma ve zorla yok etme özelliklerine sahip, her transfere kablolanmış uyumluluk kontrolleriyle birlikte kontrollü bir ERC-20. - El yapımı bir M-of-N yönetişim motoru. Her yetkili işlem (yükseltme, basma, yakma, duraklatma, kara listeye alma, dondurma, uyumluluk modülü değiştirme), düz bir multisig yerine bir talep, onay, yürütme törenine giriyor.
- Beş uyumluluk modülü. Kara liste, dondurma, bir KYC etkinleştirme servisi ve mevduat ile geri ödeme beyaz listeleri. Her modülün kendisi de kendi kontrol yetkisi kontratı tarafından yönetilen bir proxy.
Yapısal olarak, bu aynı "kontrol yetkisi artı proxy artı uygulama" birimi altı kez tekrarlanıyor (token artı beş modül) ve tüm altı kontrol yetkisi rollerini tek bir kayıt defterinde çözümlüyor. Sistemdeki tüm kontrol nihai olarak bu bir kayıt defterinde toplanıyor ve içindeki rolleri kimin yeniden yazabildiği, aşağıda ayrıntılı olarak gösterdiğimiz gibi, çok küçük bir imzacı anahtarı kümesine bağlı.
Bölüm 1: Güvenlik ve hatalar
Bu bölümdeki bulgular aşağıda özetlenmiştir; her satır belirtilen bölümde ayrıntılı olarak açıklanmıştır.
| Alan | Bulgu | Konum | Etki |
|---|---|---|---|
| 1.1 KYC ve iptal kontrolleri başarısız | KYC iptali işlevsiz kod | TokenHolderActivationServerLibrary.sol:221-235 |
isActive, sağlayıcı kayıt silme işlemini görmezden geliyor (döngü hiç çalışmıyor ve = yerine == kullanılıyor); güvenlik açığı oluşturuyor (fail-open). |
| Doğrulayıcı kayıt silme işlemi asla INACTIVE'e ayarlanmıyor | TokenHolderActivationServer.sol:504-511 |
"Kaydı silinmiş" bir doğrulayıcı hâlâ cüzdanları etkinleştirebilir ve devre dışı bırakabilir; ikinci bir çağrı geri döner (revert). | |
| KYC kanıtı zincir üzerinde asla doğrulanmıyor | TokenHolderActivationServer.sol:575-578 |
Kanıt içeri aktarılır ama kullanılmaz; boş bir dize de dahil olmak üzere herhangi bir kanıt geçer. | |
| Ücretsiz transfer istisnası dolambaçlı yolla aşılabilir | ControllableAHKD.sol:337-535 |
freeTransferLimit çağrı başına kontrol edilir, birikimli olarak değil; KYC yapılmamış faaliyet üzerinde bir üst sınır olarak kullanılırsa, limitin altında alt işlemlere bölünerek atlatılabilir. |
|
| 1.2 Yönetişim aşırı derecede merkezileşmiş | Yüksek riskli işlemler tek imzalı | authorizationMatrix; mint tx 0xa7e53c…b33d7 |
mint / burn / freeze / KYC-devre dışı bırakma (rol C), pause / destroy (rol D), kara listeye alma / dondurmayı kaldırma (rol F) her biri tek bir anahtarla yürütülüyor. |
| Bir anahtar çifti (A + B) her şeyi yükseltebiliyor | authorizationMatrix |
Token ve beş modülün tümü için upgradeTo, rol A + B; iki kişi herhangi bir uygulamayı değiştirebilir. |
|
| Aynı çift her rolü yeniden yazabiliyor | kayıt defteri 0xa728… authorizationMatrix |
Kayıt defterinde grantRole / revokeRole de rol A + B (ADMIN_ROLE yalnızca kontrat tarafından tutuluyor; DEFAULT_ADMIN_ROLE = address(0)); harici hiçbir anahtar rolleri doğrudan değiştiremez. |
|
| Bir adres altı rol tutuyor | rol kayıt defteri 0xa728… |
0x2f7f00… rol C'ye ek olarak ADMIN_TOKEN_HOLDER ve dört denetçi rolünün tümünü tutuyor; yürütme ve denetim örtüşüyor. |
|
| İptal anında değil; zaman kilidi yok | HybridControlEngine.sol:158-227 |
Sayılan bir imza, bir rol iptal edildikten sonra yeniden doğrulanmıyor; yürütme son imzayla aynı anda gerçekleşiyor, gecikme yok. | |
| Motorun denetim izi güvenilir değil | HybridControlEngine.sol:36-129, 177-196 |
evtApprove, imzacı olarak address(0) yayınlıyor; etkin talep listesi nonce 0'ı hem gerçek bir kimlik hem de boş işaretçi olarak kullanıyor, bu yüzden ters yönde tarama ilk talebi kaçırıyor. |
|
| 1.3 Tutarsız transfer kontrolleri | transfer ve transferFrom farklı kurallar uyguluyor |
ControllableAHKD.sol:313-502 |
Beyaz liste erken dönüşü KYC'yi yalnızca transferFrom üzerinden atlatıyor; checkingMode farklı tarafları kontrol ediyor; aynı transfer farklı şekilde yönetiliyor. |
| 1.4 Üretim öncesi bir yapının işaretleri | hata ayıklama günlükleri, yanlış yorum, isim/hash uyumsuzluğu, testler yüklenmiş | UpgradeableProxy.sol:115-119; ControllableAHKD.sol:25 |
Proxy fallback'inde console.log (kalıcı gaz); proxy yorumu kodla çelişiyor; rol adı/hash uyumsuzluğu; testler dahil 117 dosya yüklenmiş; optimizer runs = 0. |
| 1.5 Tek yükseltme kusurları olduğu gibi bıraktı | tek yükseltmeyi izleme | tx 0x742372…85136, 0xa7a400…630c |
Dağıtım 28 Nisan → yükseltme 10 Temmuz; A + B töreninin iki işlemi bir blok arayla (~12 saniye) gerçekleşti; Bölüm 1'deki her kusur, kurulu uygulamada mevcut. |
1.1 KYC ve iptal kontrolleri yazıldığı gibi çalışmıyor
Düzenleme kapsamında, HKDAP'ın hizmet verdiği B-tarafı (kurumsal) kullanıcıların KYC'den geçmesi gerekiyor. Kontratta bu, en az iki şeyi yapması gerektiği anlamına gelir: transferlerde KYC'yi uygulamak, böylece KYC'den geçmemiş bir cüzdan engellenir, ve bir kimlik sağlayıcı veya bir hesap sahibi kaldırıldığında erişimi iptal etmek. HKDAP'da bu süreç üç bağımsız noktada bozuk.
KYC iptali işlevsiz kod. Token, KYC modülünde isActive(address) çağırarak transferleri denetler. isActive'in iki şeyi yapması gerekir: önce, bir cüzdanın devre dışı bırakılma sayısından daha fazla KYC etkinleştirilme sayısına sahip olduğunda etkin kabul edilerek, cüzdan başına bir sayaçtan taban bir değer belirlemek; sonra, cüzdanı doğrulayan herhangi bir kimlik sağlayıcının kaydı silinmişse bu değeri false'a indirgemek. Bu iki durum iki tür iptali kapsıyor, bir hesap sahibinin KYC'sinin iptali (sayaç) ve bir sağlayıcının tamamen iptal edilmesi ve onun kaydettiği her cüzdanın onunla birlikte düşmesi (döngü). Sadece birincisi gerçekleşiyor.
// contracts/hce/erc20/libs/TokenHolderActivationServerLibrary.sol
221 active = ( tokenHolderRegistration[_address].deactivationCount < tokenHolderRegistration[_address].activationCount ) ;
223 uint256 entryCount = 0 ;
224 uint256 index = chainedItemList.firstEntry ; // 0 if such ChainedList is empty
226 while ( entryCount > chainedItemList.entryCount && active ) {
227 ChainedListLibrary.ChainedItem storage chainedItem = identityProvidersByStatuss[index] ; // deregistered provider
230 // NDLR: .... not too sure about that one to be frank
231 active == ( tokenHolderKYCProofDirectoryByProvider[_address][identityProviders[chainedItem.objectId].identifier] == 0 ) ;
233 entryCount++ ;
234 index = chainedItem.pointNext ;
235 }
- satır gerçek bir atamadır (
=) ve etkili olan tek satır da bu:active,deactivationCount < activationCountolur. Bu değeri indirgemesi gereken döngü (226-235. satırlar) iki nedenle başarısız olur. 226. satırdaki koşul,entryCount > chainedItemList.entryCount,0 > N'dir, bu yüzden gövde hiç çalışmaz; ve çalışsa bile, 231. satır sonucu atılan bir karşılaştırma olan==kullanır, oysa=ile atama yapması gerekir. Bu yüzdenisActivesadece sayaç karşılaştırmasını döndürür ve sağlayıcı iptalini tamamen görmezden gelir. Bu bir güvenlik açığı oluşturuyor (fail-open): tehlikeye girmiş bir KYC sağlayıcısının kaydını silmek, onun kaydettiği cüzdanların işlem yapmasını durdurmaz. VeunregisterVerifierbu sayaçlara dokunmadığı için, iptal edilmiş bir sağlayıcının cüzdanları pozitif bir sayaç değeri tutmaya ve etkin kalmaya devam eder.
Sağlayıcı iptali diğer taraftan da bozuk. unregisterVerifier sadece bağlantılı listede bir düğümü taşır; sağlayıcının kayıt defteri durumunu asla INACTIVE'e ayarlamaz:
// contracts/hce/erc20/modules/TokenHolderActivationServer.sol
504 function _unregisterVerifier(string calldata _verifierId) internal {
505 _removeToList(_verifierId, ACTIVE_IDENTIY_PROVIDER, "60a");
507 uint256 _ipIdx = identityProviders.length - 1;
508 uint256 _newIdx = identityProvidersByStatuss.length + 1;
510 _addToList(_ipIdx, _newIdx, INACTIVE_IDENTIY_PROVIDER, _verifierId, "60b");
511 }
Durum ACTIVE olarak kaldığı için, "kaydı silinmiş" bir doğrulayıcı hâlâ hesap sahiplerini kaydedebilir ve devre dışı bırakabilir, bir sağlayıcıyı yeniden etkinleştirmesi gereken dal ulaşılamaz durumda kalır ve ikinci bir unregisterVerifier çağrısı taşma (underflow) yaparak geri döner (revert).
KYC kanıtı zincir üzerinde asla doğrulanmıyor. Yetkili bir doğrulayıcı, registerOrRenew aracılığıyla bir cüzdanı kaydettiğinde veya yenilediğinde (sadece o an aktif olan bir doğrulayıcının çağırabileceği şekilde kısıtlanmış), akış gönderilen kanıtı sağlayıcının şemasına göre doğrulaması gereken _checkKYCProof'a ulaşır. Arayüze göre, bu kanıt "bir Oracle için bir URI veya doğrulanabilir bir kaynaktan imzalanmış bir hash"tir. Fonksiyon bunu görmezden gelir:
// contracts/hce/erc20/modules/TokenHolderActivationServer.sol
575 function _checkKYCProof( string memory _ipIdentifier, string memory, string memory _rcCode ) internal view returns ( bool isVerified ) {
576 require( identityProviderDirectory[_ipIdentifier].status == ACTIVE_IDENTIY_PROVIDER, string.concat(ERROR_404, _rcCode, "41b")) ;
577 return true ;
578 }
Kanıt bu fonksiyona ulaşıyor. registerOrRenew, gönderilen kycProof'u _registerOrRenew aracılığıyla taşır ve ikinci argüman olarak iletir. Ancak 575. satırda bu argüman, üstündeki belge yorumunun da atladığı, adı hiç olmayan bir parametreye düşer ve gövde asla okunmaz. Fonksiyon sadece sağlayıcının aktif olduğunu 576. satırda doğrular ve 577. satırda true döndürür, böylece kanıt kontrol edilmek yerine atılır. Bu bir dış saldırgan atlatması değildir, çünkü buraya sadece aktif bir doğrulayıcı ulaşabilir, ama zincir üzerinde kontrat KYC kanıtının hiçbir doğrulamasını yapmıyor, bu yüzden bütünlüğü tamamen zincir dışı doğrulayıcıya bağlıdır. Tehlikeye girmiş veya dikkatsiz bir doğrulayıcı, boş bir dize de dahil olmak üzere herhangi bir kanıtla herhangi bir cüzdanı etkinleştirebilir.
Birlikte ele alındığında, bu üç unsur, temel bir uyumluluk özelliğinin, erişimi kısıtlama ve iptal etme yeteneğinin, yazıldığı gibi çalışmadığı anlamına gelir.
Bu üçünün ötesinde, ilgili bir zayıflık var: ücretsiz transfer istisnası dolambaçlı yolla aşılabilir. Token'ın bir freeTransferLimit'i var ve bunun altındaki bir transfer isActive (KYC) kontrolünü atlar. Ancak limit sadece geçerli transferin miktarıyla karşılaştırılır; kontrat adres veya dönem başına birikimli bir toplam tutmaz. Bu yüzden limit KYC yapılmamış faaliyet üzerinde bir üst sınır olarak kullanılıyorsa, bir hesap sahibi limitin hemen altında olan tekrarlanan transferlere bölerek keyfi bir toplam miktarı taşıyabilir, bu da üst sınırı etkisiz kılar.
1.2 Yönetişim aşırı derecede merkezileşmiş ve yüksek riskli işlemler tek imzalı
M-of-N törenlerini yetkilendiren her rolü ve her rol sahibini zincir üzerinde listeledik. Ayrıntılara girmeden önce iki şey göze çarpıyor.
Birincisi, M-of-N törenlerini yetkilendiren rollerin okunabilir adları yok. Dağıtılan yapılandırmada sadece 32 bayt hash olarak görünüyorlar ve hiçbiri doğrulanmış kaynak koddaki adlandırılmış bir rol sabitiyle eşleşmiyor (SUPPLY_CONTROLLER_ROLE gibi adlandırılmış roller kontratların kendisi tarafından tutuluyor, imzacılar tarafından değil). Altı imzacı rolünü A'dan F'ye kadar etiketliyoruz. Sistemdeki en güçlü rollerin şeffaf olmayan tanımlayıcılar olması bir zayıflığın kendisidir: yönetişimi, adlandırılmış rollerin olacağından daha zor gözden geçirilebilir hale getiriyor.
İkincisi, sahip sayısı az. Aşağıdaki tablo zincir üzerindeki rol kayıt defterinden okunmuştur; adresler kısaltılmıştır.
| Rol (bizim etiketimiz) | Zincir üzerindeki hash | Sahip(ler) | Neyi yetkilendiriyor |
|---|---|---|---|
| A | 0x37f0f656… |
0x747356d525bf47f495af7c6e42f3ab9b8ba87a4b |
upgradeTo / changeAdmin / setControlAuthority için ilk imza |
| B | 0x95c27f81… |
0x8117a657df7a1c399231bfe26a096eb8f8ad5973, 0x5d9d9b28e83382e694916b0feeaf7a9badbb659c, 0xebb73f78e253539acceb4e6cc287095788eee5d4 |
neredeyse her iki imzalı işlem için ikinci imza |
| C | 0xfa2fe896… |
0x2f7f00cc5334fe2861e485ff610f74890a0316ed |
mintToDeposit, burnFrom, freeze, KYC devre dışı bırakma (tek) |
| D | 0x3dce3265… |
0x5092af62a1625fa57404557d3ad417474f3f494c |
pause, destroyBlackFunds, mevduat ve geri ödeme adreslerini kaydetme/kaydını silme, registerVerifier (tek) |
| E | 0xfd21a76d… |
0xa9315aadc89ba681f1fe5df3375ab1a87d37eca2 |
uyumluluk modüllerini değiştirme (setBlacklistServer vb.) |
| F | 0x510ac1ff… |
0x7daabe5092d3feea5cc19ddbb5380a4eac38f89c |
addBlackList, unfreeze (tek) |
Tablodan birkaç nokta ortaya çıkıyor.
Tek imzacılı yüksek riskli işlemler. Yüksek riskli işlemlerin çoğu tek bir rolü, bir kotasıyla gerektiriyor. Aşağıdaki tablo, token'ın yönetişim kontratının ve beş modül yönetişim kontratının authorizationMatrix'inden zincir üzerinden okunmuştur (bir ikinci imza gösterilmedikçe tek imza gerektirir):
| İşlem | Yöneten | Gerekli imzalar |
|---|---|---|
mintToDeposit, burnFrom |
token | C x1 |
freeze, batchFreeze |
dondurma modülü | C x1 |
deactivate, adminDeactivate (KYC) |
KYC modülü | C x1 |
pause, destroyBlackFunds |
token | D x1 |
register, unregister (mevduat / geri ödeme) |
dizin modülleri | D x1 |
registerVerifier, unregisterVerifier |
KYC modülü | D x1 |
addBlackList, batchBlackList |
kara liste modülü | F x1 |
unfreeze |
dondurma modülü | F x1 |
removeBlackList |
kara liste modülü | F x1 + B x1 |
setBlacklistServer, setFreezingServer, setCheckingMode |
token | E x1 + B x1 |
| dizin sunucusu ve arz limiti ayarlayıcıları | token | D x1 + B x1 |
upgradeTo / changeAdmin / setControlAuthority (token ve her modül), unpause |
token + modüller | A x1 + B x1 |
İhraç, dondurma ve KYC devre dışı bırakma tek imzalıdır (tümü rol C altında); duraklatma, yok etme, dizin değişiklikleri ve doğrulayıcı kaydı rol D altında tek imzalıdır; kara listeye alma ve dondurmayı kaldırma rol F altında tek imzalıdır. Sadece yükseltmeler ve yapılandırma değişiklikleri ikinci bir imza alır. Asimetriye dikkat edin: freeze ve addBlackList bir imza gerektirir, removeBlackList ise iki imza gerektirir, bu yüzden bir hesabı kısıtlamak, onu serbest bırakmaktan daha kolaydır.
Bu sadece matrisin bir okuması değil; canlı bir basımda gözlemlenebilir. Bu yazının hazırlandığı sıradaki en son ihraç, tx 0xa7e53c…b33d7, tek rol-C hesabı (0x2f7f00cc5334fe2861e485ff610f74890a0316ed) tarafından token'ın yönetişim kontratına gönderilen tek bir işlemdir. request'i çağırır ve aynı işlem kotaya ulaşır ve address(0)'dan mint Transfer'ini yayınlar, ayrı bir onay işlemi olmadan ve ikinci bir imzacı olmadan. İhraç, talep edenin kendi işlemi içinde tamamlandığı için, bir anahtar mint'i hem talep etti hem de yürüttü.
Motorda herhangi bir zaman kilidi de yok. Gereken son imza yerleştiği anda, işlem incelenebileceği, iptal edilebileceği veya itiraz edilebileceği bir gecikme olmaksızın aynı işlem içinde yürütülür; motor bir executedAt zaman damgası kaydeder ama bunu asla kontrol etmez. Bu yüzden iki imzalı işlemler de ikinci anahtar imzaladığı anda anında tamamlanır.
Bir anahtar çifti her şeyi yükseltiyor. Token'ı yükseltmek ve beş uyumluluk modülünün tamamını yükseltmek aynı gereksinimi kullanır, A artı B. A bir hesap olduğu ve B bir rolü paylaşan üç hesap olduğu için, iki kişi sistemdeki herhangi bir uygulamayı değiştirebilir.
Aynı çift ayrıca rol tablosunu da kontrol ediyor. Roller sadece kayıt defterinde (HybridControlledAuthority, 0xa7287701f7ab8f38ef57cdb2a2a69a40128ec89c), kendi töreni aracılığıyla verilebilir ve iptal edilebilir; harici hiçbir anahtar bunları doğrudan değiştiremez. Ve zincir üzerinden okunan authorizationMatrix'i, bir rol değişikliği için de bir yükseltme için olduğu gibi aynı imzaları gerektirir: rol A artı rol B. Yani herhangi bir uygulamayı değiştirebilen iki kişi, aynı zamanda rol C'ye bir anahtar ekleyebilir, mevcut bir sahibi kaldırabilir ve tüm rol tablosunu yeniden yazabilir. Bu iki imzalı geçit, yukarıdaki tek imzalı işlemlerden daha iyidir, ama sistemin köküne göre yine de düşük bir çubuktur, çünkü rol A yedeksiz tek bir hesaptır.
Bir adres, altı rol. Rol C sahibi (0x2f7f00cc5334fe2861e485ff610f74890a0316ed) ayrıca adlandırılmış ADMIN_TOKEN_HOLDER_ROLE'a (KYC doğrulayıcı yönetimi) sahip ve dört denetçi rolünün (BLACKLIST_AUDITOR_ROLE, FREEZING_AUDITOR_ROLE, WHITELIST_AUDITOR_ROLE ve AFL_TOKEN_AUDITOR_HOLDER_ROLE) tümüne üye. Bu bir anahtarın tehlikeye girmesi, ihraç, dondurma ve KYC yönetiminin aynı anda kaybı anlamına gelir.
Denetçi rollerinin kendi başlarına iki sorunu var. Birincisi, bunlar uyumluluk listeleri için salt okunur getter'ları görünüşe göre kimin okuyabileceğini kontrol etmek amacıyla kısıtlıyor, ama kamuya açık bir zincirde bu anlamsız: altta yatan depolama alanı herkes tarafından okunabilir (depolama slotlarını okumak bu sistemi haritalama yöntemimizdi), bu yüzden listeler her iki durumda da kamuya açıktır ve bu kısıtlama tasarımın kamuya açık bir zincirde olacağını hesaba katmadığını gösterir. İkincisi, konsantrasyon: dört denetçi rolünün tümü aynı 23 hesapta oturuyor ve yürütme rollerinin A, C, D ve F sahipleri de bunların arasında, bu yüzden basım, yakım, dondurma ve kara listeye alma yapan aynı anahtarlar, bu işlemleri gözden geçirmesi gereken gruba da oturuyor.
İptal anında değil. Tören motorunda, bir imzacının rolü bir kez kontrol edilir ve kota düşürülür; önceki imzacılar asla yeniden doğrulanmaz, bu yüzden sonradan bir rolü iptal etmek daha önce sayılmış bir oyu geri çekmez:
// contracts/hce/HybridControlEngine.sol
158 for ( uint256 i=0; i < approvalRequest.ceremony.length; i++ ) {
159 if ( !_hasBeenMandated && !approvalRequest.ceremony[i].completed &&
160 IControlAuthority(authorityContract).hasRole( approvalRequest.ceremony[i].expectation.authority, _signer ) ) {
161 _hasBeenMandated = true ;
163 approvalRequest.ceremony[i].expectation.quota-- ;
167 approvalRequest.ceremony[i].completed = _approvalIntent && approvalRequest.ceremony[i].expectation.quota == 0 ;
168 }
Son olarak, motorun kendi denetim izi güvenilir değil. Her onayda, evtApprove olayı, gerçek onaylayan yerine imzacı olarak address(0) yayınlar; gerçek imzacı sadece işlem gönderende ve dahili bir kayıtta hayatta kalır, bu yüzden olay günlükleri bir talebi kimin onayladığını gösteremez. Ve etkin talep listesi nonce 0'ı hem gerçek bir talep kimliği hem de boş işaretçi olarak kullanır, bu yüzden listeyi geriye doğru dolaşan izleme veya onay araçları nonce 0'daki talebi kaçırır. Hiçbiri kritik değil, ama temiz bir denetim izine ihtiyaç duyan düzenlenmiş bir sistem için her ikisi de bundan eksiltiyor.
1.3 Transfer kontrolleri transfer ile transferFrom arasında tutarsız
İki fonksiyon arasındaki farkın bir kısmı beklenen bir durumdur. transferFrom'da başlatıcı, msg.sender, fonların kaynağı yerine onaylanmış bir harcayıcıdır, bu yüzden kod her modda gerçek kaynak from'u açıkça kontrol eder; transfer'in buna gerek yoktur, çünkü orada msg.sender kaynaktır. Bu uyarlama mantıklıdır. Diğer iki fark başlatıcı ile açıklanamıyor ve aynı ekonomik işlemi farklı kurallara tabi bırakıyor.
Birincisi, mevduat ve geri ödeme beyaz listeleri sadece transferFrom yolunda danışılır, burada üyelik isActive (KYC) kontrolünü atlayan erken bir dönüşe tetikler. transfer bunlara asla danışmaz. Bir alıcının beyaz listede olup olmadığının transferi kimin başlattığıyla hiçbir ilgisi yoktur, bu yüzden aynı alıcı transfer üzerinden KYC'ye tabidir ama transferFrom üzerinden bunu atlayabilir:
// contracts/hce/ControllableAHKD.sol : transfer(), "Source" modu sadece gönderen için geçerlidir
323 else if ( activateMode == ActivateMode.Source )
325 _transferCheckSourceMode(_value, "80h");
// contracts/hce/ControllableAHKD.sol : transferFrom() -> _transferFromCheckDestinationMode(_to)
428 try depositDirectoryServer.isRegistered(_to)
429 returns ( bool isIt, IWhitelistServer.WalletAddress memory ) {
430 if ( isIt ) { return ; }
436 try redemptionDirectoryServer.isRegistered(_to)
437 returns ( bool isIt, IWhitelistServer.WalletAddress memory ) {
438 if ( isIt ) { return ; }
444 try tokenHolderActivationServer.isActive(_to) returns ( bool isIt ) {
445 require(isIt || _value < freeTransferLimit, string.concat(ERROR_404, _rcCode, "/86a" ) ) ;
İkincisi, checkingMode iki fonksiyon arasında farklı anlamlara geliyor. transfer'de, "Source" modu göndereni kontrol eder; transferFrom'da, "Source" modu harcayıcıyı (msg.sender) kontrol eder, from her modda kontrol edilirken. Bu yüzden tek bir yapılandırma ayarı, giriş noktasına bağlı olarak iki farklı politikayı uygular.
Etki, düzenlenmiş bir token'ın transfer kontrollerinin hangi fonksiyonun kullanıldığına bağlı olması ve bunun da akıl yürütmeyi zorlaştırması ve yapılandırmaya bağlı olarak atlatılabilir olmasıdır.
1.4 Üretim öncesi bir yapının işaretleri
Belirli mantık hatalarının ötesinde, kod tabanının birkaç özelliği, ana ağa üretim öncesi bir yapının dağıtıldığını gösteriyor.
Üretimde hata ayıklama günlüğü. hardhat/console.log çağrıları, her kullanıcı işleminde çalışan proxy'nin fallback'i içinde de dahil olmak üzere her yerde kalıyor. Proxy'nin kendisi yükseltilebilir olmadığı için, bu ek yük kalıcıdır:
// contracts/proxy/UpgradeableProxy.sol
115 function _beforeFallback() internal virtual override {
116 console.log("iam %s, entering fallback as %s", address(this), msg.sender) ;
117 // require(msg.sender != _getAdmin(), "[UPY]404/02");
118 super._beforeFallback();
119 }
Kodun tam tersini tanımlayan bir proxy başlık yorumu. Aynı dosya, yöneticinin uygulamaya asla düşemeyeceğini belirten OpenZeppelin'in TransparentUpgradeableProxy belgesini taşır. Bu kontrat kasıtlı olarak tersini yapıyor: 117. satırdaki koruma yorum satırı haline getirilmiş ve yönetici gerçekten de düşüyor. Yoruma güvenen bir gözden geçiren, güven sınırını yanlış modelleyecektir.
Hash'leriyle eşleşmeyen rol adları. "Yüksek risk" rolü, token'da ve modüllerde aynı sabit adla ama farklı bir keccak dizesiyle bildiriliyor, bu da iki farklı rol üretiyor:
// contracts/hce/ControllableAHKD.sol (token) hash = 0xd2b9...
25 bytes32 internal constant ELEVATEDRISK_OWNER_ROLE = keccak256('ELEVATED_RISK_OWNER_ROLE') ;
// contracts/hce/erc20/modules/BlackListServer.sol (module) hash = 0x4de4...
18 bytes32 internal constant ELEVATEDRISK_OWNER_ROLE = keccak256('ELEVATEDRISK_OWNER_ROLE') ;
Dağıtım, sorundan sadece her modülün kendi kopyasını tutması sayesinde kaçınıyor; ikinci bir rol adı (AFL_TOKEN_HOLDER_AUDITOR_ROLE) da aynı şekilde ters çevrilmiş.
Diğer işaretler. Proxy'nin doğrulama paketi, projenin test paketi de dahil olmak üzere 117 dosyayı kamuya açık gezgine yükledi, bu da bir okuyucuya dahili testleri ve uç durumları veriyor. En son yükseltme, aradaki üçüncü taraf denetimi olmadan sadece derleyici uyarısı temizliği değiştirdi. Ve optimizer sıfır çalıştırmaya ayarlanmış, bu da yoğun kullanılan bir token'ın sık kullanılan yollarını daha ucuz hale getirmek yerine daha maliyetli hale getiriyor.
Bunların hiçbiri tek başına ciddi değil. Birlikte, kodun ana ağda değer tutan bir kontrattan beklenen yayın disiplininden geçmediğini gösteriyorlar.
1.5 Kontratın tek yükseltmesinin izlenmesi
Proxy bir kez yükseltildi. 28 Nisan 2026'da 0x8ff12fe3bed22d9e40afb4b98ef4dee28d94699e uygulamasıyla dağıtıldı ve 10 Temmuz 2026'da mevcut 0xe42d38b05d7ff702193ac5ccedb411b7298ffbfc'ye yükseltildi. Yükseltme zincir üzerindeki bir yönetişim işlemi olduğu için, onu kimin onayladığını tam olarak görebiliriz.
upgradeTo, rol A artı rol B gerektirir. Yükseltme, birbirine yaklaşık on iki saniye arayla, ardışık bloklarda gerçekleşen iki işlemdi:
- talep, rol A,
0xa9315aadc89ba681f1fe5df3375ab1a87d37eca2'den, 25500519 numaralı blokta (tx0x742372…85136); - onay, rol B,
0x3795300b31429f9d37b0dc805528d9390ce87c50'den, 25500520 numaralı blokta (tx0xa7a400…630c), kotaya ulaşan ve yükseltmeyi aynı işlemde gerçekleştiren.
İki şey göze çarpıyor. Birincisi, tüm iki imzalı tören tek bir blok aralığında tamamlandı. Talepten yürütmeye kadar geçen süre bir bloktu; ikinci imzacının değişiklik canlıya geçmeden bağımsız olarak inceleyebileceği bir pencere yoktu.
İkincisi, mevcut rol kayıt defterinden hiçbir imzacı tanımlanamıyor. Roller o zamandan beri değiştirildi: talep eden 0xa9315a… artık rol A'ya sahip değil (bugün rol E'ye sahip) ve ikinci imzacı 0x3795300b… şu anda hiçbir role sahip değil. Kayıt defterini şu anki haliyle okumak, yükseltmeyi kimin yetkilendirdiğini söylemez; sadece işlem geçmişi bunu söyler. Bu, "iptal anında değil" özelliğinin diğer taraftan görünüşüdür: roller değişir, bu yüzden kimin neye sahip olduğunun bir anlık görüntüsü, kimin ne yaptığının bir kaydı değildir.
Ve yükseltme, bu incelemedeki hiçbir kusuru düzeltmedi. Kurduğu uygulama, 0xe42d38b0…, Bölüm 1'in tümünün tanımladığı uygulamadır. Yükseltmeden önce bir üçüncü taraf denetiminin gerçekleştirilip gerçekleştirilmediğini zincirden anlayamıyoruz; söyleyebileceğimiz şey, eğer gerçekleştirildiyse, Bölüm 1'deki kusurların ondan sağ çıktığıdır.
Bölüm 2: Hong Kong'un stablecoin çerçevesiyle eşleşiyor mu?
Hong Kong'un Stablecoin Yönetmeliği 1 Ağustos 2025'te yürürlüğe girdi ve lisanslı ihraççılar HKMA'nın Lisanslı Stablecoin İhraççılarının Denetimine İlişkin Yönergesi kapsamında denetlenir. Sadece bir akıllı kontratın kendi başına karşılayabileceği maddeleri karşılaştırdık; rezerv desteği, saklama ve zincir dışı anahtar törenleri, zincir üzerindeki bir inceleme kapsamı dışındadır. Aşağıdaki her madde için, yönergenin neyi gerektirdiğini, kontratın ne yaptığını ve ikisinin nerede farklılaştığını belirtiyoruz. Karşılaştırma burada özetlenmiş ve takip eden bölümlerde ayrıntılı olarak açıklanmıştır.
| HKMA maddesi | Ne gerektirir | Kontrat nerede farklılaşıyor | Sonuç |
|---|---|---|---|
| 6.5.3 | Yüksek riskli işlemler tek taraflı olmamalı (çok imzalı, ve hız limitleri veya zaman kilitleri gibi hafifletici tedbirler) | Basma, yakma, duraklatma ve dondurma her biri tek bir anahtarla yürütülüyor; zaman kilidi yok (yürütme son imzayla aynı anda gerçekleşiyor) | Farklılaşıyor |
| 6.5.4 | Yetkili kişiler arasında görevleri ayrıştırın; yetkiyi hemen iptal edin | Bir hesap altı rol tutuyor, bu yüzden yürütme ve denetim örtüşüyor; sayılan bir onay, sonraki bir iptalden sağ çıkıyor | Farklılaşıyor |
| 6.5.5 | Her kod değişikliği için üçüncü taraf denetimi; doğru, tutarlı, güvenlik açıklarından arınmış | Bölüm 1 kusurları, dağıtılmış uygulamada canlı; isActive ve sağlayıcı iptali adlarının işaret ettiğini yapmıyor |
Farklılaşıyor |
| Uyumluluk kontrollerinin etkinliği | Kara liste, dondurma, beyaz liste ve KYC kontrolleri etkili olmalı | KYC kontrolü ve sağlayıcı iptali, dağıtılmış kodda işlevsiz | Farklılaşıyor |
| 2.2.3 | Dondurulmuş veya yok edilmiş coinler tam olarak desteklenmiş ve uzlaştırılabilir kalmalı | Yok etme, address(0) yerine address(this)'e Transfer yayınlıyor ve basım limitinin kullandığı net ihraç sayaçlarını dokunmadan bırakıyor; olaylardan yeniden oluşturulan arz kayıyor |
Endişe konusu |
Madde 6.5.3: yüksek riskli işlemler tek taraflı olmamalı
Ne gerektirir. Yüksek riskli işlemler, örneğin çok imzalı bir protokol aracılığıyla, hiçbir tarafın onları tek taraflı olarak gerçekleştirememesi için tasarlanmalıdır ve yönerge, hız limitleri ve zaman geciktirmeli (zaman kilidi) kontroller gibi ek hafifletici tedbirler listeler.
Kontrat ne yapıyor. Yönetişim kontratının authorizationMatrix'inden okunduğunda (tam matris 1.2'deki tabloda), arz ve acil durum işlemlerinin her biri, bir kotasıyla tek bir rol gerektiriyor:
| İşlem | Gerekli imza |
|---|---|
mintToDeposit |
ROLE_C x1 |
burnFrom |
ROLE_C x1 |
freeze |
ROLE_C x1 |
pause |
ROLE_D x1 |
destroyBlackFunds |
ROLE_D x1 |
Nerede farklılaşıyor. Basma, yakma, duraklatma ve dondurma her biri bir anahtar tarafından yürütülebilir. Bu, "hiçbir taraf tek taraflı olarak" gereksinimini karşılamıyor. Zaman kilidi de yok: 1.2'de gösterildiği gibi, kotaya ulaşıldığında işlem aynı işlem içinde yürütülür, bu yüzden yönergenin adlandırdığı hafifletici tedbirlerden biri olan bir zaman gecikmesi de bulunmuyor. Kontrat gerçekten bir arz hız limiti (whenWithinRiskThresholds) uyguluyor, bu yüzden o hafifletici tedbir mevcut, ama bu, işlemlerin kendisi üzerinde çok imzalı kontrolün yerini almıyor.
Madde 6.5.4: görevlerin ayrıştırılması ve hemen iptal
Ne gerektirir. Farklı işlemler farklı yetkili kişiler arasında ayrıştırılmalı ve yetkili bir kişinin yetkisi hemen iptal edilebilmelidir.
Kontrat ne yapıyor. Bir harici tutulan hesap altı role sahip (ihraç, dondurma, KYC yönetimi ve dört denetçi rolünün tümü), bu yüzden yürütme ve denetim rolleri örtüşüyor. Rol değişikliklerinin kendisi de sadece rol A artı rol B gerektiriyor (bkz. 1.2), bu yüzden aynı küçük grup kimin yetkili olduğuna karar veriyor ve yürütebilir ve yükseltebilir. Ve zaten sayılmış bir imza, imzacının rolü daha sonra iptal edilirse yeniden doğrulanmıyor.
Nerede farklılaşıyor. Görevler ayrıştırılmak yerine yoğunlaştırılmış ve iptal hemen değil: iptal edilmiş bir imzacının önceki onayı, sonraki bir yürütmeye hâlâ katkıda bulunuyor.
Madde 6.5.5: her kod değişikliğini denetle; doğru, tutarlı, güvenlik açığı yok
Ne gerektirir. Nitelikli bir üçüncü taraf, her kod değişikliği için akıllı kontratları denetlemeli ve şunları yüksek bir güven düzeyinde doğrulamalıdır: (i) doğru şekilde uygulandığını, (ii) amaçlanan işlevle tutarlı olduğunu ve (iii) güvenlik açıklarından arınmış olduğunu.
Kontrat ne yapıyor. Mevcut uygulama, 10 Temmuz yükseltmesiyle kurulan uygulamadır (1.5'te izlenmiştir) ve Bölüm 1'deki kusurlar onda canlıdır.
Nerede farklılaşıyor. Zincir dışında bir denetimin yapılıp yapılmadığını göremiyoruz, ama sonuç her iki durumda da standardı karşılamıyor. isActive ve sağlayıcı iptali adlarının işaret ettiğini yapmadığı için, (i) ve (ii) koşulları karşılanmıyor; ve Bölüm 1'deki kusurlar dağıtılmış kodda mevcut olduğu için, (iii) de karşılanmıyor.
Uyumluluk kontrollerinin etkinliği
Ne gerektirir. Yönergenin yaşam döngüsü modeli (kara liste, dondurma, beyaz liste, KYC), bu kontrollerin etkili olduğunu varsayar.
Kontrat ne yapıyor. 1.1'de gösterildiği gibi, KYC kontrolü ve sağlayıcı iptali, dağıtılmış kodda işlevsel değil.
Nerede farklılaşıyor. Çalışması gereken bir kontrol çalışmıyor. Bu bir şekilcilik değil, esaslı bir boşluktur.
Madde 2.2.3: dondurulmuş veya yok edilmiş coinler tam olarak desteklenmiş ve uzlaştırılabilir kalmalı
Ne gerektirir. İcra faaliyeti tarafından dondurulan veya yok edilen stablecoinler tam olarak desteklenmiş kalmalı, böylece arz ve rezervler uzlaştırılabilir.
Kontrat ne yapıyor. Düzenlenmiş bir stablecoin için olağan düzeltme akışı, kötü bir adreste fonları yakmak ve daha sonra kurbana ayrı bir mint olarak eşit bir miktarı yeniden ihraç etmektir (USDT'nin destroyBlackFunds artı issue'sunun çalışma şekli budur). HKDAP'ın yok etme işlemi _totalSupply'ı azaltır, bu bir yakmadır, ama asla balances[address(this)]'i kredilendirmez, address(0) yerine address(this)'e bir Transfer yayınlar ve basım limitinin kullandığı net ihraç sayaçlarını dokunmadan bırakır:
// contracts/hce/ControllableAHKD.sol
628 function destroyBlackFunds(address _blackListedUser) external override whenNotPaused onlySupplyDestroyer() {
636 uint dirtyFunds = balanceOf(_blackListedUser);
637 balances[_blackListedUser] = 0;
638 _totalSupply = _totalSupply - dirtyFunds ;
639 emit DestroyedBlackFunds(_blackListedUser, dirtyFunds);
640 emit Transfer(_blackListedUser, address(this), dirtyFunds);
641 }
Nerede farklılaşıyor. Durum değişikliği bir yakmadır, ama olay tokenlerin kontrata taşındığını söyler ve orada hiçbir zaman hiçbir şey tutulmaz (balances[address(this)] sıfırda kalır). Bir indeksleyici, address(this)'i tutmadığı tokenlerle kredilendirir ve olaylardan yeniden oluşturulan toplam arz zincirle eşleşmez. Bu ayrıca düzeltmenin kendisini de karıştırır: tokenler park edilmek yerine yakıldığı için, kurbana bir yeniden ihraç yeni bir mint olmalıdır, oysa yanıltıcı Transfer(..., address(this), ...), kontratın şu anda bunları koruduğunu ve iletebileceğini önerir, ki bu mümkün değildir. Temiz bir address(0)'a yakma artı ayrı bir yeniden ihraç, hem doğru hem de uzlaştırılabilir olurdu. Yazıldığı şekilde, bir rezerv uzlaştırmasının bağlı olduğu zincir üzerindeki muhasebe, zincirin gerçek durumundan kayıyor. Bu net bir başarısızlıktan ziyade bir endişe konusudur.
Bu bulguları zincirin gösterdiği şeyle sınırlıyoruz. Rezervlerin tam olarak desteklenip desteklenmediği, anahtarların bir HSM'de veya hava boşluklu bir ortamda oturup oturmadığı ve işlemlerin imzalanmadan önce zincir dışında simüle edilip edilmediği kontrattan görünmüyor ve bunlar hakkında hiçbir iddiada bulunmuyoruz.
Sonuç
Tablo, incelemenin her iki eksende de tutarlıdır. Yazılım olarak, HKDAP, yazıldığı gibi çalışmayan uyumluluk kontrolleri de dahil olmak üzere işlevsel kusurlar içeriyor ve üretim öncesi bir yapının birkaç işaretini gösteriyor. Düzenlenmiş bir stablecoin olarak, zincir üzerindeki bazı özellikleri HKMA yönergesinin belirli maddeleriyle çelişiyor. Zincir üzerindeki kanıtlara dayanarak ve göremediğimiz zincir dışı konuları bir kenara koyarak, dağıtılmış kontrat henüz ticari bir stablecoin'in karşılaması gereken standardı karşılamıyor.
Bunu takip eden iki gözlem var ve açıkça belirtilmeye değer.
Birincisi, kamuya açık bir zincirde ihraç etmek, uyumluluğun nerede belirlendiğini değiştiriyor. "Hiçbir tarafın tek taraflı olarak hareket edememesi gerektiği" gibi bir gereksinim, dağıtılmış koddaki rol kontrolleri tarafından karşılanır veya karşılanmaz ve o kod kamuya açıktır. Bu tür bir gereksinimin gerçekten karşılandığı veya kaçırıldığı yer, lisans veya belgeleme yerine uygulamadır ve herkes hangisinin olduğunu doğrulayabilir.
İkincisi, "Beta Erişim" etiketi, dağıtılmış kodun risk profilini değiştirmiyor. Kontrat, gerçek anahtarlar tarafından yönetilen Ethereum ana ağında canlı ve Hong Kong doları üzerinde bir iddiayı temsil ediyor. Bu nedenle nasıl etiketlendiğinden bağımsız olarak üretim standartlarına göre değerlendirilmelidir.
Belirli bulguların altında ortak bir tema var. Mimari, ekosistemin zaten sağladığı ve ölçekte denetlediği ilkelleri özel bir biçimde yeniden icat ediyor: bir Safe multisig ile OpenZeppelin'in AccessManager ve TimelockController'ının yeterli olacağı bir yerde sıfırdan bir onay motoru ve rol katmanı; EnumerableSet yerine el yazısı bağlantılı liste koleksiyonu; standart TransparentUpgradeableProxy yerine değiştirilmiş bir proxy; ve OpenZeppelin'in ERC-20'si yerine el yazısı bir ERC-20. Bu incelemedeki kusurların çoğu, standart bileşenleri yeniden kullanan kısımlarda değil, o özel yapıda yaşıyor. Genel amaçlı yazılımın yapıldığı gibi soyutlanmış bir sistem gibi okunuyor, oysa zincir üzerinde geliştirmenin tercih ettiği küçük, denetlenmiş yapı taşlarından oluşturulmamış, burada her özel soyutlama katmanı aynı zamanda gaz, saldırı yüzeyi ve yükseltme riskidir. Bu standart bileşenlerden oluşturulmuş bir tasarım daha küçük, daha güvenli ve gözden geçirilmesi daha kolay olurdu ve bu sistemin şu anda eksik olduğu şeylerle birlikte gelirdi: bir zaman kilidinden gelen bir müzakere penceresi ve adlandırılmış, anlaşılır roller.
Burada açıklanan sorunlar giderilebilir. Yüksek riskli işlemlerde çok imzayı geri getirmek, yürütmeyi denetimden ayırmak, KYC iptal mantığını düzeltmek, transfer kontrollerini birleştirmek, hata ayıklama kodunu kaldırmak ve her yükseltmeden önce üçüncü taraf denetimi gerektirmek, bunların çoğunu çözerdi. Doğrulanmış kaynak koduyla ana ağa dağıtım yapmak da bu incelemeyi mümkün kılan şeydir ve bu doğru bir varsayılan değerdir. Bu tür sürekli zincir üzerinde güvenlik ve uyumluluk incelemesi, BlockSec'te yaptığımız iştir ve yardımcı olmaktan memnuniyet duyarız.



