Dynamic Fees
After graduation, every swap through the Uniswap V4 pool is subject to a dynamic fee collected by the LiquidityGenHook. The fee rate decreases as the pool's ETH depth grows.
Fee Tiers
The Hook computes the fee tier based on the approximate ETH (or BNB) held in the Uniswap V4 pool. Deeper pools get lower fees, incentivizing liquidity growth.
| Tier | Fee Rate | Base (ETH threshold) | BSC (BNB threshold) |
|---|---|---|---|
| Tier 1 | 1.2% (120 bps) | < 12 ETH | < 24 BNB |
| Tier 2 | 0.8% (80 bps) | 12–24 ETH | 24–48 BNB |
| Tier 3 | 0.4% (40 bps) | > 24 ETH | > 48 BNB |
How Fees Are Collected
The Hook implements Uniswap V4's beforeSwap and afterSwap callbacks:
- Buys (ETH → Token,
zeroForOne = true): Fee is taken inbeforeSwapby callingPoolManager.take()on the ETH delta. - Sells (Token → ETH,
zeroForOne = false): Fee is taken inafterSwapfrom the ETH output delta.
Fees accumulate in pendingFees[token] (a standalone mapping optimized for minimal gas) until distributed.
Fee Tier Caching
Computing the fee tier requires 2 external staticcalls to the StateView contract (~5.2k gas). To avoid this cost on every swap, the Hook caches the tier in cachedFeeBps[token]. The cache is updated:
- Automatically on the first swap (self-caching in
_getFee()) - During
distributeFees()calls - Manually via
refreshFeeTier(token)— callable by anyone
Fee-Free Internal Swaps
When the Hook performs internal swaps (for reinvestment), it sets a transient flag _internalSwapActive using EIP-1153. The beforeSwap and afterSwap hooks check this flag and skip fee collection, preventing fee-on-fee compounding.
The transient storage flag costs only 100 gas to read (TLOAD) compared to 2,100 gas for a cold SLOAD. It also auto-resets at the end of each transaction, eliminating cleanup costs.