- Lifecycle Hooks: initialize, position, swap and donate
- Hook managed fees
- swap and/or withdraw
- static or dynamic
- Swap and withdraw protocol fees
- ERC-1155 accounting of multiple tokens
- Native ETH pools like V1
- Donate liquidity to pools
Contract dependencies
This project uses Foundry to manage dependencies, compile contracts, test contracts and run a local node. See Foundry installation for instructions on how to install Foundry which includes forge and anvil.
git clone [email protected]:naddison36/uniswap-v4-hooks.git
cd uniswap-v4-hooks
forge install
forge update v4-periphery
The following will run the unit tests in test/CounterScript
forge test -vvv
- The CounterHook demonstrates the
beforeModifyPosition,afterModifyPosition,beforeSwapandafterSwaphooks. - The CounterScript deploys the v4 pool manager, test tokens, counter hook and test routers. It then sets up a pool, adds token liquidity and performs a swap.
- The CounterScript script deploys to a local Anvil node and does a swap.
Because v4 exceeds the bytecode limit of Ethereum and it's business licensed, we can only deploy & test hooks on a local node like Anvil.
The following runs the script/CounterScript Forge script against a local Anvil node that:
- Deploys the Uniswap v4 PoolManager
- Uses the
CounterFactoryto deploy a CounterHook contract with the correct address prefix. - Creates a new pool with
CounterHookas the hook. - Adds token liquidity to the pool
- Performs a token swap
# start anvil with a larger code limit
anvil --code-size-limit 30000# in a new terminal, run the Forge script
export PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
forge script script/CounterScript.sol \
--rpc-url http://localhost:8545 \
--code-size-limit 30000 \
--broadcastWARNING The above private key for account 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 is only used for Foundry testing. Do not use this known account on mainnet.
# Get the counter values from the CounterHook
export COUNTER=0x3CD91b522f2a6CB67F378d7fBee767602d5140bB
cast call $COUNTER "beforeSwapCounter()(uint256)" --rpc-url http://localhost:8545
cast call $COUNTER "afterSwapCounter()(uint256)" --rpc-url http://localhost:8545Summary of the modify position calls
Summary of the swap calls
See here for more detailed transaction traces with call parameters and events.
- The MyHook contract has empty
beforeInitialize,afterInitialize,beforeModifyPosition,afterModifyPosition,beforeSwap,afterSwap,beforeDonateandafterDonatehooks that can be implemented. - The MyHookScript script deploys to a local Anvil node and does a swap.
# start anvil with a larger code limit
anvil --code-size-limit 30000# in a new terminal, run the Forge script
export PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
forge script script/MyHookScript.sol \
--rpc-url http://localhost:8545 \
--code-size-limit 30000 \
--broadcast- The DynamicFeeHook contract has an empty
getFeefunction that is used to set the fee for dynamic fee pools. It also has emptybeforeModifyPosition,afterModifyPosition,beforeSwapandafterSwaphooks but they are not required for a dynamic fee hook. They can be removed if not needed. - The DynamicFeeScript script deploys to a local Anvil node and does a swap. Note the fee in the PoolKey is set with the
DYNAMIC_FEE_FLAG.
// Derive the key for the new pool
poolKey = PoolKey(
Currency.wrap(address(token0)), Currency.wrap(address(token1)), FeeLibrary.DYNAMIC_FEE_FLAG, 60, hook
);
// Create the pool in the Uniswap Pool Manager
poolManager.initialize(poolKey, SQRT_RATIO_1_1);Summary of the swap calls
See here for more examples and details.
# start anvil with a larger code limit
anvil --code-size-limit 30000The following runs the DynamicFeeScript against a local Anvil node
# in a new terminal, run the Forge script
export PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
forge script script/DynamicFeeScript.sol \
--rpc-url http://localhost:8545 \
--code-size-limit 30000 \
--broadcastThis repository was created from this GitHub project template https://github.com/saucepoint/v4-template. Thanks @saucepoint for an excellent starting point. This repo has significantly evolved from the starting template.
- Uniswap V3 Development Book
- Uniswap v4 Core whitepaper
- Uniswap v4-core repository
- Uniswap v4-periphery repository contains advanced hook implementations that serve as a great reference.
- A curated list of Uniswap v4 hooks
- Uniswap v4 Hooks: Create a fully on-chain "take-profit" orders hook on Uniswap v4
- SharkTeam's Best Security Practices for UniswapV4 Hooks
- Research - What bad hooks look like
