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.

TierFee RateBase (ETH threshold)BSC (BNB threshold)
Tier 11.2% (120 bps)< 12 ETH< 24 BNB
Tier 20.8% (80 bps)12–24 ETH24–48 BNB
Tier 30.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 in beforeSwap by calling PoolManager.take() on the ETH delta.
  • Sells (Token → ETH, zeroForOne = false): Fee is taken in afterSwap from 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.

Gas Optimization

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.