122 lines
6.0 KiB
Markdown
122 lines
6.0 KiB
Markdown
# SHINE Payments v2
|
||
|
||
## Назначение
|
||
|
||
`shine_payments` v2 — контракт очереди выплат с двумя очередями:
|
||
|
||
1. обычная покупка билета (очередь 1);
|
||
2. менеджерское добавление билетов (очередь 1 и очередь 2 по лимитам от DAO);
|
||
3. пошаговые выплаты из inflow-вольта с приоритетом очереди 1.
|
||
|
||
Сейчас тестовый этап в Devnet: расчеты и хранение в USD-центах (1 USD = 100), при этом реальные on-chain переводы выполняются в SOL по курсу Pyth SOL/USD.
|
||
|
||
## PDA
|
||
|
||
1. `config_pda` (`shine_payments_v3_config`)
|
||
- `dao_wallet`
|
||
- `manager_wallet` (сервисный параметр, для будущих сценариев)
|
||
- `inflow_vault`
|
||
|
||
2. `coef_limit_pda` (`shine_payments_v3_coef_limit`)
|
||
- `coef_ppm` (fixed-point, scale = 1_000_000)
|
||
- `limit_usd_cents` (лимит суммарной исторической суммы очереди 1 для обычной покупки)
|
||
- `call_reward_lamports` (награда за шаг выплат, максимум 0.01 SOL)
|
||
|
||
3. `queues_pda` (`shine_payments_v3_queues`)
|
||
- очередь 1: `tickets_total`, `tickets_paid`, `sum_total`, `sum_paid`
|
||
- очередь 2: `tickets_total`, `tickets_paid`, `sum_total`, `sum_paid`
|
||
|
||
4. `inflow_vault_pda` (`shine_payments_v3_inflow_vault`)
|
||
- входящий PDA-вольт программы для выплат.
|
||
|
||
5. `ticket_pda`
|
||
- очередь 1: `shine_payments_v3_q1_ticket + index_le_u64`
|
||
- очередь 2: `shine_payments_v3_q2_ticket + index_le_u64`
|
||
- поля тикета:
|
||
- `queue_id`
|
||
- `index`
|
||
- `is_paid`
|
||
- `recipient_wallet`
|
||
- `payout_usd_cents`
|
||
- `debt_before_usd_cents`
|
||
|
||
6. `manager_allowance_pda` (`shine_p_v3_manager_allow + manager_pubkey`)
|
||
- `manager_wallet`
|
||
- `q1_available_usd_cents`
|
||
- `q2_available_usd_cents`
|
||
|
||
## Методы
|
||
|
||
1. `init`
|
||
- вызывается один раз (кто угодно);
|
||
- создает `config_pda`, `coef_limit_pda`, `queues_pda`, `inflow_vault_pda`.
|
||
|
||
2. `update_coef_limit` (только `dao_wallet` из config)
|
||
- меняет коэффициент, лимит покупки в очередь 1 и награду шага выплат;
|
||
- ограничение награды: не более `0.01 SOL`.
|
||
|
||
3. `grant_manager_limits` (только `dao_wallet` из config)
|
||
- DAO выдает/добавляет лимиты менеджеру:
|
||
- `add_q1_usd_cents`
|
||
- `add_q2_usd_cents`
|
||
- если PDA менеджера нет — создается;
|
||
- если есть — лимиты увеличиваются.
|
||
|
||
4. `buy_ticket`
|
||
- обратная совместимость: покупка с входом в lamports, но запись тикета в USD-центах;
|
||
- использует Pyth SOL/USD и stale-check (не старше 120 секунд).
|
||
|
||
5. `buy_ticket_usd`
|
||
- покупка билета в очередь 1 с суммой в USD-центах;
|
||
- сумма SOL к оплате считается в контракте по Pyth;
|
||
- есть `max_pay_lamports` для slippage-защиты.
|
||
|
||
6. `buy_ticket_sol`
|
||
- покупка билета в очередь 1 с суммой в lamports;
|
||
- USD-объём покупки считается в контракте по Pyth;
|
||
- есть `min_expected_usd_cents` для slippage-защиты.
|
||
|
||
7. `manager_add_ticket`
|
||
- менеджер добавляет тикет в очередь 1 или 2;
|
||
- без денежного перевода;
|
||
- списывает лимит менеджера по выбранной очереди (в USD-центах).
|
||
|
||
8. `step_payout`
|
||
- выбирает очередь по приоритету:
|
||
1. сначала очередь 1;
|
||
2. если в 1-й нет ожидания — очередь 2.
|
||
- перед выплатой получает текущий SOL/USD из Pyth и проверяет stale.
|
||
- шаг выплаты:
|
||
- очередь 1: `X` получателю тикета + `X` в DAO + `reward` вызывающему;
|
||
- очередь 2: `X` получателю тикета + `2X` в DAO + `reward` вызывающему.
|
||
- если обе очереди пусты/выплачены:
|
||
- переводит весь доступный остаток inflow-вольта в DAO (без reward).
|
||
|
||
9. `change_ticket_recipient`
|
||
- текущий `recipient_wallet` тикета может сменить получателя на другой кошелек;
|
||
- тикет должен быть невыплаченным;
|
||
- смена запрещена, если этот тикет является следующим к выплате в текущем шаге
|
||
(с учетом приоритета очереди 1 над очередью 2).
|
||
|
||
10. Экономика покупки
|
||
- сумма покупки идет в DAO;
|
||
- тикет получает выплату `purchase_usd_cents * coef_ppm / 1_000_000`;
|
||
- проверка лимита выполняется по `q1_sum_total_usd_cents` (исторически накопленная сумма, без вычета уже выплаченного).
|
||
|
||
## Стартовые настройки
|
||
|
||
См. `programs/shine_payments/src/settings.rs`:
|
||
|
||
- `START_COEF_PPM = 5_000_000` (коэффициент 5.0)
|
||
- `START_LIMIT_USD_CENTS = 10_000 USD`
|
||
- `START_CALL_REWARD_LAMPORTS = 0.008 SOL`
|
||
- `ORACLE_MAX_AGE_SECS = 120`
|
||
- `PYTH_SOL_USD_FEED_ID`
|
||
- `PYTH_SOL_USD_ACCOUNT`
|
||
- `DAO_WALLET`
|
||
- `MANAGER_WALLET`
|
||
|
||
## Тестовый режим
|
||
|
||
Пока нет финального production-потока пополнения inflow из регистрации/экосистемы, inflow-вольт пополняется вручную в Devnet, после чего выполняются шаги выплат.
|