A Uniswap v4 Hook built with Foundry that applies a discounted swap fee for whitelisted users.
- ✅ Whitelisted users get a lower fee override (0.1% in this implementation)
- ✅ Non-whitelisted users pay the normal pool fee
- ✅ Includes Foundry tests using Uniswap v4 core test utilities (
Deployers,PoolSwapTest,HookMiner)
This hook implements the beforeSwap hook and dynamically returns a fee override:
- If
tx.originis whitelisted →feeOverride = DISCOUNTED_FEE - Otherwise →
feeOverride = 0(no override, default pool fee applies)
⚠️ Note: usingtx.originis intentional here to support router-based swaps in tests. In production systems you might want to usemsg.sender, signed payloads, or more robust user identity checks.
src/feeDiscount.sol
Key elements:
FeeDiscountHookinheritsBaseHook- owner-controlled
setWhitelist - implements
_beforeSwap(...) - returns
BeforeSwapDeltaLibrary.ZERO_DELTAand a fee override
test/feeDiscount.t.sol
Tests include:
- only owner can whitelist users
- whitelisted swaps pay less than non-whitelisted swaps
- revoked whitelist pays full fee again
- zero amount swap reverts (
SwapAmountCannotBeZero)
- Solidity
^0.8.24 - Foundry
- Uniswap v4 core + periphery
HookMinerfor deterministic hook deployment with correct permissions flags
- Install Foundry
curl -L https://foundry.paradigm.xyz | bash
foundryup# Install dependencies
forge install
# Build
forge build
# Test
forge test -vv
# Format
forge fmt-
Hook permissions
The hook declares only beforeSwap as enabled:
beforeSwap: true -
Hook deployed using HookMiner
Uniswap v4 hooks must be deployed at an address that matches the hook permissions flags.
The tests use:
HookMiner.find(...) new FeeDiscountHook{salt: salt}(manager)
so that the hook address matches the required flags.
-
Discount fee override
The hook applies:
uint24 public constant DISCOUNTED_FEE = 1000; // 0.1%
Then in
_beforeSwap:uint24 feeOverride = whitelist[tx.origin] ? DISCOUNTED_FEE : 0;
When running:
forge test -vvYou should see logs like:
Whitelisted user input paid < Non-whitelisted input paid
Savings shown in wei
This is a learning project.
- Access control is owner-based and simple.
- Using
tx.originis generally discouraged in production but useful in router-based swaps & testing.
Contributions are welcome! Please open an issue or submit a pull request.