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>
2.6 KiB
2.6 KiB
Устойчивое создание PDA (защита от «минирования» адреса)
Краткое описание
В shine_payments и shine_users функция create_pda_account переведена с жёсткого
system_instruction::create_account на паттерн «создание поверх предзаполненного»:
- если на детерминированном адресе будущего PDA нет лампортов — обычный
create_account; - если лампорты уже есть («подсев» атакующим) — добор ренты переводом, затем
allocate+assignпод подписью PDA.
Дополнительно в shine_payments is_uninitialized_account перестала требовать нулевой
баланс (проверяет только пустые данные + владельца System Program).
Это закрывает последний (LOW) пункт аудита: griefing-DoS на покупку тикетов и сквоттинг логинов через предсказуемые адреса PDA.
Что проверять (devnet/localnet)
- Обычная покупка тикета без «подсева» — создаётся как раньше (быстрый путь).
- На адрес следующего тикета заранее переведены лампорты обычным system-переводом →
покупка/
manager_add_ticketвсё равно проходит, тикет создаётся корректно, данные и владелец = program id. - На адрес
user_pdaбудущего логина заранее переведены лампорты → регистрация логина (create_user_pda) всё равно проходит; запись и комиссия корректны. - Повторная инициализация уже существующего тикета/пользователя по-прежнему отклоняется
(
PdaAlreadyExists/UserAlreadyExists). - Singleton-PDA (
init, economy config) и manager allowance создаются без регрессий.
Ожидаемый результат
Подсев лампортов на заранее известный адрес PDA не блокирует создание; вся остальная экономика и проверки повторной инициализации работают как прежде.
Статус
pending