Testing
Three layers, each proving something the others cannot.
The contracts
npm run contracts:test
Foundry, against the real Uniswap v4 PoolManager, PositionManager and Permit2, deployed fresh for every test from their compiled artifacts. A mock would prove a gauge calls what it thinks it calls; this proves the pool initialises, the position mints, swaps clear both ways and fees accrue against the code that is on Robinhood Chain.
What is covered: creation and every check on it, every trade entry point against its quote and its fee split, the minimum buy, the access registry, graduation with the expected amounts and the guard lifting, swaps both ways afterwards, the creator's reward and its claim, referrals and their tiers, the protocol's withdrawal, reentrancy through every path that pays ETH, the swap router in both directions with its floor, its deadline and its callback guard, and invariants over random trading by several actors: the gauge's ETH is always exactly the curve's value plus the creator's unclaimed reward, its tokens are always exactly the unsold supply, and the curve never sells past its target.
forge build --sizes is part of the build and fails on any contract over the size limit. The linter runs after every build and fails on a warning; every excluded rule is listed in foundry.toml with its reason.
The app
npx vitest run tests/launch tests/components
The chain reads against a stand in for ethers that answers from fixtures, the pricing of trades, the trade store's forward reads against a real MongoDB, the launchpad and holder and referral reads, recording a launch and the checks against the session, the picture's storage and claim, the referral helper, the candle builder, the chart, and the token page's rendering.
The whole flow, in a browser
npm run launchpad:local
npm run e2e:launchpad
A real browser, driven by Playwright, against the local chain. A wallet is injected into the page: on the local chain it proxies to anvil, which signs for its developer accounts. The run signs in, arrives through a referral link a second account registered, launches a token with a picture and a first buy, buys through the referral router, sells, watches the second account buy, buys the curve out so it graduates, buys and sells in the pool, claims the creator's reward, sends the protocol's fees to the treasury, collects the pool's fees as the LP receiver, changes the creation cost as the owner and puts it back, and opens the referrals page. Every step is checked against the app's API; screenshots land in .e2e.
The same script runs against Robinhood testnet with a real key and small amounts:
RPC=https://rpc.testnet.chain.robinhood.com CHAIN_HEX=0xb626 KEY_FILE=~/.creora/testnet-deployer.json \
LAUNCHPAD=0x... FIRST_BUY=0.002 PANEL_BUY=0.001 GRADUATE=0 SECOND=0 npm run e2e:launchpad
Graduation and the second account's steps are skipped there, because the curve raises almost four ETH and testnet faucets give thousandths. A key file is JSON with a private key field; the script never prints it.
Continuous integration
Three jobs. The app's lint, typecheck, tests and build; the contract build with the size check and the contract tests; and the browser flow against anvil, with Chromium installed, the local chain and launchpad deployed, the app built and started, and the screenshots uploaded as an artifact whatever the result.