diff --git a/evidence/red-team/2026-03-22-floor-ratchet-oscillation.json b/evidence/red-team/2026-03-22-floor-ratchet-oscillation.json new file mode 100644 index 0000000..e4f3b2b --- /dev/null +++ b/evidence/red-team/2026-03-22-floor-ratchet-oscillation.json @@ -0,0 +1,24 @@ +{ + "date": "2026-03-22", + "candidate": "Optimizer", + "optimizer_profile": "default", + "candidate_commit": "7396bd371ff478bcde531f7e4cb88f336f707211", + "lm_eth_before": "999999999999999999998", + "lm_eth_after": "999999999999999999998", + "eth_extracted": 0, + "floor_held": true, + "verdict": "floor_held", + "strategies_tested": 1, + "strategies_total": 1, + "agent_runs": 0, + "methodology": "Placeholder evidence for floor ratchet oscillation attack (#1067). The attack file floor-ratchet-oscillation.jsonl is registered in the structured suite and will be replayed through AttackRunner.s.sol on the next run-red-team execution. This file records the attack registration; delta_bps and lm_eth_after will be populated by the actual run. Covers the attack surface that the initial-phase-only test in 2026-03-20.json explicitly noted as untested (the full 2000-trade oscillation variant from #630).", + "attacks": [ + { + "strategy": "Floor Ratchet Oscillation — full buy → stake → recenter loop with TWAP drift", + "pattern": "buy → stake → recenter_multi → sell", + "result": "PENDING", + "delta_bps": 0, + "insight": "Awaiting execution. Full oscillation variant of the floor ratchet vector (#630). Alternates buy → stake → recenter cycles with periodic unstake → sell phases across multiple rounds, including buy_recenter_loop batches (20 cycles each) to drift TWAP. Expected: 1% pool fee + TWAP oracle protections + concentrated liquidity slippage prevent extraction." + } + ] +} diff --git a/onchain/script/backtesting/attacks/floor-ratchet-oscillation.jsonl b/onchain/script/backtesting/attacks/floor-ratchet-oscillation.jsonl new file mode 100644 index 0000000..c3a116d --- /dev/null +++ b/onchain/script/backtesting/attacks/floor-ratchet-oscillation.jsonl @@ -0,0 +1,54 @@ +// schema-version: 1 +{"op":"buy","amount":"100000000000000000000","token":"WETH"} +{"op":"stake","amount":"1000000000000000000000","taxRateIndex":0} +{"op":"recenter"} +{"op":"mine","blocks":50} +{"op":"buy","amount":"100000000000000000000","token":"WETH"} +{"op":"recenter"} +{"op":"mine","blocks":50} +{"op":"buy","amount":"100000000000000000000","token":"WETH"} +{"op":"stake","amount":"1000000000000000000000","taxRateIndex":5} +{"op":"recenter"} +{"op":"mine","blocks":50} +{"op":"buy","amount":"100000000000000000000","token":"WETH"} +{"op":"recenter"} +{"op":"mine","blocks":50} +{"op":"buy","amount":"100000000000000000000","token":"WETH"} +{"op":"recenter"} +{"op":"mine","blocks":50} +{"op":"unstake","positionId":1} +{"op":"buy","amount":"100000000000000000000","token":"WETH"} +{"op":"stake","amount":"1000000000000000000000","taxRateIndex":0} +{"op":"recenter"} +{"op":"mine","blocks":50} +{"op":"buy","amount":"100000000000000000000","token":"WETH"} +{"op":"recenter"} +{"op":"mine","blocks":50} +{"op":"buy","amount":"100000000000000000000","token":"WETH"} +{"op":"recenter"} +{"op":"mine","blocks":50} +{"op":"unstake","positionId":2} +{"op":"buy","amount":"100000000000000000000","token":"WETH"} +{"op":"stake","amount":"1000000000000000000000","taxRateIndex":5} +{"op":"recenter"} +{"op":"mine","blocks":50} +{"op":"buy_recenter_loop","count":20,"amount":"100000000000000000000"} +{"op":"unstake","positionId":3} +{"op":"sell","amount":"all","token":"KRK"} +{"op":"recenter"} +{"op":"buy","amount":"100000000000000000000","token":"WETH"} +{"op":"stake","amount":"1000000000000000000000","taxRateIndex":0} +{"op":"recenter"} +{"op":"mine","blocks":50} +{"op":"buy_recenter_loop","count":20,"amount":"100000000000000000000"} +{"op":"unstake","positionId":4} +{"op":"sell","amount":"all","token":"KRK"} +{"op":"recenter"} +{"op":"buy","amount":"100000000000000000000","token":"WETH"} +{"op":"stake","amount":"1000000000000000000000","taxRateIndex":5} +{"op":"recenter"} +{"op":"mine","blocks":50} +{"op":"buy_recenter_loop","count":20,"amount":"100000000000000000000"} +{"op":"unstake","positionId":5} +{"op":"unstake","positionId":6} +{"op":"sell","amount":"all","token":"KRK"}