Skip to main content
PlatformConfig is the platform-level overlay that sits on top of GlobalConfig. Where GlobalConfig defines the protocol-wide rules (“trade fee is 1%, supply must be at least 10M, only this wallet can graduate”), PlatformConfig is what each launch platform — pump.fun, Raydium’s own UI, third-party launchpads — uses to add their fee, claim their slice of post-graduation LP, restrict which curve shapes their launches can pick, and surface their branding (name, website, image) on-chain.

What it is

A PlatformConfig account owns five cross-cutting concerns for a platform:
  1. Branding — name, website, image link, all stored inline so any explorer or aggregator can display the platform that launched a token.
  2. Platform fee — an extra trade fee (fee_rate) on top of the protocol’s trade_fee_rate. Accrues to the platform’s platform_fee_wallet. Capped at 100 bps by GlobalConfig.max_share_fee_rate.
  3. LP migration split — three stored integers (platform_scale, creator_scale, burn_scale) that sum to 1_000_000. Before the 2026-08-17 upgrade, the creator scale produced a separate creator Fee Key. Migrations executed after the upgrade combine the first two into one platform-owned locked-LP share; the remainder is burned.
  4. Curve-parameter whitelist — a Vec<PlatformCurveParam> listing exactly which (supply, total_base_sell, total_quote_fund_raising, migrate_type, migrate_cpmm_fee_on, vesting_params...) combinations are permitted on this platform. If the vector is empty or all entries are invalid, any combination is allowed; otherwise launches must match one of the entries exactly.
  5. Global-config allowlist — an opt-in restriction that requires a platform-created PlatformAllowConfig for the selected GlobalConfig.
PDA derivation:
(See create_platform_config in the source for the canonical seed list.)

Layout

platform_scale + creator_scale + burn_scale must equal 1_000_000. Before the 2026-08-17 upgrade, creator_scale was locked separately and its Fee Key went to the token creator. For migrations executed after the upgrade, it is added to platform_scale and its locked-LP rights go to the platform instead. Example outcomes under the updated logic:
  • (0, 100_000, 900_000) — 90% LP burned, 10% locked to the platform.
  • (50_000, 100_000, 850_000) — 85% burned, 15% locked to the platform.
  • (0, 0, 1_000_000) — full burn, no NFT mints. Strict “no insiders” launches.

Branding fields

name, web, and img are inline byte arrays padded with zeros up to their size constants. To read them as strings, slice up to the first \0:
The constants are deliberately generous (name: 64, web: 256, img: 256) so platforms can include enough metadata for explorers and aggregators without touching off-chain storage. Anything that exceeds these sizes reverts at CreatePlatformConfig with InvalidInput.

Fee mechanics

A swap on a curve bound to a PlatformConfig charges three layered fees:
  • trade_fee accrues to the protocol’s protocol_fee_owner (claimed via CollectFee).
  • platform_fee accrues to a per-platform vault (claimed via ClaimPlatformFee or ClaimPlatformFeeFromVault; see instructions).
  • creator_fee accrues to a per-creator vault keyed by the creator’s pubkey + quote mint (claimed via ClaimCreatorFee).
creator_fee_rate is capped by MAX_CREATOR_FEE_RATE = 5000 (50 bps). fee_rate (the platform fee) is capped at 10000 (100 bps) by GlobalConfig.max_share_fee_rate.

NFT migration split (CPMM-only)

When a launch graduates to CPMM, the migration instruction splits the LP tokens minted by CPMM::InitializeWithPermission two ways:
If lp_to_platform is non-zero, the LP-Lock program wraps it into one Fee Key NFT owned by platform_nft_wallet. This replaces the pre-upgrade behavior that created separate platform and creator Fee Keys. Fee Keys created by migrations completed before the upgrade remain unchanged. This LP-fee right is separate from CPMM creator fees controlled by platform_cp_creator. The burn slice is burned directly, so no account can withdraw it or claim the LP fees represented by that share. Existing launches with stored migrate_type = 0 can still use the legacy AMM v4 path. New initialization rejects that migrate type.

Curve-parameter whitelist

