SHA256
174 lines
7.0 KiB
Markdown
174 lines
7.0 KiB
Markdown
# `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` остается открытым для любого подписанта, чтобы выплаты не зависели от одного оператора.
|