> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
> Use this file to discover all available pages before exploring further.

# LaunchLab PlatformConfig

> Cấu hình riêng theo nền tảng tùy chỉnh branding, chia phí, chia sẻ NFT migration, phân bổ vesting, và danh sách trắng các curve shape được phép cho bất kỳ launch nào được định tuyến qua nền tảng đó.

<Info>
  **Trang này được dịch tự động bằng AI. Phiên bản tiếng Anh là bản chính thức.**

  [Xem bản tiếng Anh →](/products/launchlab/platform-config)
</Info>

<Info>
  `PlatformConfig` là **overlay cấp nền tảng** nằm trên [`GlobalConfig`](/vi/products/launchlab/global-config). Nếu `GlobalConfig` định nghĩa các quy tắc toàn giao thức ("phí giao dịch là 1%, cấp cung phải ít nhất 10M, chỉ ví này mới có thể graduation"), thì `PlatformConfig` là cái mà mỗi nền tảng launch — pump.fun, UI của Raydium, các launchpad bên thứ ba — sử dụng để thêm phí của họ, yêu cầu phần LP sau graduation, hạn chế hình dạng curve nào mà các launch của họ có thể chọn, và hiển thị branding của họ (tên, website, hình ảnh) on-chain.
</Info>

## Nó là cái gì

Một tài khoản `PlatformConfig` quản lý bốn khía cạnh quan trọng cho một nền tảng:

1. **Branding** — tên, website, liên kết hình ảnh, tất cả được lưu trữ inline để bất kỳ explorer hay aggregator nào cũng có thể hiển thị nền tảng đã launch token.
2. **Platform fee** — một phí giao dịch bổ sung (`fee_rate`) trên đỉnh của `trade_fee_rate` của giao thức. Tích lũy vào `platform_fee_wallet` của nền tảng. Bị giới hạn ở 100 bps bởi `GlobalConfig.max_share_fee_rate`.
3. **NFT migration split** — ba số nguyên (`platform_scale`, `creator_scale`, `burn_scale`) cộng lại bằng `RATE_DENOMINATOR_VALUE = 1_000_000` và chia LP sau graduation thành một phần được mint cho ví NFT nền tảng, một phần cho ví NFT creator, và một phần bị burn (Burn & Earn). Chỉ có ý nghĩa khi graduation hướng đến CPMM (`migrate_type = 1`).
4. **Curve-parameter whitelist** — một `Vec<PlatformCurveParam>` liệt kê chính xác những kết hợp `(supply, total_base_sell, total_quote_fund_raising, migrate_type, migrate_cpmm_fee_on, vesting_params...)` nào được phép trên nền tảng này. Nếu vector trống hoặc tất cả mục nhập đều không hợp lệ, **bất kỳ** kết hợp nào cũng được phép; ngược lại, các launch phải khớp chính xác với một trong các mục nhập.

Đạo hàm PDA:

```ts theme={null}
const [platformConfigPda] = PublicKey.findProgramAddressSync(
  [
    Buffer.from("platform_config"),
    platformAdmin.toBuffer(),       // platform's owning pubkey
  ],
  LAUNCHLAB_PROGRAM_ID,
);
```

(Xem `create_platform_config` trong source để có danh sách seed chính thức.)

## Layout

```rust theme={null}
// states/platform_config.rs
pub const PLATFORM_CONFIG_SEED: &str = "platform_config";
pub const NAME_SIZE: usize = 64;
pub const WEB_SIZE:  usize = 256;
pub const IMG_SIZE:  usize = 256;
pub const MAX_CREATOR_FEE_RATE: u64 = 5000;       // 50 bps (denominator 1_000_000)
pub const MAX_TRANSFER_FEE_RATE: u16 = 500;       // 5%   (denominator 10_000)
pub const MAX_CURVE_PARAMS: usize = 10;

#[account]
pub struct PlatformConfig {
    pub epoch:                       u64,
    pub platform_fee_wallet:         Pubkey,            // signs ClaimPlatformFee
    pub platform_nft_wallet:         Pubkey,            // receives the platform NFT slice at CPMM graduation
    pub platform_scale:              u64,               // share of LP minted to platform NFT
    pub creator_scale:               u64,               // share of LP minted to creator NFT
    pub burn_scale:                  u64,               // share of LP burned via Burn & Earn
    pub fee_rate:                    u64,               // platform's trade fee (1/1_000_000)
    pub name:                        [u8; 64],          // utf-8 padded with zeros
    pub web:                         [u8; 256],
    pub img:                         [u8; 256],
    pub cpswap_config:               Pubkey,            // CPMM AmmConfig that the post-grad pool will bind to
    pub creator_fee_rate:            u64,               // creator-side fee taken pre-graduation
    pub transfer_fee_extension_auth: Pubkey,            // for Token-2022 launches: who inherits transfer-fee authorities post-graduation
    pub platform_vesting_wallet:     Pubkey,
    pub platform_vesting_scale:      u64,               // platform's slice of total_locked_amount
    pub platform_cp_creator:         Pubkey,            // optional creator-of-record on the post-graduation CPMM pool
    pub padding:                     [u8; 108],
    pub curve_params:                Vec<PlatformCurveParam>, // whitelist of permitted curve shapes
}
```

