Files
maker/scripts/dex-spin-proof.sh

76 lines
5.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# dex-spin-proof.sh — prove the Lux V4 (0x9999) DEX spins on a healthy net.
#
# The maker (signing as 0x9011, the treasury/dominant LP) deploys a base+quote
# ERC-20, opens a 0x9999 market, and pegs a 2-sided book to a fixed oracle; the
# trader then takes it → a real DEXFill emitted + read back from accepted state.
# Conservation is asserted. This is the canonical "is the DEX trading?" proof on
# a live net. Bypasses the (PAT-blocked) CI image: runs the locally-built binaries.
#
# Usage: dex-spin-proof.sh <cchain_rpc_url> [namespace]
# e.g. dex-spin-proof.sh http://127.0.0.1:19640/v1/chain/C/rpc lux-testnet
#
# PRECONDITION the caller MUST satisfy: the target C-Chain is FINALIZING blocks
# (accepted height advances). Both non-prod C-Chains were broken at authoring
# time (devnet: proposervm height-index corruption; testnet: 3/5 validators
# missing-trie-node → consensus halted at block 380). The script refuses to run
# against a halted chain. NEVER point this at mainnet without explicit user go
# (real treasury funds).
set -uo pipefail
export FOUNDRY_DISABLE_NIGHTLY_WARNING=1
RPC="${1:?usage: dex-spin-proof.sh <cchain_rpc_url> [namespace]}"
NS="${2:-lux-testnet}"
KCTX=do-sfo3-lux-k8s
MAKER=/tmp/lux-maker
TRADER=/tmp/lux-trader
# Build the binaries locally (CGO off, pure-Go; go.work references absent siblings → GOWORK=off).
[ -x "$MAKER" ] || ( cd ~/work/lux/maker && GOWORK=off CGO_ENABLED=0 go build -o "$MAKER" ./cmd/maker )
[ -x "$TRADER" ] || ( cd ~/work/lux/trader && GOWORK=off CGO_ENABLED=0 go build -o "$TRADER" ./cmd/trader )
# 0x9011 key + mnemonic from the KMS-synced lux-deployer secret (NEVER printed).
KEY9011=$(kubectl --context $KCTX -n "$NS" get secret lux-deployer -o jsonpath='{.data.LUX_PRIVATE_KEY}' | base64 -d); case "$KEY9011" in 0x*) ;; *) KEY9011="0x$KEY9011";; esac
MNEMONIC=$(kubectl --context $KCTX -n "$NS" get secret lux-deployer -o jsonpath='{.data.LUX_MNEMONIC}' | base64 -d)
OWNER=$(cast wallet address --private-key "$KEY9011"); [ "$OWNER" = "0x9011E888251AB053B7bD1cdB598Db4f9DEd94714" ] || { echo "REFUSE: key is not 0x9011 ($OWNER)"; exit 1; }
# --- Preflight: chain identity + LIVENESS (refuse on a halted chain) ---
CID=$(cast chain-id --rpc-url "$RPC"); echo "chainId=$CID"
[ "$CID" = "96369" ] && { echo "REFUSE: this is MAINNET — real funds, gated on user go"; exit 1; }
[ "$(cast codesize 0x0000000000000000000000000000000000009999 --rpc-url "$RPC")" = "1" ] || { echo "REFUSE: 0x9999 precompile absent — re-activate dexSettle first"; exit 1; }
b1=$(cast block-number --rpc-url "$RPC"); sleep 8; b2=$(cast block-number --rpc-url "$RPC")
[ "$b2" -gt "$b1" ] || { echo "REFUSE: C-Chain HALTED (accepted height $b1==$b2 over 8s) — repair consensus before proving"; exit 1; }
echo "chain live: accepted $b1 -> $b2 0x9011 bal=$(cast balance $OWNER --rpc-url "$RPC" | python3 -c 'import sys;print(int(sys.stdin.read())/1e18,"LUX")')"
# --- 1) maker seeds + opens the 0x9999 market as 0x9011 (deployer+maker), funds taker(idx2) ---
echo "=== maker coherence-init (0x9011 deploys LUX+LUSD, opens 0x9999 LUX/USD, funds maker+taker) ==="
INIT=$(COHERENCE_RPC="$RPC" COHERENCE_MNEMONIC="$MNEMONIC" \
COHERENCE_DEPLOYER_KEY="$KEY9011" COHERENCE_MAKER_KEY="$KEY9011" COHERENCE_TAKER_IDX=2 \
COHERENCE_INIT_MARKETS="LUX/USD=fixed:12.5" MAKER_MODE=coherence-init "$MAKER" 2>&1)
echo "$INIT"
MARKETS=$(echo "$INIT" | grep -E '^LUX/USD=' | tail -1)
[ -n "$MARKETS" ] || { echo "FAIL: init produced no COHERENCE_MARKETS"; exit 1; }
BASE=$(echo "$MARKETS" | awk -F: '{print $3}'); QUOTE=$(echo "$MARKETS" | awk -F: '{print $4}')
echo "market: base=$BASE quote=$QUOTE"
# taker needs native gas (init funds tokens, not gas): send 5 LUX from 0x9011 to idx2.
TAKER=$(cast wallet address --mnemonic "$MNEMONIC" --mnemonic-derivation-path "m/44'/9000'/0'/0/2")
cast send --rpc-url "$RPC" --private-key "$KEY9011" "$TAKER" --value 5ether >/dev/null && echo "funded taker $TAKER gas"
# --- 2) maker pegs the book (brief), probe taker crosses → DEXFill ---
echo "=== maker coherence (peg + probe fill), ~45s ==="
FROM=$(cast block-number --rpc-url "$RPC")
COHERENCE_RPC="$RPC" COHERENCE_MNEMONIC="$MNEMONIC" \
COHERENCE_MAKER_KEY="$KEY9011" COHERENCE_TAKER_IDX=2 \
COHERENCE_MARKETS="$MARKETS" COHERENCE_SPREAD_BPS=20 COHERENCE_REQUOTE=12s \
COHERENCE_PROBE=8s COHERENCE_PROBE_SIZE=1000 MAKER_MODE=coherence "$MAKER" &
MPID=$!; sleep 45; kill $MPID 2>/dev/null
# --- 3) independent trader fill on the same market + read DEXFills back ---
echo "=== trader bot (independent maker/taker flow on the open market) ==="
"$TRADER" --rpc "$RPC" --mnemonic "$MNEMONIC" --base "$BASE" --quote "$QUOTE" --rounds 3 bot 2>&1 | tail -20
echo "=== DEXFill events read back from accepted 0x9999 state (the proof) ==="
"$TRADER" --rpc "$RPC" --base "$BASE" --from-block "$FROM" fills 2>&1 | tail -30
echo "--- raw 0x9999 DEXFill logs ---"
cast logs --from-block "$FROM" --address 0x0000000000000000000000000000000000009999 --rpc-url "$RPC" 2>&1 | grep -c blockNumber | sed 's/^/DEXFill-bearing log events: /'