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

> 各平台的配置設定，可自訂品牌、費用拆分、NFT 遷移份額、質押分配，以及通過該平台啟動的任何代幣所允許的曲線形狀白名單。

<Info>
  **本頁內容由 AI 自動翻譯，所有內容以英文版本為準。**

  [查看英文版 →](/products/launchlab/platform-config)
</Info>

<Info>
  `PlatformConfig` 是位於 [`GlobalConfig`](/zh-Hant/products/launchlab/global-config) 之上的**平台級**配置層。`GlobalConfig` 定義了協議級規則（「交易費率為 1%、最低供應量必須至少 1000 萬、只有這個錢包可以畢業」），而 `PlatformConfig` 是每個啟動平台（pump.fun、Raydium 的 UI、第三方啟動板）用來新增其費用、領取畢業後 LP 的一部分、限制其啟動可選擇的曲線形狀，以及在鏈上顯示其品牌（名稱、網站、圖片）的方式。
</Info>

## 它是什麼

一個 `PlatformConfig` 帳戶為平台擁有四個跨領域的關注點：

1. **品牌** — 名稱、網站、圖片連結，全部內聯儲存，讓任何探索器或聚合器都能顯示啟動代幣的平台。
2. **平台費用** — 在協議 `trade_fee_rate` 之上額外收取的交易費用 (`fee_rate`)。累積到平台的 `platform_fee_wallet`。由 `GlobalConfig.max_share_fee_rate` 限制在 100 個基點。
3. **NFT 遷移拆分** — 三個整數 (`platform_scale`、`creator_scale`、`burn_scale`)，總和為 `RATE_DENOMINATOR_VALUE = 1_000_000`，將畢業後的 LP 分為三部分：一部分鑄造到平台 NFT 錢包、一部分到創作者 NFT 錢包、一部分燒毀（Burn & Earn）。僅在畢業目標為 CPMM 時有意義（`migrate_type = 1`）。
4. **曲線參數白名單** — 一個 `Vec<PlatformCurveParam>`，列出該平台允許的確切 `(supply, total_base_sell, total_quote_fund_raising, migrate_type, migrate_cpmm_fee_on, vesting_params...)` 組合。如果向量為空或所有條目都無效，則**任何**組合都允許；否則啟動必須完全匹配其中一個條目。

PDA 推導：

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

（請參閱原始碼中的 `create_platform_config` 以取得規範的種子列表。）

## 佈局

```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` 必須等於 `1_000_000`（由 `MigrateNftInfo::check` 驗證）。常見的生產環境拆分：

* `(0, 100_000, 900_000)` — 90% LP 燒毀，10% 給創作者。標準 pump 風格公平啟動。
* `(50_000, 100_000, 850_000)` — 小平台份額（5%）、10% 創作者、85% 燒毀。
* `(0, 0, 1_000_000)` — 完全燒毀，無 NFT 鑄造。嚴格「無內部人」啟動。

## 品牌欄位

`name`、`web` 和 `img` 是內聯字節陣列，用零填充至其大小常數。要將它們作為字符串讀取，請切片至第一個 `\0`：

```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");
}
```

常數刻意寬鬆（`name: 64`、`web: 256`、`img: 256`），讓平台能包含足夠的中繼資料供探索器和聚合器使用，無需涉及鏈下儲存。任何超過這些大小的內容會在 `CreatePlatformConfig` 時以 `InvalidInput` 回復。

## 費用機制

綁定到 `PlatformConfig` 的曲線上的交換收取三層分級費用：

```
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` 累積到協議的 `protocol_fee_owner`（通過 `CollectFee` 領取）。
* `platform_fee` 累積到每個平台的保險庫（通過 `ClaimPlatformFee` 或 `ClaimPlatformFeeFromVault` 領取；請參閱 [`instructions`](/zh-Hant/products/launchlab/instructions)）。
* `creator_fee` 累積到按創作者公鑰 + 報價代幣索引的每個創作者保險庫（通過 `ClaimCreatorFee` 領取）。

`creator_fee_rate` 由 `MAX_CREATOR_FEE_RATE = 5000`（50 個基點）限制。`fee_rate`（平台費用）由 `GlobalConfig.max_share_fee_rate` 限制在 `10000`（100 個基點）。

## NFT 遷移拆分（僅限 CPMM）

當啟動畢業到 CPMM（`migrate_type = 1`，由 `migrate_to_cpswap_wallet` 簽署）時，遷移指令將 `CPMM::InitializeWithPermission` 鑄造的 LP 代幣三等分：

```
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
```

平台和創作者份額由 LP 鎖定程式（`LockrWmn6K5twhz3y9w1dQERbmgSaRkfnTeTKbpofwE`）包裝成 **NFT** — NFT 持有者有權無限期地領取累積的 CPMM 費用，而無法提取底層流動性。有關畢業後的費用密鑰流程，請參閱 [`products/launchlab/creator-fees`](/zh-Hant/products/launchlab/creator-fees)。

燒毀份額以 `is_burn = true` 形式發送到鎖定程式，讓 LP 代幣永久無法訪問 — 它們保護池的價格下限，而無需向任何人支付費用。

當 `migrate_type = 0`（畢業到 AMM v4）時，NFT 拆分欄位被忽略，整個 LP 根據單獨的 AMM v4 端流程鎖定/燒毀。

## 曲線參數白名單

`curve_params: Vec<PlatformCurveParam>` 是平台限制其啟動可選擇的曲線形狀的機制。如果向量非空且至少有一個條目有效，程式在 `Initialize` 時強制啟動的參數完全匹配至少一個條目。

```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
}
```