`platform_scale + creator_scale + burn_scale` phải bằng `1_000_000` (xác thực bởi `MigrateNftInfo::check`). Các chia sẻ thường thấy trong production:

* `(0, 100_000, 900_000)` — 90% LP bị burn, 10% cho creator. Tiêu chuẩn fair launch kiểu pump.
* `(50_000, 100_000, 850_000)` — chia sẻ nền tảng nhỏ (5%), 10% creator, 85% burn.
* `(0, 0, 1_000_000)` — toàn bộ burn, không mint NFT. Launch "no insiders" nghiêm ngặt.

## Trường branding

`name`, `web`, và `img` là các byte array inline được padding bằng zero lên đến hằng số kích thước của chúng. Để đọc chúng dưới dạng chuỗi, cắt lên đến `\0` đầu tiên:

```ts theme={null}
function readString(bytes: Uint8Array): string {
  const end = bytes.indexOf(0);
  return Buffer.from(end === -1 ? bytes : bytes.subarray(0, end)).toString("utf-8");
}
```

Các hằng số có ý định được đặt rộng rãi (`name: 64`, `web: 256`, `img: 256`) để các nền tảng có thể bao gồm đủ metadata cho explorer và aggregator mà không cần chạm vào lưu trữ off-chain. Bất cứ điều gì vượt quá các kích thước này sẽ revert tại `CreatePlatformConfig` với `InvalidInput`.

## Cơ chế phí

Một swap trên một curve được ràng buộc với một `PlatformConfig` tính ba khoản phí xếp chồng:

```
trade_fee     = amount_in × global_config.trade_fee_rate    / 1_000_000
platform_fee  = amount_in × platform_config.fee_rate        / 1_000_000
creator_fee   = amount_in × platform_config.creator_fee_rate / 1_000_000

amount_after_fee = amount_in − trade_fee − platform_fee − creator_fee
```

* `trade_fee` tích lũy vào `protocol_fee_owner` của giao thức (yêu cầu qua `CollectFee`).
* `platform_fee` tích lũy vào một vault riêng theo nền tảng (yêu cầu qua `ClaimPlatformFee` hoặc `ClaimPlatformFeeFromVault`; xem [`instructions`](/vi/products/launchlab/instructions)).
* `creator_fee` tích lũy vào một vault riêng theo creator được khóa bởi pubkey của creator + quote mint (yêu cầu qua `ClaimCreatorFee`).

`creator_fee_rate` bị giới hạn bởi `MAX_CREATOR_FEE_RATE = 5000` (50 bps). `fee_rate` (phí nền tảng) bị giới hạn ở `10000` (100 bps) bởi `GlobalConfig.max_share_fee_rate`.

## NFT migration split (chỉ CPMM)

Khi một launch graduation đến CPMM (`migrate_type = 1`, ký bởi `migrate_to_cpswap_wallet`), lệnh migration chia các LP token được mint bởi `CPMM::InitializeWithPermission` thành ba phần:

```
lp_to_platform = lp_total × platform_scale / 1_000_000   → platform_nft_wallet
lp_to_creator  = lp_total × creator_scale  / 1_000_000   → creator NFT (Fee Key)
lp_to_burn     = lp_total × burn_scale     / 1_000_000   → Burn & Earn lock program
```

Các chia sẻ nền tảng và creator được gói như **NFT** bởi chương trình LP-Lock (`LockrWmn6K5twhz3y9w1dQERbmgSaRkfnTeTKbpofwE`) — chủ sở hữu NFT có quyền yêu cầu phí CPMM tích lũy vô thời hạn mà không thể rút thanh khoản cơ bản. Xem [`products/launchlab/creator-fees`](/vi/products/launchlab/creator-fees) cho luồng Fee Key sau graduation.

Chia sẻ burn được gửi đến chương trình Lock với `is_burn = true` để các LP token không thể truy cập được — chúng bảo vệ mức sàn giá của pool mà không bao giờ hoàn lại phí cho ai.

Khi `migrate_type = 0` (graduation đến AMM v4), các trường chia sẻ NFT bị bỏ qua và toàn bộ LP được khóa / burn theo một luồng riêng phía AMM v4.

## Curve-parameter whitelist

