docs(sec): SEC-16 — безвозвратная утечка ренты PDA-ставки с кошелька игрока
Найдено при приёмке боевого домена smart-updown.binom.pw (симптом «SOL не обновляется»). - SEC-16: при create_bet ренту PDA-аккаунта ставки (1 559 040 lamports = (96+32+128)*6960) платит БЕТТОР, а не шлюз; баланс шлюза-админа при этом не меняется (замер whose-fee.cjs). Аккаунт не закрывается никогда (в контракте 9ALs четыре инструкции, ни одной close = bettor) → рента теряется безвозвратно. В цепи 75 аккаунтов = 0.116928 SOL заперто, растёт линейно. Вердикт: на тестах терпимо (маскируется краном, 5 SOL = ~3207 раундов), перед mainnet — блокер. - TASKS.md: фича «если цена не изменилась — подождать ещё 15 с» (НЕ доделана), заметка про боевой домен на общем TS-шлюзе и лаг крана 8–13 с. - tools: доказательные скрипты (whose-fee, bet-pda-rent, faucet-latency, sol-balance-cycle, settle-math-test, backend-full-test) + README с питфоллами замера. - k8s/smart-updown-api-ingress.yaml: /api,/ws вынесены вне helm (релиз игры их сносил).
This commit is contained in:
@@ -91,6 +91,34 @@
|
||||
## Ссылки
|
||||
- Решения/экономика: `docs/DECISIONS.md`, `docs/ECONOMY.md`
|
||||
- Карта репозиториев: `README.md`
|
||||
|
||||
## ⭐ Добавлено 2026-09-15 — боевой домен и находки приёмки
|
||||
|
||||
**Где мы:** боевой домен `smart-updown.binom.pw` переведён на **тот же TS-шлюз** (`:8895`),
|
||||
что и `testfront.binom.pw` (некастодиальный Kotlin-бэк выключен, обратимо). Пути `/api`,`/ws`
|
||||
вынесены в **отдельный ingress вне helm** — релиз игры их больше не сносит.
|
||||
|
||||
**Найдено при приёмке живьём:**
|
||||
- `SEC-16` — безвозвратная утечка ренты PDA-аккаунта ставки: **1 559 040 lamports с кошелька
|
||||
игрока за каждую ставку**, аккаунт не закрывается никогда. Подробности — `docs/SECURITY.md`.
|
||||
*Вердикт: на тестах терпимо (маскируется краном), перед mainnet — блокер.*
|
||||
- Расчёт (выплаты) — **корректен 3/3**: выигрыш `1.3×`, проигрыш `0`, ничья — возврат залога.
|
||||
- Кран зачисляет на цепь с лагом **8–13 с** (шлюз рапортует мгновенно) — отсюда ложный симптом
|
||||
«SOL не обновился».
|
||||
|
||||
**Фича на будущее — «ждать, если цена не изменилась» (НЕ ДОДЕЛАНА):**
|
||||
- [ ] **TODO** `[pump.meta]` Если по сделанной ставке цена на момент экспирации **не изменилась**
|
||||
(`exit == entry`, ничья), нужно **подождать ещё 15 секунд** и попробовать взять цену заново —
|
||||
чтобы ставка не закрывалась возвратом залога на «плоской» цене, а получала шанс на реальный исход.
|
||||
**Суть:** ставка не меняется → ждём (не финализируем сразу возвратом).
|
||||
- [ ] **TODO** Вынести окно ожидания в конфиг: сейчас `PRICE_WAIT_TIMEOUT_MS` (default `15000`)
|
||||
отвечает лишь за **ожидание первой цены от NATS** (`relayer/src/priceSource.ts:9`) и к ничьей
|
||||
отношения не имеет — нужен **отдельный** параметр (напр. `TIE_WAIT_TIMEOUT_MS`) и логика
|
||||
отложенного ретрая в `settle.ts` (`priceAtOrBefore(expireTime*1000)` — сейчас берётся
|
||||
фиксированный момент, ретрай каждые 2 с вечно получит ту же пару, см. `SEC-9`).
|
||||
- [ ] **TODO** Решить, что делать по истечении окна ожидания: возврат залога (текущее поведение
|
||||
`SEC-9`) или иной исход.
|
||||
|
||||
## Фаза 7 — Цена из NATS и деплой в куб (2026-09-13)
|
||||
- [x] **DONE** ADR-007: цена SOL из NATS (`market.price.solusdt`), заглушка удалена
|
||||
- [x] **DONE** `natsPrice.ts` — подписка NATS, последняя цена, `waitForPrice`, ×1e8 строковым парсером
|
||||
|
||||
Reference in New Issue
Block a user