curve_params: Vec<PlatformCurveParam> is the platform’s mechanism for restricting which curve shapes its launches can pick. If the vector is non-empty and at least one entry is valid, the program enforces at Initialize that the launch’s parameters match at least one entry exactly.
Each field has a sentinel value that means wildcard (any value matches): u64::MAX for the u64 fields, u8::MAX for the u8 fields, 0 for the supply / sell / fund-raising fields. A BondingCurveParam with all sentinels is “allow anything” — equivalent to the empty-whitelist behaviour. The matching algorithm at Initialize:
  1. Filter curve_params to entries whose global_config matches the launch’s chosen GlobalConfig.
  2. If the filtered list is empty, allow any params (the platform did not whitelist anything for this GlobalConfig).
  3. If every entry in the filtered list has all_is_invalid() (every field is the wildcard), allow any params.
  4. Otherwise iterate entries; for each entry, check the launch’s params against every non-wildcard field. If all non-wildcard fields match, accept and return.
  5. If no entry matched, revert with InvalidInput.
This lets a platform say “we only allow the standard 1B-supply / 800M-sold / 30k-USDC-raise / no-vesting shape” by writing a single entry with concrete values for those four fields and wildcards everywhere else. Or a stricter platform might enumerate three or four discrete shapes, one per supported launch tier. MAX_CURVE_PARAMS = 10 caps the whitelist size.

PlatformAllowConfig — restricting a platform

Each platform decides whether to restrict which GlobalConfig accounts its launches may use. Set restrict_global_config with UpdatePlatformConfig::RestrictGlobalConfig(0 | 1).
PDA seeds: [b"platform_allow_config", platform_config, global_config]. The platform admin creates or closes one account per allowed pair via CreatePlatformAllowConfig and ClosePlatformAllowConfig. When restriction is 1, initialization searches remaining_accounts for the expected PDA and rejects a missing account with NotEnoughRemainingAccounts. When restriction is 0, no allow account is required. The former protocol-admin-managed PlatformGlobalAccess account and its create/close instructions are retired. Existing PlatformConfig and GlobalConfig sizes do not change, but decoders must replace the old global flag with the new platform flag. Old access PDAs are not consumed by the new check.

Read path

For a UI showing “where did this token launch from”, PoolState.platform_config points at the originating PlatformConfig directly — fetch it once and cache the branding.

Update path

Wallet rotations (platform_fee_wallet, platform_nft_wallet, platform_vesting_wallet, platform_cp_creator, transfer_fee_extension_auth, cpswap_config) all go through UpdatePlatformConfig. Read the source’s update_platform_config dispatch table for the exact param codes.

Common pitfalls

  • Whitelist sentinels mis-set. A BondingCurveParam with total_locked_amount = 0 is not a wildcard — it matches launches that explicitly opt out of vesting. The wildcard for that field is u64::MAX. The same trap exists for cliff_period and unlock_period. Use clear() (which the program exposes) to set sentinels correctly.
  • NFT-split rounding. The three scales must sum to exactly 1_000_000. Off-by-one errors at CreatePlatformConfig revert; off-by-one at runtime would mint or burn one extra LP unit, which is what the strict-equality check is there to prevent.
  • Platform vesting double-allocation. If platform_vesting_scale > 0, the platform must call CreatePlatformVestingAccount once after the launch’s fundraising ends; if it forgets, that share remains unallocated and dormant forever (the launch’s total_locked_amount budget is consumed but the platform never claims).
  • platform_cp_creator ambiguity. When set to Pubkey::default(), the launch creator is recorded as the post-graduation CPMM pool’s pool_creator; when set to a real key, that key is recorded instead. This determines the beneficiary of post-graduation CPMM creator fees and who can sign the original CPMM::CollectCreatorFee path. The permissionless collection path still pays this recorded key’s canonical ATAs. Decide at platform-config creation time which model you want.
  • Restriction without an allow account. Enabling restrict_global_config before creating the required PlatformAllowConfig blocks new launches that select that config.

Pointers

Sources:
  • raydium-launch/programs/launchpad/src/states/platform_config.rsPlatformConfig, PlatformParams, MigrateNftInfo, PlatformCurveParam, BondingCurveParam, is_valid_curve_param.
  • raydium-launch/programs/launchpad/src/states/platform_allow_config.rsPlatformAllowConfig.
  • raydium-launch/programs/launchpad/src/lib.rs — platform config and allow-config entrypoints.