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.
Vesting is optional on a LaunchLab launch. Set
vesting_param.total_locked_amount = 0 at Initialize and the section below does not apply. Once enabled, the schedule is fixed for the launch’s lifetime; the cliff and unlock periods cannot be changed retroactively.Why vesting
The bonding curve sellsbase_supply_graduation tokens during fundraising and seeds the post-graduation pool with the remainder. Vesting carves an additional slice out of the supply, locks it for a configurable cliff, then releases it linearly to one or more beneficiaries — typically the creator’s team, advisors, or platform partners.
Practical use cases:
- Team allocation. A creator reserves, say, 5% of the supply for the founding team, locked for 6 months and unlocking linearly over the following 12 months.
- Platform allocation. A launch platform receives a slice of every token it lists, on the same schedule, via
CreatePlatformVestingAccount. - Advisor / contributor grants. Multiple beneficiaries with their own
VestingRecordaccounts, each tracking their own claimed amount independently.
base_vault until each beneficiary calls ClaimVestedToken.
Schedule shape
Vesting for a launch is described by three numbers, recorded once atInitialize time:
| Field | Type | Meaning |
|---|---|---|
total_locked_amount | u64 | Sum of all base tokens locked across all beneficiaries (creator + platform). Must satisfy total_locked_amount <= supply * max_lock_rate / 1_000_000 from the binding GlobalConfig. |
cliff_period | u64 (seconds) | Wait time after fundraising ends before any tokens unlock. |
unlock_period | u64 (seconds) | Duration of the linear unlock window after the cliff. 0 means everything unlocks instantly at the end of the cliff. |
PoolState.vesting_schedule (a VestingSchedule struct) plus the on-chain start_time, which the program records as block_time + cliff_period at the moment fundraising successfully ends (when graduation conditions are first met).
allocated_share_amount is the total amount already assigned to VestingRecord accounts via CreateVestingAccount / CreatePlatformVestingAccount. It must never exceed total_locked_amount. If a creator over-allocates, the next CreateVestingAccount call reverts with InvalidTotalLockedAmount.
Linear unlock formula
After fundraising ends, the program computes the cumulative unlocked amount for eachVestingRecord as:
unlock_period == 0, the entire token_share_amount becomes claimable in one step at start_time. Otherwise the curve is a straight line from 0 at start_time to token_share_amount at start_time + unlock_period, capped at token_share_amount thereafter.
The amount transferred on each ClaimVestedToken call is the delta between the freshly recomputed cumulative unlocked amount and the running claimed_amount field on the record.
start_time reverts with VestingNotStarted. A claim after start_time + unlock_period settles the full remainder.
Account layouts
VestingSchedule
Lives inline on PoolState. See accounts.
VestingRecord
Per-beneficiary record. PDA derived as:
VestingRecord per launch. Allocating again to the same beneficiary on the same launch reverts because the PDA already exists.
Instructions
CreateVestingAccount
Creator-only. Allocates a slice of the pool’s total_locked_amount to a new beneficiary by initializing a fresh VestingRecord PDA.
Arguments
| # | Name | W | S | Notes |
|---|---|---|---|---|
| 1 | creator | W | S | Must equal pool_state.creator; pays rent for the new account. |
| 2 | beneficiary | W | Receives the unlocked tokens later. The pubkey is locked in here — it cannot be changed. | |
| 3 | pool_state | W | Mutated to bump vesting_schedule.allocated_share_amount. | |
| 4 | vesting_record | W | init; PDA [b"pool_vesting", pool_state, beneficiary]. | |
| 5 | system_program | Required for account creation. |
share_amount > 0.pool_state.vesting_schedule.allocated_share_amount + share_amount <= total_locked_amount.- The
beneficiarypubkey has no existingVestingRecordfor this pool.
vesting_recordinitialized withtoken_share_amount = share_amount,claimed_amount = 0.pool_state.vesting_schedule.allocated_share_amount += share_amount.
InvalidTotalLockedAmount, InvalidInput.
CreatePlatformVestingAccount
Platform-admin variant of CreateVestingAccount. The platform’s vesting wallet (stored on PlatformConfig.platform_vesting_wallet) is the beneficiary, and the share is bounded by PlatformConfig.platform_vesting_scale.
The signer must equal platform_config.platform_vesting_wallet. Other accounts mirror CreateVestingAccount. Use this when a platform contracts to receive a fixed vesting share on every launch it lists.
ClaimVestedToken
Beneficiary-only. Transfers any newly-unlocked tokens from the pool’s base_vault to the beneficiary’s ATA.
Arguments
None (the program computes the claim amount from the schedule).
Accounts
| # | Name | W | S | Notes |
|---|---|---|---|---|
| 1 | beneficiary | W | S | Must equal vesting_record.beneficiary. |
| 2 | authority | PDA [b"vault_auth_seed"]; signs the vault transfer. | ||
| 3 | pool_state | W | Mutated only if the schedule needs to be re-validated. | |
| 4 | vesting_record | W | claimed_amount is updated. | |
| 5 | base_vault | W | Pool’s base-token vault; debited. | |
| 6 | beneficiary_ata | W | Receives the unlocked tokens; init_if_needed. | |
| 7 | base_mint | Pool’s base mint. | ||
| 8 | token_program | SPL Token or Token-2022 program. | ||
| 9 | associated_token_program | For ATA creation if needed. | ||
| 10 | system_program | Required for account creation. |
block_time >= pool_state.vesting_schedule.start_time(otherwiseVestingNotStarted).pool_state.status == PoolStatus::Migrated— graduation must have already happened. Calling before graduation reverts.- The unlocked-amount delta is greater than zero. A no-op call (computed delta is 0) reverts.
vesting_record.claimed_amountadvances to the new cumulative unlocked amount.delta_amountof base token is transferred tobeneficiary_ata.
VestingNotStarted, NoAssetsToCollect, MathOverflow.
Worked example
A launch sets:supply = 1_000_000_000total_locked_amount = 100_000_000(10% of supply)cliff_period = 180 * 86400(180 days)unlock_period = 365 * 86400(1 year linear after the cliff)
VestingRecord accounts immediately after Initialize:
- Beneficiary A (team):
share_amount = 70_000_000 - Beneficiary B (advisor):
share_amount = 30_000_000
allocated_share_amount = 100_000_000, equal to total_locked_amount — no further allocations possible.
Fundraising completes on 2027-01-01T00:00Z. The program sets start_time = 2027-01-01 + 180 days = 2027-06-30.
On 2027-09-30 (90 days after start_time), Beneficiary A calls ClaimVestedToken:
vesting_record.claimed_amount advances to 17_260_274.
Six months later (2028-03-31, 270 days after start_time), A claims again:
2028-06-30 (the end of unlock_period), the next claim transfers the remaining ~18.22M and leaves claimed_amount == token_share_amount.
Edge cases
- Beneficiary loses their key. The pubkey on
VestingRecord.beneficiaryis the only signer that can callClaimVestedToken. There is no recovery path. Set the beneficiary to a multisig if recovery matters. - Token-2022 transfer fees. If the base mint is a Token-2022 mint with a transfer-fee extension, the beneficiary receives
delta_amount − transfer_fee, not the full delta. The pool’s vault still records the gross amount as transferred — the difference accrues to the mint’s withheld-fee account. - Pool not graduated. Calling
ClaimVestedTokenbefore graduation reverts. The vesting clock starts only when fundraising actually completes; an aborted launch (which never setsstart_time) leaves locked tokens unreachable in the vault. - Over-allocation attempts. The program enforces
allocated_share_amount <= total_locked_amounton everyCreateVestingAccount. The remainder (if any) oftotal_locked_amountleft unallocated is lost — those tokens stay in the vault forever once the launch graduates. Allocate the full amount unless that’s the intent.
Pointers
products/launchlab/accounts— fullPoolStatelayout includingVestingSchedule.products/launchlab/instructions— graduation lifecycle.products/launchlab/platform-config—platform_vesting_scalesemantics for platform allocations.products/launchlab/global-config—max_lock_rateceiling that boundstotal_locked_amount.
raydium-launch/programs/launchpad/src/states/vesting.rs—VestingRecord.raydium-launch/programs/launchpad/src/states/pool.rs—VestingSchedule,VestingParams,is_vesting_started,vesting_end_time.raydium-launch/programs/launchpad/src/instructions/create_vesting_account.rs.raydium-launch/programs/launchpad/src/instructions/claim_vested_token.rs.


