# 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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cetus-1.gitbook.io/cetus-developer-docs/developer/via-dlmm-contract/features-available/swap.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
