The first version of this launchpad was a bonding-curve protocol. You can still read it in the git history (contracts/BondingCurvePool.sol, contracts/LaunchpadFactory.sol and the TypeScript that settled trades against it). It had virtual reserves of 2 ETH and 1.073 billion tokens, a 5 ETH graduation goal, a 1% fee split 70/30, a 99% anti-snipe tax decaying cubically over three seconds, per-wallet caps under a 15-minute TWAP window for “crowd” launches, and an atomic graduation that added liquidity to a V2 router and burned the LP to 0xdEaD. It had tests. The curve maths was cross-checked between Solidity and TypeScript against the same inputs.
It was fine. Here is why it is gone.
1. The curve was a custody period
From the first buy until graduation, every buyer’s ETH lived in our pool contract. Our code, not Uniswap’s, was what stood between that ETH and a bug. We had a reentrancy guard and a fee-push fallback for recipients that could not accept ETH within a gas stipend — we had found that a creator wallet with a receive hook could brick the pool for everyone, and fixed it by booking pending fees instead of reverting the trade. Every one of those fixes was a reminder that we were running a DEX, badly, for the duration of the curve.
2. Graduation was a moment, and moments fail
The migration was one transaction: withdraw, approve, addLiquidityETH, burn LP. On mainnet Robinhood Chain there is a real Uniswap V2 router. On testnet there is not — the addresses the explorer returns under that name are other people’s test deployments — so on testnet pools graduated without migrating liquidity at all, which meant the exact code path that mattered most was the one we could least rehearse. We also had to guard against a router that took custody of everything and did something unexpected. That is a lot of surface for an event that fires once per token.
3. Two price regimes, two of everything
Pre-graduation, price came from our reserves. Post-graduation, from the V2 pair. The indexer needed both. The chart needed both. The swap panel needed both. Our indexer re-read reserves from the pool on every pass instead of trusting event deltas — a good rule — but it was a rule we needed only because we had invented a second source of truth.
4. The graduation goal was a tuning knob nobody could tune well
We originally set 10 ETH and found launches stalling halfway up. On a constant-product curve with 2 ETH virtual reserve, 10 ETH raised means the quote reserve goes 2 → 12, a 6× on reserves and a 36× on price, before anything could graduate. We cut it to 5 ETH (a 12.25× price move). It was better. It was still a number we were picking on behalf of every creator, with a cliff on the far side of it.
What replaced it
pons, another launchpad on Robinhood Chain, had already demonstrated the alternative: deposit the whole supply straight into a one-sided Uniswap V3 position and lock the NFT. A one-sided V3 range is a bonding curve — the same constant-product relationship, with V3 doing the arithmetic in square-root space — and it lives on the DEX from block one. There is nothing to migrate because it is already there.
| Bonding curve (retired) | Locked V3 position (current) | |
|---|---|---|
| Custodian pre-graduation | Our pool contract | Uniswap V3 |
| Graduation | Migration transaction | A threshold read; nothing moves |
| Price sources | Two (reserves, then V2 pair) | One (slot0) |
| Fee mechanism | Custom, pushed on trade | Uniswap fee tier, collected on claim |
| Anti-snipe | Time-decaying tax + TWAP caps | Block-keyed caps for two blocks |
| Testnet rehearsal | Partial (no V2) | None (no V3) |
| Contract surface we wrote | ~3 contracts + curve maths | 3 contracts adapted from verified source |
We lost some things. The anti-snipe tax, which stayed in the reserve and deepened the LP instead of becoming revenue, was a design we liked. The crowd-launch TWAP window is gone. The opening buy used to be capped at 5% of supply; on the new design it is not capped at all, which we discuss in another post. These are real trade-offs, and we made them for one reason: the amount of code we have to be right about went down by more than the amount of behaviour we gave up.
The retired application code is gone: the database-settled API routes, the curve maths, its indexer and its tests were deleted once nothing imported them. What remains is the git history and the contracts themselves, kept as a record of the design this post is about.