> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meteora.ag/llms.txt
> Use this file to discover all available pages before exploring further.

# Migration

> How a DBC virtual pool graduates to a DAMM v1 or DAMM v2 liquidity pool — triggers, liquidity distribution, vesting setup, and what happens on-chain.

## Overview

When a DBC virtual pool's `quote_reserve` reaches `migration_quote_threshold`, the bonding curve phase ends and the pool **migrates** to a real AMM. This is automatic and permissionless — any caller can trigger the migration instruction once the threshold is hit.

***

## Migration Trigger

```
if virtual_pool.quote_reserve >= config.migration_quote_threshold → migrate
```

The `finish_curve_timestamp` is recorded on the `VirtualPool` when the threshold is first crossed. Migration can be called at any point after this.

<Note>
  Trading is paused once the curve is complete (`PoolIsCompleted` error). Migration must happen before normal trading resumes.
</Note>

***

## Migration Options

| `migration_option` | Target Pool                                        |
| ------------------ | -------------------------------------------------- |
| `MeteoraDamm` (0)  | DAMM v1 (constant-product, supports stable pools)  |
| `DammV2` (1)       | DAMM v2 (concentrated liquidity, custom fee modes) |

***

## Migration Steps (On-Chain)

### 1. PreBonding → LockedVesting (standard flow)

```
migrateMeteoraDammLockLpToken         (for DAMM v1)
migrateDammV2CreatePool + lockLp      (for DAMM v2)
```

For most launches (no Jupiter lock):

1. `migration_progress = PreBondingCurve`
2. Threshold hit → caller invokes migrate instruction
3. Program creates DAMM pool with `migration_sqrt_price` and seeds liquidity
4. LP positions are distributed to partner, creator, and protocol
5. Vesting schedules are initialized on the LP positions
6. `migration_progress = LockedVesting` → `CreatedPool`

### 2. With Jupiter Lock (PostBonding flow)

Some launches integrate with Jupiter's lock mechanism:

1. `PreBondingCurve` → threshold hit
2. `PostBondingCurve` (Jupiter lock processing)
3. `LockedVesting` → `CreatedPool`

***

## Liquidity Distribution at Migration

The total migrated liquidity is split:

```
Total LP
  ├── Partner LP  (partner_liquidity_percentage %)
  │     ├── Permanently locked (partner_permanent_locked_liquidity_percentage %)
  │     └── Vesting (partner_liquidity_vesting_info schedule)
  ├── Creator LP  (creator_liquidity_percentage %)
  │     ├── Permanently locked (creator_permanent_locked_liquidity_percentage %)
  │     └── Vesting (creator_liquidity_vesting_info schedule)
  └── Protocol LP (remainder)
```

Vesting schedules use the same cliff + periodic model as DAMM v2 inner vesting:

| Parameter                            | Description                                 |
| ------------------------------------ | ------------------------------------------- |
| `cliff_duration_from_migration_time` | Seconds after migration before first unlock |
| `frequency`                          | Seconds between each periodic release       |
| `number_of_period`                   | Total number of release periods             |
| `cliff_unlock_amount`                | Amount released at the cliff                |
| `amount_per_period`                  | Amount released per period after the cliff  |

***

## Migration Fee

A one-time migration fee is taken from the migrated quote reserves:

```
migration_fee_amount = total_quote × migration_fee_bps / 10_000
```

The `migration_fee_percentage` is the total fee percentage. This total fee is split between partner and creator:

* Partner receives the portion not allocated to the creator
* `creator_migration_fee_percentage %` → creator's share of the migration fee

Both parties can claim their migration fee separately via `withdrawMigrationFee`.

The `migration_fee_withdraw_status` bitmask tracks withdrawal status:

* bit 1 (`0b010`) = creator has withdrawn
* bit 2 (`0b100`) = partner has withdrawn

***

## Surplus Claims

After migration, there may be surplus quote tokens beyond what's needed for the DAMM pool. These are claimable:

| Claimant | Instruction              | Condition                                                   |
| -------- | ------------------------ | ----------------------------------------------------------- |
| Protocol | `claimProtocolFee`       | Protocol surplus claimed via the unified fee claim endpoint |
| Partner  | `withdrawPartnerSurplus` | `is_partner_withdraw_surplus = 0`                           |
| Creator  | `withdrawCreatorSurplus` | `is_creator_withdraw_surplus = 0`                           |

The surplus split is determined by `PARTNER_AND_CREATOR_SURPLUS_SHARE` constant.

***

## Post-Migration: DAMM v2 Pool Parameters

When `migration_option = DammV2`, the created DAMM pool uses:

| DBC Config Field              | Maps to DAMM v2     |
| ----------------------------- | ------------------- |
| `migration_sqrt_price`        | `initSqrtPrice`     |
| `migrated_collect_fee_mode`   | `collectFeeMode`    |
| `migrated_pool_fee_bps`       | Base fee            |
| `migrated_pool_base_fee_mode` | `BaseFeeMode`       |
| `migrated_dynamic_fee`        | Dynamic fee enabled |

***

## Fixed Supply Migration

For fixed-supply tokens, leftover base tokens (unsold at migration) are returned to `leftover_receiver`:

```
leftover = pre_migration_token_supply - swap_base_amount - post_migration_token_supply
```

The `is_withdraw_leftover` flag on VirtualPool tracks whether this has happened.
