Seguridad ng Uniswap v4 Hook: Arkitektura, Karaniwang Vulnerability, at Pinakamahusay na Pamamaraan

iconMetaEra
I-share
AI summary iconSummary
Ang Uniswap v4 ay gumagamit ng Hook para sa programmable liquidity, ngunit dahil sa mga kakulangan sa pagkakaroon ng pahintulot, pagkontrol ng pag-access, at iba pang mga isyu, ito ay naging madalas na layunin ng mga serbisyo ng pag-atake; maging babala sa mga panganib ng maling paggamit ng Async Hook at accounting logic.

May-akda ng artikulo, pinagkukunan: Beosin

Pagkatapos ng paglunsad ng Uniswap v4 sa mainnet, ang mekanismo ng Hook ay naging isa sa pinakamalaking inobasyon sa DeFi. Ang Flaunch, isang platform para sa paglalabas ng memecoin sa Base chain, ay gumagamit ng Hook upang maabot ang fixed presale price at automatic listing清算 mechanism; ang liquidity protocol na Bunni v2 ay gumagamit ng Hook upang buuin ang programmable liquidity at re-collateralization model; sa loob ng taong ito, ang mga token tulad ng SATO, uPEG (Unipeg), at Slonks na may kaugnayan sa mga玩法 ng Hook ay nakapagbigay ng pagtaas na maraming beses sa maikling panahon.

Sa kabilang panig ng pag-unlad ng ekosistema ng Hook, lumalaki rin ang mga pag-atake na nakatuon sa mga kamalian sa implementasyon ng Hook. Ang artikulong ito ay magsisimula sa mekanismo ng Hook ng Uniswap v4, at susuriin nito nang paunlamin ang pangunahing call stack upang tulungan ang mga proyekto na maunawaan ang mga posibleng butas dito.

Uniswap v4 Hook na Seguridad

1. Paunang Paglalarawan

Ang pinakamalaking pagbabago sa arkitektura ng Uniswap v4 kumpara sa v3 ay ang pagpapakilala ng mekanismo ng Hook: nagbibigay-daan sa mga developer na i-attach ang kanilang sariling contract sa mga pangyayari sa buhay ng liquidity pool, at magdagdag ng anumang lohika sa mga punto tulad ng swap, pagdaragdag o pagbawas ng liquidity, at pag-initialize.

Ang ilang pangunahing pagbabago sa v4 ay sumusunod:

Singleton pattern: Ang lahat ng estado ng mga pool ay pinamamahalaan ng isang nag-iisang PoolManager contract, hindi na ipinapalabas ang hiwalay na contract para sa bawat pool

- Flash accounting: Ang mga pagbabago sa intermediate balance sa proseso ng transaksyon ay tanging nakarehistro sa transient storage, at iisang pagkakataon lang na isinasagawa ang pagkalkula kapag natapos na ang transaksyon

-Mekanismo ng Hook: Bawat pool ay maaaring makabind ng isang Hook contract, at ang PoolManager ay magpapalabas ng callback sa contract sa mga mahahalagang punto (beforeInitialize, beforeSwap, afterAddLiquidity, atbp.)

- Hindi maaaring palitan ang Hook: Kapag natapos na ang pag-initialize ng pool, ang nakabigay na Hook address ay permanenteng nakafiksa (hindi maaaring baguhin ang Hook address na nakabigay sa pool, ngunit ang kakayahan ng Hook contract na i-upgrade ay nakadepende sa kanyang implementasyon)

Sa panahon ng v3, kailangan lang ng mga developer na maniwala sa Uniswap protocol mismo; sa panahon ng v4, ang kaligtasan ng bawat pool ay nakasalalay sa hook na kaukulang naka-link dito. Ang mga hook ay nagpapalawak sa AMM mula sa isang fixed financial primitive hanggang sa isang programmable financial infrastructure, ngunit ang security model ay naging fragmented mula sa “protocol-level” patungo sa “pool-level”.

