Skip to content

Security: hookwright/untoll-hook

Security

SECURITY.md

Security policy

Status

Testnet-bound. The contracts compile and the invariant + unit suite is green, but a formal security review precedes mainnet, and two settlement seams are still to be authored (see docs/ARCHITECTURE.md Section 7). Do not deploy this to mainnet or place real value behind the hook until an external review of the graduate-in-place core is complete. Compiling is a green suite is not a mainnet guarantee.

Reporting a vulnerability

Please report suspected vulnerabilities privately to security@untoll.fun. Do not open a public issue for a security report. Include a description, affected files/functions, and a proof-of-concept or reproduction where possible. We aim to acknowledge within a few business days.

Trust model and non-custody

The design targets a small, explicit trusted surface:

  • No admin fund authority. No withdraw, sweep, or rescue path reaches POL, curve reserves, user funds, the reward pool, or the creator accrual (invariants 6, 24). POL is owned by the hook and is never held as pullable LP tokens; there is no function that decreases it.
  • Immutable per-launch parameters. registerLaunch is the only write of a launch's curve, fees, anti-sniper params, target, and bucket split. There is no setter (invariant 9).
  • Sole-minter, renounced at graduation. Only the hook mints the launch token; mint is renounced inside the atomic flip after POL is seeded, verifiable on-chain (invariants 2, 11).
  • Pause is pause-new-launches only. Bounded and auto-expiring, no fund authority; the guardian set must be pairwise-disjoint from treasury and timelock (an operational deploy constraint enforced by key management, not by the contract).
  • Accrue-only hot path. The swap makes no external call; every recipient pulls. A reverting, blocklisting, or gas-griefing recipient can never brick a swap (invariant 15).

Design principles

The review-critical code follows established security engineering practice:

  • Checks-effects-interactions and an explicit mutex on every path where value moves; state effects precede any interaction so a reentrant recipient cannot double-claim.
  • Least privilege: the hook requests only the permission bits it uses; no beforeDonate, no owner-callable value points.
  • Fail-safe defaults: an unwired clone is unusable rather than permissive; parameters are immutable post-init; the anti-sniper fails in the protective direction.
  • Gas metering as DoS control: no function iterates an unbounded participant set; distribution is O(1) per claim, so a Sybil of dust accounts cannot gas-DoS a payout.

Scope

In scope: everything under contracts/src/. The client/ and runtime/ trees are pre-deployment scaffolds and are not part of the on-chain trust surface. Dependencies under contracts/lib/ are upstream projects (Uniswap v4, OpenZeppelin) with their own security processes.

There aren't any published security advisories