Uniswap v4 menggunakan Hook untuk likuiditas yang dapat diprogram, namun menjadi sasaran serangan utama karena kelemahan dalam encoding izin, kontrol akses, dll., sehingga perlu waspada terhadap risiko penyalahgunaan Async Hook dan logika akuntansi.Penulis artikel, sumber: Beosin
Setelah peluncuran mainnet Uniswap v4, mekanisme Hook menjadi salah satu inovasi paling diperhatikan di DeFi. Platform peluncuran memecoin di rantai Base, Flaunch, memanfaatkan Hook untuk mewujudkan harga pra-penjualan tetap dan mekanisme peluncuran otomatis; protokol likuiditas Bunni v2 menggunakan Hook untuk membangun model likuiditas yang dapat diprogram dan model re-collateralization; tahun ini, token-token seperti SATO, uPEG (Unipeg), dan Slonks yang berfokus pada玩法 Hook juga mencatat kenaikan puluhan kali lipat dalam waktu singkat.
Di sisi lain kejayaan ekosistem Hook, serangan terhadap kelemahan implementasi Hook juga meningkat signifikan. Artikel ini akan memulai dari mekanisme Hook Uniswap v4, secara bertahap menganalisis stack pemanggilan intinya, membantu proyek memahami kerentanan yang mungkin ada.
Keamanan Uniswap v4 Hook
1. Pengantar
Perubahan arsitektur paling signifikan Uniswap v4 dibandingkan v3 adalah pengenalan mekanisme Hook: memungkinkan pengembang untuk memasang kontrak kustom pada peristiwa siklus hidup kolam likuiditas, serta menyisipkan logika apa pun pada titik-titik seperti swap, penambahan atau pengurangan likuiditas, dan inisialisasi.
Beberapa perubahan utama pada v4 adalah sebagai berikut:
Singleton pattern: Semua status kolam dikelola secara terpusat oleh kontrak PoolManager tunggal, tanpa perlu menerapkan kontrak terpisah untuk setiap kolam
- Akuntansi kilat: Perubahan saldo sementara selama proses perdagangan hanya dicatat di penyimpanan sementara, dan hanya diselesaikan secara terpusat saat perdagangan selesai.
-Mekanisme Hook: Setiap kolam dapat dikaitkan dengan kontrak Hook, dan PoolManager akan memanggil kontrak tersebut pada titik-titik kunci (beforeInitialize, beforeSwap, afterAddLiquidity, dll.)
- Hook tidak dapat diganti: Setelah pool diinisialisasi, alamat Hook yang terikat tetap permanen (alamat Hook yang terikat pada pool tidak dapat diubah, tetapi apakah kontrak Hook itu sendiri dapat ditingkatkan tergantung pada cara implementasinya)
Pada periode v3, pengembang hanya perlu mempercayai protokol Uniswap itu sendiri; sedangkan pada periode v4, keamanan setiap kolam bergantung pada Hook yang terikat padanya. Hook mengembangkan AMM dari sebuah primitif keuangan tetap menjadi infrastruktur keuangan yang dapat diprogram, tetapi model keamanan terpecah dari “tingkat protokol” menjadi “tingkat kolam”.
2. Arsitektur Hook 2.1 PoolManager dan model unlock/callback
Kontrak inti v4 adalah PoolManager yang bersifat singleton. Setiap operasi perubahan status kolam (swap, menambahkan atau mengurangi likuiditas) harus terlebih dahulu memanggil PoolManager.unlock() untuk mendapatkan izin callback satu kali, lalu menyelesaikan tindakan spesifik di dalam unlockCallback(). Pada akhir seluruh proses, PoolManager akan memverifikasi apakah buku besar seimbang:
Langsung revert saat NonzeroDeltaCount != 0, ini adalah batasan utama akuntansi flash v4. Setiap Hook dapat sementara membuat buku tidak seimbang selama eksekusi, tetapi harus menyelesaikannya sendiri sebelum akhir transaksi, jika tidak, seluruh transaksi akan rollback.
Setiap kolam diidentifikasi secara unik oleh struktur PoolKey, yang mencakup bidang hooks:
PoolId dihitung menggunakan keccak256(PoolKey), sehingga alamat hooks yang berbeda akan menghasilkan pool yang berbeda. Ini juga berarti bahwa PoolManager tidak akan memverifikasi apakah alamat Hook tertentu pernah digunakan untuk pool lain, dan kontrak Hook yang sama dapat diikat secara bersamaan oleh beberapa pool.
2.2 Kode bit izin Hook dalam alamat
Salah satu desain tidak intuitif dari v4 adalah: izin Hook tidak ditentukan oleh variabel tertentu di dalam kontrak, tetapi oleh alamat penyebaran kontrak Hook.
PoolManager memeriksa 14 bit terendah dari alamat Hook untuk menentukan apakah Hook tersebut perlu dipanggil pada titik siklus hidup tertentu:
Misalnya BEFORE_SWAP_FLAG = 1 << 7. Jika bit ke-7 dari alamat Hook bernilai 1, PoolManager akan memanggil beforeSwap() dari Hook sebelum swap; jika tidak, bahkan jika kontrak Hook mengimplementasikan beforeSwap(), itu tidak akan pernah dipanggil oleh PoolManager.
Ini berarti bahwa saat deployment Hook, alamat harus dihitung menggunakan CREATE2 + salt untuk menghasilkan alamat dengan bagian bawah yang sepenuhnya sesuai dengan izin target. Uniswap menyediakan alat HookMiner untuk tujuan ini:
Ketika bit izin tidak konsisten dengan implementasi fungsi, akan timbul dua jenis masalah:
(1) Telah mengimplementasikan fungsi hook tertentu, tetapi alamat tidak dikodekan sesuai bit izin yang sesuai — PoolManager tidak akan pernah memanggil fungsi ini, logikanya sama saja dengan tidak ada
(2) Alamat mengkodekan bit izin tertentu, tetapi hook tidak mengimplementasikan fungsi yang sesuai—PoolManager dapat mengalami revert saat callback, menyebabkan DOS atau kegagalan verifikasi nilai kembali, sehingga operasi terkait tidak dapat dieksekusi.
Ini juga merupakan hambatan alami terhadap peningkatan Hook: jika Hook dapat ditingkatkan melalui proxy, alamat penyebaran tetap tidak berubah selama peningkatan, sehingga setelah peningkatan, hanya implementasi fungsi Hook yang sudah ada yang dapat dimodifikasi, bukan menambahkan jenis Hook baru. Untuk menyediakan kemampuan ekspansi di masa depan, semua bit izin yang mungkin diperlukan harus disiapkan sejak awal penyebaran.
2.3 BaseHook dan Perangkap Kontrol Akses yang Sering Diabaikan
Kontrak abstrak BaseHook yang disediakan oleh periphery Uniswap v4 memungkinkan pengembang untuk mewarisi dan mengimplementasikan Hook khusus. Salah satu peran penting BaseHook adalah menyediakan modifier onlyPoolManager untuk fungsi unlockCallback():
Namun—ada jebakan desain yang sangat mudah diabaikan di sini—versi awal BaseHook hanya menambahkan onlyPoolManager ke unlockCallback, tanpa perlindungan apa pun untuk fungsi callback hook lainnya (beforeSwap, afterSwap, beforeAddLiquidity, dll.). Kontrol akses untuk fungsi-fungsi ini harus ditambahkan secara eksplisit oleh pengembang Hook sendiri.
3. Tinjauan kode siklus hidup Hook
Sebagai contoh swap input eksak, berikut adalah analisis seluruh stack pemanggilan dari pengguna memulai transaksi hingga penyelesaian.
3.1 Inisialisasi kolam dan pengikatan Hook
Siapa pun dapat memanggil PoolManager.initialize() untuk membuat kolam baru:
isValidHookAddress hanya memeriksa kompatibilitas antara bit izin alamat dan bidang fee, tidak memeriksa apakah Hook sudah digunakan di pool lain, atau apakah Hook tersebut "bersedia" menerima PoolKey ini. Jika Hook dirancang tanpa logika whitelist atau ikatan satu-pool di dalam beforeInitialize, siapa pun dapat membuat pool baru yang menggunakan Hook yang sama tetapi dengan pasangan token apa pun, lalu memicu semua callback berikutnya dari Hook tersebut.
3.2 beforeSwap dan BeforeSwapDelta
Titik masuk proses swap adalah PoolManager.swap(), yang memanggil Hooks.beforeSwap() sebelum menjalankan logika swap inti:
Nilai kembali dari beforeSwap adalah sebuah triple (bytes4, BeforeSwapDelta, uint24):
- bytes4: harus sama dengan IHooks.beforeSwap.selector, jika tidak, PoolManager akan langsung revert
- BeforeSwapDelta: Hook melakukan penyesuaian delta untuk token yang ditentukan dan token yang tidak ditentukan dalam swap ini
- uint24: nilai cakupan tarif LP dinamis (hanya berlaku ketika kolam mengaktifkan tarif dinamis)
BeforeSwapDelta adalah alias dari int256, 128 bit pertama adalah delta dari token yang ditentukan (yaitu token yang ditentukan oleh pengguna), dan 128 bit terakhir adalah delta dari token yang tidak ditentukan:
Perlu diperhatikan bahwa semantik BeforeSwapDelta adalah Hook harus mengembalikan nilai positif saat mengenakan biaya dan nilai negatif saat mengembalikan token. Pengembang mudah keliru dalam membalikkan tanda; selain itu, hubungan antara specified dan unspecified bergantung pada tanda positif atau negatif dari params.zeroForOne dan amountSpecified, sehingga sedikit kesalahan dalam penulisan dapat menyebabkan ketidaksesuaian token.
PoolManager akan menambahkan specifiedDelta yang dikembalikan oleh beforeSwap langsung ke amountToSwap:
Baris ini menyiratkan makna kunci: Hook dapat menangkap jumlah swap. Ketika hookDeltaSpecified sama dengan -params.amountSpecified, amountToSwap langsung menjadi nol, yang berarti Hook sepenuhnya mengambil alih swap ini—ini disebut Async Hook atau Custom Curve Hook.
Async Hook adalah salah satu pola desain paling berisiko di v4: pada dasarnya, ia menggantikan logika swap Uniswap dengan logika Hook sendiri. Jika Hook memiliki kerentanan atau bersifat jahat, dana pengguna tidak lagi dilindungi oleh logika penetapan harga asli Uniswap, melainkan bergantung terutama pada keakuratan implementasi Hook itu sendiri.
3.3 Penyelesaian Delta dan NonzeroDeltaCount
delta yang dikembalikan oleh beforeSwap dan afterSwap tidak langsung memicu transfer, tetapi dicatat ke dalam buku besar internal PoolManager:
Setiap kali delta kumulatif sebuah token berubah dari nol menjadi bukan nol, NonzeroDeltaCount bertambah; ketika kembali ke nol, NonzeroDeltaCount berkurang. Seperti yang dijelaskan pada 2.1, saat unlock() selesai, jika NonzeroDeltaCount != 0, seluruh transaksi akan revert.
Hook menyeimbangkan deltanya melalui dua tindakan: settle() (mentransfer ke PoolManager) dan take() (mengambil dari PoolManager):
Mekanisme ini memberikan makna keamanan yang jelas: semua pihak pada akhirnya harus menutup akun mereka. Namun, ia hanya menjamin “konservasi akun”, bukan “keakuratan akun”. Jika Hook mengembalikan delta yang dibuat secara jahat di dalam beforeSwap, PoolManager akan dengan setia mencatat delta tersebut, selama pada akhirnya ditutup melalui penyelesaian, transaksi dianggap berhasil—bahkan jika ini berarti Hook dapat memalsukan status bisnis sehingga sistem salah percaya bahwa penyerang memiliki hak atas aset tertentu, sementara PoolManager tidak dapat mengenali kesalahan tingkat bisnis semacam ini.
Insiden keamanan Cork Protocol sebelumnya terjadi karena kerentanan pada Hook-nya, padahal sebelum diserang, protokol tersebut telah diaudit oleh empat perusahaan audit. Setelah evaluasi pasca-insiden, kami menemukan:
Dari empat audit, tiga di antaranya tidak mencakup kontrak CorkHook
Satu-satunya audit yang dilakukan terhadap CorkHook mengidentifikasi sejumlah masalah kode dan memberikan saran perbaikan, tetapi tidak mencakup sepenuhnya masalah kontrol akses.
- Sebuah auditor lain secara eksplisit merekomendasikan dalam laporannya: "an interesting follow-up engagement would be to prove the invariants for the CorkHook functions that are being invoked by different components verified within the scope of this engagement". Rekomendasi ini memiliki target yang sangat tepat dari perspektif tinjauan pasca-insiden.
Ini mengungkapkan celah audit baru di era v4 Hook: pertumbuhan eksponensial kompleksitas protokol membuat penetapan cakupan menjadi keputusan keamanan itu sendiri. Rantai interaksi Hook dengan kontrak protokol lain sangat panjang; hanya mengaudit kontrak Hook saja tidak cukup untuk mengidentifikasi masalah komposisi lintas-kontrak; sebaliknya, mengaudit kontrak sekitarnya sambil mengecualikan Hook dari cakupan akan melewatkan permukaan serangan terbesar di era v4.
5. Refleksi
Dengan membandingkan mekanisme protokol dan analisis serangan Cork, beberapa poin inti dari model keamanan v4 Hook dapat disimpulkan:
(1) Jika fungsi callback Hook bergantung pada konteks pemanggilan yang disediakan oleh PoolManager, harus secara eksplisit membatasi agar hanya dapat dipanggil oleh PoolManager. BaseHook tidak akan melakukan hal ini untuk pengembang; ini adalah jebakan desain yang paling sering bertentangan dengan pengalaman audit kontrak umum di v4.
(2) Hubungan ikatan antara Hook dan pool tidak dibatasi oleh PoolManager. Pengembang harus mengimplementasikan whitelist pool atau ikatan satu pool secara mandiri di beforeInitialize.
(3) Hak akses alamat Hook harus konsisten secara ketat dengan implementasi fungsi. Alamat yang dihitung harus mencakup semua bit izin yang mungkin diperluas di masa depan secara pra-aktif.
(4) Hook Kurva Async / Khusus pada dasarnya adalah implementasi swap yang sepenuhnya disesuaikan. Tidak memiliki perlindungan apa pun pada tingkat protokol Uniswap dan harus diaudit sesuai standar "kontrak keuangan otonom penuh".
(5) Akuntansi Delta "konservasi" tidak sama dengan "benar". NonzeroDeltaCount == 0 hanya menjamin buku besar seimbang pada akhirnya, bukan menjamin konten buku besar tidak dimanipulasi secara jahat
(6) Kebingungan jenis token lintas pasar merupakan permukaan serangan baru di era v4. Ketika protokol memungkinkan pengguna membuat pasar, verifikasi semantik token adalah wajib, tidak boleh hanya mengandalkan pemeriksaan antarmuka.
Setiap Hook merupakan domain kepercayaan independen, dan keamanan setiap kolam ditentukan oleh Hook yang terikat padanya. Kompleksitas audit keamanan Hook karena itu tidak lagi berupa “mengaudit satu kode”, melainkan “mengaudit satu protokol sub lengkap”—perubahan ini berarti peningkatan metodologis bagi pihak proyek dan pihak audit.
Referensi
(1) Cork Protocol. “May 28 2025 Exploit Post-Mortem.” 2025-06-04. https://www.cork.tech/blog/post-mortem
(2) OWASP Smart Contract Security Top 10 2026, SC01: Kerentanan Kontrol Akses. https://scs.owasp.org/sctop10/SC01-AccessControlVulnerabilities/
(3) Whitepaper Uniswap v4. https://app.uniswap.org/whitepaper-v4.pdf
(4) Uniswap v4-core. https://github.com/Uniswap/v4-core
(5) Uniswap v4-periphery. https://github.com/Uniswap/v4-periphery
Beosin merupakan salah satu perusahaan keamanan blockchain pertama di dunia yang fokus pada verifikasi formal, menawarkan layanan komprehensif berbasis "keamanan + kepatuhan". Perusahaan ini memiliki cabang di lebih dari 10 negara dan wilayah, dengan layanan mencakup audit keamanan kode sebelum peluncuran proyek, pemantauan dan pencegahan risiko keamanan selama operasi proyek, pemulihan aset yang dicuri, anti-pencucian uang (AML) untuk aset virtual, serta penilaian kepatuhan yang sesuai dengan persyaratan regulasi setempat—semua dalam satu paket solusi kepatuhan blockchain dan layanan keamanan. Silakan kunjungi kotak pesan公众号 kami untuk menghubungi kami.

