Pre-launch. RC4 code-frozen for external audit (rc4-audit-candidate, aca5fcd). Report pending. Status, updated 2026-10-08
GENESpecimen 001
Specimen 001, the shell's lower chambers and IMMUNITY's seven ribs, folded: not expressed.
Genome anatomySpecimen 001, the shell's lower chambers and IMMUNITY's seven ribs, folded: not expressed. Rendered from the frozen Genome; no chain state.

Security and transparency

GENE's audit status, admin powers, trust assumptions, known limitations, threat model, the evidence behind the RC4 candidate and the scope notes for the external audit.

Status, updated 2026-10-08
DeploymentPre-launch. Addresses will be listed here at launch.
CodeRC4 frozen audit candidate: tag rc4-audit-candidate, commit aca5fcd. Genome VERSION 4.
Internal gate5,920 production tests, 0 failed, 0 skipped; 53,929 attack scenarios on the production code; in every one the protocol ended at or above its no-attack baseline. Verdict: ready for external audit.
External auditNext step. The code is frozen for it; the report will be linked here when it is published.
Bug bountyTo be announced.
Security contactTo be announced.
Admin powersNone after launch(): no owner, no upgrade path, no function that removes liquidity. Before launch, the launcher alone decides when the pool opens.
Outside GENEUniswap v4's protocol fee is controlled by Uniswap governance, not by GENE. If switched on (up to 0.1% per direction), the total fee becomes about 1.099% and that share never reaches GENE's positions.
Known risksPublished in full: Known limitations.

#Audit status

  • Frozen for external audit. The RC4 contracts are code-frozen at tag rc4-audit-candidate, commit aca5fcd, since 2026-10-07. Any change would make a new candidate.
  • Through the full internal gate. The production suites (unit, fuzz, manipulation, adversarial, long-hold, mainnet fork, launch rehearsal, invariants) ran 5,920 tests: 0 failed, 0 skipped, on the frozen logic (the freeze changed only the VERSION number). The production attack matrix ran 53,929 attack scenarios; in every one the protocol ended at or above its no-attack baseline (0 TRANSFER, 0 SELFFUNDED). The internal verdict is "ready for external audit". The one limitation it lists, the thin-market all-time-low ratchet, is described under Known limitations.
  • External audit is the next step. No external report has been published yet. When one exists, it will be linked here in full.
  • The code is the source of truth. Where an older design note differs from the code, the code wins.

#Scope of the audit package

In scope Not in scope
src/GeneHook.sol (1,041 lines), src/GeneLens.sol (302), src/GeneToken.sol (24), src/Genome.sol (116) Uniswap v4-core and v4-periphery (vendored, pinned)
script/Deploy.s.sol, script/Launch.s.sol, script/GeneSaltMiner.sol OpenZeppelin ERC20
The study harnesses under study-design/ (evidence tooling, not shipped)
test/ref/GeneHookRef.sol (a test-only typed reference)

#Focus areas requested of auditors

  1. _newBlock and the all-time-low rule: any path that moves the all-time low on an empty-liquidity print, or places a protocol buy above it.
  2. Net-flow accounting: any address-, router- or split-dependent way to fund a budget twice, or above the fee its flow paid.
  3. Unlock-callback actions: the ERC-6909 claims accounting and the PlacementSkipped path, which must consume no reserve, cap or budget.
  4. R1: that the caller cannot steer the REGENERATION allotment, and that repeated partial calls cannot exceed the caps.
  5. Evolution gates and IMMUNITY's two-epoch confirmation.
  6. Asks above min(spot, ATH) and GENE-side placement.
  7. Deployment: hook permission bits from the CREATE2 address, the launch sequence and the genesis position.

#Scope notes for the external audit

These are the specific questions the external audit is asked to settle, beyond the focus areas above. Each comes from reading the frozen source. Notes 2 and 11 also draw on local experiments on an unmodified copy of the RC4 source or the frozen bytecode; those experiments are not part of the RC4 test suite. None is a confirmed finding.

