# 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 %}


---

# 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://docs.dano.finance/developers/integration/concentrated-liquidity-pool-integration_bk.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.
