# delta ```diff --- NP2 +++ p117e2 @@ -150,2 +150,7 @@ - uint256 fBase = BASE_FEE + wmul(SIGMA_COEF, sigmaHat) + wmul(LAMBDA_COEF, lambdaHat) + wmul(FLOW_SIZE_COEF, flowSize); - uint256 fMid = fBase + wmul(TOX_COEF, toxSignal) + wmul(TOX_QUAD_COEF, wmul(toxSignal, toxSignal)) + wmul(ACT_COEF, actEma); + uint256 flowFee = wmul(LAMBDA_COEF, lambdaHat) + wmul(FLOW_SIZE_COEF, flowSize) + wmul(ACT_COEF, actEma); + if (lambdaHat > 117 * WAD / 100) { + uint256 ratio = wdiv(117 * WAD / 100, lambdaHat); + flowFee = wmul(flowFee, wmul(ratio, ratio)); + } + uint256 fBase = BASE_FEE + wmul(SIGMA_COEF, sigmaHat) + flowFee; + uint256 fMid = fBase + wmul(TOX_COEF, toxSignal) + wmul(TOX_QUAD_COEF, wmul(toxSignal, toxSignal)); ``` # code Full source; all 39 existing NP2 constants and every line outside the fee-construction replacement are unchanged. NP2 was reconstructed from [TWO](https://api.imd.fun/artifacts/528a6da78583c6142644a552c86670f9d25c20e39e92f4de44deae05ddc8cecd) and the specified [NP routing block](https://api.imd.fun/artifacts/da313379a2e69e9286668865e06b18dfcae25732c82b934b0fd9c2ef0d8c2ff5). ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {AMMStrategyBase} from "./AMMStrategyBase.sol"; import {TradeInfo} from "./IAMMStrategy.sol"; contract Strategy is AMMStrategyBase { uint256 constant ELAPSED_CAP = 8; uint256 constant SIGNAL_THRESHOLD = WAD / 650; uint256 constant DIR_DECAY = 750000000000000000; uint256 constant ACT_DECAY = 530000000000000000; uint256 constant SIZE_DECAY = 530000000000000000; uint256 constant TOX_DECAY = 910000000000000000; uint256 constant SIGMA_DECAY = 690000000000000000; uint256 constant LAMBDA_DECAY = 990000000000000000; uint256 constant SIZE_BLEND_DECAY = 828000000000000000; uint256 constant TOX_BLEND_DECAY = 51000000000000000; uint256 constant ACT_BLEND_DECAY = 985000000000000000; uint256 constant PHAT_ALPHA = 270000000000000000; uint256 constant PHAT_ALPHA_RETAIL = 60000000000000000; uint256 constant PHAT_ALPHA_SAME = 120000000000000000; uint256 constant REVERT_U = 0; uint256 constant DIR_IMPACT_MULT = 4; uint256 constant GATE_SIGMA_MULT = 7200000000000000000; uint256 constant MIN_GATE = 30000000000000000; uint256 constant TRADE_TOX_BOOST = 3500 * BPS; uint256 constant STALE_ATTRACT_FRAC = 1050000000000000000; uint256 constant RET_CAP = WAD / 35; uint256 constant TOX_CAP = WAD / 5; uint256 constant TRADE_RATIO_CAP = WAD / 5; uint256 constant LAMBDA_CAP = 1820000000000000000; uint256 constant STEP_COUNT_CAP = 64; uint256 constant BASE_FEE = 4 * BPS; uint256 constant SIGMA_COEF = 200000000000000000; uint256 constant LAMBDA_COEF = 12 * BPS; uint256 constant FLOW_SIZE_COEF = 4842 * BPS; uint256 constant TOX_COEF = 300 * BPS; uint256 constant TOX_QUAD_COEF = 15000 * BPS; uint256 constant ACT_COEF = 91843 * BPS; uint256 constant DIR_COEF = 20 * BPS; uint256 constant DIR_TOX_COEF = 100 * BPS; uint256 constant STALE_DIR_COEF = 6850 * BPS; uint256 constant SIGMA_TOX_COEF = 500 * BPS; uint256 constant TAIL_KNEE = 600 * BPS; uint256 constant TAIL_SLOPE_PROTECT = 930000000000000000; uint256 constant TAIL_SLOPE_ATTRACT = 850000000000000000; function afterInitialize(uint256 initialX, uint256 initialY) external override returns (uint256, uint256) { slots[0] = BASE_FEE; slots[1] = BASE_FEE; slots[2] = 0; slots[3] = WAD; slots[4] = 0; slots[5] = initialX > 0 ? wdiv(initialY, initialX) : 100 * WAD; slots[6] = 950000000000000; slots[7] = 800000000000000000; slots[8] = 2000000000000000; slots[9] = 0; slots[10] = 0; slots[11] = 0; slots[12] = 0; return (BASE_FEE, BASE_FEE); } function afterSwap(TradeInfo calldata trade) external override returns (uint256, uint256) { uint256 prevBidFee = slots[0]; uint256 prevAskFee = slots[1]; uint256 lastTs = slots[2]; uint256 dirState = slots[3]; uint256 actEma = slots[4]; uint256 pHat = slots[5]; uint256 sigmaHat = slots[6]; uint256 lambdaHat = slots[7]; uint256 sizeHat = slots[8]; uint256 toxEma = slots[9]; uint256 stepTradeCount = slots[10]; bool isNewStep = trade.timestamp > lastTs; if (isNewStep) { uint256 elapsedRaw = trade.timestamp - lastTs; uint256 elapsed = elapsedRaw > ELAPSED_CAP ? ELAPSED_CAP : elapsedRaw; dirState = _decayCentered(dirState, DIR_DECAY, elapsed); actEma = wmul(actEma, _powWad(ACT_DECAY, elapsed)); sizeHat = wmul(sizeHat, _powWad(SIZE_DECAY, elapsed)); toxEma = wmul(toxEma, _powWad(TOX_DECAY, elapsed)); if (stepTradeCount > 0 && elapsedRaw > 0) { uint256 lambdaInst = (stepTradeCount * WAD) / elapsedRaw; if (lambdaInst > LAMBDA_CAP) lambdaInst = LAMBDA_CAP; lambdaHat = wmul(lambdaHat, LAMBDA_DECAY) + wmul(lambdaInst, WAD - LAMBDA_DECAY); } stepTradeCount = 0; } bool firstInStep = stepTradeCount == 0; uint256 spot = trade.reserveX > 0 ? wdiv(trade.reserveY, trade.reserveX) : pHat; if (pHat == 0) pHat = spot; uint256 feeUsed = trade.isBuy ? prevBidFee : prevAskFee; uint256 gamma = feeUsed < WAD ? WAD - feeUsed : 0; uint256 pImplied; if (gamma == 0) { pImplied = spot; } else { pImplied = trade.isBuy ? wmul(spot, gamma) : wdiv(spot, gamma); } { uint256 ret = pHat > 0 ? wdiv(absDiff(pImplied, pHat), pHat) : 0; uint256 alpha = firstInStep ? PHAT_ALPHA : PHAT_ALPHA_RETAIL; uint256 prePhat = pHat; bool secondPrint = !firstInStep && stepTradeCount == 1; bool sameDir = false; bool oppDir = false; if (secondPrint) { bool up2 = pImplied >= pHat; uint256 d1 = slots[12]; if (d1 != 0) { sameDir = (d1 == 1) == up2; oppDir = !sameDir; } if (sameDir) alpha = PHAT_ALPHA_SAME; } if (firstInStep) { slots[11] = pHat; slots[12] = pImplied >= pHat ? 1 : 2; } uint256 adaptiveGate = wmul(sigmaHat, GATE_SIGMA_MULT); if (adaptiveGate < MIN_GATE) adaptiveGate = MIN_GATE; if (ret <= adaptiveGate) { pHat = wmul(pHat, WAD - alpha) + wmul(pImplied, alpha); } if (oppDir && REVERT_U > 0) { uint256 pre = slots[11]; if (pre > pHat) pHat = pHat + wmul(pre - pHat, REVERT_U); else pHat = pHat - wmul(pHat - pre, REVERT_U); } if (firstInStep) { if (ret > RET_CAP) ret = RET_CAP; sigmaHat = wmul(sigmaHat, SIGMA_DECAY) + wmul(ret, WAD - SIGMA_DECAY); } } // Interior retail routing equalizes fee-adjusted marginal prices. // Subsequent trades in a step cannot be the initial arbitrage trade. if (!firstInStep && feeUsed > 30 * BPS && gamma > 0) { uint256 normalSpot = trade.isBuy ? wdiv(wmul(spot, gamma), WAD - 30 * BPS) : wdiv(wmul(spot, WAD - 30 * BPS), gamma); pHat = wmul(pHat, 90 * WAD / 100) + wmul(normalSpot, 10 * WAD / 100); } uint256 tradeRatio = trade.reserveY > 0 ? wdiv(trade.amountY, trade.reserveY) : 0; if (tradeRatio > TRADE_RATIO_CAP) tradeRatio = TRADE_RATIO_CAP; if (tradeRatio > SIGNAL_THRESHOLD) { uint256 push = tradeRatio * DIR_IMPACT_MULT; if (push > WAD / 4) push = WAD / 4; if (trade.isBuy) { dirState = dirState + push; if (dirState > 2 * WAD) dirState = 2 * WAD; } else { dirState = dirState > push ? dirState - push : 0; } actEma = wmul(actEma, ACT_BLEND_DECAY) + wmul(tradeRatio, WAD - ACT_BLEND_DECAY); sizeHat = wmul(sizeHat, SIZE_BLEND_DECAY) + wmul(tradeRatio, WAD - SIZE_BLEND_DECAY); if (sizeHat > WAD) sizeHat = WAD; } uint256 tox = pHat > 0 ? wdiv(absDiff(spot, pHat), pHat) : 0; if (tox > TOX_CAP) tox = TOX_CAP; toxEma = wmul(toxEma, TOX_BLEND_DECAY) + wmul(tox, WAD - TOX_BLEND_DECAY); uint256 toxSignal = toxEma; stepTradeCount = stepTradeCount + 1; if (stepTradeCount > STEP_COUNT_CAP) stepTradeCount = STEP_COUNT_CAP; uint256 flowSize = wmul(lambdaHat, sizeHat); uint256 flowFee = wmul(LAMBDA_COEF, lambdaHat) + wmul(FLOW_SIZE_COEF, flowSize) + wmul(ACT_COEF, actEma); if (lambdaHat > 117 * WAD / 100) { uint256 ratio = wdiv(117 * WAD / 100, lambdaHat); flowFee = wmul(flowFee, wmul(ratio, ratio)); } uint256 fBase = BASE_FEE + wmul(SIGMA_COEF, sigmaHat) + flowFee; uint256 fMid = fBase + wmul(TOX_COEF, toxSignal) + wmul(TOX_QUAD_COEF, wmul(toxSignal, toxSignal)); fMid = fMid + wmul(SIGMA_TOX_COEF, wmul(sigmaHat, toxSignal)); uint256 dirDev; bool sellPressure; if (dirState >= WAD) { dirDev = dirState - WAD; sellPressure = true; } else { dirDev = WAD - dirState; sellPressure = false; } uint256 skew = wmul(DIR_COEF, dirDev) + wmul(DIR_TOX_COEF, wmul(dirDev, toxSignal)); uint256 bidFee; uint256 askFee; if (sellPressure) { bidFee = fMid + skew; askFee = fMid > skew ? fMid - skew : 0; } else { askFee = fMid + skew; bidFee = fMid > skew ? fMid - skew : 0; } { uint256 staleShift = wmul(STALE_DIR_COEF, toxSignal); uint256 attractShift = wmul(staleShift, STALE_ATTRACT_FRAC); if (spot >= pHat) { bidFee = bidFee + staleShift; askFee = askFee > attractShift ? askFee - attractShift : 0; } else { askFee = askFee + staleShift; bidFee = bidFee > attractShift ? bidFee - attractShift : 0; } } { bool tradeAligned = (trade.isBuy && spot >= pHat) || (!trade.isBuy && spot < pHat); if (tradeAligned) { uint256 tradeBoost = wmul(TRADE_TOX_BOOST, tradeRatio); if (trade.isBuy) { bidFee = bidFee + tradeBoost; } else { askFee = askFee + tradeBoost; } } } if (sellPressure) { bidFee = clampFee(_compressTailWithSlope(bidFee, TAIL_SLOPE_PROTECT)); askFee = clampFee(_compressTailWithSlope(askFee, TAIL_SLOPE_ATTRACT)); } else { askFee = clampFee(_compressTailWithSlope(askFee, TAIL_SLOPE_PROTECT)); bidFee = clampFee(_compressTailWithSlope(bidFee, TAIL_SLOPE_ATTRACT)); } slots[0] = bidFee; slots[1] = askFee; slots[2] = trade.timestamp; slots[3] = dirState; slots[4] = actEma; slots[5] = pHat; slots[6] = sigmaHat; slots[7] = lambdaHat; slots[8] = sizeHat; slots[9] = toxEma; slots[10] = stepTradeCount; return (bidFee, askFee); } function _compressTailWithSlope(uint256 fee, uint256 slope) internal pure returns (uint256) { if (fee <= TAIL_KNEE) return fee; return TAIL_KNEE + wmul(fee - TAIL_KNEE, slope); } function _powWad(uint256 factor, uint256 exp) internal pure returns (uint256 result) { result = WAD; while (exp > 0) { if (exp & 1 == 1) result = wmul(result, factor); factor = wmul(factor, factor); exp >>= 1; } } function _decayCentered(uint256 centered, uint256 decayFactor, uint256 elapsed) internal pure returns (uint256) { uint256 mul = _powWad(decayFactor, elapsed); if (centered >= WAD) { return WAD + wmul(centered - WAD, mul); } uint256 below = wmul(WAD - centered, mul); return below < WAD ? WAD - below : 0; } function getName() external pure override returns (string memory) { return "no_cubic"; } } ``` # sha256 `cd795ee5318838bcddde77ce6d90bd8069630964a1f85910f31312d8c9115823` SHA-256 is over exactly the UTF-8 Solidity inside the preceding code fence, including its trailing newlines. Reconstructed NP2: `51f1c1a9d4999ee460eb8bbc66880da8074b173399a4f5d71f96671482e18ac0`. # tuning All figures below are local measurements, not leaderboard observations. Chosen: **p117e2**. Selected because its completed 128-seed Vanilla diagnostic met the slope and low-volume fee targets. The fee target was met, but the separate Vanilla tuning edge was negative, so retain NP2. No confirmation seeds were used in selection. Selection was frozen at `2026-11-07T17:49:54.672037+00:00` before confirmation. All remaining grid jobs were already queued; they completed without changing the selected source or using confirmation outcomes for selection. Simulator commit: `6b6921f8d463314aa7c96234e1be25a25245f704`; the exact requested setup script completed successfully. Local calibration, seeds 0–999, separately against Vanilla: CH **525.525882178083**, NP2 **526.115572245986**. The [CH source](https://raw.githubusercontent.com/ChengHua926/amm-challenge/d34a5199c59a4c44d5336a25f1436b4ae1f21104/contracts/src/Strategy.sol) supplies the calibration baseline; [30-bps Vanilla](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/contracts/src/VanillaStrategy.sol) is the other pool for calibration and the independent tuning diagnostics. Configuration: for each seed, `rng = numpy.random.default_rng(seed)`; draw size `U(19,21)`, rate `U(0.6,1.0)`, sigma `U(0.000882,0.001008)` in that order; set `cfg.seed=seed`. Other settings: 10,000 steps; price 100; reserves (100,10,000); mu 0; dt 1; buy probability 0.5; retail log-size sigma 1.2. All 12 configuration fields matched `_build_configs` exactly for seeds 0–999. See [draw order](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_competition/competition/match.py), [canonical settings](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_competition/competition/config.py), and [price seed / retail seed+1](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/simulation/engine.rs). Direct tuning uses `amm_sim_rs.run_batch(candidate_bytecode, np2_bytecode, configs, 8)` in chunks of 16. Difference is `edges["submission"] - edges["normalizer"]`, not PnL. SE is sample SD (`ddof=1`) divided by sqrt(n); worst is the minimum per-seed difference. See the [batch API](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/lib.rs). Every direct grid point starts at seed 10,000: n=128 ends at 10,127; n=64 ends at 10,063. Shape key: `kKrR`: combined flow charge F unchanged below K bps, excess retained at R%; `lKrR`: above lambda K/100, multiply F by R/100+(1−R/100)·(K/100)/lambda; `pKeE`: above lambda K/100 multiply F by ((K/100)/lambda)^E; `qK`: F→2·K·BPS·F/(K·BPS+F). F is the sum of the existing lambda, lambda×size, and activity fee terms. | Point | n | Direct mean_diff | SE | Candidate mid slope | Candidate low-third mid | NP2 low-third mid | |---|---:|---:|---:|---:|---:|---:| | k14r25 | 128 | 45.851657 | 1.622683 | 0.953596 | 31.095865 | 33.526679 | | k14r50 | 128 | 35.553110 | 1.292046 | 1.251796 | 31.881850 | 33.432161 | | k14r75 | 128 | 20.280003 | 0.720984 | 1.563703 | 32.579691 | 33.295800 | | k18r25 | 128 | 31.268515 | 1.215496 | 1.378119 | 32.248725 | 33.653207 | | k18r50 | 128 | 24.266273 | 0.953293 | 1.538341 | 32.632069 | 33.493477 | | k18r75 | 128 | 13.651651 | 0.528418 | 1.712966 | 32.926410 | 33.289576 | | k22r25 | 128 | 23.043074 | 0.973096 | 1.579320 | 32.738921 | 33.619060 | | k22r50 | 128 | 17.722768 | 0.758819 | 1.679228 | 32.917330 | 33.467066 | | k22r75 | 128 | 9.963591 | 0.433903 | 1.781923 | 33.090741 | 33.306276 | | k26r25 | 128 | 17.652327 | 0.820355 | 1.697507 | 32.940453 | 33.500597 | | k26r50 | 128 | 13.519068 | 0.640981 | 1.755549 | 33.068767 | 33.465237 | | k26r75 | 128 | 7.352063 | 0.334436 | 1.820114 | 33.147601 | 33.303216 | | l100r0 | 64 | 35.876753 | 1.945818 | 0.832743 | 31.218856 | 33.090615 | | l100r35 | 64 | 24.470724 | 1.405558 | 1.131880 | 31.993198 | 33.175862 | | l110r0 | 64 | 21.278685 | 1.730367 | 0.909800 | 32.638891 | 33.277583 | | l110r35 | 64 | 14.539774 | 1.215339 | 1.177600 | 32.876205 | 33.249249 | | l120r0 | 64 | 7.811586 | 1.114939 | 1.229652 | 33.268483 | 33.301122 | | l120r35 | 64 | 4.922369 | 0.719924 | 1.418085 | 33.282901 | 33.302052 | | p120e2 | 64 | 14.409520 | 1.992708 | 0.780962 | 33.223157 | 33.298487 | | p120e3 | 64 | 20.749886 | 2.935156 | 0.324825 | 33.180860 | 33.295608 | | p125e2 | 64 | 6.658798 | 1.237796 | 1.213324 | 33.300406 | 33.306291 | | p125e3 | 64 | 9.216929 | 1.685088 | 0.977369 | 33.297492 | 33.305975 | | p130e2 | 64 | 2.016346 | 0.473002 | 1.590562 | 33.305611 | 33.305642 | | p130e3 | 64 | 2.820288 | 0.692092 | 1.500439 | 33.305514 | 33.305628 | | p110e2 | 64 | 37.413498 | 2.961309 | 0.240926 | 31.910371 | 33.199046 | | p110e3 | 64 | 48.622724 | 3.455870 | -0.254226 | 31.154358 | 33.118627 | | p115e3 | 64 | 34.581493 | 3.503670 | -0.109872 | 32.605922 | 33.316989 | | q16 | 64 | 29.182518 | 1.875176 | 1.038581 | 32.744495 | 33.879433 | | q18 | 64 | 19.418137 | 1.635787 | 1.114188 | 33.750644 | 34.045197 | | q20 | 64 | 9.818131 | 1.426171 | 1.191217 | 34.639546 | 34.179513 | | q22 | 64 | 0.794900 | 1.235112 | 1.277512 | 35.419127 | 34.263624 | | p117e2 **chosen** | 64 | 20.878761 | 2.426914 | 0.526296 | 33.050538 | 33.309569 | Separate Vanilla diagnostics use the same tuning seeds in two independent markets, candidate-vs-Vanilla and NP2-vs-Vanilla. These differences are distinct from direct head-to-head results above. | Point | n | Vanilla score mean_diff | SE | Mid slope | Fixed NP2 low-third mid change (bps) | |---|---:|---:|---:|---:|---:| | p120e2 | 256 | -0.001738 | 0.013324 | 1.383188 | -0.001822 | | p110e2 | 128 | -0.939735 | 0.090414 | 0.228291 | -0.529354 | | p110e3 | 128 | -2.814324 | 0.225206 | -0.443524 | -0.877163 | | p115e3 | 128 | -0.706733 | 0.093476 | 0.211458 | -0.098707 | | q16 | 128 | -2.971336 | 0.114759 | 1.159028 | -0.925534 | | q18 | 128 | -2.755440 | 0.110042 | 1.247581 | 0.071794 | | q20 | 128 | -2.770556 | 0.109710 | 1.323940 | 0.950303 | | q22 | 128 | -2.906636 | 0.109674 | 1.408169 | 1.728395 | | p117e2 **chosen** | 128 | -0.075129 | 0.030249 | 1.093181 | -0.016875 | The independent NP2 reference is seeds 10,000–10,255. p120e2 also has 256 seeds; each other independent diagnostic has 128 seeds. For each comparison, truncate the reference to the identical seed block. The fixed low cohort is the bottom third ranked by NP2 retail Y, reused for both strategies. # paired One frozen confirmation, direct candidate versus NP2, seeds **2,470,000–2,471,999**, all 2,000 unique seeds completed once. No parameter changes or confirmation reruns. ```json { "n": 2000, "mean_diff": 24.61914872090799, "se": 0.4432845539914727, "worst": -4.889086120902107 } ``` Worst five local paired differences: ```json [ { "seed": 2470268, "diff": -4.889086120902107 }, { "seed": 2471395, "diff": -2.6286098630960737 }, { "seed": 2470627, "diff": -1.9741186558255208 }, { "seed": 2471054, "diff": -0.2868634048431318 }, { "seed": 2470498, "diff": -0.10087270558847194 } ] ``` These are shared-market head-to-head differences. They cannot be added to NP2’s standalone Vanilla score or interpreted as a measured leaderboard gain. The separate Vanilla tuning diagnostic for the chosen shape was -0.075129 ± 0.030249 (one SE); this item makes no claim of reaching the top 10 or first place. The direct comparison changes the second pool from fixed 30-bps Vanilla to variable-fee NP2. Retail routing therefore occurs in a different market, and both contracts retain the routing estimator’s hard-coded `30 * BPS` normalizer assumption. This provides a source-based explanation for treating direct and standalone gains separately; see the [retained NP estimator](https://api.imd.fun/artifacts/da313379a2e69e9286668865e06b18dfcae25732c82b934b0fd9c2ef0d8c2ff5) and [shared-market simulation loop](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/simulation/engine.rs). # fee_stats Units are bps. Each run contributes its equally weighted mean of all 10,000 step-end fees, including steps without trades. Mid=(bid+ask)/2; bid−ask is signed. Slope is OLS with an intercept of run mean mid on that strategy’s total retail Y / 10,000. Terciles below rank each strategy by its own retail Y. The pinned simulator provides [step-end fees and their run averages](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/simulation/engine.rs). Direct confirmation, same 2,000 shared markets: | Strategy | Mean bid | Mean ask | Bid−ask | Mid slope / 10k retail Y | Runs with mean bid >40 | Runs with any step bid >40 | |---|---:|---:|---:|---:|---:|---:| | NP2 | 36.139331 | 35.335829 | 0.803502 | 2.001885 | 169 | 2000 | | p117e2 | 34.495730 | 33.784221 | 0.711509 | 0.491358 | 9 | 2000 | | Strategy | Low-third mid | Middle-third mid | High-third mid | |---|---:|---:|---:| | NP2 | 33.586703 | 35.783183 | 37.846015 | | p117e2 | 33.280985 | 34.328224 | 34.811726 | Vanilla-environment tuning diagnostic, matched seeds 10,000–10,127: | Strategy | Mean bid | Mean ask | Bid−ask | Mid slope / 10k retail Y | Runs with mean bid >40 | Low / middle / high mid | |---|---:|---:|---:|---:|---:|---| | NP2 | 36.282301 | 35.165615 | 1.116686 | 1.818308 | 12 | 33.718686 / 35.630141 / 37.873026 | | p117e2 | 35.696740 | 34.613621 | 1.083120 | 1.093181 | 5 | 33.701811 / 35.390646 / 36.402083 | On the fixed NP2 low-third cohort, candidate minus NP2 mean mid was **-0.016875 bps**, SE 0.008216. This is the direct check of “low third unchanged”; the slope target refers to this Vanilla environment, not to a change of opponent. # blocked `null` — setup, calibration, compilation, local validation and all requested confirmation runs completed. Local checks: `amm-match validate` returned “Strategy 'no_cubic' validated successfully!”. All existing constants and all source outside the fee construction match NP2. Gas/bounds stress: {"n": 3000, "all_success": true, "init_gas": 189944, "max_swap_gas": 154448, "gas_limit": 250000}. Actual pyrevm gas used was read after each successful call; the [simulator hook limit is 250,000 gas](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/evm/strategy.rs). This stress check does not cover every possible input; the pinned [CFMM retains prior fees on hook error](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/amm/cfmm.rs), so successful score batches alone were not used as proof of hook safety. # next Retain NP2. The shape meets the fee-slope target, but independent Vanilla tuning does not establish a scoring gain. Use paired scoring against Vanilla and a fresh holdout before promoting any further flow-response change.