Comprehensive testing harness for Uniswap v4 hooks.
A Foundry-based testing framework that introspects hook permission flags, dynamically generates test scenarios, and validates both functional correctness and security properties of Uniswap v4 hooks.
uni-v4-hooks-checker.Demo.mp4
Capability Detection
- Parses hook address flags to determine implemented callbacks
- Conditionally executes tests based on
Hooks.Permissionsbitmap - Validates permission consistency between address flags and
getHookPermissions()
Security Validation
- Access control: Verifies
onlyPoolManagermodifier on all entry points - Delta integrity: Validates
BeforeSwapDeltahandling and settlement accounting - State isolation: Checks for proper pool key validation and exclusivity patterns
- Return value correctness: Ensures proper selector returns for all callbacks
Functional Coverage
- Core operations: Swap (both directions), liquidity modification, donations
- Delta mechanics: Tests
beforeSwapReturnDelta,afterAddLiquidityReturnDelta, etc. - Edge cases: Sequential operations, boundary values, revert scenarios
- Integration: Full PoolManager interaction flows with proper router usage
Extensibility
- Fuzz testing support via Foundry's property-based testing
- Configurable strictness via environment variables
- Fork-compatible for testing deployed hooks
- Modular test suites for custom extension
Development & CI/CD
- Integration testing during hook development
- Regression detection in continuous integration pipelines
- Pre-deployment validation of security properties
Security Audits
- Automated verification of common vulnerability patterns
- Access control and authorization validation
- Delta manipulation and accounting correctness checks
Protocol Integration
- Third-party hook verification before allowlisting
- Compliance validation against Uniswap v4 hook standards
- Behavior analysis under various market conditions
First, install Foundry if you haven't already:
curl -L https://foundry.paradigm.xyz | bash
foundryupgit clone <repository-url>
cd uni-v4-hooks-checker
# Initialize submodules and build
./build.shRun the included example to see the framework in action:
forge test --match-contract ExampleHookTest -vvThis will:
- Deploy a fresh PoolManager
- Deploy the ExampleHook to a valid address
- Run all security and functional tests
- Show a detailed report of results
This project uses a hybrid dependency management approach:
- Git Submodules: Complex Uniswap repositories (
v4-core,v4-periphery,uniswap-hooks) - Foundry Dependencies: Standard libraries (
forge-std,solmate)
- Git submodules handle repositories with nested dependencies and complex structures
- Foundry dependencies manage simple, standalone libraries efficiently
- Unified build script (
./build.sh) handles all setup automatically: submodules, dependencies, and compilation with correct remappings @uniswap/v4-core/=lib/v4-core/ @uniswap/v4-periphery/=lib/v4-periphery/ solmate/=lib/solmate/
Create `test/TestMyHook.t.sol`:
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {MainTestEntry} from "uni-v4-hooks-checker/test/MainTestEntry.t.sol";
contract TestMyHook is MainTestEntry {}
Test your hook by setting its address:
# Set hook address and run all tests
HOOK_ADDRESS=0xYourHookAddress forge test --match-contract TestMyHook -vv
# Or with .env file
echo "HOOK_ADDRESS=0xYourHookAddress" > .env
forge test --match-contract TestMyHook -vvFunctional
- Swap operations (single, multiple, exact in/out, price limits)
- Liquidity operations (add, remove, modify positions)
- Donate operations
- Initialize operations
Security
- Authorization and access control
- EOA guard validation
- Configuration checks
- Delta manipulation detection
- Exclusivity patterns
Analysis
- Hook capability detection
- Function introspection
- Coverage reporting
Optional .env file:
HOOK_ADDRESS=0x...
POOL_MANAGER=0x...
RPC_URL=https://eth.llamarpc.com# Test against mainnet fork
forge test --match-contract MainTestEntry \
--fork-url https://eth.llamarpc.com \
-vv# Terminal 1: Start local node
anvil --port 8545
# Terminal 2: Deploy your hook
forge script script/Deploy.s.sol \
--rpc-url http://127.0.0.1:8545 \
--private-key 0x0 \
--broadcast
# Terminal 2: Run tests
HOOK_ADDRESS=0x... forge test \
--match-contract MainTestEntry \
--fork-url http://127.0.0.1:8545 \
-vvHOOK_ADDRESS=0x... forge test \
--match-contract FuzzTestEntry \
--fuzz-runs 100 \
-vvimport {MainTestEntry} from "uv4-hook-check/test/MainTestEntry.t.sol";
contract TestHook is MainTestEntry {
function test_custom() public onlyReady {
(int256 amt0, int256 amt1) = _swap(key, true, -1e18, ZERO_BYTES);
assertEq(amt0, expectedAmount);
}
}Update your dependencies:
git submodule update --remote --merge
forge clean
forge buildSet the HOOK_ADDRESS environment variable or use --fork-url.
Check that:
- Your hook is properly deployed
- The hook address has correct permission flags
- Anvil is running if testing locally
- Foundry (latest version)
- Solidity ^0.8.24
- Git
MIT