# Liquidity Provider Token 介绍与解析

## 什么是 LP Token？

当您在 UTXOSwap 上提供流动性时，将会获得作为流动性提供证明的 Liquidity Provider Token（以下简称 LP Token）。

每个流动性池创建时会同时生成对应的独立 LP Token。这些代币遵循 xUDT 标准，可以像其他 xUDT 代币一样进行转移。然而，由于 LP Token 在参数（args）结构上略大于普通 xUDT 代币，它会占用更多的 capacity。

{% hint style="info" %}
虽然所有 LP Token 在 LP Token Info 中的 Symbol 名称相同，但不同流动性池的 LP Token 的 `args` 字段是不同的，使每个代币独一无二，因此这些 LP Token 实际上是不同的代币，无法进行合并。
{% endhint %}

{% hint style="info" %}
需要注意的是，转移或销毁 LP Token 相当于转移或销毁用户在 UTXOSwap 上的流动性资产。

因此，虽然从技术上可以将 LP Token 当作普通的 xUDT Token 来操作，但我们并不推荐为 LP Token 提供与其他 xUDT Token 相同的操作界面。

如果确实需要提供这类操作功能，务必清晰地告知用户操作的潜在风险，以防止用户资产的损失。
{% endhint %}

## LP Token 的格式

LP\_token 的 Type Script 格式如下：

```
LP_token Type Script
    code_hash: xudt_type_code_hash
    hash_type: xudt_type_hash_type
    args: pool_type_hash|0x40000000_u32.to_le_bytes()
```

在 `args` 字段中，`0x40000000_u32.to_le_bytes()` 表示这是一个 xUDT 标志位，使用 `owner` 模式的 `output_type`。该值占用 4 字节。因此，整个 LP Token 的 Type Script 的长度比标准 xUDT 的 65 字节多出 4 字节，总长为 69 字节。

## LP Token 的创建

当创建流动性池时，会同时生成 LP Token 及 LP Token Info Cell，交易结构大致如下：

```
inputs:
    Asset_x Cell
        type: asset_x type
        lock: intent lock
        data: udt amount or none
    Asset_y Cell
        type: asset_y type
        lock: intent lock
        data: udt amount
    capacity Cell

outputs:
    LP Token Cell
        type: lp_token type
        lock: user lock
        data: udt amount
    Pool Cell
        type: pool type
        lock: sequencer proxy lock
        data: pool info
    Asset_x Cell
        type: asset_x type
        lock: pool controlled lock
        data: udt amount or none
    Asset_y Cell
        type: asset_y type
        lock: pool controlled lock
        data: udt amount
    LP Token Info cell:
        type: unique cell type
        lock: all zero
        data: LP Token Info
```

Pool Cell 中 data 对应的 pool info 的 molecule 如下：

```
import blockchain;
struct PairInfo {
    total_fee_rate: byte, // 流动性池的交易费率
    batch_id: Uint64,     // batch 标识，每个 batch 处理后递增
    asset_x: Byte32,      // asset_x 的 udt_type_hash
    reserve_x: Uint128,   // asset_x 在流动性池中的数量
    asset_y: Byte32,      // asset_y 的 udt_type_hash
    reserve_y: Uint128,   // asset_y 在流动性池中的数量
    total_lp_supply: Uint128, // LP token 的总发行量
    protocol_lp_amount: Uint128, // 归属于协议的 LP token 数量
}
```

Pool Cell 的 pool type script 格式如下：

```
Pool Type Script
    code_hash: pool_type_code_hash
    hash_type: pool_type_hash_type
    args: type_id
```

## LP Token 的解析

### 方案1: 通过 Pool Cell 进行解析

1. **定位 Pool Cell**：首先通过 LP Token 的 `pool_type_hash` 定位对应的 Pool Cell。
2. **解析 Pool Info**：反序列化 Pool Cell 中的 `data` 部分，解析出 `asset_x_type_hash` 和 `asset_y_type_hash`。
3. **查询资产符号**：通过解析得到的类型哈希（type hash），查询 Asset X 和 Asset Y 的代币符号。
4. **记录 LP Token**：将 LP Token 标记为 Asset X/Asset Y LP，以反映 LP Token 代表的资产组合。

### 方案2: 通过 LP Token 的创建交易进行解析

1. **追溯创建交易**：找到创建 LP Token 和 LP Token Info Cell 的初始交易。
2. **解析交易输出**：从该交易中解析出涉及的 AssetX 和 AssetY 信息。
3. **查询资产符号**：同样，查询和记录 AssetX 和 AssetY 的代币符号。
4. **记录 LP Token**：将 LP Token 标记为 Asset X/Asset Y LP，以反映 LP Token 代表的资产组合。

**方案 1** 依赖于链上现存的数据结构，适用于动态查询，能够实时反映当前状态。这种方法对于需要实时数据的应用场景更为合适。

**方案 2** 则是一种静态分析方法，依赖于交易历史，适用于历史数据分析和在特定时间点的状态复现。

## 链上部署信息

主网部署信息：

```
pool_type_code_hash: hex!
("c70a8b00526419826023bcf196852eecdc87406cdff7366234f6387265413c98"),
pool_type_hash_type: ScriptHashType::Type,

xudt_type_code_hash: hex!
("50bd8d6680b8b9cf98b73f3c08faf8b2a21914311954118ad6609be6e78a1b95"),
xudt_type_hash_type: ScriptHashType::Data1,
```

测试网部署信息：

```
pool_type_code_hash: hex!
("5b9228b156fc20c2f091ce0ebd366aac6a2510fff150c6664f065edff59f8735"),
pool_type_hash_type: ScriptHashType::Type,

xudt_type_code_hash: hex!
("25c29dc317811a6f6f3985a7a9ebc4838bd388d19d0feeecf0bcd60f6c0975bb"),
xudt_type_hash_type: ScriptHashType::Type,
```
