The bond
The moment a coin stops being backed by dollars and starts being backed by a leveraged position on a real stock.
The threshold
Once a coin's own pool has accumulated $15,000 of USDC, it is eligible. That value is immutable on the launcher and public — read it rather than trusting a number written on a website:
MemeLauncherV3.bondBackingUsd() → 15000000000 (15,000 USDC, 6 decimals)The coin page shows the same figure as a market cap, because that is the number a buyer can actually watch approach. The two are the same statement — see Reading a coin page for why the supply cancels out of that conversion entirely.
The protocol triggers it
bondAndMigrate(coin) is sent by the protocol's keeper as soon as a coin's pool crosses the threshold, so bonding needs nothing from you. The function itself stays permissionless: nobody decides whether a coin bonds — the threshold does — and a stranger paying the gas (a few cents of USDC on Arc) would get exactly the same result.
That is deliberate. A migration that depended on us running a bot would be a migration that stops when our bot stops.
What happens, in one transaction
- The entire position is withdrawn from the
COIN / USDCpool. - The accumulated USDC mints the coin's leveraged tracker at its live NAV, inside the locker. The USDC lands in the tracker's vault.
- A new pool is opened at
COIN / TRACKER, at the same dollar price, and the whole float goes back in. - The new position NFT is locked in the same locker, under the same rules.
Holders do nothing. Their tokens never move, their balances do not change, and the dollar price of the coin is the same on both sides of the transaction. What changes is what stands behind it — and from that block on, the coin's own trading is what funds its hedge.
The coin side must go back in whole. The tracker side cannot always fit exactly, because the new range is derived from the price; whatever tracker the new position does not absorb is booked to the protocol's claimable balance in the locker (MigrationResidualBooked) rather than left stranded, and redeeming it at the vault undoes the dilution it would otherwise cause.
And then the hedge
A tracker starts life bond-gated: while it is, its NAV is pinned at 1.0 and its vault refuses to send anything to the venue (fundHedge reverts NotBonded). The coin bond puts real dollars into the vault; once a tracker's vault holds $15,000 of backing, the keeper flips the tracker bonded (LTFactory.pokeBond), posts its first NAV, and starts moving the backing above the vault's floor to the venue, where it becomes a position on edgeX at the tracker's multiple. Unlike the coin threshold, that $15,000 is the keeper's rule, not a contract's: pokeBond is permissionless and the factory's own depth gate (bondDepthUsd) is set to zero at deployment. How the money travels, and who holds which key, is in The hedge book.
The price, carried across
The new pool has to open at the same value in dollars, but its quote is now worth NAV rather than one dollar, and its decimals differ (the tracker has 18, USDC 6). The rescale is done on the square root — never by squaring a sqrtPriceX96, which overflows a uint256 since (2^160)^2 = 2^320:
sqrt(P') = sqrt(P) · sqrt( 10^(18 − dq) · 10^18 / NAV )What the contract guarantees
| Once per coin | the migrated flag is set before anything moves |
| Only its own tracker | fixed at launch, not chosen by the caller |
| Everything goes back in | reverts if more than MIGRATION_DUST of coin is left behind |
| Never two markets at once | the old position is closed and the new one opened in the same transaction |
| Trigger | the protocol bonds it automatically; the call stays permissionless |
Where the lower bound comes from
The new position's range is derived from the amounts actually withdrawn and rounded up, not carried over from the old pool.
That is not a detail. Carrying the old lower tick and flooring it widens the band beneath the current price, which means the position needs dollars it does not have to fill the space underneath — and the deposit strands coin. That bug shipped once, on an earlier deployment (before Arc), and reverted a live bond with MigrationWouldStrandLiquidity; the fix is pinned by tests, including fork tests against the real Uniswap contracts on Arc that bond a coin and check the whole float comes back.