2. Arkitektura ng Hook 2.1 PoolManager at modelo ng unlock/callback

Ang pangunahing kontrato ng v4 ay ang singleton na PoolManager. Kailangan munang tawagan ang PoolManager.unlock() para sa anumang pagbabago sa estado ng pool (swap, pagdaragdag o pagbawas ng liquidity), upang makakuha ng isang beses na callback permission, at tapusin ang espesipikong aksyon sa unlockCallback(). Sa wakas ng buong proseso, susuriin ng PoolManager kung balanse ang libro:

Kapag ang NonzeroDeltaCount != 0, agad na i-revert; ito ang pangunahing pagkakabawas sa v4 flash accounting. Ang anumang Hook ay maaaring pansamantala'y magdulot ng di-balanseng account sa panahon ng pagpapatupad, ngunit kailangan nito na i-settle ang sarili nito bago matapos ang transaksyon, kung hindi ay babalik ang buong transaksyon.

Ang bawat pool ay ikinakilanlang may unikong PoolKey structure, na naglalaman ng field na hooks:

Ang PoolId ay kalkulahin gamit ang keccak256(PoolKey), kaya ang iba’t ibang hooks address ay magdudulot ng iba’t ibang pool. Ito ay nangangahulugan din na ang PoolManager ay hindi aasikasuhin kung ang isang hooks address ay dating ginamit sa ibang pool; ang iisang Hook contract ay maaaring i-bind ng maraming pool nang sabay-sabay.

2.2 Ang pag-encode ng permission bit sa address

Isang hindi intuitibong disenyo ng v4 ay: ang pahintulot ng Hook ay hindi natukoy ng isang variable sa loob ng contract, kundi ng address kung saan isinagawa ang Hook contract.

Ang PoolManager ay nag-iinspect sa 14 na pinakamababang bit ng Hook address upang matukoy kung kailangang tawagan ang Hook sa isang partikular na punto ng buhay:

Halimbawa, BEFORE_SWAP_FLAG = 1 << 7. Kung ang 7th bit ng Hook address ay 1, tatawagan ng PoolManager ang beforeSwap() ng Hook bago ang swap; kung hindi, kahit na ang Hook contract ay nag-implement ng beforeSwap(), hindi ito maiiwan ng PoolManager.

Ibig sabihin nito na ang Hook ay dapat i-deploy gamit ang CREATE2 + salt upang kalkulahin ang address at lumikha ng isang address na may mababang bahagi na may pantay na pagsasakop sa target. Binibigyan ng Uniswap ang HookMiner tool para sa layuning ito:

Kapag hindi tugma ang mga bit ng pahintulot at ang pagpapatupad ng mga punsiyon, lumalabas ang dalawang uri ng problema:

(1) Ipinatupad ang isang hook function, ngunit ang address ay hindi encoded sa tamang permission bit—hahawakan ng PoolManager ang function na ito, kaya ang lohika ay walang kwenta

(2) Ang address ay nag-encode ng isang permission bit, ngunit ang hook ay hindi nag-implement ng katugmang function—ang PoolManager ay maaaring mag-revert sa callback, na nagdudulot ng DOS o pagkabigo sa pag-verify ng return value, na nagresulta sa pagkakabigo ng kaugnay na operasyon.

Ito ay isang natural na hadlang sa pag-upgrade ng Hook: kung ang Hook ay maaaring i-upgrade sa pamamagitan ng proxy, ang deployment address ay mananatiling hindi nagbabago sa panahon ng upgrade, kaya ang pag-upgrade ay maaaring baguhin lamang ang implementasyon ng mga umiiral na hook function, at hindi magdagdag ng mga uri ng hook. Upang mag-iwan ng espasyo para sa pagpapalawig sa hinaharap, kailangan mong i-pre-allocate ang lahat ng posibleng permission bits sa oras ng unang deployment.

