v4-hook-permission-flags-mismatch

Solid

Detect Uniswap V4 hooks whose address-encoded permission flags don't match the callbacks the hook actually implements. In V4 the hook's permissions live in the low bits of its deployed address (mined via CREATE2 salt) and must agree with getHookPermissions(); a callback the hook implements but whose flag bit is unset is never invoked, and a flag set without a real implementation makes pool initialization revert in Hooks.validateHookPermissions. Activate on any BaseHook/IHooks contract, getHookPermissions overrides, or hook address mining.

AI & Automation 38 stars 5 forks Updated 2 days ago MIT

Install

View on GitHub

Quality Score: 82/100

Stars 20%
53
Recency 20%
100
Frontmatter 20%
70
Documentation 15%
100
Issue Health 10%
50
License 10%
100
Description 5%
100

Skill Content

# Uniswap V4 hook permission-flag mismatch detection ## When this applies Trigger on any of: - Contracts inheriting `BaseHook` / implementing `IHooks` - An overridden `getHookPermissions()` returning a `Hooks.Permissions` struct - Implemented callbacks: `beforeSwap`, `afterSwap`, `beforeAddLiquidity`, `afterAddLiquidity`, `beforeRemoveLiquidity`, `afterRemoveLiquidity`, `beforeInitialize`, `afterInitialize`, `beforeDonate`, `afterDonate` - `*ReturnDelta` permission flags (`afterSwapReturnDelta`, `beforeSwapReturnDelta`, etc.) - CREATE2 / `HookMiner.find` salt mining to encode flags into the hook address - Pool initialization that passes the hook address to `PoolManager.initialize` ## Detection patterns ### Implemented callback whose flag bit is unset (HIGH) ```solidity function getHookPermissions() public pure override returns (Hooks.Permissions memory) { return Hooks.Permissions({ beforeSwap: true, afterSwap: false, /* ...all else false */ }); } function afterSwap(...) external override returns (bytes4, int128) { _accrueFees(...); // ← real logic, but afterSwap flag is FALSE return (this.afterSwap.selector, 0); } ``` The pool reads permissions from the hook *address bits*, not from the function table. With the `AFTER_SWAP` bit unset, the PoolManager never calls `afterSwap`; `_accrueFees` silently never runs. **Signal:** a callback is implemented (non-reverting body) but its corresponding permission is `false` / the address bit is unmined. ### Flag ...

Details

Author
iktok90-design
Repository
iktok90-design/ai-smart-contract-auditor
Created
1 weeks ago
Last Updated
2 days ago
Language
JavaScript
License
MIT

Bundled in these plugins

Similar Skills

Semantically similar based on skill content — not just same category