{
 "credit": "Taylor (gtmcknight), github.com/gtmcknight/amm-sim@4812a6382311624e1506aca131ca35c378f930d9 research/solved: the solved policy, replica2.py and the fast LEAN replica this core is meant to replace as the tuning target. enginecore.py is a port of the Rust engine benedictbrady/amm-challenge@6b6921f8d463314aa7c96234e1be25a25245f704 (amm_sim_rs), not of the replica.",
 "item": "r2 (b-core): engine-faithful fast simulation core, proven seed by seed against the Rust engine",
 "ready": true,
 "summary": "enginecore.py reproduces the engine's submission edge bit for bit on all 128 runs (seeds 9700000..9700063, constant 30/30 and 25/45 bps). A third contract whose fees depend on every afterSwap argument down to the last WAD digit is also bit-equal on 16 seeds, so the callback is handed what the contract is handed, and a contract that returns fees above MAX_FEE is bit-equal on 8 seeds, so refused returns are treated as the engine treats them. One difference the differences list did not have was needed: the libm crate's exp for order sizes.",
 "parity": {
  "n": 128,
  "max_abs_diff": 0.0,
  "max_rel_diff": 0.0,
  "bit_identical": 128,
  "worst": {
   "seed": 9700000,
   "policy": "30/30",
   "engine": 346.0273756163182,
   "enginecore": 346.0273756163182
  },
  "worst_note": "all 128 differences are exactly 0; the entry shown is the first run",
  "seeds": "9700000..9700063",
  "policies": [
   "30/30",
   "25/45"
  ],
  "mean_edge": {
   "30/30": {
    "engine": 337.9826448365718,
    "enginecore": 337.9826448365718
   },
   "25/45": {
    "engine": 345.4532596083489,
    "enginecore": 345.4532596083489
   }
  },
  "engine_path": "kit engine_eval.run_batch(seeds, Strategy.sol), one singleton run per seed",
  "engine_after_swap_peak_gas": {
   "30/30": 22606,
   "25/45": 22614
  }
 },
 "step_logs": {
  "compared": {
   "logging_patch_built": false,
   "what": "No cargo or rustc on this worker, so the engine was not rebuilt with a logging patch. Compared instead: the per-step results the release wheel already returns (LightweightStepResult: fair_price, spot_prices, pnls, fees) against enginecore's step log, plus each run's totals (edges, pnl, arb_volume_y, retail_volume_y, average_fees) for both pools.",
   "seeds": [
    9700000,
    9700001,
    9700002,
    9700003
   ],
   "policies": [
    "30/30",
    "25/45"
   ],
   "runs": 8,
   "steps": 80000,
   "values": 560080,
   "values_equal_bit_for_bit": true,
   "per_step_fields": [
    "fair_price",
    "spot_price submission",
    "spot_price normalizer",
    "running pnl submission",
    "running pnl normalizer",
    "bid fee",
    "ask fee"
   ],
   "covers": "price exactly; reserves and fee buckets of both pools through reserve_y/reserve_x and through PnL = reserves and fee buckets valued at the fair price, after every step",
   "not_compared": "individual orders, fills and reserve values were not read from the engine"
  },
  "first_divergence": null
 },
 "callback_probe": {
  "what": "fees = f(isBuy, amountX, amountY, timestamp, reserveX, reserveY) using the low WAD digits of each; same rule as an njit policy on the WAD floats",
  "seeds": [
   9700000,
   9700015
  ],
  "n": 16,
  "bit_identical": 16,
  "max_abs_diff": 0.0,
  "max_rel_diff": 0.0,
  "worst": {
   "seed": 9700000,
   "engine": 350.31465485856995,
   "enginecore": 350.31465485856995
  },
  "refused_fee_returns": 0,
  "after_swap_calls": 166246,
  "engine_after_swap_peak_gas": 23409,
  "step_logs": {
   "runs": 2,
   "steps": 20000,
   "values": 140020,
   "distinct_fee_pairs": [
    6715,
    6203
   ],
   "first_divergence": null
  }
 },
 "refusal_probe": {
  "what": "afterSwap returns a bid or an ask above MAX_FEE on steps with timestamp % 4 in (0, 1), exactly MAX_FEE on some others; the engine must keep the current pair when it refuses",
  "seeds": [
   9700000,
   9700007
  ],
  "n": 8,
  "edges_bit_identical": 8,
  "totals_bit_equal": 80,
  "totals": 80,
  "steps": 80000,
  "values": 560080,
  "first_divergence": null,
  "after_swap_calls": 53237,
  "refused_fee_returns": 24854,
  "max_fee_seen": 0.1,
  "edges": [
   {
    "seed": 9700000,
    "engine": 311.3452369545313,
    "enginecore": 311.3452369545313
   },
   {
    "seed": 9700001,
    "engine": 284.1180622865175,
    "enginecore": 284.1180622865175
   },
   {
    "seed": 9700002,
    "engine": 372.177824353839,
    "enginecore": 372.177824353839
   },
   {
    "seed": 9700003,
    "engine": 237.90572061292448,
    "enginecore": 237.90572061292448
   },
   {
    "seed": 9700004,
    "engine": 355.42236240933573,
    "enginecore": 355.42236240933573
   },
   {
    "seed": 9700005,
    "engine": 205.56412750199036,
    "enginecore": 205.56412750199036
   },
   {
    "seed": 9700006,
    "engine": 321.37814964217426,
    "enginecore": 321.37814964217426
   },
   {
    "seed": 9700007,
    "engine": 323.2916337640074,
    "enginecore": 323.2916337640074
   }
  ]
 },
 "ported": [
  {
   "what": "k recomputed from the stored (rounded) reserves at every quote and at every arbitrage sizing",
   "engine": "amm_sim_rs/src/amm/cfmm.rs:131,152,180; amm_sim_rs/src/market/arbitrageur.rs:56,106",
   "done": true
  },
  {
   "what": "reserves moved by increments (net = amount - fee_amount), fee kept in a separate bucket that counts in PnL but not in k; execute_sell_x re-derives net_y = total_y - fee_amount",
   "engine": "amm_sim_rs/src/amm/cfmm.rs:207-210,238-241,269-272",
   "done": true
  },
  {
   "what": "arbitrage: spot against fair, closed-form size, 99% cap, profit from the quote, trade only if profit > 0; edge -= profit",
   "engine": "amm_sim_rs/src/market/arbitrageur.rs:35-147; amm_sim_rs/src/simulation/engine.rs:141-148",
   "done": true
  },
  {
   "what": "router split (sqrt(x*gamma*y), r, numerator, denominator, clamp to [0,total]), 0.0001 threshold, total_x = size / fair_price; same operations in the same order",
   "engine": "amm_sim_rs/src/market/router.rs:40-75,82-117,188,221",
   "done": true
  },
  {
   "what": "execution order: the submission is arbitraged and filled first, then the 30 bps pool",
   "engine": "amm_sim_rs/src/simulation/engine.rs:120,141; amm_sim_rs/src/market/router.rs:198-218,224-244",
   "done": true
  },
  {
   "what": "truncated WAD integers at the EVM boundary: afterInitialize and afterSwap arguments are trunc(value*1e18); retail edge and retail volume use the WAD-truncated amount read back as float",
   "engine": "amm_sim_rs/src/amm/cfmm.rs:77-78,212-219,243-250,274-281; amm_sim_rs/src/types/wad.rs:33,39; amm_sim_rs/src/market/router.rs:160,170,203,214,228,239",
   "done": true
  },
  {
   "what": "the fee clamp: a returned fee above 1e17 is refused, not clamped (decode fails, current fees stay; in afterInitialize the run fails); fee = int/1e18; gamma clamped to [0,1] in the quotes",
   "engine": "amm_sim_rs/src/types/trade_info.rs:113-131; amm_sim_rs/src/amm/cfmm.rs:81,125,154,182,293-298; amm_sim_rs/src/types/wad.rs:71-73",
   "done": true,
   "note": "proven on the engine by refusal_probe: a contract returning fees above MAX_FEE, and exactly MAX_FEE, gives bit-equal edges and per-step fees; the afterInitialize failure is unit-tested only"
  },
  {
   "what": "random streams: Pcg64 seeded with seed (price) and seed+1 (retail); GBM step; Poisson count, then per order lognormal size and uniform side",
   "engine": "amm_sim_rs/src/market/price_process.rs:37-67; amm_sim_rs/src/market/retail.rs:43-100; amm_sim_rs/src/simulation/engine.rs:51-69",
   "done": true
  },
  {
   "what": "found here, not in the differences list: order sizes and the Poisson threshold take exp from the pure-Rust libm crate (rand_distr builds num-traits with features=[libm], no std), while the price step and the normal's pdf use the C library's exp. With the C exp everywhere the core was within 1.6e-13 relative but bit-equal on 1 of 4 edges; with libm's exp ported it is bit-equal",
   "engine": "amm_sim_rs/src/market/retail.rs:56-60,77,87 (rand_distr 0.4.3 normal.rs:314, poisson.rs Poisson::new; libm src/math/exp.rs)",
   "done": true
  },
  {
   "what": "per-seed config draw (retail_mean_size, retail_arrival_rate, gbm_sigma from numpy default_rng(seed))",
   "engine": "kit bootstrap/smoke_engine.py config_for; amm_competition/competition/config.py",
   "done": true
  },
  {
   "what": "edge, PnL, volume and average-fee accounting",
   "engine": "amm_sim_rs/src/simulation/engine.rs:143-161,165-205",
   "done": true
  },
  {
   "what": "gas limit (250,000), revert and out-of-gas handling, contract storage",
   "engine": "amm_sim_rs/src/evm/strategy.rs:32-34,197-232",
   "done": false,
   "note": "the policy is a callback; nothing to meter"
  },
  {
   "what": "Poisson for lambda >= 12 (Cauchy rejection branch)",
   "engine": "rand_distr 0.4.3 src/poisson.rs",
   "done": false,
   "note": "the puzzle's arrival rate is 0.6..1.0; enginecore returns status 2 instead of guessing"
  }
 ],
 "rng": {
  "generator": "rand_pcg Pcg64 = Lcg128Xsl64: 128-bit LCG, multiplier 0x2360ED051FC65DA44385DF649FCCF645, XSL-RR 64-bit output; ported in uint64 limbs and checked against a big-integer reference and the crate's own test vector",
  "seeding": "rand_core SeedableRng::seed_from_u64: eight PCG32 words (mul 6364136223846793005, inc 11634580027462260723) fill the 32-byte seed; state = bytes 0..16, increment = bytes 16..32 | 1; then state += increment and one step. Price stream: seed. Retail stream: seed + 1. The seed is the config's seed, which the kit sets to the run's seed number.",
  "distributions": {
   "price": "z = StandardNormal (ZIGNOR ziggurat, 256 layers, tables ZIG_NORM_X/F, tail by two Open01 logs); price *= exp((mu - sigma^2/2)*dt + sigma*sqrt(dt)*z) with the C library's exp",
   "arrivals": "Poisson(lambda), Knuth: multiply Standard f64 uniforms until the product is <= exp(-lambda) (libm crate exp); count - 1",
   "sizes": "LogNormal(ln(mean) - sigma^2/2, sigma): libm-crate exp(mu + sigma*z), z StandardNormal",
   "sides": "buy if Standard f64 uniform < retail_buy_prob; per order the size is drawn before the side",
   "uniform": "Standard f64 = (next_u64 >> 11) * 2^-53; Open01 = 1.fraction - (1 - 2^-53) from the top 52 bits",
   "config": "numpy default_rng(seed).uniform for retail_mean_size [19,21], retail_arrival_rate [0.6,1.0], gbm_sigma [0.000882,0.001008], in that order (kit bootstrap/smoke_engine.config_for)"
  },
  "crate_versions": {
   "required_by_engine_Cargo_toml": {
    "rand": "0.8",
    "rand_pcg": "0.3",
    "rand_distr": "0.4"
   },
   "ported_from": {
    "rand": "0.8.5",
    "rand_core": "0.6.4",
    "rand_pcg": "0.3.1",
    "rand_distr": "0.4.3",
    "libm": "0.2.8 (src/math/exp.rs and scalbn.rs; exp.rs is the same code in 0.2.11 and 0.2.15)",
    "num-traits": "0.2.19"
   },
   "in_the_wheel": "not readable: the checkout has no Cargo.lock and the binary carries no version strings for these crates (it does for pyo3 0.22.6, revm 18.0.0, revm-interpreter 14.0.0, rayon 1.12.0). The versions above are the last releases of each required series; that they are the ones compiled in is shown by the bit-equal streams, not by a lock file."
  }
 },
 "runs_per_core_s": 227.4,
 "speed": {
  "what": "constant-fee policy, 10,000 steps, one compiled call per run on one thread, warm (JIT compiled before timing), config draw and Python wrapper included; 128 runs",
  "timing_s": {
   "engine_s_30/30": 63.50445265322924,
   "enginecore_s_30/30": 0.388289799913764,
   "engine_s_25/45": 49.45927847363055,
   "enginecore_s_25/45": 0.17461299523711205
  },
  "engine_runs_per_s": 1.13,
  "varies": "the worker was shared: the same 128-run measurement gave 366, 353 and 319 runs per core-second on three earlier runs of this session and the figure reported here on the last; the engine's own rate moved with it (3.5, 3.2, then the figure here)",
  "note": "the callback probe policy costs more per call; a tracker policy will set its own rate"
 },
 "api": {
  "main_file": "enginecore/enginecore.py",
  "policy": "Policy(name, init_fn, swap_fn, state_size, params); init_fn(params, state, initial_x_wad, initial_y_wad) and swap_fn(params, state, is_buy, amount_x_wad, amount_y_wad, timestamp, reserve_x_wad, reserve_y_wad) are njit functions returning (bid_wad, ask_wad) as int64",
  "wad": "arguments are float64 holding the exact truncated WAD integer (reserve_y is about 1e22, above int64); wad_split(w) gives exact int64 limbs hi*2^60 + lo",
  "calls": "run(seed, bid_bps, ask_bps), run_batch(seeds, bid_bps, ask_bps) for constant fees; Policy.run(seed, params, log=True) returns the per-step log; Policy.run_batch is one threaded compiled call",
  "example": "parity_engine.py make_probe: a contract and the same rule as a policy"
 },
 "code_zb64": "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",
 "code_encoding": "base64(zlib(tar)); members enginecore/enginecore.py, enginecore/test_enginecore.py, enginecore/parity_engine.py",
 "source_sha256": "0c7fe0e2fff79f278cf5eddcf2c8883d0ce81099962ca5e93b8a76279013784b",
 "files_sha256": {
  "enginecore.py": "0c7fe0e2fff79f278cf5eddcf2c8883d0ce81099962ca5e93b8a76279013784b",
  "test_enginecore.py": "655db0d681d5e51a2667bb4cdb75b5a53eee0b0a9352633a4262d318456d3f05",
  "parity_engine.py": "c48dffed2daa7b8519d547179d47c3015958a0d24eaca5d52b5a323b77b4f6a7"
 },
 "tests": {
  "command": "python3 -B test_enginecore.py",
  "last_line": "PASS 9 tests"
 },
 "run": [
  "git init kitrepo && cd kitrepo && git remote add origin https://github.com/identity-md-launches/goal-3178-build-shared-evaluation-kit.git && git fetch --depth 1 origin 45e7563d1a29ffca9d608fdf60c90bf2624d2d01 && git checkout FETCH_HEAD   # under test/scratch",
  "bash setup_fast.sh --platform linux-x86_64 --cache test/scratch/cache --scratch test/scratch/rt   # from kitrepo, absolute paths",
  "python3 -c 'import base64,zlib,io,tarfile,json; tarfile.open(fileobj=io.BytesIO(zlib.decompress(base64.b64decode(json.load(open(\"result.json\"))[\"code_zb64\"])))).extractall(\"test/scratch/work\")'",
  ". test/scratch/rt/env.sh && cd test/scratch/work/enginecore && python3 -B test_enginecore.py",
  ". test/scratch/rt/env.sh && cd test/scratch/work/enginecore && python3 -B parity_engine.py --kit ../../kitrepo --first 9700000 --n 64 --steplog 4 --probe 16 --refusal 8 --work ../pw --out ../parity_64.json"
 ],
 "environment": {
  "platform": "linux-x86_64",
  "python": "3.12.16",
  "numba": "0.68.1",
  "numpy": "2.5.4",
  "llvmlite": "0.50.0",
  "engine_wheel": "amm_sim_rs 0.1.0.post1, native sha256 ff88b6353c2aad7342f0a26194f7347e78b9c3b38d683a7449006d423978cd14",
  "solc": "0.8.24",
  "note": "the price step uses the C library's exp and ln on both sides; bit equality was shown on this platform with the kit's pinned runtime only"
 },
 "seeds_used": "engine seeds 9700000..9700063 only; no seed from 10,200,000 up; nothing submitted to the leaderboard",
 "not_done": [
  "Engine not rebuilt with a logging patch: this worker has no cargo or rustc, and no C compiler or linker (cc, gcc, ld) to build one with. Orders, fills and reserves were not compared one by one; the engine's own per-step fair price, spot prices, running PnL and fees were, on 4 seeds x 2 constant policies, 2 seeds of the callback probe and 8 seeds of the refusal probe, with no divergence.",
  "LEAN / QLX5 is not ported onto this core; only constant-fee policies are delivered, plus the callback probe inside parity_engine.py. Re-tuning on the core is the next step, not part of this item.",
  "Gas, reverts, out-of-gas and contract storage are not modelled.",
  "A contract whose afterInitialize returns a fee above 10% was not run on the engine; enginecore returns status 1 for it, from the engine source (engine.rs:94-95).",
  "Poisson with lambda >= 12 is not ported (status 2).",
  "The crate versions compiled into the wheel could not be read; see rng.crate_versions.",
  "Parity was run on linux-x86_64 with the kit runtime only; macOS was not tried."
 ]
}