每個欄位都有一個哨兵值，表示**萬用符** （任何值匹配）：`u64` 欄位為 `u64::MAX`、`u8` 欄位為 `u8::MAX`、供應/銷售/籌資欄位為 `0`。所有哨兵為 `BondingCurveParam` 是「允許任何項目」— 等同於空白名單行為。

`Initialize` 時的匹配演算法：

1. 將 `curve_params` 篩選為 `global_config` 與啟動選擇的 `GlobalConfig` 相符的條目。
2. 如果篩選列表為空，允許任何參數（平台未為此 `GlobalConfig` 列入白名單任何內容）。
3. 如果篩選列表中的每個條目都有 `all_is_invalid()`（每個欄位都是萬用符），允許任何參數。
4. 否則迭代條目；對於每個條目，針對每個非萬用符欄位檢查啟動的參數。如果所有非萬用符欄位匹配，接受並返回。
5. 如果沒有條目匹配，以 `InvalidInput` 回復。

這讓平台可以說「我們只允許標準 1B 供應量/ 800M 售出/ 30k USDC 籌資/無質押形狀」，只需寫一個為這四個欄位具有具體值、其他地方為萬用符的條目。或者更嚴格的平台可能會列舉三到四個離散形狀，每個支持的啟動層級一個。

`MAX_CURVE_PARAMS = 10` 限制白名單大小。

## `PlatformGlobalAccess` — 授權平台

當 `GlobalConfig` 具有 `requires_platform_auth = 1` 時，針對它的每個 `Initialize` 都必須包含一個 `PlatformGlobalAccess` PDA，證明平台已獲得預授權：

```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],
}
```

PDA 種子：`[b"platform_global_access", global_config, platform_config]`。

協議管理員為每個 `(GlobalConfig, PlatformConfig)` 對通過 `CreatePlatformGlobalAccess` 創建一個，並通過 `ClosePlatformGlobalAccess` 撤銷。沒有此帳戶，啟動無法從閘控平台綁定到該 `GlobalConfig`。

## 讀取路徑

```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);
```

對於顯示「此代幣是從哪裡啟動的」的 UI，`PoolState.platform_config` 直接指向原始 `PlatformConfig` — 拿取一次並緩存品牌。

## 更新路徑

| 指令                          | 誰簽署                   | 什麼變更                                                        |
| --------------------------- | --------------------- | ----------------------------------------------------------- |
| `CreatePlatformConfig`      | 平台管理員（一次性）            | 使用 `PlatformParams` 初始化帳戶。                                  |
| `UpdatePlatformConfig`      | 平台管理員                 | 由 `param: u8` 索引的通用調度；每次調用修改一個欄位。品牌欄位、費率、質押錢包和各種錢包都可通過此設定。  |
| `UpdatePlatformCurveParam`  | 平台管理員                 | 按 `(global_config, index)` 新增或替換一個 `PlatformCurveParam` 條目。 |
| `RemovePlatformCurveParam`  | 平台管理員                 | 清除一個條目（將其設為全哨兵 = 萬用符）。                                      |
| `ClaimPlatformFee`          | `platform_fee_wallet` | 從 `PoolState.quote_vault` 掃除每個池的平台費用。                       |
| `ClaimPlatformFeeFromVault` | `platform_fee_wallet` | 掃除每個平台的費用保險庫（PDA 在 `[platform_config, quote_mint]`）。        |

錢包輪換（`platform_fee_wallet`、`platform_nft_wallet`、`platform_vesting_wallet`、`platform_cp_creator`、`transfer_fee_extension_auth`、`cpswap_config`）都通過 `UpdatePlatformConfig` 進行。請讀原始碼的 `update_platform_config` 調度表以取得確切的 `param` 代碼。

## 常見陷阱

* **白名單哨兵設置錯誤。** 具有 `total_locked_amount = 0` 的 `BondingCurveParam` *不是*萬用符 — 它匹配明確選擇退出質押的啟動。該欄位的萬用符是 `u64::MAX`。對 `cliff_period` 和 `unlock_period` 也存在相同陷阱。使用 `clear()`（程式公開）正確設定哨兵。
* **NFT 拆分舍入。** 三個標度必須恰好加起來為 `1_000_000`。`CreatePlatformConfig` 時的差一錯誤會回復；執行時的差一會鑄造或燒毀一個額外的 LP 單位，這正是嚴格相等檢查所防止的。
* **平台質押雙重分配。** 如果 `platform_vesting_scale > 0`，平台必須在啟動籌資結束後調用 `CreatePlatformVestingAccount` 一次；如果遺漏，該份額將保持未分配和休眠狀態（啟動的 `total_locked_amount` 預算已消耗但平台永遠無法領取）。
* **`platform_cp_creator` 歧義。** 當設置為 `Pubkey::default()` 時，啟動創作者被記錄為畢業後 CPMM 池的 `pool_creator`；當設置為真實密鑰時，該密鑰被記錄。這影響後來誰可以調用 `CPMM::CollectCreatorFee`。在平台配置創建時決定你想要哪種模型。

## 指標

* [`products/launchlab/global-config`](/zh-Hant/products/launchlab/global-config) — 啟動必須滿足的協議端規則。
* [`products/launchlab/vesting`](/zh-Hant/products/launchlab/vesting) — `platform_vesting_scale` 機制。
* [`products/launchlab/creator-fees`](/zh-Hant/products/launchlab/creator-fees) — 費用密鑰 NFT、Burn & Earn。
* [`products/launchlab/platforms`](/zh-Hant/products/launchlab/platforms) — 平台整合者使用指南。

來源：

* `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`。
