SHiNE-server/Dev_Docs/Pending_Features/2026-06-11_payments-recipient-not-vault.md
AidarKC cf6a2830c8 solana: закрыть griefing создания PDA и заморозку выплат, добавить аудит №2
shine_payments + shine_users:
- create_pda_account переведён на «создание поверх предзаполненного»
  (allocate+assign+добор ренты), чтобы подсев лампортов на детерминированный
  адрес PDA (тикет/логин) не блокировал создание — закрыт LOW из аудита №1;
  в shine_payments is_uninitialized_account перестала зависеть от баланса.

shine_payments (HIGH из аудита №2):
- запрещён recipient == inflow_vault в buy_ticket*, manager_add_ticket и
  change_ticket_recipient; добавлена защита по умолчанию в transfer_from_vault
  (require vault.key != recipient.key). Это убирает алиасинг аккаунта в
  step_payout, который навсегда замораживал очередь выплат и средства вольта.

Документация и учёт:
- doc/programs/shine_payments.md §3.4, §10.1; doc/programs/shine_users.md §3.3;
- Dev_Docs/audit: добавлен аудит №2, обе закрытые находки помечены ИСПРАВЛЕНО;
- Dev_Docs/Pending_Features: две записи на ручную e2e-проверку на devnet;
- VERSION.properties: client 1.2.161, server 1.2.150.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 04:10:31 +04:00

2.4 KiB
Raw Blame History

Запрет получателя тикета, равного inflow-вольту (защита от заморозки очереди)

Краткое описание

Закрыта HIGH-находка второго аудита (Dev_Docs/audit/Solana-audit-2-by-Claude-11июня2026.md). Тикет с recipient_wallet == адрес inflow_vault приводил к алиасингу аккаунта в step_payout (вольт одновременно источник и получатель), второй mutable-займ лампортов в transfer_from_vault падал, и такой тикет навсегда блокировал обслуживание очереди и замораживал средства вольта.

Исправление в shine_payments:

  • buy_ticket_by_purchase_usdrequire!(recipient_wallet != config.inflow_vault);
  • process_manager_add_ticket — запрет через find_single_pda(INFLOW_VAULT_SEED);
  • process_change_ticket_recipient — тот же запрет для new_recipient_wallet;
  • transfer_from_vault — защита по умолчанию require!(vault.key != recipient.key).

Ошибка во всех случаях — InvalidTicketRecipient.

Что проверять (devnet/localnet)

  1. Покупка тикета с recipient_wallet = <адрес inflow_vault PDA> → отклоняется (InvalidTicketRecipient), тикет не создаётся.
  2. manager_add_ticket с тем же recipient → отклоняется.
  3. change_ticket_recipient с new_recipient = inflow_vault → отклоняется.
  4. Обычные покупки/выплаты с нормальным получателем → работают как раньше, очередь обслуживается, step_payout выплачивает корректно.
  5. Регресс не затронул выплаты в dao_wallet и call_reward подписанту (их адреса не совпадают с вольтом).

Ожидаемый результат

Тикет с получателем-вольтом невозможно создать; ранее существовавший вектор перманентной заморозки очереди закрыт. Прочая логика выплат без изменений.

Статус

pending