`curve_params: Vec<PlatformCurveParam>` là cơ chế của nền tảng để hạn chế hình dạng curve nào mà các launch của nó có thể chọn. Nếu vector không trống và ít nhất một mục nhập hợp lệ, chương trình bắt buộc tại `Initialize` rằng tham số của launch khớp chính xác với ít nhất một mục nhập.

```rust theme={null}
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct PlatformCurveParam {
    pub epoch:                u64,
    pub index:                u8,           // ordinal within this platform's whitelist
    pub global_config:        Pubkey,       // which GlobalConfig this entry applies to
    pub bonding_curve_param:  BondingCurveParam,
    pub padding:              [u64; 50],
}

#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct BondingCurveParam {
    pub migrate_type:               u8,    // 0 = AMM v4, 1 = CPMM. u8::MAX = wildcard
    pub migrate_cpmm_fee_on:        u8,    // 0 = quote-only, 1 = both. u8::MAX = wildcard
    pub supply:                     u64,   // 0 = wildcard
    pub total_base_sell:            u64,   // 0 = wildcard
    pub total_quote_fund_raising:   u64,   // 0 = wildcard
    pub total_locked_amount:        u64,   // u64::MAX = wildcard
    pub cliff_period:               u64,   // u64::MAX = wildcard
    pub unlock_period:              u64,   // u64::MAX = wildcard
}
```

Mỗi trường có một giá trị sentinel có nghĩa là **wildcard** (bất kỳ giá trị nào khớp): `u64::MAX` cho các trường `u64`, `u8::MAX` cho các trường `u8`, `0` cho các trường supply / sell / fund-raising. Một `BondingCurveParam` với tất cả sentinel là "cho phép bất kỳ cái gì" — tương đương với hành vi whitelist trống.

Thuật toán khớp tại `Initialize`:

1. Lọc `curve_params` để các mục nhập có `global_config` khớp với `GlobalConfig` được chọn của launch.
2. Nếu danh sách được lọc trống, cho phép bất kỳ tham số nào (nền tảng đã không whitelist bất cứ cái gì cho `GlobalConfig` này).
3. Nếu mỗi mục nhập trong danh sách được lọc có `all_is_invalid()` (mỗi trường là wildcard), cho phép bất kỳ tham số nào.
4. Ngược lại, lặp qua các mục nhập; cho mỗi mục nhập, kiểm tra tham số của launch với mỗi trường không phải wildcard. Nếu tất cả các trường không phải wildcard khớp, chấp nhận và trả về.
5. Nếu không có mục nhập nào khớp, revert với `InvalidInput`.

Điều này cho phép một nền tảng nói "chúng tôi chỉ cho phép hình dạng 1B-supply / 800M-sold / 30k-USDC-raise / no-vesting tiêu chuẩn" bằng cách viết một mục nhập duy nhất có giá trị cụ thể cho bốn trường đó và wildcard ở mọi nơi khác. Hoặc một nền tảng nghiêm ngặt hơn có thể liệt kê ba hoặc bốn hình dạng riêng biệt, mỗi một cho một tầng launch được hỗ trợ.

`MAX_CURVE_PARAMS = 10` giới hạn kích thước whitelist.

## `PlatformGlobalAccess` — cấp quyền cho nền tảng

Khi một `GlobalConfig` có `requires_platform_auth = 1`, mỗi `Initialize` đối với nó phải bao gồm một `PlatformGlobalAccess` PDA chứng minh rằng nền tảng đã được pre-authorized:

```rust theme={null}
// states/platform_global_access.rs
pub const PLATFORM_GLOBAL_ACCESS_SEED: &str = "platform_global_access";

#[account]
pub struct PlatformGlobalAccess {
    pub bump:            u8,
    pub global_config:   Pubkey,
    pub platform_config: Pubkey,
    pub padding:         [u64; 8],
}
```

Seed PDA: `[b"platform_global_access", global_config, platform_config]`.

Admin giao thức tạo một trong số này cho mỗi cặp `(GlobalConfig, PlatformConfig)` thông qua `CreatePlatformGlobalAccess` và thu hồi nó thông qua `ClosePlatformGlobalAccess`. Mà không có tài khoản này, một launch không thể ràng buộc với `GlobalConfig` đó từ nền tảng được gated.

## Đường dẫn đọc

```ts theme={null}
const platformConfig = await raydium.launchpad.getPlatformConfig(platformConfigPda);

console.log("Platform:", readString(platformConfig.name));
console.log("Fee rate:", platformConfig.feeRate, "(/1M)");
console.log("NFT split:",
  platformConfig.platformScale,
  platformConfig.creatorScale,
  platformConfig.burnScale,
);
console.log("Curve whitelist size:", platformConfig.curveParams.length);
```

