mirror of
https://github.com/luxfi/migration.git
synced 2026-10-30 15:25:07 +00:00
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]>
7 lines
910 B
JSON
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 }
|
|
}
|