{
 "approach": "Parameter lookup: first 400 steps estimate sigma from arb-implied fair prices (first trade per timestamp; p=spot*(1-f) or spot/(1-f)), retail count and mean amountY of later trades; then pick a symmetric fee from an 18-bucket table (3 sigma x 3 rate x 2 size). Finding: ranges are so narrow that the table adds nothing over the best single fixed pair (75 bps); post-arb widening hurt (-5 at +20 bps), so final W=0. Gain vs starter comes almost entirely from the higher base fee.",
 "tried": [
  "fixed 32 bps vs starter(50), seeds 0..399: -23.055 (se 0.388)",
  "fixed 36 bps vs starter(50), seeds 0..399: -16.844 (se 0.286)",
  "fixed 40 bps vs starter(50), seeds 0..399: -11.146 (se 0.195)",
  "fixed 45 bps vs starter(50), seeds 0..399: -5.005 (se 0.092)",
  "fixed 60 bps vs starter(50), seeds 0..399: +6.969 (se 0.155)",
  "fixed 70 bps vs starter(50), seeds 0..399: +10.439 (se 0.281)",
  "fixed 85 bps vs starter(50), seeds 0..399: +10.337 (se 0.431)",
  "table B (70/85 per bucket, oracle-picked), W=0 vs fixed70: -0.061 (se 0.029)",
  "table B + post-arb widening +20bps vs fixed70: -4.955 (se 0.200)",
  "table B + post-arb widening +40bps vs fixed70: -16.473 (se 0.372)",
  "table B + post-arb narrowing -10bps vs fixed70: -1.178 (se 0.084)",
  "flat 75 (single best fixed pair) vs fixed70: +0.587 (se 0.055)",
  "FINAL table H (75/80 per bucket) vs flat 75: +0.006 (se 0.015); vs fixed70: +0.593 (se 0.060)",
  "Oracle per-bucket table using TRUE params (offline, fees 45..85) gains only +0.38/sim over fixed 70 on seeds 0..399: parameter ranges are narrow (size 19-21, rate 0.6-1.0, sigma 0.000882-0.001008)"
 ],
 "lookup_table": {
  "index": "b = sigmaBucket*6 + rateBucket*2 + sizeBucket; sigma var/step thresholds 8.54e-7,9.33e-7; retail trades seen in steps<400 thresholds 293,347; mean amountY threshold 20",
  "fees_bps": [
   75,
   80,
   75,
   80,
   75,
   80,
   75,
   80,
   75,
   75,
   75,
   80,
   75,
   80,
   75,
   75,
   75,
   80
  ],
  "gain_vs_best_fixed_pair_75": "+0.006 (se 0.015) overall on seeds 0..399; per-bucket gains not separately measurable (each bucket 13-31 seeds, oracle per-bucket gains vs 70 range -0 to +1.7 at n<=31, all within noise)"
 },
 "next": [
  "Abandon per-simulation lookup; parameter ranges too narrow to matter",
  "Fair-price-anchored asymmetric bid/ask (quote around arb-implied p) instead of symmetric fee",
  "Fee decaying toward 30 bps between arbs to win retail, re-widen on arb"
 ],
 "code": "pragma solidity ^0.8.24;\n\nimport {AMMStrategyBase} from \"./AMMStrategyBase.sol\";\nimport {IAMMStrategy, TradeInfo} from \"./IAMMStrategy.sol\";\n\ncontract Strategy is AMMStrategyBase {\n    uint256 constant TAB = 6994604135210398105598697396841905583247435;\n    uint256 constant W = 0;\n    uint256 constant T0 = 400;\n\n    function afterInitialize(uint256, uint256) external override returns (uint256, uint256) {\n        slots[0] = 75 * BPS;\n        return (slots[0], slots[0]);\n    }\n\n    function afterSwap(TradeInfo calldata t) external override returns (uint256, uint256) {\n        uint256 f = slots[0];\n        uint256 spot = t.reserveY * WAD / t.reserveX;\n        bool arb = t.timestamp != slots[1];\n        if (arb) {\n            slots[1] = t.timestamp;\n            uint256 p = t.isBuy ? wmul(spot, WAD - f) : wdiv(spot, WAD - f);\n            uint256 q = slots[2];\n            if (q != 0 && t.timestamp < T0) {\n                uint256 r = wdiv(absDiff(p, q), q);\n                slots[3] += wmul(r, r);\n                slots[4] += t.timestamp - slots[5];\n            }\n            slots[2] = p;\n            slots[5] = t.timestamp;\n        } else if (t.timestamp < T0) {\n            slots[6] += 1;\n            slots[7] += t.amountY;\n        }\n        if (slots[8] == 0 && t.timestamp >= T0) {\n            slots[8] = 1;\n            uint256 v = slots[4] == 0 ? 0 : slots[3] / slots[4];\n            uint256 n = slots[6];\n            uint256 m = n == 0 ? 0 : slots[7] / n;\n            uint256 b = (v < 854000000000 ? 0 : v < 933000000000 ? 1 : 2) * 6\n                + (n < 293 ? 0 : n < 347 ? 1 : 2) * 2 + (m < 20000000000000000000 ? 0 : 1);\n            f = ((TAB >> (8 * b)) & 255) * BPS;\n            slots[0] = f;\n        }\n        if (arb) return (f - W, f - W);\n        return (f, f);\n    }\n\n    function getName() external pure override returns (string memory) {\n        return \"ParamLookup\";\n    }\n}\n",
 "code_sha256": "d3882f26604849eacfb2d0101bfcc8bed8c078a4a601117e5f308c2cc5e85f36",
 "score": {
  "n": 1000,
  "mean_edge": 380.1341
 },
 "paired": {
  "n": 2000,
  "seed_start": 300000,
  "mean_diff": 10.729,
  "se": 0.1608,
  "worst": [
   {
    "seed": 300441,
    "diff": -8.3583
   },
   {
    "seed": 300691,
    "diff": -7.2447
   },
   {
    "seed": 300341,
    "diff": -7.087
   },
   {
    "seed": 300941,
    "diff": -6.8022
   },
   {
    "seed": 301129,
    "diff": -6.1653
   }
  ]
 },
 "candidate_mean_edge_300000": 379.443,
 "starter_mean_edge": 368.7139,
 "seconds_per_simulation": 0.25,
 "validate": "pass (amm-match validate: 'validated successfully', warning only: missing SPDX license identifier, dropped per no-comments rule)",
 "notes": "Runs via amm_sim_rs.run_batch with configs replicating MatchRunner._build_configs per explicit seed, 8 workers; seconds_per_simulation is wall time per sim at 8 workers. Tuning used seeds 0..399 only."
}