Docs
Graduation

Locked liquidity on Uniswap V3

When a bonding curve hits its threshold, the buy that crosses it creates a Uniswap V3 pool on Robinhood Chain, puts the whole raise plus the reserved LP supply into one full-range position, and locks that position in a contract that cannot give it back. This page is the lifecycle, the contracts, and the three layers of proof.

Lifecycle

What happens on-chain

VectrBondingCurve.buy()  -- realQuoteReserves >= threshold (or curve sold out) -->  _graduate()
        |
        v  approve + migrate{value}(token, unsold + LP reserve, quoteAsset, raised)
VectrUniswapMigrator
        |  1. pull both sides; native ETH -> WETH (V3 pools are ERC-20 only)
        |  2. createAndInitializePoolIfNecessary(token, quote, tier, sqrt(raised / tokens))
        |  3. if someone pre-created the pool at a bogus price: swap it back to ours
        |  4. NonfungiblePositionManager.mint(full range, recipient = VectrLPLocker)
        |  5. burn token dust, quote dust -> platform wallets
        v
VectrLPLocker  holds position NFT #n forever. Only exit: collect() -> LP fees -> platform wallets

The curve does not wait for a keeper or a multisig. Graduation is a branch inside the buy that crosses the line, so the pool exists in the same transaction as the last curve trade. After it, buy and sell on the curve revert and quotes return zero.

ETH-paired tokens graduate into a token/WETH pool. Stock-paired tokens graduate into a token/stock pool with no WETH involved; the LP fee then accrues in the stock token.

Contracts

The addresses on Robinhood Chain

VectrUniswapMigrator
0x384EEd2Ba540146FB09E4EE228B454091913F837 Creates the pool, mints the position, hands it to the locker
VectrLPLocker
0xcf489e55a1167Cf883e0EE43D2354fdFc82b2B58 Holds every graduation position. No transfer, no decreaseLiquidity, no burn
Pool fee tier
1.00%Accrues to the locked position; swept to platform wallets by collect()
The lock

No withdrawal path, by construction

VectrLPLocker owns every graduation position. It implements no transferFrom, approve, decreaseLiquidity or burn. A test reads the compiled ABI and fails the build if any of them appears. The one function that moves value is collect(tokenId), callable by anyone, which forwards accrued pool fees through the FeeCollector's platform split. Principal never leaves.

"Cannot rug" here means something specific: the liquidity is a Uniswap V3 NFT held by a contract with no function that can transfer, decrease or burn it. Check the verified source on the explorer, not this sentence.
Proof

Three layers of tests

All in the public contracts repo. The numbers are the test counts at the time of writing; the suite is the source of truth.

1. Uniswap's own bytecode, locally
19 testsDeploys the artifacts from @uniswap/v3-core, v3-periphery and swap-router-contracts, then the Vectr stack on top. Pool creation, full migration to the wei, price continuity, locker ABI, griefed pools, stock-quoted pools, sell-out graduation, access control.
2. Robinhood Chain mainnet, forked
4 testsForks the chain in-process and points the migrator at the real Uniswap factory, position manager and WETH. Verified against those contracts, not ours.
3. Live
demo-graduation.tsLaunches a throwaway token on the target network, buys past the line, then checks the result against Uniswap's getPool, ownerOf, positions, a router buy that must match the quoter, a router sell, and a fee sweep. Prints every transaction hash.
cd contracts/token-launchpad
npx hardhat test                                                   # layer 1
ROBINHOOD_FORK=1 npx hardhat test test/fork/robinhood-graduation.fork.test.ts   # layer 2
FACTORY_ADDRESS=0x... SCALED=1 THRESHOLD=0.02 npx hardhat run scripts/demo-graduation.ts --network robinhood   # layer 3
FAQ

Questions people ask

Can the team withdraw the liquidity after graduation?

No. The position NFT is owned by VectrLPLocker, whose compiled ABI exposes no transferFrom, approve, decreaseLiquidity or burn. The only function that moves value is collect(), which pays accrued pool fees to the platform wallets and cannot touch principal. A test reads the ABI and fails if any exit function appears.

What happens to the price at graduation?

The pool is initialised at exactly raised divided by tokens migrated, so the full-range mint absorbs both sides. With the production curve parameters that lands within about 2% of the curve's last spot price.

What if someone creates the pool first at a fake price?

Uniswap pool addresses are deterministic, so anyone can pre-create token/WETH at the graduation tier and initialise it anywhere. The migrator does not revert; it swaps against whatever is there, spending at most its own balance, until the price is back at target, then mints. Both the empty-pool and stray-liquidity cases are tested.

Where do trades go after graduation?

Through Uniswap's SwapRouter02, priced by QuoterV2. The token keeps its address and its Vectr page; only the venue changes. The pool's 1.00% LP fee accrues to the locked position and is swept to the platform wallets.

Keep going

Threshold and fee-tier values on this page come from GET /config at render time. Vectr is built on Robinhood Chain and uses the canonical Uniswap V3 deployment; it is not affiliated with Robinhood or Uniswap.