Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
Вестинг опционален при запуске LaunchLab. Установите
vesting_param.total_locked_amount = 0 при инициализации, и раздел ниже не применяется. После активации график фиксируется на весь жизненный цикл запуска; cliff и периоды разблокировки не могут быть изменены задним числом.Зачем нужен вестинг
Bonding curve продаётbase_supply_graduation токенов во время сбора средств и засевает постградуальный пул оставшимся количеством. Вестинг выделяет дополнительную часть предложения, блокирует её на настраиваемый cliff, а затем линейно высвобождает её одному или нескольким получателям — обычно команде создателя, советникам или партнёрам платформы.
Практические варианты использования:
- Распределение команде. Создатель резервирует, скажем, 5% предложения для основной команды, заблокированное на 6 месяцев и разблокировавшееся линейно в течение следующих 12 месяцев.
- Распределение платформе. Платформа запуска получает часть каждого токена, который она перечисляет, по той же схеме, через
CreatePlatformVestingAccount. - Гранты советникам и участникам. Несколько получателей с собственными аккаунтами
VestingRecord, каждый отслеживающий свою заявленную сумму независимо.
base_vault пула до тех пор, пока каждый получатель не вызовет ClaimVestedToken.
Форма графика
Вестинг для запуска описывается тремя числами, записанными один раз во время инициализации:
Эти три значения находятся на
PoolState.vesting_schedule (структура VestingSchedule) плюс on-chain start_time, который программа записывает как block_time + cliff_period в момент, когда сбор средств успешно заканчивается (когда условия выпуска впервые выполняются).
allocated_share_amount — это общая сумма, уже назначенная аккаунтам VestingRecord через CreateVestingAccount / CreatePlatformVestingAccount. Она никогда не должна превышать total_locked_amount. Если создатель переалоцирует, следующий вызов CreateVestingAccount вернёт ошибку InvalidTotalLockedAmount.
Формула линейной разблокировки
После окончания сбора средств программа вычисляет совокупную разблокированную сумму для каждогоVestingRecord как:
unlock_period == 0, весь token_share_amount становится требуемым в один шаг в start_time. В противном случае кривая представляет собой прямую линию от 0 в start_time до token_share_amount в start_time + unlock_period, ограниченную token_share_amount впоследствии.
Сумма, переведённая при каждом вызове ClaimVestedToken, — это разница между вновь рассчитанной совокупной разблокированной суммой и текущим полем claimed_amount в записи.
start_time вернёт ошибку VestingNotStarted. Получение после start_time + unlock_period выплатит полный остаток.
Схемы аккаунтов
VestingSchedule
Находится inline на PoolState. См. accounts.
VestingRecord
Запись для каждого получателя. PDA получен как:
VestingRecord для каждого запуска. Алоцирование снова одному и тому же получателю при одном запуске вернёт ошибку, так как PDA уже существует.
Инструкции
CreateVestingAccount
Только создатель. Выделяет часть total_locked_amount пула новому получателю путём инициализации свежего PDA VestingRecord.
Аргументы
Предусловия
share_amount > 0.pool_state.vesting_schedule.allocated_share_amount + share_amount <= total_locked_amount.- Pubkey
beneficiaryне имеет существующегоVestingRecordдля этого пула.
vesting_recordинициализирован сtoken_share_amount = share_amount,claimed_amount = 0.pool_state.vesting_schedule.allocated_share_amount += share_amount.
InvalidTotalLockedAmount, InvalidInput.
CreatePlatformVestingAccount
Вариант CreateVestingAccount для администратора платформы. Кошелёк вестинга платформы (хранящийся на PlatformConfig.platform_vesting_wallet) является получателем, а доля ограничена PlatformConfig.platform_vesting_scale.
Подписавший должен равняться platform_config.platform_vesting_wallet. Другие аккаунты зеркалируют CreateVestingAccount. Используйте это, когда платформа контрактует получать фиксированную долю вестинга при каждом запуске, который она перечисляет.
ClaimVestedToken
Только получатель. Переводит любые вновь разблокированные токены из base_vault пула на ATA получателя.
Аргументы
Нет (программа вычисляет сумму претензии из графика).
Аккаунты
Предусловия
block_time >= pool_state.vesting_schedule.start_time(иначеVestingNotStarted).pool_state.status == PoolStatus::Migrated— выпуск должен был уже произойти. Вызов перед выпуском вернёт ошибку.- Дельта разблокированной суммы больше нуля. Холостой вызов (рассчитанная дельта 0) вернёт ошибку.
vesting_record.claimed_amountпереходит в новую совокупную разблокированную сумму.delta_amountбазового токена переводится наbeneficiary_ata.
VestingNotStarted, NoAssetsToCollect, MathOverflow.
Практический пример
Запуск устанавливает:supply = 1_000_000_000total_locked_amount = 100_000_000(10% предложения)cliff_period = 180 * 86400(180 дней)unlock_period = 365 * 86400(1 год линейно после cliff)
VestingRecord сразу же после инициализации:
- Получатель A (команда):
share_amount = 70_000_000 - Получатель B (советник):
share_amount = 30_000_000
allocated_share_amount = 100_000_000, равно total_locked_amount — дальнейшие алокации невозможны.
Сбор средств завершается на 2027-01-01T00:00Z. Программа устанавливает start_time = 2027-01-01 + 180 дней = 2027-06-30.
На 2027-09-30 (90 дней после start_time), получатель A вызывает ClaimVestedToken:
vesting_record.claimed_amount переходит к 17_260_274.
Шесть месяцев спустя (2028-03-31, 270 дней после start_time), A получает снова:
2028-06-30 (конец unlock_period), следующий вызов передаёт оставшиеся ~18,22 млн и оставляет claimed_amount == token_share_amount.
Граничные случаи
- Получатель потеряет ключ. Pubkey на
VestingRecord.beneficiary— единственный подписавший, который может вызватьClaimVestedToken. Пути восстановления нет. Установите получателя на multisig, если восстановление важно. - Комиссии за передачу Token-2022. Если базовый mint — это mint Token-2022 с расширением комиссии за передачу, получатель получает
delta_amount − transfer_fee, а не полную дельту. Хранилище пула всё ещё записывает валовую переданную сумму — разница начисляется на счёт удержанных комиссий mint. - Пул не выпущен. Вызов
ClaimVestedTokenперед выпуском вернёт ошибку. Часы вестинга начинают работать только когда сбор средств действительно завершится; отменённый запуск (который никогда не устанавливаетstart_time) оставляет заблокированные токены недостижимыми в хранилище. - Попытки переалокации. Программа устанавливает
allocated_share_amount <= total_locked_amountпри каждомCreateVestingAccount. Остаток (если есть) изtotal_locked_amount, оставшийся неалоцированным, теряется — эти токены остаются в хранилище навсегда после выпуска пула. Алоцируйте полную сумму, если это не намеренно.
Ссылки
products/launchlab/accounts— полная схемаPoolStateвключаяVestingSchedule.products/launchlab/instructions— жизненный цикл выпуска.products/launchlab/platform-config— семантикаplatform_vesting_scaleдля алокаций платформе.products/launchlab/global-config— потолокmax_lock_rate, ограничивающийtotal_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.

