Hook System
The Zora protocol uses a unified Uniswap V4 hook to automatically manage pool interactions and reward distribution for all coin types.
Overview
The hook system now uses a single implementation, ZoraV4CoinHook, which encapsulates the full logic for pool initialization, fee collection, multi-hop payout conversion, and reward distribution across both Content Coins and Creator Coins.
Previously, two specialized hook contracts were used (ContentCoinHook and CreatorCoinHook). As of coins v2.3.0, these have been consolidated into the single ZoraV4CoinHook for simplicity and maintainability while preserving identical external behavior.
Inheritance Structure
The unified hook centralizes shared functionality and derives reward behavior from coin configuration:
ZoraV4CoinHook
Contains all core functionality used by both coin types:
Automated Operations:- Pool initialization and automatic liquidity position creation
- Automatic fee collection from all LP positions on every swap
- Multi-hop currency conversion through optimal swap paths
- Hook upgrade and migration support
- Comprehensive event emission and transaction logging
- Uniswap V4
afterInitializeandafterSwaphook permissions - Doppler multi-curve liquidity positioning
- Trusted message sender validation
- Pool-to-coin mapping and position tracking
Reward distribution is unified and determined at runtime from the coin type via CoinRewardsV4.
Key Insight: Logic that was previously split across two hooks is now implemented in one place; reward behavior is selected based on the coin type and configuration.
Deployment Addresses
| Chain | Chain ID | Hook Contract | Address |
|---|---|---|---|
| Base | 8453 | ZoraV4CoinHook | See @zoralabs/protocol-deployments |
Hook Permissions
The unified hook has the following Uniswap V4 permissions:
function getHookPermissions() external pure override returns (Hooks.Permissions memory) {
return Hooks.Permissions({
beforeInitialize: false,
afterInitialize: true, // ✅ Enabled
beforeAddLiquidity: false,
afterAddLiquidity: false,
beforeRemoveLiquidity: false,
afterRemoveLiquidity: false,
beforeSwap: false,
afterSwap: true, // ✅ Enabled
beforeDonate: false,
afterDonate: false,
beforeSwapReturnDelta: false,
afterSwapReturnDelta: false,
afterAddLiquidityReturnDelta: false,
afterRemoveLiquidityReturnDelta: false
});
}Core Functionality
After Initialize Hook
When a new pool is initialized, the hook automatically:
- Validate Pool Setup: Ensure the pool is properly configured for the coin type
- Create Initial Positions: Set up liquidity positions based on the coin's configuration
- Register Pool: Link the pool to the appropriate coin contract
- Configure Reward Distribution: Set up the reward distribution mechanism
After Swap Hook
On every swap, the hook automatically:
- Collect LP Fees: Gather accrued fees from all liquidity positions
- Convert to Payout Currency: Swap collected fees through optimal paths
- Distribute Rewards: Allocate rewards based on coin type and configuration
- Emit Events: Log detailed swap and reward information
Reward Distribution
The unified hook implements the same reward distribution mechanism across coin types, with the specific split determined by the coin type via CoinRewardsV4.
Key Details
- Both Content Coins and Creator Coins share the unified fee structure and support platform referral, trade referral, creator, protocol, and Doppler distributions (as of v2.2.0+).
Fee Split: A portion of collected fees is reminted as LP rewards to maintain liquidity, while the remainder is distributed as market rewards to stakeholders.
Multi-Hop Reward Swapping
The hook automatically supports complex swap paths for coins that aren't directly paired with the final payout currency:
Example: Content Coin → Creator Coin → ZORA
- Content Coin fees automatically collected in Content Coin tokens
- First hop: Content Coin → Creator Coin (backing currency)
- Second hop: Creator Coin → ZORA token (final payout currency)
- Distribution: ZORA tokens automatically distributed to reward recipients
This automatically enables complex token economies where Content Coins can be backed by Creator Coins, which are in turn backed by ZORA tokens.
Liquidity Management
The hook automatically manages liquidity positions throughout the pool lifecycle:
Automatic Position Creation
During pool initialization, the hook automatically creates:
- Discovery Positions: Initial price discovery ranges
- Market Positions: Main trading ranges
- Multi-Position Support: Complex liquidity curves with multiple ranges
Position Structure
struct LiquidityPosition {
int24 tickLower; // Lower price bound
int24 tickUpper; // Upper price bound
uint128 liquidity; // Liquidity amount
uint256 feeGrowthInside0X128; // Fee tracking
uint256 feeGrowthInside1X128; // Fee tracking
}Migration Support
The hook supports controlled liquidity migration to enable upgrades to new hook versions while preserving all existing liquidity.
Migration Resources:- Complete Migration Guide - Step-by-step migration process and security considerations
- Migration Flow Diagram - Visual sequence diagram of the migration process
- Migration Events - Event emission details for tracking migrations
Events
Swapped Event
event Swapped(
address indexed sender,
address indexed swapSender,
bool isTrustedSwapSenderAddress,
PoolKey key,
bytes32 indexed poolKeyHash,
SwapParams params,
int128 amount0,
int128 amount1,
bool isCoinBuy,
bytes hookData,
uint160 sqrtPriceX96
);Emitted on every swap with detailed transaction information including:
- sender: The address that initiated the swap transaction
- swapSender: The original message sender (may differ from sender if using trusted message senders)
- isTrustedSwapSenderAddress: Whether the sender is registered as a trusted message sender
- key: The complete pool key identifying the pool
- poolKeyHash: Indexed hash of the pool key for efficient filtering
- params: The swap parameters (amount, direction, etc.)
- amount0/amount1: The actual token amounts exchanged
- isCoinBuy: Whether this swap is purchasing the coin (true) or selling it (false)
- hookData: Additional data passed to the hook (often contains referral information)
- sqrtPriceX96: The final sqrt price after the swap
CoinMarketRewardsV4 Event
event CoinMarketRewardsV4(
address coin,
address currency,
address payoutRecipient,
address platformReferrer,
address tradeReferrer,
address protocolRewardRecipient,
address dopplerRecipient,
MarketRewardsV4 marketRewards
);Emitted when market rewards are distributed from collected fees, showing exact amounts to each recipient:
- coin: The coin contract that generated the rewards
- currency: The currency in which rewards are paid out
- payoutRecipient: The creator's reward recipient address
- platformReferrer: Address receiving platform referral rewards
- tradeReferrer: Address receiving trade referral rewards
- protocolRewardRecipient: Protocol treasury address
- dopplerRecipient: Doppler rewards recipient
- marketRewards: Detailed breakdown of reward amounts for each recipient
LpReward Event
Historical Note
Prior to v2.3.0, the system used two hooks (ContentCoinHook and CreatorCoinHook). With the introduction of the unified ZoraV4CoinHook, all behavior is consolidated. Existing pools can migrate liquidity using the liquidity migration flow.
event LpReward(
address indexed coin,
address indexed currency,
uint256 amountCurrency,
int24 tick,
uint128 liquidity
);Emitted when liquidity provider rewards are reminted back into the pool:
- coin: The coin contract generating the LP rewards
- currency: The currency of the reminted LP position
- amountCurrency: The amount of currency reminted as new liquidity
- tick: The current pool tick when the reward was reminted
- liquidity: The amount of liquidity reminted back into the pool
This event tracks the portion of collected fees that are automatically reminted as liquidity rather than distributed as market rewards.
