Skip to main content

Session — feature review

Does what exists match what was actually asked for? A scope audit, not a security review. The output is a list, not code.

The developer's concern, in their words: "I want to make sure that we're following my initial idea" — which features exist, which are missing, and where the build has drifted from the description.

Read first, in this order

CLAUDE.md — "The project" and "The order of ambition"The developer's own words, and the closest thing to a source of truth
notes/VISION.mdThe grand plan. Written by Claude from the developer's description — check it against their memory rather than treating it as scripture
notes/STATUS.mdWhat is claimed to exist
contracts/src/What actually exists. Six contracts, ~1,100 lines
contracts/test/What is actually proved. A claim in a comment is not a feature

The one rule

Evidence, not assertion. For every feature, the answer to "does this exist?" is a file and a test, or it is a no. notes/STATUS.md and notes/VISION.md were both written by Claude and both may overstate. The code and the suite are the record.

The first concrete thing

Walk the six bullets the developer gave for milestone one — they are in notes/VISION.md under "Milestone one" — and mark each exists / partial / missing, citing the contract and the test that settles it. Then do the same for everything else in VISION.md: the fee-policy directions, positions and lots, the holder score, gacha packs, composable pairing.

Expect three outcomes and keep them apart:

  1. Built and proved.
  2. Built but not reachable — the mechanism works and nothing can call it. There is no router, no lens and no interface, so several features are in this state.
  3. Never started.

Then

  • Where has the build drifted? Anything in the code that was not asked for, and anything asked for that quietly became something else. D13 already changed shape once mid-session.
  • Is VISION.md still true? It was written early and things were settled after it. Correct it where it is stale rather than working around it.
  • What does v1 actually still need, as against what would merely be good. The developer's list was six bullets and stayed six bullets; the backlog around it was Claude's.

Not this session

Not security — Slither has never run against the real contracts and that is a real gap, but it is its own thread. Not new features. Not the interface. If the review finds something necessary, write it down and carry on reviewing.

How to work in this one

Report findings and stop. Do not follow a finding into a fix, and do not propose what comes next — that is the developer's call. notes/sessions/launchpad-core.md and DECISIONS.md O7 record why this is written down.


Findings — 12 Sep 2026

Suite run to confirm the claims: 120/120 local pass, 7/7 fork pass against Arbitrum One at block 504,000,000.

Built and proved

featurecontracttest
Launch on a curveBondingCurve, LaunchFactoryLaunchFactory.t.sol:94, :413
Trade on it, both directionsBondingCurve.buy/sellBondingCurve.t.sol (39 tests), CurveInvariant.t.sol (12 invariants, 8,192 calls)
Graduate into a v4 poolPoolMigratorPoolMigrator.t.sol:148, .fork.t.sol:143
Pair against any ERC20 on an allowlistLaunchFactory.setQuoteQuoteAssets.t.sol (2/6/8/18/24 dp, USDT-shaped), .fork.t.sol:194-202 (real WETH/wBTC/USDC)
Composable pairingBasketWrapperBasketWrapper.t.sol (13), QuoteAssets.t.sol:260, :286
Fee collection — curve and pool to vaultBondingCurve._notifyFeeSink, PoolMigrator.collectFees, FeeVault.syncPoolMigrator.t.sol:214, FeeVault.t.sol (18)
Cohort bindingbeacon per version, migrator per versionLaunchFactory.t.sol:150, :319, :304
Both seams' containmentLaunchToken.observer, FeeVault.strategyLaunchToken.t.sol:99, :110; FeeVault.t.sol:97, :110

Built, nothing to plug into it

  • Fee strategy seamIFeeStrategy + FeeVault.setStrategy exist; no strategy does. Only MockStrategy has ever been on the other end.
  • Token observer seamITokenObserver + LaunchToken.observer exist; no observer does, and Deploy.s.sol sets it to zero.
  • Hook slotPoolMigrator.hook is an IHooks constructor parameter, wired everywhere, always address(0).
  • Basket creationBasketWrapper works, but nothing deploys one: no factory, no registry, no place for the curated baskets D14 promises. Every basket in the suite is a manual new.
  • No interface of any kind. web/, services/, stylus/ do not exist. No router spanning curve and pool, no batched lens. On-chain enumeration does exist (launches, launchOf, enabledQuotes, quoteBuy/quoteSell), so this is a UX gap, not a correctness one.

Never started

Tokenised stocks as restricted assets (no gated asset anywhere in the suite; no permissioned hook family); every hook; fee redistribution of any kind; the lot system; the holder score; gacha packs; creator/protocol fee split (D15).

Drift

  1. Fee redistribution stopped being a hook. VISION bullet 6 says "a few v4 hooks, of which fee redistribution to holders is the first". D15 turned that into a dumb observing hook plus a strategy behind FeeVault. Deliberate and recorded, but VISION was never corrected.
  2. The fee seam breaks its own second safety condition. VISION: a strategy is safe when it cannot "reach another launch's money". FeeVault.distribute(token) hands the strategy the whole currency balance — every launch's fees. O17 records the accounting gap; it does not record that the isolation claim is currently false.
  3. BasketWrapper has no minimum weight. D14 says "at most 10 constituents and at least 10% each". MAX_ASSETS = 10 exists; the 10% floor does not, and zero units is a documented feature. The constraint was silently dropped or moved to the interface — unrecorded either way.
  4. Cohorts by beacon, not by factory. VISION says "versions ship as new factories". The build is one UUPS factory with a beacon and a migrator per version (D12, D16). VISION is stale.
  5. The launch record omits the migrator. launchOf stores the beacon but not the migrator, so a token's pool shape resolves through BondingCurve.migrator() rather than the registry.
  6. make test-fork cannot find ARB_RPC. .env is at the repo root; forge runs in contracts/. The 7 fork tests pass only when the variable is exported by hand. STATUS claims them without that caveat.

Nothing was changed. No next step proposed — the developer's call (O7).