Найдено при приёмке боевого домена 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 (релиз игры их сносил).
15 пунктов, отмечаются [ ]/[x]. Критичное найдено воспроизведением на
testfront.binom.pw, не чтением кода:
- close_bet проверяет только нижнюю границу окна (now >= expire_time) —
верхней нет, ставка висит open бесконечно, момент расчёта выбирает
вызывающий /close;
- в шлюзе нет авто-закрытия (единственный setInterval — WS-heartbeat);
- /bet, /close, /faucet открыты наружу без авторизации; faucet выдал
5 SOL + 10000 фантиков при SMART_ALLOW_AIRDROP=1 в боевом поде;
- эксплойт воспроизведён: ставка DOWN (entry=9998000000) висела open >2 мин
после экспирации 15с и закрыта при exitPrice=9997000000 -> payout_done.
Плюс: множитель 1.3x требует 77% винрейта, запертые средства в ваулте,
равные цены не финализируют ставку, NATS без auth, релейер — точка доверия.
ADR-007 (выбор источника binance-market/NATS) пришёл из другой сессии —
оставлен как есть, с апдейт-сноской. Реализация зафиксирована отдельным
ADR-008: NATS-консьюмер в шлюзе, цена x1e8 строковым парсером, раздача
фронту по WebSocket, деплой в k3s на testfront.binom.pw.
- README: новая секция «Внешние зависимости» — binance-market как общий
инфраструктурный upstream, а не часть игры (~/common-projects/invest/binance-market,
контракт: NATS market.price.solusdt или WS /ws/price).
- docs/DECISIONS: добавлен ADR-007 с обоснованием; ADR-006 получил апдейт-сноску.
- docs/ECONOMY: «Курс и балансы» — указано, откуда берётся реальная цена SOL.
- TASKS: задачи «Цена SOL: реальный источник» (Фаза 0) и «PriceSource: реальная
цена» (Фаза 2) переведены из TODO в IN_PROGRESS, со ссылкой на ADR-007 и
binance-market; test-front задача тоже помечена.