메인 콘텐츠로 건너뛰기

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.

이 페이지는 AI 자동 번역입니다. 모든 내용은 영문판을 기준으로 합니다.영문판 보기 →
PlatformConfigGlobalConfig 위에 겹쳐있는 플랫폼 수준 설정입니다. GlobalConfig가 프로토콜 전체 규칙을 정의한다면 (“거래 수수료는 1%, 공급량은 최소 10M, 지정된 지갑만 졸업 가능”), PlatformConfig는 각 론칭 플랫폼(pump.fun, Raydium의 자체 UI, 제3자 론칭패드)이 자신의 수수료를 추가하고, 졸업 후 LP의 지분을 청구하고, 론칭할 수 있는 곡선 형태를 제한하고, 온체인에 자신의 브랜딩(이름, 웹사이트, 이미지)을 표시하는 데 사용합니다.

개요

PlatformConfig 계정은 플랫폼을 위한 네 가지 핵심 관심사를 관리합니다:
  1. 브랜딩 — 이름, 웹사이트, 이미지 링크는 모두 인라인으로 저장되어 탐색기나 애그리게이터가 토큰을 론칭한 플랫폼을 표시할 수 있습니다.
  2. 플랫폼 수수료 — 프로토콜 trade_fee_rate에 추가되는 거래 수수료(fee_rate). 플랫폼의 platform_fee_wallet으로 누적됩니다. GlobalConfig.max_share_fee_rate에 의해 100 bps로 상한이 정해집니다.
  3. NFT 마이그레이션 분배RATE_DENOMINATOR_VALUE = 1_000_000으로 합산되는 세 정수(platform_scale, creator_scale, burn_scale)로, 졸업 후 LP를 플랫폼 NFT 지갑에 민트된 부분, 크리에이터 NFT 지갑에 민트된 부분, 그리고 소각되는 부분(Burn & Earn)으로 분할합니다. 졸업이 CPMM을 대상으로 할 때만 의미가 있습니다(migrate_type = 1).
  4. 곡선 매개변수 화이트리스트 — 이 플랫폼에서 허용되는 정확한 (supply, total_base_sell, total_quote_fund_raising, migrate_type, migrate_cpmm_fee_on, vesting_params...) 조합을 나열하는 Vec<PlatformCurveParam>. 벡터가 비어있거나 모든 항목이 유효하지 않으면 모든 조합이 허용됩니다. 그 외에는 론칭이 항목 중 하나와 정확히 일치해야 합니다.
PDA 도출:
const [platformConfigPda] = PublicKey.findProgramAddressSync(
  [
    Buffer.from("platform_config"),
    platformAdmin.toBuffer(),       // platform's owning pubkey
  ],
  LAUNCHLAB_PROGRAM_ID,
);
(정식 시드 목록은 소스의 create_platform_config를 참조하세요.)

레이아웃

// 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_scale1_000_000과 같아야 합니다(MigrateNftInfo::check에 의해 검증). 실제 환경에서 자주 보이는 분배:
  • (0, 100_000, 900_000) — LP의 90% 소각, 10%는 크리에이터에게. 표준 pump 스타일의 공정한 론칭.
  • (50_000, 100_000, 850_000) — 작은 플랫폼 지분(5%), 10% 크리에이터, 85% 소각.
  • (0, 0, 1_000_000) — 전체 소각, NFT 민팅 없음. 엄격한 “인사자 제외” 론칭.

브랜딩 필드

name, web, img는 크기 상수까지 0으로 패딩된 인라인 바이트 배열입니다. 이들을 문자열로 읽으려면 첫 \0까지 슬라이싱하세요:
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). 플랫폼이 오프체인 저장소에 의존하지 않고도 탐색기와 애그리게이터를 위한 충분한 메타데이터를 포함할 수 있습니다. 이 크기를 초과하는 것은 InvalidInput으로 CreatePlatformConfig에서 되돌아갑니다.

수수료 메커니즘

곡선에 바인드된 스왑은 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 참조).
  • creator_fee는 크리에이터 공개키 + 견적 민트로 키지된 크리에이터당 금고로 누적됩니다(ClaimCreatorFee를 통해 청구).
creator_fee_rateMAX_CREATOR_FEE_RATE = 5000(50 bps)에 의해 상한이 정해집니다. fee_rate(플랫폼 수수료)는 GlobalConfig.max_share_fee_rate에 의해 10000(100 bps)으로 상한이 정해집니다.

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-Lock 프로그램(LockrWmn6K5twhz3y9w1dQERbmgSaRkfnTeTKbpofwE)에 의해 NFT로 래핑됩니다. NFT의 소유자는 기본 유동성을 인출할 수 없으면서도 무한정 누적된 CPMM 수수료를 청구할 자격이 있습니다. products/launchlab/creator-fees에서 졸업 후 Fee Key 흐름을 참조하세요. 소각 부분은 Lock 프로그램에 is_burn = true로 전송되어 LP 토큰에 영구적으로 접근할 수 없게 되므로, 누구에게도 수수료를 반환하지 않으면서 풀의 가격 하한을 보호합니다. migrate_type = 0(AMM v4로 졸업)일 때, NFT 분배 필드는 무시되고 전체 LP는 별도의 AMM v4 쪽 흐름에 따라 잠금/소각됩니다.

곡선 매개변수 화이트리스트

