> ## 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.

# Bonding Curve Formulas

> Mathematical formulas behind DBC's multi-segment bonding curve: price calculation, token supply, and migration threshold.

The Dynamic Bonding Curve is a customizable bonding curve that allows you to configure up to 16 curve segments to control the curve's shape and price action. Each curve segment follows a constant product formula:

```math theme={"system"}
x \times y = k
```

# Mathematical Foundation

A simple constant product formula can be expressed as:

```math theme={"system"}
x \times y = \text{Virtual Base Reserve} \times \text{Virtual Curve Reserve}
```

This can also be represented as:

```math theme={"system"}
x \times y = \text{Liquidity}^2
```

Where:

```math theme={"system"}
\text{Liquidity} = \sqrt{\,\text{Virtual Base Reserve} \times \text{Virtual Curve Reserve}\,}
```

With a constraint on `migration_quote_threshold`, this can be presented as a function of liquidity, minimum price, and maximum price. We denote:

* `l` = liquidity
* `pa` = minimum price
* `pb` = maximum price

Therefore:

```math theme={"system"}
\text{Bonding Curve Constant Product} = f(l, p_a, p_b)
```

## Example Configuration

Consider a pool with the following configuration:

```
sqrt_start_price = 1
curve = [
  (sqrt_price = 2, liquidity = 100),
  (sqrt_price = 4, liquidity = 500)
]
```

The bonding curve will function across 2 price ranges:

* **Range 1**: `(l = 100, pa = 1, pb = 2)`
* **Range 2**: `(l = 500, pa = 2, pb = 4)`

<Note>These are just example values and are not real values in the actual curve. You will have to calculate the actual `sqrt_price` and `liquidity` values which will be much bigger.</Note>

# Core Formulas

Below are the core formulas used in the dynamic bonding curve program. We use the following notation:

* Let $L_i$ = liquidity in $i$ index
* Let $P_i$ = price at $i$ index
* $P_{i-1}$ = price at the lower boundary of $i$ index

***

## 1. Bonding Curve Amount

The total amount of base mint tokens in the bonding curve is given by:

```math theme={"system"}
\text{Bonding Curve Amount} = \sum_{i} L_i \left( \frac{1}{P_{i-1}} - \frac{1}{P_i} \right)
```

***

## 2. Migration Quote Threshold

The migration quote threshold required for the pool to migrate is calculated as:

```math theme={"system"}
\text{Migration Quote Threshold} = \sum_{i} L_i (P_i - P_{i-1})
```

***

## 3. Migration Price Calculation

To determine the migration price squared ($p_\text{max}^2$) during migration, use:

```math theme={"system"}
p_\text{max}^2 = \frac{\text{Migration Quote Threshold} \times (1 - \text{Migration Fee Percentage})}{\text{Migration Amount}}
```

Where:

* `Migration Fee Percentage` is the fee (as a decimal, e.g., 0.01 for 1%)
* `Migration Amount` is the total amount of base mint tokens being migrated

***

These formulas allow you to compute swap amounts, migration thresholds, and price limits for any custom liquidity distribution along the bonding curve.

# Fee Formulas

The total swap fee ($f_s$) will have two components:

1. **A base fee** ($f_b$)
2. **A variable fee** ($f_v$)

The **total swap fee** is calculated as:

```math theme={"system"}
f_s = f_b + f_v
```

## Pool Fee Interface

```
poolFees: {
    baseFee: {
        cliffFeeNumerator: BN // Initial fee numerator (base fee)
        firstFactor: number // feeScheduler: numberOfPeriod, rateLimiter: feeIncrementBps
        secondFactor: BN // feeScheduler: periodFrequency, rateLimiter: maxLimiterDuration
        thirdFactor: BN // feeScheduler: reductionFactor, rateLimiter: referenceAmount
        baseFeeMode: number // 0: FeeSchedulerLinear, 1: FeeSchedulerExponential, 2: RateLimiter
    }
    dynamicFee: {
        // Optional dynamic fee
        binStep: number // u16 value representing the bin step in bps
        binStepU128: BN // u128 value for a more accurate bin step
        filterPeriod: number // Minimum time that must pass between fee updates
        decayPeriod: number // Period after the volatility starts decaying (must be > filterPeriod)
        reductionFactor: number // Controls how quickly volatility decys over time
        variableFeeControl: number // Multiplier that determines how much volatility affects fees
        maxVolatilityAccumulator: number // Caps the maximum volatility that can be accumulated
    } | null
}
```

