Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.geode.ag/llms.txt

Use this file to discover all available pages before exploring further.

Overview

GeodeHook.sol is the entire Geode protocol in a single contract (~1,260 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

IPoolManager public immutable poolManager;    // Uniswap v4 PoolManager
ISignatureTransfer public immutable permit2;  // Canonical Permit2 contract
address public immutable protocolTreasury;    // Receives 50% of direct swap fees
address public immutable factory;             // GeodeFactory — authorized to register launches

Constants

uint256 public constant PROTOCOL_FEE_SHARE_BPS = 5000;          // 50% of direct swap fees → treasury
uint256 public constant DEFAULT_GRADUATION_ETH = 85 ether;      // Graduation threshold
uint256 public constant MIN_GRADUATION_DISTRIBUTION_BPS = 9500; // 95% supply distributed
address public constant DEAD_ADDRESS = 0x...dEaD;               // Unsold token retirement

State Variables

mapping(PoolId => PoolConfig) internal _poolConfigs;      // Per-pool configuration
mapping(PoolId => bool) public poolInitialized;           // Configuration flag
mapping(PoolId => uint256) public lastSettledBlock;       // Batch interval enforcement
mapping(PoolId => BatchState) internal _currentBatch;     // Current batch tracking
mapping(PoolId => uint256) public surplusCurrency0;       // Accumulated surplus (token0)
mapping(PoolId => uint256) public surplusCurrency1;       // Accumulated surplus (token1)
mapping(PoolId => LaunchState) internal _launchStates;    // Launch curve state
mapping(PoolId => uint256) public launchTokenReserve;     // Token reserve for curve dispensing
mapping(PoolId => uint256) public launchEthReserve;       // ETH reserve from curve sales
mapping(PoolId => uint160) public batchAnchorSqrtPrice;   // Batch-open anchor for residual protection

External Entry Points

geodeSettleBatch()

The main settlement function. Permissionless — anyone can call it and earn rewards.
function geodeSettleBatch(
    PoolKey calldata key,
    GeodeIntent[] calldata buys,
    GeodeIntent[] calldata sells,
    bytes[] calldata buySignatures,
    bytes[] calldata sellSignatures
) external
Flow:
  1. Validate pool is configured and batch interval has elapsed
  2. Validate all intent bindings (poolId, deadlines)
  3. Record batch-open anchor sqrtPriceX96 for residual protection
  4. Compute clearing price and determine fills (phase-aware: curve vs AMM)
  5. Update batch state, emit GeodeIntentFilled events
  6. Call poolManager.unlock() → enters flash accounting context
  7. Inside unlockCallback():
    • Pull tokens from each user via Permit2
    • Route residual through AMM (or curve in launch mode)
    • Distribute outputs pro-rata to filled intents
    • Pay settler (fees + gas reimbursement)

beforeSwap()

Hook callback intercepting every swap on configured pools.
function beforeSwap(
    address sender,
    PoolKey calldata key,
    SwapParams calldata params,
    bytes calldata
) external onlyPoolManager returns (bytes4, BeforeSwapDelta, uint24)
Behavior:
  • If sender == address(this) (hook routing residual): no fee, pass through
  • If pool is in Active/PendingGraduation launch phase: revert (LaunchNotGraduated)
  • Otherwise: charge directSwapFeeBps on the swap amount
    • 50% → protocolTreasury via poolManager.take()
    • 50% → per-pool surplus (held as ERC20 on hook)
Delta accounting: The fee uses paired deltas that net to zero for the hook:
  1. take(unspecified, hook, feeAmount) → negative hook delta
  2. BeforeSwapDelta(0, +feeAmount) → positive hook delta charged to swapper

geodeInitializePool()

One-time pool configuration. Curve pools (with deployer set) require the factory as caller.
function geodeInitializePool(
    PoolKey calldata key,
    PoolConfig calldata config
) external

registerLaunch()

Called by the factory to register launch curve state. Sets up LaunchState with virtual reserves and graduation threshold.

finalizeGraduation()

Permissionless. Called after PendingGraduation phase. Initializes the v4 pool at terminal curve price and seeds permanent full-range liquidity.

Internal Settlement Functions

_computeSettlement()

Phase-aware routing:
  • Active launchConstantProductCurveLib.computeLaunchSettlement()
  • PendingGraduation → revert (no trading)
  • Standard / GraduatedClearingPriceLib.computeClearingPrice()

_routeAndDistribute()

Standard mode: routes residual through poolManager.swap() with anchor price protection, then distributes outputs.

_routeAndDistributeLaunchMode()

Launch mode: dispenses/absorbs tokens via bonding curve. Updates launchTokenReserve, launchEthReserve, and cumulativeSupplyDistributed. Checks graduation conditions after every batch.

_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

function getBatchState(PoolId) external view returns (BatchState memory);
function getPoolConfig(PoolId) external view returns (PoolConfig memory);
function getSurplusCurrency0(PoolId) external view returns (uint256);
function getSurplusCurrency1(PoolId) external view returns (uint256);
function getLastSettledBlock(PoolId) external view returns (uint256);
function canSettle(PoolId) external view returns (bool);
function getLaunchState(PoolId) external view returns (LaunchState memory);
function getLaunchMetrics(PoolId) external view returns (
    uint256 currentPriceQ96, uint256 marketCap, uint256 fdv,
    uint256 ethRaised, uint256 circulatingSupply
);
function isGraduated(PoolId) external view returns (bool);

Events

EventWhen
GeodeBatchSettledBatch settlement completes
GeodeIntentFilledEach filled intent
SettlerPaidSettler receives payment (per-currency breakdown)
GeodeDirectSwapDirect swap fee charged
GeodeProtocolFeeCollectedProtocol treasury receives fee share
GeodePoolConfiguredPool configured for batching
GeodeLaunchedLaunch token registered
GraduationTriggeredPhase → PendingGraduation
GeodeGraduatedPhase → Graduated, AMM seeded
UnsoldTokensRetiredUnsold tokens sent to dead address
GeodeDeployerRoyaltyPaidDeployer royalty paid from surplus

Source

GeodeHook.sol

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