curve_params: Vec<PlatformCurveParam>은 플랫폼이 자신의 론칭이 선택할 수 있는 곡선 형태를 제한하는 메커니즘입니다. 벡터가 비어있지 않고 최소한 하나의 항목이 유효하면, 프로그램은 Initialize에서 론칭의 매개변수가 정확히 하나의 항목과 일치하는지 강제합니다.
#[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, supply/sell/fund-raising 필드의 경우 0. 모든 센티널이 포함된 BondingCurveParam는 “무엇이든 허용” — 빈 화이트리스트 동작과 동등합니다. Initialize에서의 일치 알고리즘:
  1. curve_paramsglobal_config이 론칭의 선택한 GlobalConfig과 일치하는 항목으로 필터링합니다.
  2. 필터링된 목록이 비어있으면, 모든 매개변수를 허용합니다(플랫폼이 이 GlobalConfig에 대해 화이트리스트를 설정하지 않음).
  3. 필터링된 목록의 모든 항목이 all_is_invalid()이면(모든 필드가 와일드카드), 모든 매개변수를 허용합니다.
  4. 그 외에는 항목을 반복합니다. 각 항목에 대해 론칭의 매개변수를 모든 비-와일드카드 필드와 확인합니다. 모든 비-와일드카드 필드가 일치하면 수락하고 반환합니다.
  5. 일치하는 항목이 없으면 InvalidInput으로 되돌아갑니다.
이를 통해 플랫폼은 “우리는 표준 1B-supply / 800M-sold / 30k-USDC-raise / no-vesting 형태만 허용합니다”라고 네 필드에 구체적인 값과 다른 곳에 와일드카드를 작성하여 단일 항목으로 표현할 수 있습니다. 또는 더 엄격한 플랫폼은 지원되는 론칭 계층당 세 개 또는 네 개의 이산 형태를 열거할 수 있습니다. MAX_CURVE_PARAMS = 10은 화이트리스트 크기를 제한합니다.

PlatformGlobalAccess — 플랫폼 인증

GlobalConfigrequires_platform_auth = 1을 가질 때, 이에 대한 모든 Initialize는 플랫폼이 사전 승인되었음을 증명하는 PlatformGlobalAccess PDA를 포함해야 합니다:
// 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]. 프로토콜 어드민은 CreatePlatformGlobalAccess를 통해 (GlobalConfig, PlatformConfig) 쌍당 하나씩 생성하고 ClosePlatformGlobalAccess를 통해 취소합니다. 이 계정이 없으면 론칭은 게이트된 플랫폼에서 해당 GlobalConfig에 바인드될 수 없습니다.

읽기 경로

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플랫폼 어드민매개변수 u8로 키지된 일반 디스패치; 호출당 한 필드를 변경합니다. 브랜딩 필드, 수수료율, 베스팅 지갑, 그리고 여러 지갑이 모두 이를 통해 설정 가능합니다.
UpdatePlatformCurveParam플랫폼 어드민(global_config, index)로 하나의 PlatformCurveParam 항목을 추가하거나 교체합니다.
RemovePlatformCurveParam플랫폼 어드민하나의 항목을 지웁니다(모든 센티널 = 와일드카드로 설정).
ClaimPlatformFeeplatform_fee_walletPoolState.quote_vault에서 풀별 플랫폼 수수료를 매깭니다.
ClaimPlatformFeeFromVaultplatform_fee_wallet플랫폼별 수수료 금고(PDA at [platform_config, quote_mint])를 매깭니다.
지갑 로테이션(platform_fee_wallet, platform_nft_wallet, platform_vesting_wallet, platform_cp_creator, transfer_fee_extension_auth, cpswap_config)은 모두 UpdatePlatformConfig를 통해 이뤄집니다. 정확한 param 코드는 소스의 update_platform_config 디스패치 테이블을 읽으세요.

흔한 함정

  • 화이트리스트 센티널이 잘못 설정됨. total_locked_amount = 0BondingCurveParam은 와일드카드가 아닙니다 — 명시적으로 베스팅을 거절한 론칭과 일치합니다. 해당 필드의 와일드카드는 u64::MAX입니다. 같은 함정이 cliff_periodunlock_period에도 존재합니다. clear()(프로그램이 노출함)를 사용하여 센티널을 올바르게 설정하세요.
  • NFT 분배 반올림. 세 스케일은 정확히 1_000_000으로 합산되어야 합니다. CreatePlatformConfig의 1 오차는 되돌아갑니다. 런타임의 1 오차는 추가 LP 단위 하나를 민팅하거나 소각할 것이므로, 엄격한 등호 검사가 그것을 방지하기 위해 있습니다.
  • 플랫폼 베스팅 이중 할당. platform_vesting_scale > 0이면, 플랫폼은 론칭의 펀드레이징이 끝난 후 한 번 CreatePlatformVestingAccount를 호출해야 합니다. 잊으면, 그 지분은 할당되지 않고 영구적으로 비활성 상태입니다(론칭의 total_locked_amount 예산은 소비되지만 플랫폼은 절대 청구하지 않음).
  • platform_cp_creator 모호성. Pubkey::default()로 설정되면, 론칭 크리에이터는 졸업 후 CPMM 풀의 pool_creator로 기록됩니다. 실제 키로 설정되면, 그 키가 대신 기록됩니다. 이는 나중에 CPMM::CollectCreatorFee를 호출할 수 있는 사람에게 영향을 미칩니다. 플랫폼 설정 생성 시 어떤 모델을 원하는지 결정하세요.

참조

소스:
  • raydium-launch/programs/launchpad/src/states/platform_config.rsPlatformConfig, PlatformParams, MigrateNftInfo, PlatformCurveParam, BondingCurveParam, is_valid_curve_param.
  • raydium-launch/programs/launchpad/src/states/platform_global_access.rsPlatformGlobalAccess.
  • raydium-launch/programs/launchpad/src/lib.rscreate_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.