Skip to main content

Overview

GeodeHook.sol is the entire Geode protocol in a single contract (~1,190 lines). It implements the Uniswap v4 IHooks interface and IUnlockCallback, intercepting swaps via beforeSwap and providing batch settlement through geodeSettleBatch(). Hook flags: BEFORE_SWAP | BEFORE_SWAP_RETURNS_DELTA

Immutables

Constants

State Variables

External Entry Points

geodeSettleBatch()

The main settlement function. Permissionless — anyone can call it and earn rewards.
Flow:
  1. Validate pool is configured and batch interval has elapsed
  2. Validate all intent bindings (poolId, deadlines)
  3. Compute clearing price and determine fills (phase-aware: curve vs standard)
  4. Update batch state, emit GeodeIntentFilled events
  5. Call poolManager.unlock() → enters flash accounting context
  6. Inside unlockCallback():
    • Pull tokens from each user via Permit2
    • Route residual through AMM (standard) or bonding curve (curve mode)
    • Distribute outputs pro-rata to filled intents
    • Pay settler (fees + gas reimbursement)

beforeSwap()

Hook callback intercepting every swap on configured pools.
Behavior:
  • If sender == address(this) (hook routing residual): no fee, pass through
  • If pool is an Active curve pool: _curveDirectSwap() — the hook computes the bonding curve output, charges 0.3% split three ways (reserve, treasury, surplus), and returns the full delta. The AMM processes nothing.
  • Otherwise (standard pool): charge directSwapFeeBps on the swap amount — ~1/3 → treasury, ~2/3 → surplus
Curve direct swap delta accounting: The hook absorbs the entire swap through BEFORE_SWAP_RETURNS_DELTA:
  1. Takes the user’s input from the PoolManager
  2. Computes curve output via ConstantProductCurveLib
  3. Provides output to the user
  4. Returns a BeforeSwapDelta that fully satisfies the swap

geodeInitializePool()

One-time pool configuration. Curve pools (with deployer set) require the factory as caller.

registerLaunch()

Called by the factory to register permanent curve state. Sets up LaunchState with virtual reserves and token tracking.

Internal Functions

_curveDirectSwap()

Handles direct swaps on curve pools — the core of the permanent curve architecture:
  1. Validates exactInput only (positive amountSpecified reverts)
  2. Computes 0.3% fee, split three ways:
    • Reserve fee (3334 bps) → added to launchEthReserve / launchTokenReserve
    • Protocol fee (3333 bps) → sent to treasury
    • Surplus fee (remainder) → accumulated in pool surplus
  3. Computes curve output from net input
  4. Updates cumulativeSupplyDistributed, reserves, and token balances
  5. Returns BeforeSwapDelta that fully absorbs the swap
  6. Emits GeodeCurveSwap event

_computeSettlement()

Phase-aware routing:
  • Active curveConstantProductCurveLib.computeLaunchSettlement()
  • StandardClearingPriceLib.computeClearingPrice()

_routeAndDistribute()

Standard mode: routes residual through poolManager.swap(), then distributes outputs.

_routeAndDistributeLaunchMode()

Curve mode: dispenses/absorbs tokens via bonding curve. Updates launchTokenReserve, launchEthReserve, and cumulativeSupplyDistributed.

_paySettler()

Pays the settler:
  1. Settlement fees from unrouted input deposits via poolManager.take()
  2. Gas reimbursement from surplus via _fundSettlerFromSurplus() (capped at maxGasReimbursement)
Emits SettlerPaid with exact per-currency breakdown.

_distributeBuyOutputs() / _distributeSellOutputs()

Pro-rata distribution using each intent’s amountIn as weight. Remainder dust goes to the last filled intent.

View Functions

Events

Source

GeodeHook.sol

View the full source code on GitHub (~1,190 lines).