Deploy blockers (both from 658b50d's cleaning rewrite)
- Length: the grapheme cut alone let one letter carry thousands of combining
marks ("a" + 3000 x U+0301 saved as a 3,000-character name; a bio kept
4,001). Each character now keeps at most 4 combining marks and 16 code
points (the longest emoji, a family with skin tones, is 11), and a field at
most 4 code points per allowed character. Real diacritics and emoji are
kept; an emoji at the limit is kept or dropped whole, never split.
- Tags: tag characters survive only inside the three subdivision flags emoji
have (England, Scotland, Wales). Any other black flag + tags rendered as a
plain flag while carrying hidden ASCII ("ignoreallprevinstruc" got
through), the kind of text that steers an LLM reading names or bios.
- Pasted line breaks and tabs in a one-line field become a space instead of
gluing words together.
- Tests: zalgo name and bio under their caps, fake flags stripped, the three
real flags unchanged, 👨💻 / 🏳️🌈 / a skin-tone family at the exact limit,
and the idempotency fuzz still holds.
Review leftovers
- migrate.mjs: a failed concurrent build names the index and the likely
cause (55P03: an older transaction is still open, or another session holds
the table; 57014: past the 20 min timeout). Still exits 1; retrying the
deploy is safe.
- The availability check takes the form's X handle, so a verified owner's
claim matches the save's rule (only while keeping that handle).
- The as-sent signature candidate counts only when the fields hold no C0/C1
controls, bidi marks, overrides or isolates, or line / paragraph
separators (the bio may keep line breaks); otherwise only the cleaned text
is accepted.
- approve_x takes each released wallet's profile lock (in wallet order)
before touching its rows, as that wallet's own verify does.
- deleteProfile's doc says when a name is held (kept a day or more).
openlaunch.lol — app
Launch a token. Free. Open source. On Base, Robinhood Chain or Arc.
The site for the openlaunch launchpad. One transaction deploys a fixed-supply ERC-20,
opens a Uniswap v4 pool and locks 100% of the supply as liquidity in an ownerless locker — forever.
No platform fee anywhere. Contracts live in ../contracts (LaunchFactory.sol, LaunchLocker.sol,
LaunchToken.sol; design in ../contracts/docs/LAUNCHPAD.md).
Next 16 app router, React 19, Tailwind 4, wagmi 3 + viem 2, Postgres (postgres.js). Runs on Fly.io
(two web machines + an attached Postgres with WAL backups to Tigris); see LAUNCH.md for the runbook.
Pages / API
/list (new · active · volume · market cap) + live tape ·/launchform ·/t/<token>trade + fees/ruleshow it works ·/agentscontract call + JSON ·/llms.txtGET /api/launch/list?sort=&limit=·GET /api/launch/feed·GET /api/launch/meta/<token>POST /api/launch/meta(metadata before launching →{uri, token}) ·POST /api/launch/sync?tx=·GET /api/health
How it hangs together
src/lib/launchpad/—abi.ts(factory / locker / PoolManager Swap / StateView / Quoter / Universal Router / Permit2),math.ts(ticks ↔ prices, FDV, formatting),swap.ts(V4_SWAP encoding),meta.ts,queries.ts,indexer.ts(receipt apply + chunked poller),loop.ts.- Trades happen in the page through the Universal Router (
TradePanel.tsx): buys send ETH as value; sells approve the token to Permit2 once, then a 30-day Permit2 allowance to the router. db/schema.sql—bb_launches,bb_launch_swaps,bb_launch_fee_events,bb_launch_meta,bb_launch_sync_state(+bb_migrations). Idempotent; applied on every deploy.
Local dev against a Base fork
anvil --fork-url https://mainnet.base.org --port 8545 --chain-id 8453
cd ../contracts && DEPLOYER_PRIVATE_KEY=<anvil key 0> forge script script/dev/SeedLaunchpadLocal.s.sol --rpc-url http://127.0.0.1:8545 --broadcast
createdb basebid_dev && DATABASE_URL=postgres://localhost/basebid_dev npm run migrate
# .env.development.local: NEXT_PUBLIC_CHAIN=base, NEXT_PUBLIC_RPC_URL/BASE_RPC_URL=http://127.0.0.1:8545,
# NEXT_PUBLIC_LAUNCH_FACTORY/_LOCKER + LAUNCH_DEPLOY_BLOCK from the seed output, LAUNCH_SYNC_CONFIRMATIONS=0, LAUNCH_SYNC_LOOP=1
npm run dev
Gotcha: anvil's default accounts carry EIP-7702 delegations on Base mainnet — ETH sent to them is
forwarded away. Use a fresh key (cast wallet new + anvil_setBalance) when testing sells.
Deploy
See LAUNCH.md.