# 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
Course Overview
About the course
Difference between Uniswap v3 and v4
Uniswap v4 PoolManager
Uniswap v4 Hooks
Uniswap v4 PositionManager
Uniswap v4 Universal Router
Uniswap v4 Singleton architecture and flash accounting
Uniswap v4 operations and lifecycle
Uniswap v4 multihopping and quoting
How to build a Uniswap v4 swap router
How to build a smart contract a liquidation bot executes
Last updated on November 6, 2025
Duration: 6min
Duration: 8min
Duration: 39min
Duration: 35min
Duration: 34min
Duration: 31min
Course Overview
About the course
Difference between Uniswap v3 and v4
Uniswap v4 PoolManager
Uniswap v4 Hooks
Uniswap v4 PositionManager
Uniswap v4 Universal Router
Uniswap v4 Singleton architecture and flash accounting
Uniswap v4 operations and lifecycle
Uniswap v4 multihopping and quoting
How to build a Uniswap v4 swap router
How to build a smart contract a liquidation bot executes
Last updated on November 6, 2025