docs(security): SEC-1, SEC-2, SEC-4 закрыты по сути — цена закрытия из истории
Механизм: шлюз берёт цену закрытия из локальной истории на момент expire_time ставки (priceHistory, node:sqlite, ретеншен 24ч), а не текущую. Момент клика перестаёт влиять на исход — окно выбора времени закрыто. Живая проверка (ставка №10, релиз updown-relayer:3): цена на момент экспирации 9977000000 текущая цена в момент клика 9976000000 exitPrice в транзакции 9977000000 -> взята история, не 'сейчас' статус payout_done Также: tools/ — скрипты проверки (price-history-probe, exploit-decisive, exploit-check, check-close-window.sh). Остаток: в контракте верхней границы окна по-прежнему нет (второй слой, не критично); серверное авто-закрытие — следующая итерация.
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env bash
|
||||
# Живая проверка того, что окно выбора времени ЗАКРЫТО.
|
||||
#
|
||||
# Схема проверки (повторяет поведение вора):
|
||||
# 1. создаём кошелёк, пополняем
|
||||
# 2. ставим ставку
|
||||
# 3. ЖДЁМ существенно дольше экспирации (по умолчанию 60 с; экспирация 15 с)
|
||||
# 4. закрываем и смотрим, какую цену вернул шлюз
|
||||
#
|
||||
# Ожидание ПОСЛЕ фикса: цена закрытия == цена на момент экспирации (из истории),
|
||||
# а НЕ текущая цена на момент клика. Плюс шлюз должен отказать, если цена закрытия
|
||||
# совпала с ценой входа (ставка останется open — это отдельная задача).
|
||||
#
|
||||
# Использование: bash check-exploit.sh [секунды_ожидания]
|
||||
set -uo pipefail
|
||||
|
||||
G="${GW_URL:-https://testfront.binom.pw/api}"
|
||||
WAIT_SEC="${1:-60}"
|
||||
|
||||
jqget() { python3 -c "import sys,json;print(json.load(sys.stdin)$1)" 2>/dev/null; }
|
||||
|
||||
echo "=== 1. кошелёк ==="
|
||||
W=$(curl -s --max-time 30 -X POST "$G/wallet" -H 'Content-Type: application/json' -d '{}')
|
||||
A=$(echo "$W" | jqget "['address']")
|
||||
echo "address=$A"
|
||||
[ -z "$A" ] && { echo "ОШИБКА: адрес не получен ($W)"; exit 1; }
|
||||
|
||||
echo "=== 2. пополнение ==="
|
||||
curl -s --max-time 60 "$G/faucet/$A" | head -c 200; echo
|
||||
|
||||
echo "=== 3. ставка ==="
|
||||
BET=$(curl -s --max-time 45 -X POST "$G/bet" -H 'Content-Type: application/json' \
|
||||
-d "{\"side\":\"UP\",\"amountUnits\":\"100000000\",\"address\":\"$A\"}")
|
||||
echo "$BET"
|
||||
ID=$(echo "$BET" | jqget "['id']")
|
||||
ENTRY=$(echo "$BET" | jqget "['entryPrice']")
|
||||
[ -z "$ID" ] && { echo "ОШИБКА: ставка не создана"; exit 1; }
|
||||
echo "id=$ID entryPrice=$ENTRY"
|
||||
|
||||
echo
|
||||
echo "=== 4. цена шлюза СЕЙЧАС (до экспирации) ==="
|
||||
curl -s --max-time 20 "$G/price"; echo
|
||||
|
||||
echo
|
||||
echo "=== 5. ждём ${WAIT_SEC}с (экспирация 15с — окно прошло) ==="
|
||||
sleep "$WAIT_SEC"
|
||||
|
||||
echo "=== 6. цена шлюза ПОСЛЕ ожидания (текущая, которую вор хотел бы получить) ==="
|
||||
P_NOW=$(curl -s --max-time 20 "$G/price")
|
||||
echo "$P_NOW"
|
||||
|
||||
echo
|
||||
echo "=== 7. ЗАКРЫТИЕ — какую цену возьмёт? ==="
|
||||
BEFORE=$(date -u +%s)
|
||||
CLOSE=$(curl -s --max-time 45 -X POST "$G/close" -H 'Content-Type: application/json' -d "{\"id\":\"$ID\"}")
|
||||
AFTER=$(date -u +%s)
|
||||
echo "$CLOSE"
|
||||
|
||||
EXIT=$(echo "$CLOSE" | jqget "['exitPrice']")
|
||||
echo
|
||||
echo "================ ИТОГ ================"
|
||||
echo "entryPrice (вход) : $ENTRY"
|
||||
echo "exitPrice (шлюз вернул) : $EXIT"
|
||||
echo "цена в момент клика : $P_NOW"
|
||||
echo
|
||||
if [ -z "$EXIT" ]; then
|
||||
echo "ВЕРДИКТ: закрытие НЕ выполнилось (см. ответ выше)."
|
||||
elif [ "$EXIT" = "$ENTRY" ]; then
|
||||
echo "ВЕРДИКТ: exit == entry -> ставка осталась open (равные цены, отдельная задача)."
|
||||
echo " Главное: цена НЕ взята произвольно с момента клика."
|
||||
else
|
||||
# Сравниваем exit с ценой, которая была бы при старом поведении
|
||||
CUR=$(echo "$P_NOW" | jqget "['price']")
|
||||
if [ -n "$CUR" ]; then
|
||||
echo "Текущая цена в момент клика: $CUR (в целом виде $(python3 -c "print(int(float('$CUR')*10**8))" 2>/dev/null))"
|
||||
fi
|
||||
echo "Смотрим глазами: exitPrice должен соответствовать цене НА МОМЕНТ ЭКСПИРАЦИИ,"
|
||||
echo "а не текущей. Если exitPrice == текущей цене клика — ОКНО ОТКРЫТО, фикс не работает."
|
||||
fi
|
||||
echo "закрытие заняло: $((AFTER-BEFORE))с"
|
||||
Reference in New Issue
Block a user