# Question for the audit What the code and tests show today Code
1 Whether the wide-band branch of _bidRange, which returns [top, GENESIS_TICK_UPPER], is reachable in any state. It needs top + GRID <= GENESIS_TICK_UPPER, a lower edge of tick 177,480 or less. The invariant suite asserts atlTick >= GENESIS_TICK_UPPER (GenePermanence.t.sol:101), and top = alignUp(atlTick + GAP, GRID). So in every state the tests reach, top is 178,200 or higher and every ETH band starts below the opening price. GeneHook.sol:484, 498-499, 516, 782-786
2 Whether metabolize() can revert InvariantBroken when the pool price sits at or beyond the METABOLISM or churn bid band, for example after an earlier swap in the same block or with the price held in empty ticks. An ETH placement that would need GENE reverts the whole call, including its harvest and its cooldown write (GeneHook.sol:284-286, 655-660). A local test on an unmodified copy of the RC4 source reaches this revert in both cases; a retry in a later block succeeded in each tested case, and no funds were lost. The RC4 grief tests buy back before the keeper runs (AtlGrief.t.sol:74, :108). GeneHook.sol:484, 516-518, 655-660
3 Whether any condition a caller controls can make a metabolize() call place less than it otherwise would, while the call still starts its cooldown. The cooldown starts on every call that does not revert. GeneHook.sol:284-286, 465
4 Whether it is intended that an epoch whose close is recorded only after a further untouched epoch funds no budget while still advancing the cumulative water marks. At the first touch after such a gap, _newBlock writes the budget of the last touched epoch and moves to the current epoch; epoch e spends only the budgets of e − 1. GeneHook.sol:747-765, 837-873
5 Whether any revert path exists in beforeSwap or afterSwap for the canonical pool. The hook has no rule that rejects a swap by size, direction or sender. From every state the invariant runs reach, a small and a very large sell succeed (GenePermanence.t.sol:167-185). GeneHook.sol:355-390, 734-780
6 Whether the NatSpec of MassAdded.anchorTick matches the code for kinds 1 and 4. The NatSpec describes the bid anchor as the all-time low or spot if lower; the code reports atlTick for kinds 1 and 4, and the documentation follows the code. This concerns a source comment, not behaviour. GeneHook.sol:139-140, 484-485, 516-518
7 Whether band clamping near the maximum usable tick can place a buy band at or above the all-time low, and whether that state is reachable. Bid, churn and IMMUNITY bands clamp their lower tick at MAX_USABLE_TICK − NEAR_WIDTH. The case needs the all-time low within about 1,200 ticks of the maximum tick. GeneHook.sol:157, 500, 517, 783
8 Whether the hook's ERC-6909 claim balances equal its reserves on every path, including rounding in the REGENERATION fee split. The invariant suite checks that claims are at least the reserves (GenePermanence.t.sol:139-151). GeneHook.sol:707-725
9 Whether every narrowing integer cast is bounded in every reachable state. The casts rely on bounds from the fixed supply and the per-call and per-epoch caps. GeneHook.sol:486-487, 753, 849-858
10 Whether METABOLISM bids and the churn tier together can place more than BID_CAP_EPOCH in one epoch. _metabolizeBids limits bids against bids already placed (_caps.bid); the churn tier subtracts both tiers. The derived case needs about 1,100 ETH of buys in one epoch. No value leaves the protocol in either case. GeneHook.sol:478-491, 526-540; Genome.sol:33
11 Whether REGENERATION's buyback window is reachable in practice. regenerate() buys only while the price is no more than about 1% (REGEN_PREMIUM_TICKS, 100 ticks) above the all-time-low price; otherwise a call spends nothing and the ETH stays in regenReserve (GeneHook.sol:574-577; Genome.sol:46; invariant REGEN). In a local rehearsal on the frozen bytecode, with every GENE in circulation bought from the pool, the price stayed about 11% to 13% outside the window after every account sold everything it held, and no regenerate() call bought. RC4 tests reach a buyback after adding GENE to a seller's balance with a test cheatcode (RegenCooldown.t.sol:60; Rc4Rules.t.sol:58; SecurityCaps.t.sol:118). GeneHook.sol:561-591

#Immutability and admin powers

No party can change GENE after deployment.

Property Source
No admin, operator or other privileged role: after launch(), no function checks the caller GeneHook.sol:33; invariant ROLE
No upgrade path: GeneHook's external ABI is exactly the reviewed 27-function set, with no fallback and no receive GeneHook.sol:44-45; test/unit/HookAbi.t.sol; invariant ABI
The fee cannot change: a static 1% in the PoolKey, and no call to updateDynamicLPFee GeneHook.sol:26-27, 239
Liquidity cannot be removed: the only modifyLiquidity call takes a non-negative amount GeneHook.sol:28-29, 594-608
No claims or tokens are moved to any address: no approvals, no operators, no ETH take; GENE is taken only to the hook, to burn it GeneHook.sol:30-31
External calls go only to the PoolManager and GeneToken GeneHook.sol:32; invariant CALL
GeneToken: fixed supply, no privileged account, no further mint, no pause, no blacklist, no transfer fee, no transfer hook; burn destroys only the caller's own balance GeneToken.sol:6-24
The Genome constants are compile-time constants; no function takes one as input Genome.sol:4-7

