{
  "n": 0,
  "status": "blocked_invalid_oog",
  "blocked": {
    "step": "V2 gas-validity check, seeds 10000..10999",
    "error": "V2 produced 19 OutOfGas halts across 12 seeds at the unchanged 250000 call gas limit. The brief invalidates any result with OOG; no valid performance estimate is claimed."
  },
  "definition": {
    "edge": "Y-denominated sum over executed trades at contemporaneous true price p (Y/X): delta_reserve_y + p*delta_reserve_x + fee_y + p*fee_x. Only newly collected fees enter each trade; existing holdings are not revalued into edge. This excludes inventory mark-to-market between trades.",
    "retail": "Cash-flow equivalent used in the existing engine: if AMM buys X, gross_X_in*p - Y_out; if AMM sells X, gross_Y_in - X_out*p. These gross inputs already include the separately retained fee; do not add it twice. Accumulate only trades returned by OrderRouter (retail counterparties).",
    "arb": "Negative arbitrageur profit. Its input quotes are gross of fees, so this equals the same pool-value-change-plus-fee expression. Accumulate only trades returned by Arbitrageur. Retail edge + arb edge = original engine total edge up to floating-point rounding.",
    "retail_volume": "Sum of positive trade.amount_y across V2 retail fills only; Y received gross of Y fee when AMM sells X, Y paid when AMM buys X. This is actual routed V2 volume, not all generated retail demand and not X converted at true price.",
    "mean_fee": "For each seed, arithmetic average of bid and ask quotes captured after each of the 10000 simulation steps: (sum_t bid_t + sum_t ask_t)/(2*10000). Then equal-weight average across seeds; fractional fees, with bps also supplied. This is a time-average quote, not a paid-fee or volume-weighted average.",
    "realised_sigma": "Sample SD (ddof=1) of ln(p_t/p_(t-1)), including the initial-price-to-first-step return, divided by sqrt(gbm_dt). Computed with Welford accumulation; gbm_dt=1. Configured sigma is supplied separately.",
    "terciles": "Sort all 1000 seeds by V2 retail volume ascending (seed breaks ties); numpy.array_split into low/middle/high groups of 334/333/333. No seeds, including OOG seeds, are excluded from the explicitly invalid diagnostics.",
    "se": "Sample SD across per-seed values (ddof=1) / sqrt(group n). These are descriptive Monte Carlo standard errors, not a claim of gas-valid performance.",
    "correlations": "Pearson sample correlations across 1000 seeds; volume means V2 retail_volume_y, sigma means realised_sigma.",
    "gas": "Instrumentation in EVMStrategy::call observes each getName, afterInitialize and afterSwap result for both V2/submission and Vanilla/normalizer. max_ok is maximum gas_used of successful nondeployment calls, including transaction intrinsic gas. OOG includes every OutOfGas Halt; other_halts includes other Halt reasons, Revert and call transaction errors. Deployments are separately counted and their gas maximum is separate (10M deployment budget); their Halt/Revert is also included in failure counters."
  },
  "patch": "diff --git a/amm_sim_rs/src/amm/cfmm.rs b/amm_sim_rs/src/amm/cfmm.rs\nindex 02e6645..72b6270 100644\n--- a/amm_sim_rs/src/amm/cfmm.rs\n+++ b/amm_sim_rs/src/amm/cfmm.rs\n@@ -84,6 +84,8 @@ impl CFMM {\n         Ok(())\n     }\n \n+    pub fn gas_stats(&self) -> (u64, u64, u64, u64, u64, u64) { self.strategy.gas }\n+\n     /// Get current reserves.\n     pub fn reserves(&self) -> (f64, f64) {\n         (self.reserve_x, self.reserve_y)\ndiff --git a/amm_sim_rs/src/evm/strategy.rs b/amm_sim_rs/src/evm/strategy.rs\nindex 1d06af1..1eeeeca 100644\n--- a/amm_sim_rs/src/evm/strategy.rs\n+++ b/amm_sim_rs/src/evm/strategy.rs\n@@ -50,6 +50,7 @@ const CALLER_ADDRESS: Address = Address::new([\n pub struct EVMStrategy {\n     /// Strategy name (cached after first call)\n     name: String,\n+    pub gas: (u64, u64, u64, u64, u64, u64), // max call, OOG, other failures, successful calls, max deploy, deploy count\n     /// Compiled bytecode (for reset)\n     bytecode: Vec<u8>,\n     /// In-memory database for EVM state\n@@ -63,6 +64,7 @@ impl EVMStrategy {\n     pub fn new(bytecode: Vec<u8>, default_name: String) -> Result<Self, EVMError> {\n         let mut strategy = Self {\n             name: default_name,\n+            gas: (0, 0, 0, 0, 0, 0),\n             bytecode: bytecode.clone(),\n             db: InMemoryDB::default(),\n             trade_calldata: [0u8; 196],\n@@ -104,6 +106,11 @@ impl EVMStrategy {\n             let result = evm.transact_commit()\n                 .map_err(|e| EVMError::DeploymentFailed(format!(\"{:?}\", e)))?;\n \n+            self.gas.4 = self.gas.4.max(result.gas_used());\n+            self.gas.5 += 1;\n+            if let ExecutionResult::Halt { reason, .. } = &result {\n+                if matches!(reason, revm::primitives::HaltReason::OutOfGas(_)) { self.gas.1 += 1; } else { self.gas.2 += 1; }\n+            } else if matches!(&result, ExecutionResult::Revert { .. }) { self.gas.2 += 1; }\n             match result {\n                 ExecutionResult::Success { output, .. } => {\n                     match output {\n@@ -207,10 +214,12 @@ impl EVMStrategy {\n             .build();\n \n         let result = evm.transact_commit()\n-            .map_err(|e| EVMError::ExecutionFailed(format!(\"{:?}\", e)))?;\n+            .map_err(|e| { self.gas.2 += 1; EVMError::ExecutionFailed(format!(\"{:?}\", e)) })?;\n \n         match result {\n-            ExecutionResult::Success { output, .. } => {\n+            ExecutionResult::Success { output, gas_used, .. } => {\n+                self.gas.0 = self.gas.0.max(gas_used);\n+                self.gas.3 += 1;\n                 match output {\n                     Output::Call(data) => Ok(data.to_vec()),\n                     Output::Create(_, _) => {\n@@ -219,12 +228,15 @@ impl EVMStrategy {\n                 }\n             }\n             ExecutionResult::Revert { output, .. } => {\n+                self.gas.2 += 1;\n                 Err(EVMError::ExecutionFailed(format!(\"Reverted: {:?}\", output)))\n             }\n             ExecutionResult::Halt { reason, .. } => {\n                 if matches!(reason, revm::primitives::HaltReason::OutOfGas(_)) {\n+                    self.gas.1 += 1;\n                     Err(EVMError::OutOfGas)\n                 } else {\n+                    self.gas.2 += 1;\n                     Err(EVMError::ExecutionFailed(format!(\"Halted: {:?}\", reason)))\n                 }\n             }\ndiff --git a/amm_sim_rs/src/simulation/engine.rs b/amm_sim_rs/src/simulation/engine.rs\nindex 6834c43..348adab 100644\n--- a/amm_sim_rs/src/simulation/engine.rs\n+++ b/amm_sim_rs/src/simulation/engine.rs\n@@ -113,6 +113,12 @@ impl SimulationEngine {\n         edges.insert(submission_name.clone(), 0.0);\n         edges.insert(baseline_name.clone(), 0.0);\n \n+        let mut retail_edges = edges.clone();\n+        let mut arb_edges = edges.clone();\n+        let mut previous_price = initial_fair_price;\n+        let mut log_mean = 0.0;\n+        let mut log_m2 = 0.0;\n+\n         // Run simulation steps\n         let mut steps = Vec::with_capacity(self.config.n_steps as usize);\n \n@@ -136,11 +142,17 @@ impl SimulationEngine {\n         for t in 0..self.config.n_steps {\n             // 1. Generate new fair price\n             let fair_price = price_process.step();\n+            let r = (fair_price / previous_price).ln();\n+            previous_price = fair_price;\n+            let delta = r - log_mean;\n+            log_mean += delta / (t + 1) as f64;\n+            log_m2 += delta * (r - log_mean);\n \n             // 2. Arbitrageur extracts profit from each AMM\n             for amm in amms.iter_mut() {\n                 if let Some(arb_result) = arbitrageur.execute_arb(amm, fair_price, t as u64) {\n                     *arb_volume_y.get_mut(&arb_result.amm_name).unwrap() += arb_result.amount_y;\n+                    *arb_edges.get_mut(&arb_result.amm_name).unwrap() -= arb_result.profit;\n                     let entry = edges.entry(arb_result.amm_name).or_insert(0.0);\n                     // AMM edge is the negative of arbitrageur profit at true price\n                     *entry += -arb_result.profit;\n@@ -157,6 +169,7 @@ impl SimulationEngine {\n                 } else {\n                     trade.amount_y - trade.amount_x * fair_price\n                 };\n+                *retail_edges.get_mut(&trade.amm_name).unwrap() += trade_edge;\n                 let entry = edges.entry(trade.amm_name).or_insert(0.0);\n                 *entry += trade_edge;\n             }\n@@ -205,6 +218,10 @@ impl SimulationEngine {\n         }\n \n         Ok(LightweightSimResult {\n+            retail_edges,\n+            arb_edges,\n+            gas_stats: amms.iter().map(|amm| (amm.name.clone(), amm.gas_stats())).collect(),\n+            realised_sigma: (log_m2 / (n_steps - 1.0) / self.config.gbm_dt).sqrt(),\n             seed,\n             strategies: vec![submission_name, baseline_name],\n             pnl,\ndiff --git a/amm_sim_rs/src/types/result.rs b/amm_sim_rs/src/types/result.rs\nindex 0257335..bbd1ff8 100644\n--- a/amm_sim_rs/src/types/result.rs\n+++ b/amm_sim_rs/src/types/result.rs\n@@ -58,6 +58,15 @@ pub struct LightweightSimResult {\n     #[pyo3(get)]\n     pub edges: HashMap<String, f64>,\n \n+    #[pyo3(get)]\n+    pub retail_edges: HashMap<String, f64>,\n+    #[pyo3(get)]\n+    pub arb_edges: HashMap<String, f64>,\n+    #[pyo3(get)]\n+    pub gas_stats: HashMap<String, (u64, u64, u64, u64, u64, u64)>,\n+    #[pyo3(get)]\n+    pub realised_sigma: f64,\n+\n     /// Initial fair price\n     #[pyo3(get)]\n     pub initial_fair_price: f64,\n",
  "terciles": null,
  "overall": null,
  "gas": {
    "max_ok": 243701,
    "oog": 19,
    "other_halts": 0,
    "by_strategy": {
      "submission": {
        "max_ok": 243701,
        "oog": 19,
        "other_halts": 0,
        "successful_calls": 10333234,
        "max_deployment_gas": 1560600,
        "deployments": 1000,
        "oog_seeds": [
          {
            "seed": 10043,
            "oog": 2
          },
          {
            "seed": 10044,
            "oog": 1
          },
          {
            "seed": 10057,
            "oog": 1
          },
          {
            "seed": 10150,
            "oog": 2
          },
          {
            "seed": 10231,
            "oog": 1
          },
          {
            "seed": 10295,
            "oog": 1
          },
          {
            "seed": 10300,
            "oog": 1
          },
          {
            "seed": 10305,
            "oog": 2
          },
          {
            "seed": 10386,
            "oog": 2
          },
          {
            "seed": 10697,
            "oog": 2
          },
          {
            "seed": 10786,
            "oog": 2
          },
          {
            "seed": 10795,
            "oog": 2
          }
        ]
      },
      "normalizer": {
        "max_ok": 22592,
        "oog": 0,
        "other_halts": 0,
        "successful_calls": 10733330,
        "max_deployment_gas": 191464,
        "deployments": 1000,
        "oog_seeds": []
      }
    }
  },
  "invalid_run_diagnostics": {
    "warning": "All statistics below include fallback-on-OOG execution and are invalid as challenge performance estimates. Provided only to diagnose the requested decomposition. Top-level n=0 counts accepted gas-valid observations; completed measurement runs=1000.",
    "completed_runs": 1000,
    "terciles": [
      {
        "tercile": 1,
        "n": 334,
        "total_edge": {
          "mean": 433.35651557584896,
          "se": 2.4179035837504035
        },
        "retail_edge": {
          "mean": 457.36366910586725,
          "se": 2.7966286855562235
        },
        "arb_edge": {
          "mean": -24.007153530018087,
          "se": 0.6147760726231803
        },
        "retail_volume_y": {
          "mean": 65254.49599520983,
          "se": 185.8162004550562
        },
        "mean_fee": {
          "mean": 0.003492838271994923,
          "se": 6.061779179753161e-06
        },
        "mean_fee_bps": 34.92838271994923,
        "mean_bid_fee": 0.0035477439493149555,
        "mean_ask_fee": 0.0034379325946748895,
        "realised_sigma": {
          "mean": 0.0009467452530336275,
          "se": 2.0766573945793762e-06
        },
        "configured_sigma": {
          "mean": 0.0009462699776739214,
          "se": 2.011468318812331e-06
        },
        "volume_min_y": 56486.15978238176,
        "volume_max_y": 70665.38617367185
      },
      {
        "tercile": 2,
        "n": 333,
        "total_edge": {
          "mean": 524.808923984361,
          "se": 2.3902754076402672
        },
        "retail_edge": {
          "mean": 552.4612137571365,
          "se": 3.1588298314123837
        },
        "arb_edge": {
          "mean": -27.65228977277536,
          "se": 1.265123298138561
        },
        "retail_volume_y": {
          "mean": 76285.4248810925,
          "se": 171.19496207561926
        },
        "mean_fee": {
          "mean": 0.003693157292043369,
          "se": 5.266636187489252e-06
        },
        "mean_fee_bps": 36.93157292043369,
        "mean_bid_fee": 0.0037400882770088797,
        "mean_ask_fee": 0.003646226307077857,
        "realised_sigma": {
          "mean": 0.0009456649001791552,
          "se": 2.064425370053132e-06
        },
        "configured_sigma": {
          "mean": 0.000945482641761706,
          "se": 2.0117239164566038e-06
        },
        "volume_min_y": 70698.22926121175,
        "volume_max_y": 81341.36683379854
      },
      {
        "tercile": 3,
        "n": 333,
        "total_edge": {
          "mean": 623.583601739829,
          "se": 3.2452303962701263
        },
        "retail_edge": {
          "mean": 656.1908685065297,
          "se": 4.091834890845453
        },
        "arb_edge": {
          "mean": -32.60726676670062,
          "se": 1.2638697475309781
        },
        "retail_volume_y": {
          "mean": 87051.56384042121,
          "se": 204.38862813292747
        },
        "mean_fee": {
          "mean": 0.003888258386066206,
          "se": 5.892625339634127e-06
        },
        "mean_fee_bps": 38.88258386066206,
        "mean_bid_fee": 0.0039614386030153905,
        "mean_ask_fee": 0.0038150781691170224,
        "realised_sigma": {
          "mean": 0.0009424366540139546,
          "se": 1.941416845463417e-06
        },
        "configured_sigma": {
          "mean": 0.0009426880447163905,
          "se": 1.9153231597563796e-06
        },
        "volume_min_y": 81344.48460940433,
        "volume_max_y": 98205.47208725398
      }
    ],
    "overall": {
      "n": 1000,
      "total_edge": {
        "mean": 527.1557872684889,
        "se": 2.91401927422812
      },
      "retail_edge": {
        "mean": 555.2406088751605,
        "se": 3.229606768662933
      },
      "arb_edge": {
        "mean": -28.08482160667154,
        "se": 0.6390764439747086
      },
      "retail_volume_y": {
        "mean": 76186.21890666414,
        "se": 301.69443638520715
      },
      "mean_fee": {
        "mean": 0.003691219403656793,
        "se": 6.091281782023063e-06
      },
      "mean_fee_bps": 36.912194036567925,
      "mean_bid_fee": 0.0037495549301192776,
      "mean_ask_fee": 0.003632883877194308,
      "realised_sigma": {
        "mean": 0.0009449507320595371,
        "se": 1.171425552179941e-06
      },
      "configured_sigma": {
        "mean": 0.0009448150111402959,
        "se": 1.1430956871846447e-06
      },
      "volume_min_y": 56486.15978238176,
      "volume_max_y": 98205.47208725398
    },
    "correlations": {
      "total": {
        "volume": 0.9079377961185319,
        "sigma": -0.060464462144176424,
        "configured_sigma": -0.053871438498096336
      },
      "retail": {
        "volume": 0.8579717631501361,
        "sigma": -0.05143946122166812,
        "configured_sigma": -0.04584020211483713
      },
      "arb": {
        "volume": -0.1958500850435051,
        "sigma": -0.0157498778917468,
        "configured_sigma": -0.01398359018103167
      }
    },
    "max_abs_edge_reconciliation_error": 1.3642420526593924e-11
  },
  "provenance": {
    "simulator_commit": "6b6921f8d463314aa7c96234e1be25a25245f704",
    "strategy_source_url": "https://api.imd.fun/artifacts/1f4f14f040b309e004904672ec6e2bb051f97b8d1195602d36b35a54c05d6c0f",
    "v2_sha256": "28417e116f57f1029fdd1803832e852574902c1ae7253c05657f317db76da4ab",
    "v2_creation_bytecode_sha256": "2d73bb233d6b9a126481277393c61277e460843b120fd022222b5ccf830fb87b",
    "vanilla_creation_bytecode_sha256": "3bcbd8a295b9d9c357e76df36a08c6232f8afa692a2189c643fe0d029a9efc05",
    "patch_sha256": "26a140baf849631979801c84f36357aab3d56f1a29de70dde13368c83679dcea",
    "observed_rows_sha256": "226c698ede87d2d2a0c50066d0a35163a974fd5407e0d70389394f8cd2117a96",
    "source_edits": [
      {
        "from": "if (g > 4) g = 4;",
        "to": "if (g > 1) g = 1;"
      },
      {
        "from": "_powWad(925000000000000000, g)",
        "to": "_powWad(800000000000000000, g)"
      }
    ],
    "compiler": {
      "version": "0.8.24",
      "optimizer_runs": 200,
      "viaIR": true,
      "evmVersion": "paris"
    },
    "configs": {
      "seeds_inclusive": [
        10000,
        10999
      ],
      "n_steps": 10000,
      "initial_price": 100,
      "initial_x": 100,
      "initial_y": 10000,
      "gbm_mu": 0,
      "gbm_dt": 1,
      "retail_buy_prob": 0.5,
      "retail_size_sigma": 1.2,
      "draws": "For each seed, np.random.default_rng(seed), then uniform(19,21) retail_mean_size, uniform(.6,1) retail_arrival_rate, uniform(.000882,.001008) gbm_sigma in that order; SimulationConfig.seed=seed. Rust price uses seed, retail uses seed+1."
    },
    "execution": "amm_sim_rs.run_batch(V2_creation_bytecode, Vanilla_creation_bytecode, configs, 8), consecutive batches of 20; V2 is never co-located with another candidate. No holdout or other seeds used.",
    "measurement_script": "import json,time,math\nfrom pathlib import Path\nimport numpy as np\nimport amm_sim_rs\nfrom amm_competition.competition.config import build_config\nv2=list(Path('scratch/V2.bin').read_bytes()); vanilla=list(Path('scratch/Vanilla.bin').read_bytes())\nrows=json.loads(Path(\"scratch/rows.json\").read_text()) if Path(\"scratch/rows.json\").exists() else []; start=time.monotonic()\nfor first in range(10000+len(rows),11000,20):\n configs=[]\n for seed in range(first,first+20):\n  rng=np.random.default_rng(seed)\n  size=rng.uniform(19,21); rate=rng.uniform(.6,1.0); sigma=rng.uniform(.000882,.001008)\n  configs.append(build_config(seed=seed,gbm_sigma=sigma,retail_arrival_rate=rate,retail_mean_size=size))\n result=amm_sim_rs.run_batch(v2,vanilla,configs,8)\n for r,c in zip(result.results,configs):\n  assert r.seed==c.seed\n  total=r.edges['submission']; retail=r.retail_edges['submission']; arb=r.arb_edges['submission']\n  assert abs(total-retail-arb)<1e-7,(r.seed,total,retail,arb)\n  fees=r.average_fees['submission']\n  rows.append(dict(seed=r.seed,total=total,retail=retail,arb=arb,volume=r.retail_volume_y['submission'],fee=(fees[0]+fees[1])/2,bid_fee=fees[0],ask_fee=fees[1],sigma=r.realised_sigma,configured_sigma=c.gbm_sigma,retail_mean_size=c.retail_mean_size,retail_arrival_rate=c.retail_arrival_rate,gas={k:list(v) for k,v in r.gas_stats.items()}))\n Path('scratch/rows.json').write_text(json.dumps(rows,allow_nan=False))\n gas={k: [max(x['gas'][k][0] for x in rows),sum(x['gas'][k][1] for x in rows),sum(x['gas'][k][2] for x in rows)] for k in ['submission','normalizer']}\n print(json.dumps(dict(n=len(rows),elapsed_s=time.monotonic()-start,edge=np.mean([x['total'] for x in rows]),gas=gas)),flush=True)\n del result\nprint('DONE',flush=True)\n"
  },
  "checks": {
    "setup_script_run_once": true,
    "starter_validation_passed": true,
    "instrumented_release_build_passed": true,
    "v2_source_sha256_matches_required": true,
    "all_1000_unique_requested_seeds_present": true,
    "all_summary_inputs_finite": true,
    "all_arb_edges_nonpositive": true,
    "every_seed_edge_split_reconciles_within_1e_7": true,
    "gas_valid": false
  },
  "notes": [
    "The goal-wide tuning and holdout directions are superseded by this item: this is only the V2 decomposition on 10000..10999; no fee rule was designed, changed, tuned or submitted.",
    "The simulator intentionally keeps previous fees when afterSwap fails; therefore apparently reasonable means can conceal invalid OOG paths. The reported invalid-run diagnostics include this unchanged fallback behavior.",
    "The controller stopped after 60 seeds when counters first found OOG, then resumed at 10060 solely to complete the requested 1000-seed diagnostic and full halt count. No completed seed was rerun or replaced. The supplied script supports that resume through scratch/rows.json.",
    "No gas limit, contract, base math, routing, fee-update behavior or configuration source was modified; patch only adds measurements. Max successful gas below 250000 does not prove no OOG; explicit Halt counters are decisive.",
    "519.68 is the requester-provided board reference; it was not independently retrieved. No claim of equality, improvement or board transfer is made from an OOG-invalid measurement.",
    "Null top-level terciles and overall intentionally withhold valid performance statistics. Detailed arithmetic summaries are under invalid_run_diagnostics. Locally measured values have local provenance; public sources listed in sources.json support the source code and definitions, not independent validation of this run.",
    "All setup/build/measurement work stayed in disposable test/scratch. Only result.json and sources.json are delivered. No requester input is needed to report this failure."
  ]
}
