Skip to Content
Smart ContractsCeosHook (Uniswap V4)

CeosHook (Uniswap V4)

CeosHook is a Uniswap V4 hook contract that collects a 2.5% fee on every swap involving graduated company tokens. The fee is routed to FeeSplitterV2 for protocol revenue distribution.

Overview

When a company token graduates from its bonding curve to a Uniswap V4 pool (at $10K market cap), the pool is initialized with CeosHook attached. Every subsequent swap through that pool triggers the hook’s afterSwap callback, which deducts a 2.5% fee from the output amount.

PropertyValue
Hook TypeafterSwap
Fee Rate2.5% of swap output
Fee RecipientFeeSplitterV2 (0xf672ef2D80874E2E7Cd01b282Db14b08cAdcEB7c)
Applies ToAll graduated company token pools
PoolManager0x05E73354cFDd6745C338b50BcFDfA3Aa6fA03408

Architecture

User Swap → PoolManager.swap() → CeosHook.afterSwap() → 2.5% fee extracted FeeSplitterV2 ├── 50% $RUN burn ├── 25% Protocol Treasury treasury └── 25% Scout Fund

The hook is injected at pool initialization time by the CompanyTokenLauncher during the graduation process:

// In CompanyTokenLauncher._graduateToV4(): PoolKey memory key = PoolKey({ currency0: currency0, currency1: currency1, fee: poolFee, tickSpacing: tickSpacing, hooks: IHooks(ceosHook) // CeosHook address }); poolManager.initialize(key, sqrtPriceX96);

Hook Lifecycle

Pool Initialization

The CompanyTokenLauncher sets the ceosHook address via setCeosHook() (admin function). When a company token graduates, the hook address is embedded in the PoolKey.hooks field. The PoolManager validates the hook address against the V4 hook address flag scheme.

afterSwap Callback

After each swap in a hooked pool, the PoolManager calls afterSwap on the hook contract. CeosHook:

  1. Calculates 2.5% of the swap output amount.
  2. Transfers the fee to FeeSplitterV2.
  3. Returns the modified amounts to the PoolManager.

Fee Distribution

The 2.5% fee collected by CeosHook flows into FeeSplitterV2, which splits it according to the protocol revenue model:

DestinationSharePurpose
$RUN Burn50%Deflationary pressure on $RUN supply
Dev Treasury25%Protocol development and operations
Scout Fund25%Protocol-owned liquidity via ScoutFundV2

Configuration

The CeosHook address is set on CompanyTokenLauncher by an admin:

// Set the hook address (DEFAULT_ADMIN_ROLE required) companyTokenLauncher.setCeosHook(ceosHookAddress);

Once set, all future token graduations will use this hook. Existing pools cannot have their hooks changed — the hook is immutable per pool.

Integration with CompanyTokenLauncher

The CeosHook is referenced during graduation only. The relevant configuration on CompanyTokenLauncher:

/// @notice CeosHook address for V4 pools (address(0) = no hook) address public ceosHook; /// @notice Pool fee in hundredths of a bip (3000 = 0.3%) uint24 public poolFee; /// @notice Tick spacing for the V4 pool int24 public tickSpacing;

Security Considerations

  • The hook runs within the PoolManager’s execution context via a callback. It cannot arbitrarily move user funds outside the swap flow.
  • The fee is extracted from swap output, not from user balances. Users see the net output amount after the fee deduction.
  • The hook address is immutable per pool — once a pool is initialized, its hook cannot be replaced.
  • The PoolManager enforces that the hook address matches the V4 hook flags encoded in its address.
  • FeeSplitterV2 is a trusted recipient. The hook’s fee transfer is a direct SafeERC20.safeTransfer.