5/5
# Counter Hooks Exercises In this exercise, you'll learn how to write a custom hooks contract. The starter code for this exercise is provided in [`foundry/src/exercises/CounterHook.sol`](https://github.com/Cyfrin/defi-uniswap-v4/blob/main/foundry/src/exercises/CounterHook.sol) Solution is in [`foundry/src/solutions/CounterHook.sol`](https://github.com/Cyfrin/defi-uniswap-v4/blob/main/foundry/src/solutions/CounterHook.sol) ## Task 1 - Configure hook permissions ```solidity function getHookPermissions() public pure returns (Hooks.Permissions memory) { return Hooks.Permissions({ beforeInitialize: false, afterInitialize: false, beforeAddLiquidity: false, afterAddLiquidity: false, beforeRemoveLiquidity: false, afterRemoveLiquidity: false, beforeSwap: false, afterSwap: false, beforeDonate: false, afterDonate: false, beforeSwapReturnDelta: false, afterSwapReturnDelta: false, afterAddLiquidityReturnDelta: false, afterRemoveLiquidityReturnDelta: false }); } ``` Set `beforeAddLiquidity`, `beforeRemoveLiquidity`, `beforeSwap` and `afterSwap` to `true`. ## Task 2 - Increment counts For each hook functions above, increment the state variable `counts`. `counts` is a nested mapping from `PoolId`, name of the function, to the number of times the function was called. For example the current count of `afterSwap` is ```solidity counts[key.toId()]["beforeSwap"] ``` ## Test 1. Find the value of `salt` needed to deploy the hooks contract at a valid address. ```shell forge test --match-path test/FindHookAddr.sol -vvv ``` 2. Export the salt printed to your terminal from executing the command in the previous step. ```shell export SALT=YOUR_SALT forge test --fork-url $FORK_URL --match-path test/CounterHook.test.sol -vvv ```
In this exercise, you'll learn how to write a custom hooks contract.
The starter code for this exercise is provided in foundry/src/exercises/CounterHook.sol
Solution is in foundry/src/solutions/CounterHook.sol
Set beforeAddLiquidity, beforeRemoveLiquidity, beforeSwap and afterSwap to true.
For each hook functions above, increment the state variable counts.
counts is a nested mapping from PoolId, name of the function, to the number of times the function was called.
For example the current count of afterSwap is
Find the value of salt needed to deploy the hooks contract at a valid address.
Export the salt printed to your terminal from executing the command in the previous step.
A stateful exercise to Counter Hooks Exercises - Learn how to write a custom hook contract by setting permissions and implementing logic to count various pool actions like swaps and liquidity changes.
Previous lesson
Previous
Next lesson
Next
Give us feedback
Course Overview
About the course
Difference between Uniswap v3 and v4
Uniswap v4 PoolManager
Uniswap v4 Hooks
Uniswap v4 Singleton architecture
Uniswap v4 flash accounting
Uniswap v4 operations
Uniswap v4 lifecycle
How to build a Uniswap v4 swap router
Last updated on September 29, 2025
Duration: 5min
Duration: 7min
Duration: 39min
Duration: 35min
Course Overview
About the course
Difference between Uniswap v3 and v4
Uniswap v4 PoolManager
Uniswap v4 Hooks
Uniswap v4 Singleton architecture
Uniswap v4 flash accounting
Uniswap v4 operations
Uniswap v4 lifecycle
How to build a Uniswap v4 swap router
Last updated on September 29, 2025