# Swap

## 1. Standard Swap (Without Partner) <a href="#id-11-using-router-contract" id="id-11-using-router-contract"></a>

### 1.1 Using Router Contract <a href="#id-11-using-router-contract" id="id-11-using-router-contract"></a>

**Location**: `dlmm_router::swap` module

#### **swap\_a2b**

Swap Coin A to Coin B.

```move
public fun swap_a2b<CoinTypeA, CoinTypeB>(
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    coin_a: &mut Coin<CoinTypeA>,
    by_amount_in: bool,
    amount: u64,
    amount_limit: u64,
    config: &GlobalConfig,
    versioned: &Versioned,
    clock: &Clock,
    ctx: &mut TxContext,
)
```

#### **swap\_b2a**

Swap Coin B to Coin A.

```move
public fun swap_b2a<CoinTypeA, CoinTypeB>(
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    coin_b: &mut Coin<CoinTypeB>,
    by_amount_in: bool,
    amount: u64,
    amount_limit: u64,
    config: &GlobalConfig,
    versioned: &Versioned,
    clock: &Clock,
    ctx: &mut TxContext,
)
```

**Parameters**

<table><thead><tr><th width="158.97265625">Parameter</th><th width="134.1015625">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>pool</code></td><td><code>&#x26;mut Pool</code></td><td>Pool object (mutable)</td></tr><tr><td><code>coin_a</code> / <code>coin_b</code></td><td><code>&#x26;mut Coin</code></td><td>Input coin object</td></tr><tr><td><code>by_amount_in</code></td><td><code>bool</code></td><td><code>true</code>: fix input amount, <code>false</code>: fix output amount</td></tr><tr><td><code>amount</code></td><td><code>u64</code></td><td>If <code>by_amount_in=true</code>: input amount; else: output amount</td></tr><tr><td><code>amount_limit</code></td><td><code>u64</code></td><td>If <code>by_amount_in=true</code>: min output; else: max input</td></tr><tr><td><code>config</code></td><td><code>&#x26;GlobalConfig</code></td><td>Global config for validations</td></tr><tr><td><code>versioned</code></td><td><code>&#x26;Versioned</code></td><td>Versioned object for version checking</td></tr><tr><td><code>clock</code></td><td><code>&#x26;Clock</code></td><td>Clock object (<code>0x6</code>)</td></tr></tbody></table>

### 1.2 Build Custom Swap (Using Flash Swap) <a href="#id-12-build-custom-swap-using-flash-swap" id="id-12-build-custom-swap-using-flash-swap"></a>

```move
fun swap_<CoinTypeA, CoinTypeB>(
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    coin_a: &mut Coin<CoinTypeA>,
    coin_b: &mut Coin<CoinTypeB>,
    a2b: bool,
    by_amount_in: bool,
    amount: u64,
    amount_limit: u64,
    versioned: &Versioned,
    config: &GlobalConfig,
    clock: &Clock,
    ctx: &mut TxContext,
) {
    // Step 1: Flash swap - borrow output tokens
    let (receive_a, receive_b, flash_receipt) = pool::flash_swap<CoinTypeA, CoinTypeB>(
        pool,
        a2b,
        by_amount_in,
        amount,
        config,
        versioned,
        clock,
        ctx,
    );

    // Step 2: Validate amounts
    let (in_amount, out_amount) = (
        flash_receipt.pay_amount(),
        if (a2b) receive_b.value() else receive_a.value(),
    );

    if (by_amount_in) {
        assert!(in_amount == amount, ESwapAmountIncorrect);
        assert!(out_amount >= amount_limit, EAmountOutBelowMinLimit);
    } else {
        assert!(out_amount == amount, ESwapAmountIncorrect);
        assert!(in_amount <= amount_limit, EAmountInAboveMaxLimit);
    };

    // Step 3: Prepare repayment
    let (pay_coin_a, pay_coin_b) = if (a2b) {
        assert!(coin_a.value() >= in_amount, ENotEnoughCoin);
        (coin_a.split(in_amount, ctx).into_balance(), balance::zero<CoinTypeB>())
    } else {
        assert!(coin_b.value() >= in_amount, ENotEnoughCoin);
        (balance::zero<CoinTypeA>(), coin_b.split(in_amount, ctx).into_balance())
    };

    // Step 4: Repay flash swap
    pool::repay_flash_swap<CoinTypeA, CoinTypeB>(
        pool,
        pay_coin_a,
        pay_coin_b,
        flash_receipt,
        versioned,
    );

    // Step 5: Collect output
    coin_a.join(receive_a.into_coin(ctx));
    coin_b.join(receive_b.into_coin(ctx));
}
```

***

## 2. Partner Swap (With Referral Fee) <a href="#id-2-partner-swap-with-referral-fee" id="id-2-partner-swap-with-referral-fee"></a>

