# `shine_payments` ## Кратко `shine_payments` — третья программа Solana-модуля SHiNE. Она отвечает за vault входящих средств, DAO-казну, покупку тикетов, менеджерские лимиты, очереди выплат и пошаговое исполнение выплат. Папка программы: `shine-solana/shine/programs/shine_payments/`. ## Текущие функции 1. `init` - Создает основные PDA: `config_pda`, `coef_limit_pda`, `queues_pda`, `inflow_vault_pda`. - Записывает `dao_wallet` и стартовые параметры выплат. 2. `update_coef_limit` - Обновляет коэффициент выплаты, лимит очереди и награду вызвавшему `step_payout`. - Требует подпись DAO-кошелька из `ConfigState`. 3. `grant_manager_limits` - DAO выдает менеджеру лимиты на создание тикетов в очередях Q1/Q2. - Создает или обновляет `manager_allowance_pda`. 4. `buy_ticket` - Покупка тикета с суммой в lamports, пересчетом через Pyth SOL/USD. 5. `buy_ticket_usd` - Покупка тикета от USD-центов с защитой по максимальному платежу в lamports. 6. `buy_ticket_sol` - Покупка тикета в lamports с проверкой минимального ожидаемого USD-эквивалента. 7. `manager_add_ticket` - Менеджер создает тикет за счет выданного ему DAO-лимита. 8. `step_payout` - Любой подписант может вызвать шаг выплат. - Программа выплачивает следующий тикет, DAO-часть и награду вызывающему. 9. `change_ticket_recipient` - Текущий получатель тикета может поменять адрес получателя, если тикет еще не следующий на выплату. ## Аргументы инструкций `init` аргументов не принимает. `update_coef_limit`: - `coef_ppm: u64` - `limit_usd_cents: u64` - `call_reward_lamports: u64` `grant_manager_limits`: - `manager_wallet: Pubkey` - `add_q1_usd_cents: u64` - `add_q2_usd_cents: u64` `buy_ticket`: - `amount_lamports: u64` - `recipient_wallet: Pubkey` `buy_ticket_usd`: - `amount_usd_cents: u64` - `max_pay_lamports: u64` - `recipient_wallet: Pubkey` `buy_ticket_sol`: - `amount_lamports: u64` - `min_expected_usd_cents: u64` - `recipient_wallet: Pubkey` `manager_add_ticket`: - `queue_id: u8` — только `1` или `2` - `recipient_wallet: Pubkey` - `payout_usd_cents: u64` `change_ticket_recipient`: - `new_recipient_wallet: Pubkey` ## Главные PDA 1. `config_pda` - Seed: `shine_payments_config`. - Хранит `dao_wallet` и `inflow_vault`. - Размер PDA: `8 + 160` байт. 2. `coef_limit_pda` - Seed: `shine_payments_coef_limit`. - Хранит коэффициент выплат, лимит и награду `step_payout`. - Размер PDA: `8 + 96` байт. 3. `queues_pda` - Seed: `shine_payments_queues`. - Хранит агрегаты очередей Q1/Q2. - Размер PDA: `8 + 192` байт. 4. `inflow_vault_pda` - Seed: `shine_payments_inflow_vault`. - Принимает деньги от `shine_users`. - Из него выполняются выплаты тикетам, DAO и вызывающему `step_payout`. - Размер PDA: `8 + 32` байт. 5. `ticket_pda` - Seed зависит от очереди и индекса тикета. - Отдельная PDA-запись на каждый тикет. - Q1 seed: `shine_payments_q1_ticket` + `ticket_index`. - Q2 seed: `shine_payments_q2_ticket` + `ticket_index`. - Размер PDA: `8 + 160` байт. 6. `manager_allowance_pda` - Seed: `shine_p_manager_allow` + адрес менеджера. - Хранит доступный лимит менеджера по Q1/Q2. - Размер PDA: `8 + 128` байт. ## Текущие параметры Параметры initial config из `programs/shine_payments/src/settings.rs`: | Поле | Значение | Смысл | | --- | --- | --- | | `START_COEF_PPM` | `5_000_000` | коэффициент 5.0x в ppm-масштабе | | `START_LIMIT_USD_CENTS` | `1_000_000` | стартовый лимит Q1: 10_000 USD | | `START_CALL_REWARD_LAMPORTS` | `8_000_000` | награда вызвавшему `step_payout`, 0.008 SOL | | `MAX_CALL_REWARD_LAMPORTS` | `10_000_000` | максимум награды, 0.01 SOL | | `ORACLE_MAX_AGE_SECS` | `120` | максимальный возраст цены Pyth | Для расчетов используется Pyth SOL/USD: - feed id: `0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d` - price update account: `7UVimffxr9ow1uXYxsr4LHAcV58mLzhmwaeKvJ1pjLiE` ## Деньги Входы: - из `shine_users` в `inflow_vault_pda` при регистрации и увеличении лимита; - от покупателя тикета сразу в `dao_wallet` при `buy_ticket*`. Выходы: - из `inflow_vault_pda` получателю тикета; - из `inflow_vault_pda` в `dao_wallet`; - из `inflow_vault_pda` вызвавшему `step_payout`; - если очереди пустые, весь доступный остаток `inflow_vault_pda` переводится в DAO. ## Очереди и выплаты Выплаты идут строго пошагово: - если есть невыплаченные Q1-тикеты, `step_payout` берет следующий Q1; - если Q1 пустая, берется следующий Q2; - для Q1 DAO-часть равна сумме тикета в USD; - для Q2 DAO-часть равна двойной сумме тикета в USD; - перед выплатой суммы пересчитываются из USD-центов в lamports по Pyth SOL/USD; - если в `inflow_vault_pda` не хватает средств на тикет, DAO-часть и награду вызвавшему, шаг отклоняется. `change_ticket_recipient` запрещает менять получателя у тикета, который является следующим на выплату. ## Ключи и управление На старте удобно считать, что у программы есть отдельный управляющий ключ `key_3`. Целевая модель: - `update_coef_limit` вызывает DAO; - `grant_manager_limits` вызывает DAO; - upgrade-authority программы после проверки передается DAO; - `step_payout` остается открытым для любого подписанта, чтобы выплаты не зависели от одного оператора.