> For the complete documentation index, see [llms.txt](https://docs.dano.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dano.finance/developers/integration/concentrated-liquidity-pool-integration_bk.md).

# Concentrated Liquidity Pool Integration\_BK

## Purpose

Guide on how to Build Transaction Swap Concentrated Pool Token:

* Example transaction: [`https://preprod.cardanoscan.io/transaction/04d7b78eed6960c51db4e0128304225469db8bb45277d9278717749f50b19271`](https://preprod.cardanoscan.io/transaction/04d7b78eed6960c51db4e0128304225469db8bb45277d9278717749f50b19271)

## Steps to Build a Transaction Swap Token

{% stepper %}
{% step %}

### Retrieve Necessary Parameters

Use the APIs to retrieve the necessary parameters for the Token Swap operation.
{% endstep %}

{% step %}

### Build the Redeemer Structure

**Concentrated ExchangeActionRedeemer Structure:**

To optimize data size and allow one transaction (txn) to swap across multiple pools simultaneously, the Redeemer is a ByteArray, where each field has a defined index and byte size.

* ExchangeActionRedeemer structure for Token Swap:

```rust
pub type ExchangeActionRedeemer {
    in_idx: Int, // 1 byte: pool or staking
    action: ExchangeAction // 1 byte
}

pub type ExchangeAction {
    CreatePool(CreatePoolParams)
    // platform_fee_out_idx > 0 if platform_fee_X/Y > 0
    ModifyLiquidity(Int, List<ModifyLiquidityParams>)
    // (UTxOType, LicenseIdx)
    WithdrawPlatformFee((Int, Int) ,List<WithdrawPlatformFeeParams>)
    Swap(List<SwapParams>)
    // platfrom_fee_out_idx
    ClaimUndefined((Int, Int) ,List<ClaimUndefinedParams>)
    DelegatePool
}

type SwapParams {
    pool_in_idx: Int, // 1 byte
    pool_out_idx: Int, // 1 byte
    delta_amount: Int, // 32 byte (Int256)
}
```

* Diagnostic Notation format:

```
h'0103...' // Swap Action = 03
```

* CBOR format:

```
  58240103... // 36 bytes (<in_idx><action><pool_in_idx><pool_out_idx><delta_amount>)
```

{% endstep %}

{% step %}

### Create the Transaction

Use the retrieved parameters to create the token swap transaction.

* Note: To minimize DDoS attacks in multi-hop pools, each pool, when swapped, will collect ADA fees according to protocol\_config.swap\_fee and add them to the Pool Datum:

  ```
  pool_out_datum.total_swap_fee=pool_in_datum.total_swap_fee+protocol_config.swap_fee
  ```
* If swap\_fee = 0, no fee will be charged.
* The above fee is updated by Admin NFT.

{% stepper %}
{% step %}

#### Validity range

* Ensure the time-to-live (TTL) <=6 minutes.
  {% endstep %}

{% step %}

#### Input

* Note: The `outRef`, `address`, `coin`, and `multiAssets` information is fully returned by the API.
  * PoolInUtxo: The pool you intend to swap tokens with.
    * Spend Redeemer: Build the redeemer according to the **ExchangeActionRedeemer** Swap structure for Concentrated Pool, ensuring the specified indices are correct.
    * The input Pool UTxO must have the valid PoolNFT:
      * pool\_in\_asset\[PoolNFT] = 1
        {% endstep %}

{% step %}

#### Output

* PoolOutUtxo: The output of the pool after the swap.
  * All information for the pool output UTxO is fully returned by the API.
  * The pool datum structure must adhere to the correct order:

```
type PoolDatum {
    // Pool liquidity pair used for trading
    token_X: TupleAsset,
    token_Y: TupleAsset,
    //
    lp_fee_rate: Basis, // LP fee decided by pool creator
    platform_fee_X: Int, // platform fee accumulated on each swap transaction collected in token X
    platform_fee_Y: Int, // platform fee accumulated on each swap transaction collected in token Y
    total_swap_fee: Int, // total swap_fee (ADA) accumulated
    // to save costs, onchain will let offchain calculate sqrt price
    sqrt_lower_price: PRational,
    sqrt_upper_price: PRational,
    // min X, min Y to avoid DDOS when ModifyLiquidity and Swap
    min_x_change: Int,
    min_y_change: Int,
    circulating_lp_token: Int, // current lp token in circulation, changed when supply/withdraw liquidity
    last_withdraw_epoch: Int // the last epoch when a withdrawal was made from the pool
}
```

* Diagnostic Notation format:

```
24_0(<<121_0([_
     [_
         h'9a614be30284aa88eb845da7657b5d0a235f1b95628b23c08050d502',
         h'6655534441',
     ],
     [_
         h'834a15101873b4e1ddfaa830df46792913995d8738dcde34eda27905',
         h'665553444d',
     ],
     0,
     0,
     0,
     121_0([_ 15811388300841898_3, 10000000000000000_3]),
     121_0([_ 17320508075688772_3, 10000000000000000_3]),
     1090866_2,
     399256_2,
     10000000_2,
     65339_1,
])>>)
```

{% endstep %}

{% step %}

#### Reference Input

* Add all reference inputs from [SDK](https://github.com/danogo-finance/clmm-sdk) .
  {% endstep %}

{% step %}

#### Withdrawal

* **Withdraw Redeemer**:
  * Add a withdrawal to the reward address with the reward amount from [SDK](https://github.com/danogo-finance/clmm-sdk).
  * The reward redeemer has the **ExchangeActionRedeemer** structure.
* **Withdraw Staking Reward**: Must add staking withdrawal if the staking reward amount is greater than 0.
  * Staking reward address with the reward amount from [SDK](https://github.com/danogo-finance/clmm-sdk).
  * Staking redeemer: Built according to the **ExchangeActionRedeemer** structure.
    {% endstep %}
    {% endstepper %}

**Note**: After sorting the inputs and reference inputs according to the chain's sort order, ensure the correct indices are used when specifying them in the redeemers.
{% endstep %}
{% endstepper %}
