chore: зафиксированы все текущие изменения проекта

This commit is contained in:
AidarKC
2026-05-25 23:46:54 +03:00
parent 8c5de781ea
commit 8941582d54
53 changed files with 2303 additions and 106 deletions
@@ -0,0 +1,173 @@
# `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` остается открытым для любого подписанта, чтобы выплаты не зависели от одного оператора.