The launcher. One address, fixed in the constructor, may call launch() once (GeneHook.sol:163, 252-255). Before launch it alone decides whether and when the pool opens; the whole supply sits in the hook until then, and nobody else can initialize the pool (GeneHook.sol:233, 332-334). After launch it has no power.

What GENE does not control. The Uniswap v4 PoolManager, the Uniswap protocol fee (set by Uniswap governance), and the routing lists of the Uniswap interface and other services, which affect discoverability rather than whether the pool can be traded.

The same immutability applies to the code itself: after deployment, no one can patch it.

#Trust assumptions

Assumption Basis
Trusted: Uniswap v4 PoolManager correctness (an assumption), Ethereum consensus, the Solidity compiler Design assumption
Trusted once: the launcher, for exactly one launch() call GeneHook.sol:163, 252-255
Untrusted: everyone else, including routers, aggregators, solvers, validators and builders, wash traders and external pools Design assumption
The build pins Uniswap v4-core 59d3ecf5 (1.0.2) and v4-periphery ad04c9f2 foundry.toml:1-3
The EVM must support Cancun: unlockCallback uses transient storage foundry.toml:12; GeneHook.sol:395-418
The launcher must be an address with no code; the chain does not enforce this Operational check before deployment
The launch transaction goes through a private bundle or private RPC; there is no anti-snipe surcharge Launch.s.sol:4-10
The economic evidence depends on the test harness's model of third-party traders Test harness
The attack-matrix maxima are observed bounds over the tested grid, not a proof over every strategy Test harness

#Known limitations

The audit package's own text is published verbatim at /limitations/. In brief:

  • §0 The all-time-low ratchet. RC4 accepts a block start as the all-time low only where the pool has active liquidity, which closes the free permanent disable of the earlier design. A paid, liquidity-backed ratchet remains: an attacker can sell through every protocol position and hold a block start there, moving the all-time low, and with it every later protocol buy, lower. Measured cumulative attacker cost in a thin market (about 30 ETH per epoch of organic trades, falling): 0.014 / 0.057 / 0.23 / 1.35 / 2.8 ETH for a 10% / 20% / 40% / 80% / 90% move of the all-time-low price. The attacker never profits in the tests (test/grief/AtlRatchet.t.sol), and the protocol ends with more Permanent Mass than an un-ratcheted control. Nothing in RC4 bounds how far below spot future protocol support can sit. Persistent or lagging anchors and a separate deployment reference were tested and rejected, because each produced a profitable, third-party-funded placement sandwich.
  • §1 Falling markets. Every METABOLISM, churn and IMMUNITY bid sits at or below the all-time-low block-start price (GeneHook.sol:484, :498-499, :516), and REGENERATION's buyback pays at most about 1% above it (GeneHook.sol:574-577). In every falling regime tested, protocol ETH reachable from spot within 5%, 10% and 25% is 0 / 0 / 0, with the all-time low between 44.6% and 86.2% below spot.
  • §2 IMMUNITY in sell-offs. RC4 places 0.3-0.8 ETH by S+7, none within 25% of spot. Price-restoring round trips create no IMMUNITY budget.
  • §3 REGENERATION on the genesis curve. About 0.05-0.1 ETH of book sits within its price limit per call, so the limit binds before the call cap. Under R1 the cooldown cannot be used to lock it out.
  • §4 Young markets. Near launch, 150 ETH of buys funds about 0.23 ETH of bids. The part of the revenue metric not funded by net buying sizes the churn tier, so those fees can still be committed as Permanent Mass, within the shared epoch bid cap and the ETH reserve (GeneHook.sol:526-539).
  • §5 Positive "assisted" cells. 0 SELFFUNDED and 0 TRANSFER cells across 53,929 matched rows. Positive "assisted" cells exist: up to +1.03 ETH, and +116 / +14.45 ETH in the intra-block-wick families 6 and 8. In each, the protocol ends above its matched counterfactual, and third-party traders in the harness pay the attacker's extra.
  • §6 Coverage. 228 cells cannot execute; the dense 50-tick pump sweep was not run; the grid maxima are observed bounds.
  • §7 Carried from RC3. An epoch with no flow places no ETH in the next epoch (asks from geneReserve are not budgeted, GeneHook.sol:541-543); with more than 8 pending epochs, ETH placement waits for evolve(); the first metabolize() needs a prior evolve(); epoch-dependent views update at the new epoch's first touch; a launcher with code is accepted on chain; route discovery needs a live pool.