Cho một UI hiển thị "token này được launch từ đâu", `PoolState.platform_config` chỉ trực tiếp vào `PlatformConfig` gốc — tìm nạp một lần và cache branding.

## Đường dẫn cập nhật

| Instruction                 | Ai ký                    | Cái gì thay đổi                                                                                                                                                                  |
| --------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CreatePlatformConfig`      | platform admin (một lần) | Khởi tạo tài khoản với `PlatformParams`.                                                                                                                                         |
| `UpdatePlatformConfig`      | platform admin           | Dispatch chung được khóa bởi một `param: u8`; thay đổi một trường mỗi lần gọi. Các trường branding, tỷ lệ phí, ví vesting, và các ví khác nhau đều có thể đặt thông qua cái này. |
| `UpdatePlatformCurveParam`  | platform admin           | Thêm hoặc thay thế một mục nhập `PlatformCurveParam` bởi `(global_config, index)`.                                                                                               |
| `RemovePlatformCurveParam`  | platform admin           | Xóa một mục nhập (đặt nó thành all-sentinel = wildcard).                                                                                                                         |
| `ClaimPlatformFee`          | `platform_fee_wallet`    | Quét phí nền tảng riêng theo pool từ `PoolState.quote_vault`.                                                                                                                    |
| `ClaimPlatformFeeFromVault` | `platform_fee_wallet`    | Quét vault phí riêng theo nền tảng (PDA tại `[platform_config, quote_mint]`).                                                                                                    |

Các quay số ví (`platform_fee_wallet`, `platform_nft_wallet`, `platform_vesting_wallet`, `platform_cp_creator`, `transfer_fee_extension_auth`, `cpswap_config`) đều đi qua `UpdatePlatformConfig`. Đọc bảng dispatch `update_platform_config` trong source để các mã `param` chính xác.

## Những lỗi thường gặp

* **Whitelist sentinel bị đặt sai.** Một `BondingCurveParam` với `total_locked_amount = 0` *không phải* wildcard — nó khớp với các launch rõ ràng không opt vào vesting. Wildcard cho trường đó là `u64::MAX`. Cùng một cạm bẫy tồn tại cho `cliff_period` và `unlock_period`. Sử dụng `clear()` (mà chương trình để lộ) để đặt sentinel một cách chính xác.
* **NFT-split rounding.** Ba scale phải cộng lại bằng chính xác `1_000_000`. Lỗi off-by-one tại `CreatePlatformConfig` revert; off-by-one tại runtime sẽ mint hoặc burn một đơn vị LP thêm, đó là những gì kiểm tra strict-equality được đặt ở đó để ngăn chặn.
* **Platform vesting double-allocation.** Nếu `platform_vesting_scale > 0`, nền tảng phải gọi `CreatePlatformVestingAccount` một lần sau khi fundraising của launch kết thúc; nếu nó quên, chia sẻ đó vẫn chưa được phân bổ và ngủ yên mãi mãi (ngân sách `total_locked_amount` của launch được tiêu thụ nhưng nền tảng không bao giờ yêu cầu).
* **`platform_cp_creator` ambiguity.** Khi đặt thành `Pubkey::default()`, creator launch được ghi lại là `pool_creator` của pool CPMM sau graduation; khi đặt thành một khóa thực, khóa đó được ghi lại thay thế. Điều này ảnh hưởng đến ai có thể gọi `CPMM::CollectCreatorFee` sau này. Quyết định tại thời gian tạo platform-config mô hình nào bạn muốn.

## Con trỏ

* [`products/launchlab/global-config`](/vi/products/launchlab/global-config) — quy tắc phía giao thức mà launch phải thỏa mãn.
* [`products/launchlab/vesting`](/vi/products/launchlab/vesting) — cơ chế `platform_vesting_scale`.
* [`products/launchlab/creator-fees`](/vi/products/launchlab/creator-fees) — Fee Key NFT, Burn & Earn.
* [`products/launchlab/platforms`](/vi/products/launchlab/platforms) — hướng dẫn integrator nền tảng.

Nguồn:

* `raydium-launch/programs/launchpad/src/states/platform_config.rs` — `PlatformConfig`, `PlatformParams`, `MigrateNftInfo`, `PlatformCurveParam`, `BondingCurveParam`, `is_valid_curve_param`.
* `raydium-launch/programs/launchpad/src/states/platform_global_access.rs` — `PlatformGlobalAccess`.
* `raydium-launch/programs/launchpad/src/lib.rs` — `create_platform_config`, `update_platform_config`, `update_platform_curve_param`, `remove_platform_curve_param`, `create_platform_global_access`, `close_platform_global_access`, `claim_platform_fee`, `claim_platform_fee_from_vault`.