Using the relevant parameters, you can calculate the base fee and variable fee for any given swap.

* For **Fee Scheduler** you can refer to the [Fee Scheduler Formulas](/anti-sniper-suite/fee-time-scheduler/fee-time-scheduler-math).
* For **Rate Limiter** you can refer to the [Rate Limiter Formulas](/anti-sniper-suite/rate-limiter/rate-limiter-math).
* For **Dynamic Fees** you can refer to the [Dynamic Fee Formulas](/overview/products/dbc/trading-fees-calculation#dynamic-fee-variable-fee).

# Migration Fee

We introduced a new migration fee feature that allows users to collect a percentage of the `quote_min` from the `migration_quote_threshold` amount.

```
migrationFee: {
    // Optional migration fee (set as 0 for feePercentage and 0 for creatorFeePercentage for no migration fee)
    feePercentage: number // The percentage of fee taken from migration quote threshold (0-99)
    creatorFeePercentage: number // The fee share percentage for the creator from the migration fee (0-100)
}
```

ONLY if you are using the `buildCurveWithMarketCap` function from the DBC Typescript SDK, you will need to calculate the actual `initial_market_cap` value that you want based on the desired initial market cap.

## Formula

```
let D = desiredMarketCap and M = migrationMarketCap and f = migrationFee and I = initialMarketCap

requiredRatio = sqrt(D / M)
percentageSupplyOnMigration = (requiredRatio * (1 - f) * 100) / (1 + requiredRatio * (1 - f))
x = percentageSupplyOnMigration / ((100 - V - L) - percentageSupplyOnMigration)
I = M * x²
```

## Example

```
const curveConfig = buildCurveWithMarketCap({
    token: {
        tokenType: TokenType.SPL,
        tokenBaseDecimal: TokenDecimal.SIX,
        tokenQuoteDecimal: TokenDecimal.NINE,
        tokenUpdateAuthority: TokenUpdateAuthorityOption.Immutable,
        totalTokenSupply: 1_000_000_000,
        leftover: 1,
    },
    fee: {
        baseFeeParams: {
            baseFeeMode: BaseFeeMode.FeeSchedulerLinear,
            feeSchedulerParam: {
                startingFeeBps: 100,
                endingFeeBps: 100,
                numberOfPeriod: 0,
                totalDuration: 0,
            },
        },
        dynamicFeeEnabled: false,
        collectFeeMode: CollectFeeMode.QuoteToken,
        creatorTradingFeePercentage: 0,
        poolCreationFee: 0,
        enableFirstSwapWithMinFee: false,
    },
    migration: {
        migrationOption: MigrationOption.MET_DAMM_V2,
        migrationFeeOption: MigrationFeeOption.FixedBps100,
        migrationFee: { feePercentage: 50, creatorFeePercentage: 0 },
    },
    liquidityDistribution: {
        partnerLiquidityPercentage: 0,
        partnerPermanentLockedLiquidityPercentage: 100,
        creatorLiquidityPercentage: 0,
        creatorPermanentLockedLiquidityPercentage: 0,
    },
    lockedVesting: {
        totalLockedVestingAmount: 0,
        numberOfVestingPeriod: 0,
        cliffUnlockAmount: 0,
        totalVestingDuration: 0,
        cliffDurationFromMigrationTime: 0,
    },
    activationType: ActivationType.Slot,
    initialMarketCap: 4000,
    migrationMarketCap: 69000,
})
```

<Note>A leftover value is needed to cover precision loss when you indicate a migration fee.</Note>