2.3 BaseHook at isang karaniwang napapaligiran na trap sa pagkontrol ng pag-access

Ang BaseHook abstract contract na ibinigay ng Uniswap v4 periphery ay maaaring maging basehan ng mga developer para makabuo ng custom Hook. Ang isang mahalagang papel ng BaseHook ay magbigay ng onlyPoolManager modifier sa function na unlockCallback():

Ngunit — mayroong isang napakadaling makalimutang design trap — ang mga naunang bersyon ng BaseHook ay nagdagdag lamang ng onlyPoolManager sa unlockCallback, at walang proteksyon sa iba pang hook callback functions (beforeSwap, afterSwap, beforeAddLiquidity, atbp.). Dapat ng magdagdag ng eksplisitong kontrol ng pag-access ang mga developer ng Hook sa mga function na ito.

3. Pagbabasa ng code ng Hook lifecycle

Halimbawa ng isang exact-input swap, ang sumusunod ay ang pagsusuri sa buong call stack mula sa pagpapahintulot ng transaksyon ng user hanggang sa pagkumpleto.

3.1 Pag-initialize at Pagkakabit ng Hook

Sino man ang makakapag-call ng PoolManager.initialize() upang lumikha ng bagong pool:

Ang isValidHookAddress ay nagpapatotoo lamang sa pagkakatugma ng mga pahintulot sa address at ang field na fee, hindi ito nagpapatotoo kung ang Hook ay naka-use na sa ibang pool o kung ang Hook ay “nais” tanggapin ang PoolKey na ito. Kung ang Hook ay hindi isinama ang logic ng whitelist o single-pool binding sa beforeInitialize, makakapag-construct ng anumang tao ng isang bagong pool na gumagamit ng parehong Hook ngunit may anumang token pair at makakapag-trigger ng lahat ng susunod na callback ng Hook.

3.2 beforeSwap at BeforeSwapDelta

Ang entry point ng swap ay ang PoolManager.swap(), na tumatawag sa Hooks.beforeSwap() bago mag-execute ng core swap logic:

Ang return value ng beforeSwap ay isang triple (bytes4, BeforeSwapDelta, uint24):

- bytes4: Dapat katumbas ng IHooks.beforeSwap.selector, k otherwise, i-revert agad ng PoolManager

- BeforeSwapDelta: Ang Hook ay nag-aadjust ng delta para sa specified token at unspecified token sa swaps na ito

- uint24: halagang sakop ng dinamikong LP fee (tanging epektibo kapag naka-enable ang dinamikong fee sa pool)

Ang BeforeSwapDelta ay isang alias ng int256, kung saan ang mataas na 128 bit ay ang delta ng specified token (ang token na tinukoy ng user), at ang mababang 128 bit ay ang delta ng unspecified token:

Dapat tandaan na ang kahulugan ng BeforeSwapDelta ay ang Hook ay dapat magbalik ng positibong halaga kapag kinukuha ang bayarin, at negatibong halaga kapag ibinabalik ang token. Madaling maliin ng mga developer ang sign; samantala, ang ugnayan ng specified at unspecified ay nakadepende sa params.zeroForOne at ang sign ng amountSpecified, at isang maliit na pagkakamali sa pagsulat ay maaaring magdulot ng pagkakamali sa token.

Ang PoolManager ay dadagdagan nang direkta ang specifiedDelta na ibinigay ng beforeSwap sa amountToSwap:

Ang isang mahalagang kahulugan na nakapaloob dito ay ang Hook ay maaaring humawak ng halaga ng swap. Kapag ang hookDeltaSpecified ay katumbas ng -params.amountSpecified, ang amountToSwap ay diretso nang magiging zero, na nangangahulugan na ang Hook ay buong kinontrol ang swap na ito—ito ang tinatawag na Async Hook o Custom Curve Hook.