Partners can earn referral fees by using partner-specific swap functions. See [Partner Integration Guide](https://vscode-remote+ssh-002dremote-002bwork.vscode-resource.vscode-cdn.net/home/bond/github/cetus/cetus-dlmm/docs/partner-integration-guide.md) for complete partner setup.

### 2.1 Using Router Contract <a href="#id-21-using-router-contract" id="id-21-using-router-contract"></a>

**Location**: `dlmm_router::swap` module

#### **swap\_a2b\_with\_partner**

```move
public fun swap_a2b_with_partner<CoinTypeA, CoinTypeB>(
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    partner: &mut Partner,
    coin_a: &mut Coin<CoinTypeA>,
    by_amount_in: bool,
    amount: u64,
    amount_limit: u64,
    config: &GlobalConfig,
    versioned: &Versioned,
    clock: &Clock,
    ctx: &mut TxContext,
)
```

#### **swap\_b2a\_with\_partner**

```move
public fun swap_b2a_with_partner<CoinTypeA, CoinTypeB>(
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    partner: &mut Partner,
    coin_b: &mut Coin<CoinTypeB>,
    by_amount_in: bool,
    amount: u64,
    amount_limit: u64,
    config: &GlobalConfig,
    versioned: &Versioned,
    clock: &Clock,
    ctx: &mut TxContext,
)
```

**Additional Parameter**

<table><thead><tr><th width="121.46875">Parameter</th><th width="140.02734375">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>partner</code></td><td><code>&#x26;mut Partner</code></td><td>Partner object (shared, mutable)</td></tr></tbody></table>

> Other parameters are the same as standard swap.

### 2.2 Build Custom Swap with Partner (Using Flash Swap) <a href="#id-22-build-custom-swap-with-partner-using-flash-swap" id="id-22-build-custom-swap-with-partner-using-flash-swap"></a>

```move
fun swap_with_partner_<CoinTypeA, CoinTypeB>(
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    partner: &mut Partner,
    coin_a: &mut Coin<CoinTypeA>,
    coin_b: &mut Coin<CoinTypeB>,
    a2b: bool,
    by_amount_in: bool,
    amount: u64,
    amount_limit: u64,
    config: &GlobalConfig,
    versioned: &Versioned,
    clock: &Clock,
    ctx: &mut TxContext,
) {
    // Step 1: Flash swap with partner - calculates referral fee
    let (receive_a, receive_b, flash_receipt) = pool::flash_swap_with_partner<CoinTypeA, CoinTypeB>(
        pool,
        partner,
        a2b,
        by_amount_in,
        amount,
        config,
        versioned,
        clock,
        ctx,
    );

    // Step 2: Validate amounts
    let (in_amount, out_amount) = (
        flash_receipt.pay_amount(),
        if (a2b) receive_b.value() else receive_a.value(),
    );

    if (by_amount_in) {
        assert!(in_amount == amount, ESwapAmountIncorrect);
        assert!(out_amount >= amount_limit, EAmountOutBelowMinLimit);
    } else {
        assert!(out_amount == amount, ESwapAmountIncorrect);
        assert!(in_amount <= amount_limit, EAmountInAboveMaxLimit);
    };

    // Step 3: Prepare repayment
    let (pay_coin_a, pay_coin_b) = if (a2b) {
        assert!(coin_a.value() >= in_amount, ENotEnoughCoin);
        (coin_a.split(in_amount, ctx).into_balance(), balance::zero<CoinTypeB>())
    } else {
        assert!(coin_b.value() >= in_amount, ENotEnoughCoin);
        (balance::zero<CoinTypeA>(), coin_b.split(in_amount, ctx).into_balance())
    };

    // Step 4: Repay flash swap - referral fee is automatically deposited to partner
    pool::repay_flash_swap_with_partner<CoinTypeA, CoinTypeB>(
        pool,
        partner,
        pay_coin_a,
        pay_coin_b,
        flash_receipt,
        versioned,
    );

    // Step 5: Collect output
    coin_a.join(receive_a.into_coin(ctx));
    coin_b.join(receive_b.into_coin(ctx));
}
```

#### 2.3 Key Differences from Standard Swap <a href="#id-23-key-differences-from-standard-swap" id="id-23-key-differences-from-standard-swap"></a>

<table><thead><tr><th width="152.23046875">Aspect</th><th width="291.0078125">Standard Swap</th><th>Partner Swap</th></tr></thead><tbody><tr><td>Function</td><td><code>flash_swap</code> / <code>repay_flash_swap</code></td><td><code>flash_swap_with_partner</code> / <code>repay_flash_swap_with_partner</code></td></tr><tr><td>Partner param</td><td>Not required</td><td>Required (<code>&#x26;mut Partner</code>)</td></tr><tr><td>Referral fee</td><td>None</td><td>Calculated and deposited to partner</td></tr><tr><td>Fee collection</td><td>N/A</td><td>Partner must manually claim</td></tr></tbody></table>

### Related Documentation <a href="#id-3-typescript-sdk-usage" id="id-3-typescript-sdk-usage"></a>

***

* [Partner Integration Guide](https://vscode-remote+ssh-002dremote-002bwork.vscode-resource.vscode-cdn.net/home/bond/github/cetus/cetus-dlmm/docs/partner-integration-guide.md) - Partner setup and fee claiming