#Threat model

Only entries valid for the RC4 code are listed. Earlier designs are superseded and not repeated here.

ID Threat RC4 mechanism Status and evidence
RC4-1 Manufactured conditions make the protocol place Mass near a manipulated price, then the attacker trades against it (rise-then-pin and related loops) Every METABOLISM, churn and IMMUNITY bid sits at or below the all-time low (REGENERATION's buyback at most about 1% above it); budgets count only net directional flow, once (GeneHook.sol:35-38, 837-858) 0 SELFFUNDED and 0 TRANSFER cells in the 53,929 matched rows
RC4-2 Funding a budget through wash trades, many addresses, routers or splits Budgets depend only on curve flow, counted against cumulative water marks, valued at the epoch's cheapest price (GeneHook.sol:378-383, 834-873) test/unit/Provenance.t.sol, test/unit/Rc4Rules.t.sol; residual +1.03 ETH assisted cells paid by third-party churn in the harness
RC4-3 Intra-block prints below the all-time low The anchor reads block-start prices only (GeneHook.sol:732-733, 770-774) 0 positive cells for attacker-made wicks
RC4-4 Free permanent disable by parking the price in empty ticks Closed: the all-time low moves only where the pool has active liquidity; oversized placements are skipped (GeneHook.sol:771-774, 619-621) test/grief/AtlGrief.t.sol, test/grief/PlacementSkip.t.sol
RC4-4b Paid, liquidity-backed ratchet of the all-time low No mechanism bounds it Accepted known limitation (§0); attacker never profits in test/grief/AtlRatchet.t.sol
RC4-6 REGENERATION cooldown lock-out by zero-spend or dust calls Closed by R1: the cooldown starts only after a full-allotment buyback (GeneHook.sol:302-307) test/unit/RegenCooldown.t.sol, test/grief/RegenCooldownAttack.t.sol
RC4-5 Usefulness residuals No near-spot support in falling markets; small IMMUNITY placements in sell-offs; small REGENERATION buys early By design (known limitations §1-§4); REGENERATION's buyback window is scope note 11
HK-1 Third-party liquidity in the canonical pool beforeAddLiquidity and beforeRemoveLiquidity always revert; v4 skips them only for the hook's own calls (GeneHook.sol:41-43, 337-352) Invariants PM2, PM3
HK-2 A rogue pool that names this hook beforeInitialize always reverts; the hook opens its own pool inside launch() (GeneHook.sol:258, 332-334) Code
HK-3 Swap callbacks reached with another key or by another caller beforeSwap checks currencies, fee and tick spacing (WrongPool); both swap callbacks require the PoolManager as caller (GeneHook.sol:359-363, 372) Code
HK-4 Spoofed unlock callback unlockCallback requires the PoolManager as caller and an action matching the hook's own transient action slot (GeneHook.sol:395-418) Code
HK-5 Fee changes The fee is static in the PoolKey; no updateDynamicLPFee call exists (GeneHook.sol:26-27, 239) Invariants FEE1, FEE2
HK-6 Donations to the pool The hook has no donate permission; a donation becomes fees owed to protocol positions in range, collected at a later harvest (GeneHook.sol:43-45, 669-697) Code
DEP-1 Launch-block sniping No anti-snipe surcharge; the launch goes through a private bundle or private RPC (Launch.s.sol:4-10) Operational
DEP-2 Wrong hook permissions at deployment The constructor reverts unless the address's low 14 bits are exactly 0x2AC0 and its first byte is not 0x91 (GeneHook.sol:226-229) Invariant ADDR

#Verification

Anyone can check a deployment against the frozen source; the full procedure, including the steps that need an address after deployment, is in verify the deployment. The committed genome hash is:

0x39c130f616c32abfb40f8ab51eb54544cffd3e0d99602c71dc336bc8083c36ae

The frozen bytecode hashes to compare against include the GeneHook runtime with immutables zeroed: 23,389 bytes, sha256 17e1418e1ec5689bcdce02aeec08aeaf89aba182136a917d728cd854e084b4d4. Each gene expression carries an evidence hash that can be recomputed from stored epoch records: verify evidence hashes.

#Evidence

Counts from the RC4 internal gate.

Evidence Result
Suites on the frozen source aca5fcd 347 passed / 0 failed / 0 skipped: unit 115, manipulation 108, adversarial 40, fork 15, launch rehearsal 11, grief 23, invariants (default profile) 29, gas 6
Full regression on the R1 source 4ff8abd, which differs only in Genome.VERSION 5,920 passed / 0 failed / 0 skipped, including long-hold 5,544 and deep-profile invariants 29
Long-hold / rise-then-pin 88 runs, 183,260 rows, each asserting attacker total at or below zero: 0 positive; worst −3.479543 ETH
Production attack matrix 241 files, 4,505 forge tests; 53,929 matched attack rows plus 406 boundary rows; 0 TRANSFER, 0 SELFFUNDED; 760 NONTRANSFER cells; all 406 boundary rows have assisted at or below zero
R1 attack tests 0 profitable REGENERATION sandwiches; suppression cannot reduce REGENERATION's buying. These tests reach a buyback after adding GENE with a test cheatcode (see scope note 11)
Disabled or skipped assertions over test/ 0

How a matrix cell is classified. "Assisted" is the attacker's P&L with the protocol acting, minus the matched PURE run in which the protocol only evolves. NONTRANSFER: the protocol ends no worse than in PURE, so the attacker's extra came from third parties. SELFFUNDED: only the attacker's own flow funded the budgets, and the gain is no more than the fees paid. TRANSFER: anything else; this is the blocking class.

Cases that cannot execute. Two figures are reported, in different units:

  • 228 cells (known limitations §6): high-wash churn cells at 5,000 and 20,000 ETH/day that buy the pool's entire remaining GENE and fail with PriceLimitAlreadyExceeded. They are excluded, not counted as passes.
  • 129 forge tests in 24 files of the production matrix fail by design: 107 with PriceLimitAlreadyExceeded and 22 with SwapAmountCannotBeZero. They have no matched PURE row and are neither passes nor classified.

Test inventory:

Suite Tests
unit and fuzz 115
manipulation 108
adversarial 40
long-hold / rise-then-pin, 88 contract runs 5,544
mainnet fork: real PoolManager, Universal Router 2.0 and 2.1.2, Permit2, V4Quoter, multi-hop, scripts 15
launch rehearsal on a mainnet fork 11
grief release tests, placement skip, R1 attack tests 23
stateful invariants, default and deep profiles 29 + 29
gas 6
production attack matrix 241 files, 4,505 forge tests

Log integrity hashes and the re-run commands ship with the audit package (tag rc4-audit-package).

#Disclosure

No security contact or bug bounty is published yet.

Sources (30)
  • src/GeneHook.sol:25-45
  • src/GeneHook.sol:139-140
  • src/GeneHook.sol:148-157
  • src/GeneHook.sol:224-273
  • src/GeneHook.sol:281-309
  • src/GeneHook.sol:332-418
  • src/GeneHook.sol:479-560
  • src/GeneHook.sol:561-591
  • src/GeneHook.sol:594-627
  • src/GeneHook.sol:655-660
  • src/GeneHook.sol:707-725
  • src/GeneHook.sol:734-873
  • src/GeneHook.sol:782-786
  • src/GeneHook.sol:965-973
  • src/GeneToken.sol:6-24
  • src/Genome.sol:33
  • src/Genome.sol:46
  • script/Launch.s.sol:4-10
  • foundry.toml:1-3
  • foundry.toml:12
  • test/unit/HookAbi.t.sol
  • test/invariant/GenePermanence.t.sol:96-102
  • test/invariant/GenePermanence.t.sol:139-151
  • test/invariant/GenePermanence.t.sol:167-185
  • test/grief/AtlGrief.t.sol:74
  • test/grief/AtlGrief.t.sol:108
  • test/grief/AtlRatchet.t.sol
  • test/unit/RegenCooldown.t.sol:60
  • test/unit/Rc4Rules.t.sol:58
  • test/unit/SecurityCaps.t.sol:118

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