Ang Async Hook ay isa sa pinakamataas na panganib na disenyo sa v4: ito ay nagpapalit ng sariling lohika ng Hook sa swap logic ng Uniswap. Kung may butas ang Hook o ito ay masama nang itself, ang mga pondo ng user ay hindi na nakadepende sa native pricing logic ng Uniswap, kundi pangunahing nakabatay sa tamang implementasyon ng Hook mismo.

3.3 Delta Settlement at NonzeroDeltaCount

Hindi agad sinisimulan ng beforeSwap at afterSwap na ibinabalik na delta ang paglipat ng pondo, kundi ito ay nakarehistro sa loob na talaan ng PoolManager:

Kapag nagbabago ang kumulatibong delta ng isang token mula sa zero patungo sa non-zero, dumadagdag ang NonzeroDeltaCount; at dumededepreso nito kapag bumabalik sa zero. Ayon sa 2.1, kung ang NonzeroDeltaCount != 0 sa pagtatapos ng unlock(), babalikin ang buong transaksyon.

Balansahan ang sariling delta sa pamamagitan ng dalawang aksyon: settle() (pagpapadala sa PoolManager) at take() (pagkuha mula sa PoolManager):

Ang seguridad na ibinibigay ng mekanismong ito ay malinaw: lahat ay kailangang i-balance ang kanilang account sa huli. Ngunit ito ay nagtataguyod lamang ng “conservation ng accounting” at hindi ng “tamang accounting.” Kung ang Hook ay bumalik ng isang masamang nilikhang delta sa beforeSwap, gagawin nang tapat ng PoolManager ang pagtatala batay sa delta na iyon, kahit anong mangyari—basta’t i-balance sa huli, matagumpay ang transaksyon—kahit na ito ay nangangahulugan na maaaring gamitin ng Hook ang pagpapalito ng business state upang gawing tila may-ari ng ilang asset rights ang attacker, habang ang PoolManager ay hindi makakakilala sa ganitong uri ng error sa antas ng negosyo.

Ang nakaraang security incident sa Cork Protocol ay dulot ng vulnerability sa kanyang Hook, at bago ito masira, ito ay nagsagawa na ng apat na audit mula sa mga audit company. Pagkatapos ng insidente, natuklasan namin:

Sa apat na pagsusuri, tatlo ang sakop na hindi kasama ang CorkHook contract

- Ang tanging auditor ng CorkHook ay nakakita ng ilang mga problema sa code at nagbigay ng mga rekomendasyon para sa pagpapabuti, ngunit hindi ito lubos na nakapag-coverage sa mga isyu sa pagkontrol ng pag-access

- May isa pang auditor na nagbigay ng malinaw na rekomendasyon sa kanilang ulat: “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”. Ang rekomendasyong ito ay may malakas na kahalagahan mula sa pananaw ng pagtataya pagkatapos ng insidente.

Ito ay nagpapakita ng isang bagong blind spot sa panahon ng v4 Hook: ang pagtaas ng komplikasyon ng protokolo ay nagiging isang seguridad na desisyon sa pagtukoy ng sakop. Ang mga ugnayan ng Hook sa iba pang mga kontrato ng protokolo ay napakahaba; ang pag-audit lamang sa Hook contract ay hindi sapat upang makita ang mga problema sa komposisyon sa pagitan ng mga kontrato; sa kabilang banda, ang pag-audit sa mga kapaligirang kontrato habang isinisiwalat ang Hook mula sa sakop ay magtatanggal sa pinakamalaking attack surface sa panahon ng v4.

5. Pagsusuri

Kapag isinasalin ang mekanismo ng protokolo at ang Cork attack side by side, maaaring maipaliwanag ang ilang pangunahing punto ng v4 Hook security model:

(1) Kung ang Hook callback function ay nakadepende sa call context na ibinibigay ng PoolManager, dapat ito ay eksplisitong limitahan na tanging ng PoolManager ang maaaring mag-call. Hindi gagawin ng BaseHook ito para sa developer, at ito ang pinakamadaling magkakaroon ng konflikto sa disenyo sa pagitan ng v4 at karaniwang karanasan sa audit ng contract.

