Liquidity migration options
Learn more about how liquidity migration can be customized
Overview
Doppler supports migrating liquidity from auction contracts to long-term AMM pools optimized for sustained trading. Migration triggers are configurable at creation, typically based on proceeds thresholds that indicate sufficient liquidity for the next growth phase. Currently supported migration targets include Uniswap v2, v3, and v4, with configurable fee structures. Support for additional AMMs and ecosystems is expected.
Non-migration (recommended)
In a variety of use cases, it may often make sense to not migrate liquidity from the pool utilized to auction the token and bootstrap liquidity to another, longer term AMM pool. This can be done to maximize simplicity, for example, providing unified experiences on trading charts and terminals, or a variety of other reasons. To not migrate liquidity, use the noOp parameter in the migration config. Notably this is supported for launches using Doppler Multicurve or "Lockable" V3 static auctions.
Migration Options Guide
The SDK encodes post‑auction liquidity migration via a discriminated union MigrationConfig:
export type MigrationConfig =
| { type: 'noOp' }
| { type: 'uniswapV2' }
| { type: 'uniswapV3'; fee: number; tickSpacing: number }
| {
type: 'uniswapV4'
fee: number
tickSpacing: number
streamableFees: {
lockDuration: number // seconds
beneficiaries: { address: Address; percentage: number }[] // in basis points
}
}Internally, the factory resolves the on‑chain migrator address for your chain and ABI‑encodes the specific data shape required by that migrator.
Quick Decision Guide
Want the simpliest solution and unified charts/UX?
Want simplest AMM and immediate trading? Use V2
Want a concentrated liquidity range in the resulting pool? Use V3
Want programmable fee streaming to beneficiaries and are on a V4‑ready chain? Use V4
No Migration
.withMigration({ type: 'noOp' })Supported on: UniswapV4MulticurveInitializer, LockableUniswapV3Initializer
V2 Migration
.withMigration({ type: 'uniswapV2' })Encoded data: empty (
0x)Migrator address resolved per chain (see
src/addresses.ts)
V3 Migration
.withMigration({ type: 'uniswapV3', fee: 3000, tickSpacing: 60 })Encoded data:
(fee:uint24, tickSpacing:int24)Ensure
tickSpacingmatches the selectedfeetier on your chain
V4 Migration (streamable fees)
.withMigration({
type: 'uniswapV4',
fee: 3000,
tickSpacing: 60,
streamableFees: {
lockDuration: 365 * 24 * 60 * 60, // 1 year
beneficiaries: [
{ address: '0x...', percentage: 6000 },
{ address: '0x...', percentage: 4000 },
],
},
})Encoded data:
(fee:uint24, tickSpacing:int24, lockDuration:uint32, beneficiaries: (address, shares[WAD])[])The SDK converts
percentage(basis points) tosharesin WAD (1e18), and sorts beneficiaries by address (ascending) as required by the contract
Validation:
At least one beneficiary
Percentages must sum to exactly 10000
Contract enforces: airlock owner must receive at least 5% of streamed fees (add as a beneficiary if applicable)
Chain support:
Ensure
streamableFeesLockerandv4Migratorare deployed on your target chain (seesrc/addresses.ts)
Governance Selection
Required: You must call
withGovernance(...)in the builders.Standard governance: Call
withGovernance()with no arguments to use standard defaults, or pass{ initialVotingDelay?, initialVotingPeriod?, initialProposalThreshold? }or{ useDefaults: true }.No‑op governance: Call
withGovernance({ noOp: true }). The SDK throws ifnoOpGovernanceFactoryis not deployed on the chain.
Address Resolution
Migrator contracts are selected per chain via getAddresses(chainId) (see src/addresses.ts).
v2Migrator,v3Migrator,v4Migratormust be present for the chosen typeSome optional contracts (
noOpGovernanceFactory,streamableFeesLocker) may be0x0on certain chains — avoid V4 migration with fee streaming where not supported. Using no‑op governance requiresnoOpGovernanceFactory.
When to choose which
No migration (noOp)
Simpliest possible solution & fastest time to market
Unified charts for pre and post liquidity bootstrapping
Reduced complexity, debugging, and testing requirements
Utilizing Multicurve or another supported initializer
Uniswap V2
Basic constant‑product pool; broad ecosystem tooling
No price range configuration; least complexity
Good default if you do not require V3/V4‑specific features
Uniswap V3
Concentrated liquidity with a fixed range
Requires
feetier and matchingtickSpacingChoose when you want to seed a V3 pool with explicit range after the sale
Uniswap V4
Pools with hooks; supports fee streaming via
StreamableFeesLockerRequires
fee,tickSpacing, andstreamableFeesChoose when you want programmable fee distribution to beneficiaries, and V4 infra is available on your chain
Last updated