Files
migration/v3v4/tools/oracle.example.json
zeekayandHanzo Dev 91af9c85b5 v3v4: harden mainnet V3->V4 migration executor (Red FIX-THEN-SHIP)
DEX LP migration toolkit for Lux C-Chain 96369. Contract (LiquidityDeployer.sol)
unchanged and RED-approved (16/16 tests). All hardening is in the Python executor,
plan builder, Makefile, and RUNBOOK.

FIX 1 (HIGH #4) oracle sanity bound — BLOCKED BROADCAST.
  The old one-sided guard (tick_o < v3edge-1000) only fired at ~25,000x error; a 10x
  oracle typo cloned a honeypot and let an LBTC-seller drain 4.29M WLUX. oracle.json is
  now a dual-control object per base {price, expected_tick(, band_ticks)}: the executor
  recomputes the tick from `price` and ABORTS if it strays > ORACLE_TICK_BAND (2000
  ticks ~= +/-22%) from the SECOND operator's independent expected_tick. A hard
  ONESIDED_MAX_WLUX cap (5,000,000e18) bounds per-pool WLUX at risk. The honeypot-edge
  check is kept as a backstop. Oracle validation runs BEFORE any V3 decrease.
  tools/execute.py: onesided_band_ok(), compute_onesided_bid(); tools/oracle.example.json.

FIX 2 (HIGH #5b) freeze baseline — prevents double-decrease to 75%.
  Re-running `make snapshot && make plan` mid-migration used to read already-halved
  liquidity as the new baseline and remove 50% of the remainder. build_plan.py now
  freezes tools/baseline.json (original liquidity + one-shot 50% target per tokenId) on
  first plan and reads it thereafter; a position already <= its baseline target is a
  no-op via the executor's on-chain precheck. Regenerating the plan is idempotent.

FIX 3 (MED #6) per-tx nonce + stop masking nonce errors.
  Re-read the live pending nonce before every tx and ABORT on drift (concurrent signer
  on treasury 0x9011); preflight asserts nonce stable across two reads 3s apart. A
  nonce too low/high is now FATAL (abort before the 240s receipt wait) instead of being
  masked as "sent"; benign "already known" still counts as accepted; 0/5 acceptance
  aborts.

FIX 4 (LOW) finalize + gas gate.
  Opt-in FINALIZE=1: after all adds, zero residual LD approvals and transferOwnership
  LD -> DAO Safe (0x51284...). Execute-mode preflight aborts if baseFee > gasPrice.
  state.json pools deduped (upsert by v4PoolId).

Verify: make test 16/16; tools/test_red_oracle.py PASS (K>=1.5x REJECT, 10x aborts);
make migrate dry-run clean end-to-end; fat-finger oracle aborts before touching V3.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-04 21:33:24 -07:00

7 lines
910 B
JSON

{
"_comment": "Base-asset prices for MIGRATE_ONESIDED_ORACLE pools. Copy to oracle.json and set LIVE values at execute time. Each one-sided base is an OBJECT: price = base USD (Kraken XBTUSD/AVAXUSD/...); expected_tick = the SECOND operator's INDEPENDENT tick anchor computed from their OWN read of the live mid (DO NOT derive it from `price` here — it is the dual-control cross-check). The executor ABORTS if the price-derived tick strays > ORACLE_TICK_BAND (default 2000 ticks ~= +/-22%) from expected_tick; optional per-base `band_ticks` overrides that width. LUX_USD is the WLUX peg (LETH/LUX = ETHUSD/12.5 => LUX_USD = 12.5). The V4 pool inits at price = <base>USD/LUX_USD (WLUX per base) with treasury WLUX placed as a resting BID ladder BELOW it.",
"LUX_USD": 12.5,
"LBTC": { "price": 100000.0, "expected_tick": 89876, "band_ticks": 2000 },
"LAVAX": { "price": 30.0, "expected_tick": 8755 }
}