(2) Ang ugnayan ng Hook at ang pool ay hindi pinipigilan ng PoolManager. Dapat ng sarili naming i-implement ng developer ang whitelist ng pool o single-pool binding sa beforeInitialize.

(3) Ang mga pahintulot sa address ng hook ay dapat magkakatugma nang tumpak sa implementasyon ng punsiyon. Ang kalkuladong address ay dapat maglalaman na ng lahat ng mga pahintulot na maaaring palawigin sa hinaharap.

(4) Ang Async / Custom Curve Hook ay isang hoàn na kustomisadong implementasyon ng swap. Walang anumang proteksyon mula sa antas ng protokolo ng Uniswap at kailangang ma-audit batay sa pamantayan ng “puno ng sariling pananalapi”

(5) Ang “conservation” sa delta accounting ay hindi katumbas ng “tama”. Ang NonzeroDeltaCount == 0 ay nagtataglay lamang ng pagpapakita na ang libro ay balanse sa wakas, hindi naman ito nagpapatunay na ang laman ng libro ay hindi naaapektuhan ng masamang pagmamalabis.

(6) Ang kalituhan sa uri ng token sa iba't ibang merkado ay isang bagong anyo ng panganib sa panahon ng v4. Kapag pinapayagan ng protokolo ang mga gumagamit na lumikha ng mga merkado, kailangan ang semantic validation ng token at hindi maaaring mag-asa lamang sa pag-check ng interface

Bawat Hook ay isang independiyenteng domain ng pagkakatiwala, at ang kaligtasan ng bawat pool ay tinukoy ng kanyang nakabigay na Hook. Dahil dito, ang kumplikadong pag-audit ng Hook ay hindi na “pag-audit ng isang code”, kundi “pag-audit ng isang buong sub-protocol”—ang pagbabagong ito ay nangangahulugan ng pag-upgrade sa metodolohiya para sa mga proyekto at mga auditor.

Mga sanggunian

(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: Mga Vulnerabilidad sa Access Control. https://scs.owasp.org/sctop10/SC01-AccessControlVulnerabilities/

(3) Uniswap v4 Whitepaper. 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

Ang Beosin ay isa sa mga unang global na kompanya sa blockchain security na nagtataguyod ng formal verification, na nakatuon sa buong ecosystem na “security + compliance”. May mga sangay ito sa higit sa 10 bansa at rehiyon sa buong mundo, at ang mga serbisyo nito ay kumakalat sa code security audit bago ang paglulunsad ng proyekto, real-time monitoring at pagbabawal sa security risks habang nagpapatakbo ang proyekto, pagbabalik ng nasiraan, virtual asset anti-money laundering (AML), at compliance assessment na sumusunod sa mga regulasyon ng bawat rehiyon—lahat ng ito ay isang “one-stop” blockchain compliance product at security service. Mangyaring i-click ang message box sa aming public account para makipag-ugnayan sa amin.

Disclaimer: Ang information sa page na ito ay maaaring nakuha mula sa mga third party at hindi necessary na nagre-reflect sa mga pananaw o opinyon ng KuCoin. Ibinigay ang content na ito para sa mga pangkalahatang informational purpose lang, nang walang anumang representation o warranty ng anumang uri, at hindi rin ito dapat ipakahulugan bilang financial o investment advice. Hindi mananagot ang KuCoin para sa anumang error o omission, o para sa anumang outcome na magreresulta mula sa paggamit ng information na ito. Maaaring maging risky ang mga investment sa mga digital asset. Pakisuri nang maigi ang mga risk ng isang produkto at ang risk tolerance mo batay sa iyong sariling kalagayang pinansyal. Para sa higit pang information, mag-refer sa aming Terms ng Paggamit at Disclosure ng Risk.