Pre-launch. RC4 code-frozen for external audit (rc4-audit-candidate, aca5fcd). Report pending. Status, updated 2026-10-08
GENESpecimen 001

Documentation · Learn

The pool and the hook

Why GENE uses exactly one Uniswap v4 pool with one hook, and what the hook does on each pool action.

GENE has one canonical Uniswap v4 pool. GENE is a plain ERC-20, so other pools can list it, but their trades never reach GeneHook (GeneToken.sol:6-10). The canonical pool is fixed when the hook is constructed, and the hook is written so that no second pool can use it and nobody else can provide liquidity to it.

#One pool, fixed at construction

A Uniswap v4 pool is identified by its PoolKey: two currencies, a fee, a tick spacing and a hook address (Uniswap: create a pool). GeneHook builds its own key in its constructor: native ETH as currency0, GENE as currency1, a static LP fee (parameters), a fixed tick spacing (parameters) and the hook itself (GeneHook.sol:236-244). The pool's identifier, poolId, is the hash of that key and is stored as an immutable. Exact values are on permissions and PoolKey.

#Why the hook rejects everyone else

In Uniswap v4 a hook's address encodes which callbacks the PoolManager calls (Uniswap: hooks). GeneHook enables five: beforeInitialize, beforeAddLiquidity, beforeRemoveLiquidity, beforeSwap and afterSwap (GeneHook.sol:40-45, :148-149).

The first three always revert (GeneHook.sol:332-352). The PoolManager skips a hook's callbacks when the hook itself is the caller (Hooks.sol:171-175). Together these rules mean:

  • No rogue pool. Any other attempt to initialize a pool that names this hook reverts, so only GeneHook's own launch() can open the pool.
  • No outside liquidity. Every add from another address reverts, so the hook is the only liquidity provider and every LP fee accrues to its positions.
  • No outside removal. Removes from other addresses revert as well. The hook itself has no remove path at all (see Permanent Mass).

Donations are not blocked: GENE sets no donate flag, so a donation becomes fees owed to the protocol's in-range positions.

#What happens on a swap

GENE does not restrict who may trade. The swap callbacks only observe:

  • beforeSwap checks that the key matches the canonical pool's currencies, fee and tick spacing (WrongPool otherwise). On a block's first swap it records the block-start state (GeneHook.sol:355-366).
  • afterSwap adds the swap to the open epoch's accumulators: net GENE leaving the curve, block ETH volume and, on buys only, the revenue metric (GeneHook.sol:368-390).

Both return zero deltas and no fee override, so the hook neither takes a fee nor changes a swap's amounts (GeneHook.sol:365, :389). The hook contains no rule that rejects a swap by size, direction or sender (GeneHook.sol:355-390). From every state the invariant runs reach, a small and a very large sell both succeed (GenePermanence.t.sol:167-185). Audit scope note: revert paths in the swap callbacks across all states (see Security).

#Reading the price

Ticks in this pool measure GENE per ETH, so a higher tick means cheaper GENE, and a buy moves the tick down (GeneHook.sol:103-104). This orientation matters on every page that talks about bands "below" or "above" the price: an ETH bid below the GENE price sits at higher ticks.

#Opening the pool

At launch the pool is initialized at the opening tick (parameters) and, in the same transaction, the whole supply is added as one GENE-only band whose other edge is the genesis lower tick (parameters) (GeneHook.sol:252-273, :420-435). The pool is never initialized and empty across a transaction boundary (GeneHook.sol:252-273). See Protocol for the full sequence.

Sources (11)
  • src/GeneHook.sol:40-45
  • src/GeneHook.sol:103-104
  • src/GeneHook.sol:148-149
  • src/GeneHook.sol:224-248
  • src/GeneHook.sol:332-390
  • src/GeneHook.sol:420-435
  • src/Genome.sol:16-19
  • lib/v4-core/src/libraries/Hooks.sol:171-175
  • https://developers.uniswap.org/docs/protocols/v4/guides/create-pool
  • https://developers.uniswap.org/docs/protocols/v4/concepts/hooks
  • src/GeneToken.sol:6-10

Paths are relative to the GENE repository at tag rc4-audit-candidate (aca5fcd).