ContentCoinHook on Base

Uniswap v4 Hook Contract 0x9ea932730a7787000042e34390b8e435dd839040 on Base · Rewards · Verified contract

Volume (24h)
$400
Value locked (TVL)
$147.97K
All-time volume
$50.53M
Pools using this hook
1.9M
Swaps (24h)
129 (17 traders)
Total swaps
2.3M

What it does

Hook for Zora content coin pools on Uniswap v4 that seeds the pool with a multi-curve liquidity ladder at launch, then on every swap collects LP fees, recycles part into new liquidity and pays the rest out as rewards to the creator, referrers and the protocol.

How it works step by step

  • On pool initialization, the hook checks that the initializing sender is a registered v4 coin, computes a log-normal ladder of single-sided LP positions plus a tail position from the coin's pool configuration, and mints them from the hook itself.
  • After every swap it collects accrued fees from all of its stored positions by calling modifyLiquidity with a zero liquidity delta.
  • About one third of the collected fees (3333 bps) is re-minted as a new single-sided one-tick-spacing LP position placed at least two tick spacings away from the current tick.
  • The remaining fees are swapped through the coin's payout path (multi-hop, e.g. coin to backing coin to backing currency) and taken to the hook, then split: 50% creator, 15% platform referrer, 15% trade referrer (read from hookData), 5% Doppler, and the remainder to the protocol recipient.
  • It emits Swapped and CoinMarketRewardsV4 events on each swap, and it supports one-way liquidity migration to a new hook version if the upgrade gate has registered that upgrade path.
Swap behaviour
afterSwap looks up the coin for the pool and reverts if none is registered. It then collects LP fees, mints the LP reward share as new liquidity, and swaps the rest via the payout path inside the pool manager. It takes the output to the hook, transfers the reward shares out, and emits Swapped with the original msg.sender, which it reads from the router through IMsgSender when available. It does not change the swap delta, because the return delta is 0.
Liquidity behaviour
No liquidity callbacks. Only the hook itself holds LP positions; it mints them at initialization or migration and re-mints fee-derived liquidity after swaps. Outside users do not supply liquidity through the hook.
Fee behaviour
The pool fee is a static fee (the config sets LP_FEE_V4 at 3%). The hook does not override fees per swap and takes no return deltas. It harvests the LP fees earned by its own positions and splits them: about 33% is compounded as new liquidity, and the other roughly 67% is converted to the payout currency and paid out as rewards under fixed basis-point splits.
Owner & admin controls
No owner, pause or parameter-setting functions are exposed in the hook ABI. Trusted message senders and the upgrade gate and coin lookup addresses are fixed at construction. The only privileged path is migrateLiquidity, callable by the coin associated with the pool, and only to a new hook registered in the external upgrade gate. That gate's own admin controls are not visible in this input.

Enabled Uniswap v4 callbacks

afterInitialize, afterSwap

afterInitialize registers the coin for the pool, validates that it is a v4 coin, and mints the initial liquidity positions (or returns early when the hook itself initializes a migrated pool). afterSwap harvests fees, compounds part of them as liquidity, swaps the rest to the payout currency and distributes rewards.

Security & trust assessment

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

Who controls it: The hook has no owner. Configuration is immutable, but reward recipients are read live from the coin contract, so whoever controls the coin can redirect reward payouts. The coin and the upgrade gate can also trigger a migration of liquidity to another hook.

Risk to user funds: The hook owns all pool liquidity positions as the LP of record and can burn them via the coin-triggered migration path. It does not hold balances of ordinary traders. Swaps can be blocked if coin getters or reward transfers revert.

Security findings

  • [medium] Coin-triggered liquidity migration: migrateLiquidity lets the pool's coin contract burn all hook-owned positions and send the proceeds to a new hook, provided the upgrade gate has registered the path. Whoever controls the gate or the coin could therefore move pool liquidity to a different hook implementation.
  • [medium] Swaps depend on external coin contract calls: afterSwap calls getPayoutSwapPath, payoutRecipient, platformReferrer, protocolRewardRecipient and dopplerFeeRecipient on the coin. A reverting or misbehaving coin, or a failing recipient, makes swaps revert. For native ETH payouts, a recipient that rejects ETH causes EthTransferFailed and blocks the swap.
  • [low] Hook performs nested swaps and liquidity changes during afterSwap: Each swap triggers fee collection across all positions, a new mint, and one or more internal pool swaps with no price limit (min/max sqrt price). This raises gas cost and exposes the payout conversion to price impact in thin payout pools.
  • [low] Trade referrer taken from user-supplied hookData: The trade referrer address is decoded from hookData, so the swapper picks who receives the 15% trade-referral share. A swapper can name themselves, which is a reward-routing design choice, not a theft vector. Malformed hookData longer than zero bytes can revert the swap on decode.
  • [info] Funds held by the hook only transiently: Liquidity positions are owned by the hook address inside the pool manager, and reward tokens are taken to the hook and transferred out within the same call. The hook has no withdrawal function and a receive() restricted to the pool manager.

Contract details

Verified source
Yes (ContentCoinHook)
Compiler
solc 0.8.28+commit.7893614a
Bytecode size
21,155 bytes
Upgradeable proxy
No
Detected patterns
moves-currency, rewards, self-unlock

Pools using ContentCoinHook