FeeHook on Ethereum

Uniswap v4 Hook Contract 0x1b9f3544dc4915e0c08882d1c3f39b6e464e4844 on Ethereum · Fee sharing · Verified contract

Volume (24h)
$23
Value locked (TVL)
$21.47K
All-time volume
$14.05K
Pools using this hook
2
Swaps (24h)
1 (1 traders)
Total swaps
190

What it does

A Uniswap v4 hook that collects LP fees from its own position on swaps and distributes accumulated ETH each week to users who checked in while holding vMoney.

This read was written for the hook 0x3f74…0844 on Base and reused here: the two share a code shape, so constants such as fees, owners and addresses can differ.

How it works step by step

  • Records the position token id for each pool the first time liquidity is added through beforeAddLiquidity.
  • Accumulates a notional fee on exact-input zeroForOne swaps using the pool fee.
  • Once accumulated fees exceed minWithdraw, decreases liquidity on the hook-owned position and takes the pair to the hook.
  • Burns non-native currency1 collected from fees by sending it to the dead address.
  • Lets users check in weekly when they hold vMoney, and after the week ends anyone can call distributeFees to split the contract's ETH balance pro rata by vMoney balance.
  • Owner can reassign the LP position NFT, change minWithdraw, change the vMoney token address, and reset the week start.
Swap behaviour
On swaps, afterSwap accrues a fee estimate for exact-input zeroForOne swaps, and once accumulated fees exceed minWithdraw it decreases the hook's liquidity and takes the pair, then burns currency1 by sending it to 0x...dEaD. It returns zero delta, so it does not change the swapper's amounts.
Liquidity behaviour
beforeAddLiquidity records the most recent position NFT id for a pool the first time liquidity is added. The hook holds the LP position NFT in the PositionManager. No removal callbacks are enabled.
Fee behaviour
Hook does not change the pool fee. It accrues a notional fee of swap amount times key.fee divided by 1e6 on exact-input zeroForOne swaps, collects LP fees from the hook-owned position once the threshold is reached, burns the non-native currency1 to 0x...dEaD, and forwards native ETH balance to weekly check-in distributions.
Owner & admin controls
Owner (Ownable) can set minWithdraw via setMinWithdraw, set vMooneyAddress via setvMooneyAddress, reset weekStart via setWeekStart, transfer the LP position NFT via transferPosition, and transfer or renounce ownership. No pause or upgrade mechanism found.

Enabled Uniswap v4 callbacks

beforeAddLiquidity, afterSwap, afterSwapReturnDelta

beforeAddLiquidity: records the position token id for the pool on first liquidity add. afterSwap: accrues fee accounting, collects LP fees above minWithdraw, burns currency1 to dead address, and returns zero delta. afterSwapReturnDelta: enabled flag only; the hook returns 0 so no delta is taken from swappers.

Security & trust assessment

Risk level: medium (verified source, high confidence).

Who controls it: The owner can reset weekStart to any value, redirect the vMoney token used for weight calculation, lower minWithdraw to trigger frequent collection, and move the LP position NFT to any address, including removing the fee income stream from the pool. The owner cannot directly withdraw ETH held by the contract.

Risk to user funds: The hook holds the LP position NFT and native ETH balance and can receive ETH via receive/fallback. The owner can redirect the NFT and vMoney weight token. Swappers and LPs pay no extra fee through the hook; it does not take deltas from swaps. Users checking in can receive ETH shares, but that payout depends on owner-controlled parameters.

Security findings

  • [medium] Owner controls the vMoney weight token: The owner can call setvMooneyAddress to point the weight token at an arbitrary contract, changing how check-in balances translate into ETH payouts.
  • [medium] Owner can move the LP position NFT: The owner can call transferPosition to move the LP position NFT held by the hook to any address, permanently removing the pool's fee income from this hook.
  • [low] Unbounded loops and adjustable week timer: distributeFees is callable by anyone once the week ends and loops over all checked-in users with external balanceOf calls, so a large checkedIn array can make it exceed gas limits. Also setWeekStart can move the timer backward or forward.
  • [medium] External calls inside swap path can block swaps: afterSwap performs external calls into the PositionManager and token transfers during swaps. A revert in those calls, for example in a pool with a token that blocks transfers, would cause swaps to fail for that pool.
  • [info] Fee accounting is approximate: The fee accrual uses only exact-input zeroForOne swaps and the hook owns the LP position, so the notional fee accounting may not match actual fees earned, and unclaimed amounts from fee-token burns can be lost.

Contract details

Verified source
Yes (FeeHook)
Compiler
solc 0.8.26+commit.8a97fa7a
Bytecode size
7,706 bytes
Upgradeable proxy
No
Detected patterns
ownable, return-delta

Pools using FeeHook