> ## 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.

# GeodeHook.sol

> The core Uniswap v4 hook contract — batch settlement, direct curve swaps, and fee management.

## 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

```solidity theme={null}
IPoolManager public immutable poolManager;    // Uniswap v4 PoolManager
ISignatureTransfer public immutable permit2;  // Canonical Permit2 contract
address public immutable protocolTreasury;    // Receives ~1/3 of direct swap fees
address public immutable factory;             // GeodeFactory — authorized to register launches
```

## Constants

```solidity theme={null}
uint256 public constant CURVE_RESERVE_FEE_SHARE_BPS = 3334; // ~1/3 of fee → curve ETH reserve
uint256 public constant PROTOCOL_FEE_SHARE_BPS = 3333;      // ~1/3 of fee → treasury
// Remainder (~1/3) → surplus pool
```

## State Variables

```solidity theme={null}
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;    // Permanent curve state
mapping(PoolId => uint256) public launchTokenReserve;     // Token reserve for curve dispensing
mapping(PoolId => uint256) public launchEthReserve;       // ETH reserve from curve sales
```

## External Entry Points

### `geodeSettleBatch()`

The main settlement function. Permissionless — anyone can call it and earn rewards.

```solidity theme={null}
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. 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.

```solidity theme={null}
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 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.

```solidity theme={null}
function geodeInitializePool(
    PoolKey calldata key,
    PoolConfig calldata config
) external
```

### `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 curve** → `ConstantProductCurveLib.computeLaunchSettlement()`
* **Standard** → `ClearingPriceLib.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

```solidity theme={null}
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
);
```

## Events

| Event                       | When                                              |
| --------------------------- | ------------------------------------------------- |
| `GeodeBatchSettled`         | Batch settlement completes                        |
| `GeodeIntentFilled`         | Each filled intent                                |
| `SettlerPaid`               | Settler receives payment (per-currency breakdown) |
| `GeodeCurveSwap`            | Direct bonding curve swap executed                |
| `GeodeDirectSwap`           | Direct swap fee charged (standard pools)          |
| `GeodeProtocolFeeCollected` | Protocol treasury receives fee share              |
| `GeodePoolConfigured`       | Pool configured for batching                      |
| `GeodeLaunched`             | Launch token registered                           |
| `GeodeDeployerRoyaltyPaid`  | Deployer royalty paid from surplus                |

## Source

<Card title="GeodeHook.sol" icon="github" href="https://github.com/Geode-vAMM/geodex/blob/main/contracts/src/GeodeHook.sol">
  View the full source code on GitHub (\~1,190 lines).
</Card>
