# later-a: later-print filter Frozen candidate versus NP2 on **2800000–2801999**: **+0.117579958 edge**, SE **0.009836751**, n=2000. These are local simulator measurements, not a leaderboard submission. `blocked`: null. The item-specific setup script passed, including StarterStrategy validation. ## Delta and interpretation The exact edit below is relative to NP2 reconstructed from [TWO](https://api.imd.fun/artifacts/528a6da78583c6142644a552c86670f9d25c20e39e92f4de44deae05ddc8cecd) and [NP](https://api.imd.fun/artifacts/da313379a2e69e9286668865e06b18dfcae25732c82b934b0fd9c2ef0d8c2ff5), using the insertion boundaries in the assignment. ```diff --- NP2.sol +++ Strategy.sol @@ -17,7 +17,7 @@ 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_RETAIL = 30000000000000000; uint256 constant PHAT_ALPHA_SAME = 120000000000000000; uint256 constant REVERT_U = 0; uint256 constant DIR_IMPACT_MULT = 4; @@ -118,7 +118,7 @@ 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); + pHat = wmul(pHat, 900000000000000000) + wmul(normalSpot, 100000000000000000); } uint256 tradeRatio = trade.reserveY > 0 ? wdiv(trade.amountY, trade.reserveY) : 0; ``` Frozen tuning point: `{"a": 0.03, "b": 0.1, "f": 1.05, "k": 6850, "s": 0.12}`. Parameters a, s, b mean other-later alpha, same-direction alpha, and normalizer blend; k is STALE_DIR_COEF in BPS units and f is STALE_ATTRACT_FRAC expressed as a real-valued WAD fraction. The selected point reduces the gain on the existing later-print observation path. The tested hard directional filters did not beat it on the 240-seed selection sample. This is a modest estimator-gain change; the experiment did not find a large new mechanism. “second” preserves NP2’s classification: on the second print, compare the sign of pImplied − current pHat with the first print’s stored sign; third+ prints use a. “all” applies that same first-sign test to every later print. “side_second” / “side_all” instead store and compare trade.isBuy. “gated_second” / “gated_all” use the implied-sign classification and also restrict normalizer blending to same-direction seconds / all later prints, respectively. First-print alpha remains 0.27. Except in the explicitly gated modes, normalizer blending, when nonzero, still applies to every eligible later print, independently of the alpha filter. Thus a=s=0,b=0 is no later pHat update; a=s=0,b=.1 retains only NP’s later blend. All variants retain NP2’s fee-used/gamma and adaptive gates. At b=.1, the literal WAD weights in the normalizer blend are exactly equivalent to NP2’s 90/10 expression; that textual rewrite does not change the blend weight. ## Calibration and measurement Simulator: [pinned commit 6b6921f8d463314aa7c96234e1be25a25245f704](https://github.com/benedictbrady/amm-challenge/tree/6b6921f8d463314aa7c96234e1be25a25245f704). [Configuration source](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_competition/competition/config.py) and [draw order](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_competition/competition/match.py) were used directly. For each seed: default_rng(seed), draw size U(19,21), rate U(.6,1), sigma U(.000882,.001008), then build_config with those values. 10000 steps; initial price 100, reserves 100/10000; mu=0, dt=1, retail log-size sigma=1.2 and buy probability=.5. Engine price seed is seed, retail seed is seed+1. [VanillaStrategy](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/contracts/src/VanillaStrategy.sol) is the compiled 30bps normalizer. Each candidate and NP2 is simulated against Vanilla in separate run_batch calls, never against each other. n_workers=8. Paired difference is candidate submission edge minus NP2 submission edge for the identical seed/config; SE uses sample SD (ddof=1)/sqrt(n). Worst five means the five smallest signed differences. Cached NP2 results were reused across tuning points. |Calibration, seeds 0–999|SHA256 of source bytes|Mean edge| |---|---|---:| |[CH source](https://raw.githubusercontent.com/ChengHua926/amm-challenge/d34a5199c59a4c44d5336a25f1436b4ae1f21104/contracts/src/Strategy.sol)|`6dd68f77a70900319460215374143dbd5d924198450a46d9f5f91f6b1e3d35c3`|525.525882178| |Reconstructed NP2|`51f1c1a9d4999ee460eb8bbc66880da8074b173399a4f5d71f96671482e18ac0`|526.115572246| CH reproduced 525.5258821780834 (required 525.525882178). NP2 reproduced 526.1155722459862 (assignment rounded to 526.1156). Batching deviation and repair: the first 34 completed exploratory points used 128 seeds, with 20-seed calls followed by an 8-seed tail. I caught this, stopped the exploratory jobs, and retained only the first 120 for the screening table below. All subsequent simulation calls used exactly 20 seeds, including refinement and the entire confirmation. The initial discarded eight results were observed; they are not included in screening selection or reported n. Refinement uses the same contiguous 240-seed tuning block, so every point has at most 240 unique tuning seeds, including the preliminary observations. This early deviation cannot be undone and is disclosed rather than claiming perfect execution of the requested batching method. ## Tuning All 225 screening points below use seeds 10000–10119, n=120 each. The 125-point factorial sweeps a,s ∈ {0,.03,.06,.09,.12}, b ∈ {0,.025,.05,.075,.1}. Twenty additional points per each of all, side_second, side_all, gated_second and gated_all use a=0, s ∈ {.03,.06,.09,.12}, the same b grid. k=6850, f=1.05 throughout screening. This tests no later update with and without the 10% blend, plus both meanings of same-direction-only updates. Requested no-update ablations (n=120, seeds 10000–10119): |later alpha update|normalizer blend|mean_diff|se| |---|---:|---:|---:| |disabled|0|-1.775739792|0.434652852| |disabled|0.1|-1.117680857|0.419324765| Best screening point per family (selection-biased; confirmation below is decisive): |family|a|s|b|n|mean_diff|se| |---|---:|---:|---:|---:|---:|---:| |second|0.03|0.12|0.1|120|0.168126633|0.047066746| |all|0|0.09|0.1|120|0.061165010|0.066929053| |side_second|0|0.12|0.1|120|-0.088685280|0.078662056| |side_all|0|0.09|0.1|120|0.023996026|0.068849280| |gated_second|0|0.09|0.1|120|-0.275103108|0.080949217| |gated_all|0|0.09|0.1|120|0.011330289|0.075594971| Complete screening table: |mode|a|s|b|n|mean_diff|se| |---|---:|---:|---:|---:|---:|---:| |all|0|0.03|0|120|-1.015274152|0.205921169| |all|0|0.03|0.025|120|-0.853522430|0.200505146| |all|0|0.03|0.05|120|-0.638844658|0.200414694| |all|0|0.03|0.075|120|-0.519204219|0.195189129| |all|0|0.03|0.1|120|-0.364552805|0.148807428| |all|0|0.06|0|120|-0.508178809|0.119077313| |all|0|0.06|0.025|120|-0.353362140|0.113490859| |all|0|0.06|0.05|120|-0.223455668|0.100148206| |all|0|0.06|0.075|120|-0.128541164|0.098599667| |all|0|0.06|0.1|120|-0.069233475|0.094730903| |all|0|0.09|0|120|-0.223812579|0.066745287| |all|0|0.09|0.025|120|-0.091902027|0.060205927| |all|0|0.09|0.05|120|0.027775487|0.054350456| |all|0|0.09|0.075|120|0.058382993|0.068593340| |all|0|0.09|0.1|120|0.061165010|0.066929053| |all|0|0.12|0|120|-0.251567829|0.068785329| |all|0|0.12|0.025|120|-0.102542862|0.060943534| |all|0|0.12|0.05|120|-0.013361483|0.057349146| |all|0|0.12|0.075|120|0.029216031|0.055611649| |all|0|0.12|0.1|120|-0.005537130|0.057496286| |gated_all|0|0.03|0|120|-1.015274152|0.205921169| |gated_all|0|0.03|0.025|120|-0.855853360|0.201044049| |gated_all|0|0.03|0.05|120|-0.654552676|0.202542328| |gated_all|0|0.03|0.075|120|-0.539612108|0.200274450| |gated_all|0|0.03|0.1|120|-0.399482542|0.152838735| |gated_all|0|0.06|0|120|-0.508178809|0.119077313| |gated_all|0|0.06|0.025|120|-0.377646290|0.114693848| |gated_all|0|0.06|0.05|120|-0.273605737|0.103399365| |gated_all|0|0.06|0.075|120|-0.173540952|0.103644301| |gated_all|0|0.06|0.1|120|-0.116656099|0.100540621| |gated_all|0|0.09|0|120|-0.223812579|0.066745287| |gated_all|0|0.09|0.025|120|-0.101734804|0.065390868| |gated_all|0|0.09|0.05|120|-0.008573102|0.062142958| |gated_all|0|0.09|0.075|120|-0.013920087|0.076039971| |gated_all|0|0.09|0.1|120|0.011330289|0.075594971| |gated_all|0|0.12|0|120|-0.251567829|0.068785329| |gated_all|0|0.12|0.025|120|-0.135320237|0.063750273| |gated_all|0|0.12|0.05|120|-0.040994114|0.060552762| |gated_all|0|0.12|0.075|120|-0.044040481|0.061175281| |gated_all|0|0.12|0.1|120|-0.064618609|0.061044641| |gated_second|0|0.03|0|120|-1.145882798|0.207899331| |gated_second|0|0.03|0.025|120|-1.046073675|0.201693754| |gated_second|0|0.03|0.05|120|-0.905207363|0.203109370| |gated_second|0|0.03|0.075|120|-0.825830007|0.205193847| |gated_second|0|0.03|0.1|120|-0.728795548|0.160976729| |gated_second|0|0.06|0|120|-0.775686463|0.125876833| |gated_second|0|0.06|0.025|120|-0.655523611|0.123411464| |gated_second|0|0.06|0.05|120|-0.581932385|0.123482052| |gated_second|0|0.06|0.075|120|-0.503680614|0.109997980| |gated_second|0|0.06|0.1|120|-0.440809320|0.106959337| |gated_second|0|0.09|0|120|-0.549607703|0.091514305| |gated_second|0|0.09|0.025|120|-0.461325529|0.086665361| |gated_second|0|0.09|0.05|120|-0.368715562|0.085708144| |gated_second|0|0.09|0.075|120|-0.314957713|0.083563492| |gated_second|0|0.09|0.1|120|-0.275103108|0.080949217| |gated_second|0|0.12|0|120|-0.489709619|0.083379472| |gated_second|0|0.12|0.025|120|-0.396522877|0.082118723| |gated_second|0|0.12|0.05|120|-0.331729827|0.086144685| |gated_second|0|0.12|0.075|120|-0.290939218|0.082809695| |gated_second|0|0.12|0.1|120|-0.290241120|0.079567840| |second|0|0|0|120|-1.775739792|0.434652852| |second|0|0|0.025|120|-1.538875812|0.429247374| |second|0|0|0.05|120|-1.340351704|0.422670261| |second|0|0|0.075|120|-1.206131029|0.421705306| |second|0|0|0.1|120|-1.117680857|0.419324765| |second|0|0.03|0|120|-1.145882798|0.207899331| |second|0|0.03|0.025|120|-0.963678670|0.200103479| |second|0|0.03|0.05|120|-0.753187936|0.199153040| |second|0|0.03|0.075|120|-0.630411240|0.200279075| |second|0|0.03|0.1|120|-0.508205317|0.152863350| |second|0|0.06|0|120|-0.775686463|0.125876833| |second|0|0.06|0.025|120|-0.603261065|0.120198759| |second|0|0.06|0.05|120|-0.442718024|0.115396352| |second|0|0.06|0.075|120|-0.280249044|0.101865293| |second|0|0.06|0.1|120|-0.239199584|0.098778752| |second|0|0.09|0|120|-0.549607703|0.091514305| |second|0|0.09|0.025|120|-0.372921812|0.083147209| |second|0|0.09|0.05|120|-0.210662215|0.078826987| |second|0|0.09|0.075|120|-0.135571396|0.076055586| |second|0|0.09|0.1|120|-0.074917993|0.070004567| |second|0|0.12|0|120|-0.489709619|0.083379472| |second|0|0.12|0.025|120|-0.372135090|0.077463517| |second|0|0.12|0.05|120|-0.236031767|0.075802851| |second|0|0.12|0.075|120|-0.128262869|0.070315621| |second|0|0.12|0.1|120|-0.060030429|0.076228083| |second|0.03|0|0|120|-1.527094443|0.427941633| |second|0.03|0|0.025|120|-1.339818391|0.423271518| |second|0.03|0|0.05|120|-1.165277397|0.420660831| |second|0.03|0|0.075|120|-1.061727533|0.418550861| |second|0.03|0|0.1|120|-0.956740943|0.402455093| |second|0.03|0.03|0|120|-0.907366142|0.202868965| |second|0.03|0.03|0.025|120|-0.739746367|0.196556260| |second|0.03|0.03|0.05|120|-0.559887973|0.199057242| |second|0.03|0.03|0.075|120|-0.399235861|0.147105756| |second|0.03|0.03|0.1|120|-0.343746920|0.146000600| |second|0.03|0.06|0|120|-0.543725034|0.119266689| |second|0.03|0.06|0.025|120|-0.357381596|0.111359760| |second|0.03|0.06|0.05|120|-0.193377923|0.096686333| |second|0.03|0.06|0.075|120|-0.094024215|0.091724594| |second|0.03|0.06|0.1|120|-0.085698150|0.088580791| |second|0.03|0.09|0|120|-0.264368372|0.067174478| |second|0.03|0.09|0.025|120|-0.115199387|0.058652347| |second|0.03|0.09|0.05|120|0.007739514|0.050558259| |second|0.03|0.09|0.075|120|0.070292538|0.046168733| |second|0.03|0.09|0.1|120|0.058278645|0.054218098| |second|0.03|0.12|0|120|-0.184354726|0.062415905| |second|0.03|0.12|0.025|120|-0.045693347|0.054141886| |second|0.03|0.12|0.05|120|0.058319260|0.046536535| |second|0.03|0.12|0.075|120|0.125000301|0.043859744| |second|0.03|0.12|0.1|120|0.168126633|0.047066746| |second|0.06|0|0|120|-1.224923790|0.091538196| |second|0.06|0|0.025|120|-1.047727696|0.082990403| |second|0.06|0|0.05|120|-1.311145137|0.419838983| |second|0.06|0|0.075|120|-1.178159423|0.405715775| |second|0.06|0|0.1|120|-1.109186597|0.401934956| |second|0.06|0.03|0|120|-0.957127673|0.201558622| |second|0.06|0.03|0.025|120|-0.817059810|0.200262356| |second|0.06|0.03|0.05|120|-0.483667587|0.065704735| |second|0.06|0.03|0.075|120|-0.396249181|0.061766691| |second|0.06|0.03|0.1|120|-0.346916287|0.056379468| |second|0.06|0.06|0|120|-0.519785040|0.065211878| |second|0.06|0.06|0.025|120|-0.356355637|0.060465508| |second|0.06|0.06|0.05|120|-0.218510045|0.051145058| |second|0.06|0.06|0.075|120|-0.145593137|0.046014470| |second|0.06|0.06|0.1|120|-0.102157901|0.044583136| |second|0.06|0.09|0|120|-0.309358872|0.059385407| |second|0.06|0.09|0.025|120|-0.170657309|0.050960004| |second|0.06|0.09|0.05|120|-0.064662926|0.040705610| |second|0.06|0.09|0.075|120|-0.011137337|0.034452704| |second|0.06|0.09|0.1|120|0.029740472|0.032002662| |second|0.06|0.12|0|120|-0.288816453|0.054376795| |second|0.06|0.12|0.025|120|-0.115296288|0.044863711| |second|0.06|0.12|0.05|120|-0.048103287|0.030026879| |second|0.06|0.12|0.075|120|-0.005489688|0.023750097| |second|0.06|0.12|0.1|120|0.000000000|0.000000000| |second|0.09|0|0|120|-1.688069813|0.092510089| |second|0.09|0|0.025|120|-1.476382288|0.085052847| |second|0.09|0|0.05|120|-1.411391822|0.078825345| |second|0.09|0|0.075|120|-1.284629291|0.076312161| |second|0.09|0|0.1|120|-1.265176913|0.072584687| |second|0.09|0.03|0|120|-1.274121292|0.082667147| |second|0.09|0.03|0.025|120|-1.124181988|0.076487573| |second|0.09|0.03|0.05|120|-1.008035384|0.069288900| |second|0.09|0.03|0.075|120|-0.920213642|0.067626813| |second|0.09|0.03|0.1|120|-0.860249419|0.064623731| |second|0.09|0.06|0|120|-0.979597633|0.074476905| |second|0.09|0.06|0.025|120|-0.849627536|0.068418382| |second|0.09|0.06|0.05|120|-0.704823480|0.059674441| |second|0.09|0.06|0.075|120|-0.635684689|0.053267457| |second|0.09|0.06|0.1|120|-0.632215144|0.051631264| |second|0.09|0.09|0|120|-0.760402571|0.065776492| |second|0.09|0.09|0.025|120|-0.631479757|0.056569638| |second|0.09|0.09|0.05|120|-0.535851793|0.051724165| |second|0.09|0.09|0.075|120|-0.491779566|0.044706997| |second|0.09|0.09|0.1|120|-0.476711406|0.043300997| |second|0.09|0.12|0|120|-0.673825028|0.056833180| |second|0.09|0.12|0.025|120|-0.566702440|0.050651443| |second|0.09|0.12|0.05|120|-0.475812661|0.040906863| |second|0.09|0.12|0.075|120|-0.449600650|0.036360598| |second|0.09|0.12|0.1|120|-0.462394891|0.035814298| |second|0.12|0|0|120|-2.448137885|0.101656083| |second|0.12|0|0.025|120|-2.243300544|0.095162730| |second|0.12|0|0.05|120|-2.151583183|0.092737954| |second|0.12|0|0.075|120|-2.062880492|0.090968197| |second|0.12|0|0.1|120|-2.013682035|0.092035356| |second|0.12|0.03|0|120|-2.002926868|0.093466019| |second|0.12|0.03|0.025|120|-1.876783569|0.085966452| |second|0.12|0.03|0.05|120|-1.775927490|0.081659957| |second|0.12|0.03|0.075|120|-1.686068719|0.076313821| |second|0.12|0.03|0.1|120|-1.690276721|0.073650552| |second|0.12|0.06|0|120|-1.727021172|0.085886762| |second|0.12|0.06|0.025|120|-1.571845046|0.078493210| |second|0.12|0.06|0.05|120|-1.501026372|0.071137339| |second|0.12|0.06|0.075|120|-1.452375795|0.065174096| |second|0.12|0.06|0.1|120|-1.444437123|0.065414730| |second|0.12|0.09|0|120|-1.540905226|0.080674174| |second|0.12|0.09|0.025|120|-1.442324068|0.074374267| |second|0.12|0.09|0.05|120|-1.344236134|0.065896160| |second|0.12|0.09|0.075|120|-1.329871791|0.061482820| |second|0.12|0.09|0.1|120|-1.329293649|0.058666149| |second|0.12|0.12|0|120|-1.424915733|0.071117276| |second|0.12|0.12|0.025|120|-1.323974110|0.065346687| |second|0.12|0.12|0.05|120|-1.281992836|0.060268927| |second|0.12|0.12|0.075|120|-1.284564686|0.057678654| |second|0.12|0.12|0.1|120|-1.301365935|0.053573078| |side_all|0|0.03|0|120|-1.048428114|0.209030628| |side_all|0|0.03|0.025|120|-0.874122641|0.203252697| |side_all|0|0.03|0.05|120|-0.669410201|0.200973483| |side_all|0|0.03|0.075|120|-0.518556861|0.195637208| |side_all|0|0.03|0.1|120|-0.375353663|0.150076806| |side_all|0|0.06|0|120|-0.548774490|0.121508551| |side_all|0|0.06|0.025|120|-0.385539288|0.114095633| |side_all|0|0.06|0.05|120|-0.252206585|0.101338869| |side_all|0|0.06|0.075|120|-0.127497571|0.100253445| |side_all|0|0.06|0.1|120|-0.084140891|0.096766972| |side_all|0|0.09|0|120|-0.259705129|0.067643662| |side_all|0|0.09|0.025|120|-0.131252970|0.059634377| |side_all|0|0.09|0.05|120|-0.040420110|0.069772957| |side_all|0|0.09|0.075|120|0.022967863|0.070353254| |side_all|0|0.09|0.1|120|0.023996026|0.068849280| |side_all|0|0.12|0|120|-0.289747148|0.067571035| |side_all|0|0.12|0.025|120|-0.156762047|0.062211946| |side_all|0|0.12|0.05|120|-0.044584937|0.060214037| |side_all|0|0.12|0.075|120|-0.012394026|0.059657270| |side_all|0|0.12|0.1|120|-0.033256550|0.059969681| |side_second|0|0.03|0|120|-1.170976801|0.211717500| |side_second|0|0.03|0.025|120|-0.996724478|0.202048183| |side_second|0|0.03|0.05|120|-0.775960866|0.199151272| |side_second|0|0.03|0.075|120|-0.639712776|0.200672256| |side_second|0|0.03|0.1|120|-0.517984826|0.153153904| |side_second|0|0.06|0|120|-0.811113345|0.127678131| |side_second|0|0.06|0.025|120|-0.629734334|0.121684094| |side_second|0|0.06|0.05|120|-0.473590093|0.116181710| |side_second|0|0.06|0.075|120|-0.298179798|0.102988548| |side_second|0|0.06|0.1|120|-0.249970231|0.099239083| |side_second|0|0.09|0|120|-0.592387437|0.094152912| |side_second|0|0.09|0.025|120|-0.418902323|0.084368809| |side_second|0|0.09|0.05|120|-0.259137295|0.079663771| |side_second|0|0.09|0.075|120|-0.162176090|0.076810912| |side_second|0|0.09|0.1|120|-0.108958813|0.072128582| |side_second|0|0.12|0|120|-0.501965666|0.074504790| |side_second|0|0.12|0.025|120|-0.404544476|0.080142312| |side_second|0|0.12|0.05|120|-0.255306176|0.076887832| |side_second|0|0.12|0.075|120|-0.154312102|0.072662138| |side_second|0|0.12|0.1|120|-0.088685280|0.078662056| Refinement uses seeds 10000–10239, n=240 per point; the first 120 are reused, the next 120 added. Shortlist = top eight screening points plus each mode’s best if absent. Pick each mode’s best shortlisted 240-seed result, then sweep k ∈ {6000,6850,7700}, f ∈ {.9,1.05,1.2} for those six. Around the best coarse result, test k offsets {-400,0,400} and f offsets {-.075,0,.075}. Duplicate points use cached measurements. Choose the highest 240-seed mean across shortlist/coarse/fine, then freeze source/hash before touching confirmation seeds. Tuning SEs do not correct for selection across many points. |stage|mode|a|s|b|k|f|n|mean_diff|se| |---|---|---:|---:|---:|---:|---:|---:|---:|---:| |shortlist|second|0.03|0.12|0.1|6850|1.05|240|0.141408416|0.030566905| |shortlist|second|0.03|0.12|0.075|6850|1.05|240|0.107526244|0.030200837| |shortlist|second|0.03|0.09|0.075|6850|1.05|240|0.061194245|0.034212009| |shortlist|all|0|0.09|0.1|6850|1.05|240|0.032098550|0.046032253| |shortlist|all|0|0.09|0.075|6850|1.05|240|0.034204561|0.048180836| |shortlist|second|0.03|0.12|0.05|6850|1.05|240|0.019070003|0.034532728| |shortlist|second|0.03|0.09|0.1|6850|1.05|240|0.087042842|0.035468902| |shortlist|second|0.06|0.09|0.1|6850|1.05|240|0.005839566|0.021553060| |shortlist|side_second|0|0.12|0.1|6850|1.05|240|-0.122203198|0.050177133| |shortlist|side_all|0|0.09|0.1|6850|1.05|240|-0.004663366|0.046813439| |shortlist|gated_second|0|0.09|0.1|6850|1.05|240|-0.290786577|0.058588425| |shortlist|gated_all|0|0.09|0.1|6850|1.05|240|-0.042768519|0.053479286| |stale_coarse|second|0.03|0.12|0.1|6000|0.9|240|-4.022679350|0.094126683| |stale_coarse|second|0.03|0.12|0.1|6000|1.05|240|-3.262803039|0.086501566| |stale_coarse|second|0.03|0.12|0.1|6000|1.2|240|-3.045515494|0.084589104| |stale_coarse|second|0.03|0.12|0.1|6850|0.9|240|-0.264401340|0.032460182| |stale_coarse|second|0.03|0.12|0.1|6850|1.05|240|0.141408416|0.030566905| |stale_coarse|second|0.03|0.12|0.1|6850|1.2|240|-0.009190292|0.040659097| |stale_coarse|second|0.03|0.12|0.1|7700|0.9|240|-9.123663405|1.157279810| |stale_coarse|second|0.03|0.12|0.1|7700|1.05|240|-9.179713327|1.159838733| |stale_coarse|second|0.03|0.12|0.1|7700|1.2|240|-9.615202278|1.160932749| |stale_coarse|all|0|0.09|0.075|6000|0.9|240|-3.268375899|0.084278685| |stale_coarse|all|0|0.09|0.075|6000|1.05|240|-2.602869353|0.079081012| |stale_coarse|all|0|0.09|0.075|6000|1.2|240|-2.476872572|0.079142253| |stale_coarse|all|0|0.09|0.075|6850|0.9|240|-0.258942002|0.047389623| |stale_coarse|all|0|0.09|0.075|6850|1.05|240|0.034204561|0.048180836| |stale_coarse|all|0|0.09|0.075|6850|1.2|240|-0.140081366|0.046188174| |stale_coarse|all|0|0.09|0.075|7700|0.9|240|-9.947945149|1.106638437| |stale_coarse|all|0|0.09|0.075|7700|1.05|240|-10.112407521|1.106296169| |stale_coarse|all|0|0.09|0.075|7700|1.2|240|-10.586591297|1.137009525| |stale_coarse|side_second|0|0.12|0.1|6000|0.9|240|-3.533442449|0.089809911| |stale_coarse|side_second|0|0.12|0.1|6000|1.05|240|-2.829746293|0.084325343| |stale_coarse|side_second|0|0.12|0.1|6000|1.2|240|-2.672723755|0.081576829| |stale_coarse|side_second|0|0.12|0.1|6850|0.9|240|-0.429155933|0.049354543| |stale_coarse|side_second|0|0.12|0.1|6850|1.05|240|-0.122203198|0.050177133| |stale_coarse|side_second|0|0.12|0.1|6850|1.2|240|-0.332550322|0.050811461| |stale_coarse|side_second|0|0.12|0.1|7700|0.9|240|-9.840759992|1.146233729| |stale_coarse|side_second|0|0.12|0.1|7700|1.05|240|-10.014309420|1.144081525| |stale_coarse|side_second|0|0.12|0.1|7700|1.2|240|-10.385335089|1.148236876| |stale_coarse|side_all|0|0.09|0.1|6000|0.9|240|-3.425995540|0.089264269| |stale_coarse|side_all|0|0.09|0.1|6000|1.05|240|-2.742225288|0.084929511| |stale_coarse|side_all|0|0.09|0.1|6000|1.2|240|-2.581985064|0.083102022| |stale_coarse|side_all|0|0.09|0.1|6850|0.9|240|-0.314604940|0.045413029| |stale_coarse|side_all|0|0.09|0.1|6850|1.05|240|-0.004663366|0.046813439| |stale_coarse|side_all|0|0.09|0.1|6850|1.2|240|-0.130043211|0.045537260| |stale_coarse|side_all|0|0.09|0.1|7700|0.9|240|-9.697416072|1.110116961| |stale_coarse|side_all|0|0.09|0.1|7700|1.05|240|-9.971070531|1.148147441| |stale_coarse|side_all|0|0.09|0.1|7700|1.2|240|-10.436771409|1.148755382| |stale_coarse|gated_second|0|0.09|0.1|6000|0.9|240|-3.118076363|0.082364494| |stale_coarse|gated_second|0|0.09|0.1|6000|1.05|240|-2.510305588|0.077266866| |stale_coarse|gated_second|0|0.09|0.1|6000|1.2|240|-2.431389817|0.075595501| |stale_coarse|gated_second|0|0.09|0.1|6850|0.9|240|-0.490926550|0.060609911| |stale_coarse|gated_second|0|0.09|0.1|6850|1.05|240|-0.290786577|0.058588425| |stale_coarse|gated_second|0|0.09|0.1|6850|1.2|240|-0.575241993|0.090600358| |stale_coarse|gated_second|0|0.09|0.1|7700|0.9|240|-10.858065390|1.190519563| |stale_coarse|gated_second|0|0.09|0.1|7700|1.05|240|-11.162236620|1.192829045| |stale_coarse|gated_second|0|0.09|0.1|7700|1.2|240|-11.644131685|1.195809240| |stale_coarse|gated_all|0|0.09|0.1|6000|0.9|240|-3.253493537|0.085800858| |stale_coarse|gated_all|0|0.09|0.1|6000|1.05|240|-2.584620702|0.081052589| |stale_coarse|gated_all|0|0.09|0.1|6000|1.2|240|-2.447219918|0.080438451| |stale_coarse|gated_all|0|0.09|0.1|6850|0.9|240|-0.327360975|0.051367291| |stale_coarse|gated_all|0|0.09|0.1|6850|1.05|240|-0.042768519|0.053479286| |stale_coarse|gated_all|0|0.09|0.1|6850|1.2|240|-0.188602416|0.048966042| |stale_coarse|gated_all|0|0.09|0.1|7700|0.9|240|-10.092875937|1.113029667| |stale_coarse|gated_all|0|0.09|0.1|7700|1.05|240|-10.422239537|1.139716042| |stale_coarse|gated_all|0|0.09|0.1|7700|1.2|240|-10.862944134|1.149539978| |stale_fine|second|0.03|0.12|0.1|6450|0.975|240|-1.097039713|0.052050948| |stale_fine|second|0.03|0.12|0.1|6450|1.05|240|-0.887777335|0.047779345| |stale_fine|second|0.03|0.12|0.1|6450|1.125|240|-0.811302139|0.048248883| |stale_fine|second|0.03|0.12|0.1|6850|0.975|240|0.043412948|0.030958894| |stale_fine|second|0.03|0.12|0.1|6850|1.05|240|0.141408416|0.030566905| |stale_fine|second|0.03|0.12|0.1|6850|1.125|240|0.135255131|0.033206590| |stale_fine|second|0.03|0.12|0.1|7250|0.975|240|-0.765001124|0.183745652| |stale_fine|second|0.03|0.12|0.1|7250|1.05|240|-0.729637341|0.182721663| |stale_fine|second|0.03|0.12|0.1|7250|1.125|240|-0.824298444|0.182688422| Selected tuning record: ```json { "stage": "stale_fine", "point": { "a": 0.03, "s": 0.12, "b": 0.1, "k": 6850, "f": 1.05 }, "sha256": "0aeda3210f9d7ab51a1bd6b6d9a810ec9233069009655459a501df84b41b26ec", "n": 240, "mean_diff": 0.14140841555304604, "se": 0.030566905263280562, "worst": [ { "seed": 10182, "diff": -1.1714359148659241, "candidate": 596.7293372770125, "np2": 597.9007731918784 }, { "seed": 10001, "diff": -0.9303041464928583, "candidate": 550.8265032717611, "np2": 551.756807418254 }, { "seed": 10011, "diff": -0.8874544149846315, "candidate": 623.8840048478573, "np2": 624.771459262842 }, { "seed": 10124, "diff": -0.8327237821450808, "candidate": 513.914178192686, "np2": 514.7469019748311 }, { "seed": 10151, "diff": -0.7636759724366584, "candidate": 527.9292873929415, "np2": 528.6929633653782 } ] } ``` ## Fresh confirmation and edge split The frozen candidate was confirmed once on the requested untouched block 2800000–2801999. No candidate rerun or selection after observing confirmation. Each side used 100 separate calls of 20 seeds. Arbitrage/retail counters were added to the scratch simulator before confirmation; their additions leave the original total-edge accumulation unchanged. The scratch engine was also changed to abort on a hook error instead of silently retaining fees. [Original edge accounting](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/simulation/engine.rs). Instrumentation cross-check: CH and NP2 on seeds 0–19 matched their unmodified-engine edges within 1e-10. Both holdout runs completed without hook errors. For every holdout result, abs(total − arb − retail) < 1e-8. ```json { "paired": { "n": 2000, "mean_diff": 0.11757995821214902, "se": 0.009836750636400594, "worst": [ { "seed": 2800210, "diff": -4.154895774780698, "candidate": 530.234722027618, "np2": 534.3896178023987 }, { "seed": 2801376, "diff": -1.804803945731237, "candidate": 552.4871646328096, "np2": 554.2919685785408 }, { "seed": 2801873, "diff": -1.7955327951278832, "candidate": 577.5702372356461, "np2": 579.365770030774 }, { "seed": 2800801, "diff": -1.7655798289956692, "candidate": 703.6391162187969, "np2": 705.4046960477925 }, { "seed": 2801013, "diff": -1.2898374408424615, "candidate": 605.2534626384689, "np2": 606.5433000793114 } ] }, "split": { "candidate": { "edge": 523.915815992171, "arb": -29.39443817306715, "retail": 553.3102541652382 }, "NP2": { "edge": 523.7982360339588, "arb": -30.81215241982894, "retail": 554.6103884537879 } }, "blocked": null } ``` Split values are mean submission edge per seed, not volumes or normalizer edge. Arb edge is negative arbitrageur profit at true price; retail edge is amountX*fair − amountY for AMM buys, and amountY − amountX*fair for AMM sells. Relative to NP2, mean arb edge changes by +1.417714247; mean retail edge changes by -1.300134289. The small positive net comes from reduced arbitrage loss offset by reduced retail edge. ## Checks and next Candidate passed amm-match validate. Separate pyrevm stress check: 5000 constant-product trades with both sides, randomized sizes .01–120 Y-equivalent and timestamp increments drawn from [0,0,0,1,1,2,8,19]. All hook calls succeeded at the simulator’s [250000 gas limit](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/evm/strategy.rs), returned fees in [0,0.1], and used gas recorded from EVM.result.gas_used rather than the Python executor’s estimate. This stress sample is not an exhaustive proof. ```json { "n_calls": 5000, "initialization_gas": 189944, "max_after_swap_gas": 133857, "gas_limit": 250000, "all_success": true } ``` Next: this frozen candidate has a positive local confirmation gain exceeding two SEs; offer it for integration with the exact code/hash below. The assignment’s target gaps are +5.8 for top 10 and +9.6 for first. This experiment does not establish either target or a new leaderboard rank. Do not tune further on the confirmation block. ## Full Strategy.sol SHA256 of the UTF-8 bytes inside the following Solidity block, including its final LF(s): `0aeda3210f9d7ab51a1bd6b6d9a810ec9233069009655459a501df84b41b26ec`. The source preserves NP2’s two trailing LF bytes. Imports resolve against the pinned simulator’s contracts/src, compiled with solc 0.8.24, optimizer 200, viaIR, evmVersion paris, using its [compiler](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_competition/evm/compiler.py). ```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 = 30000000000000000; 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, 900000000000000000) + wmul(normalSpot, 100000000000000000); } 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 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); 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"; } } ``` ## Reproducing the split instrumentation Apply this script only to a scratch checkout of the pinned simulator, rebuild amm_sim_rs, then run the candidate and NP2 separately against compiled Vanilla with the configurations above. The added fields are arb_edges and retail_edges. The confirmation used this instrumentation; screening/refinement used the original engine. ```python from pathlib import Path p=Path('amm_sim_rs/src/types/result.rs');x=p.read_text();old=' pub edges: HashMap,';assert x.count(old)==1;x=x.replace(old,old+'\n\n #[pyo3(get)]\n pub arb_edges: HashMap,\n #[pyo3(get)]\n pub retail_edges: HashMap,');p.write_text(x) p=Path('amm_sim_rs/src/simulation/engine.rs');x=p.read_text();old=' // Run simulation steps';assert x.count(old)==1;x=x.replace(old,' let mut arb_edges = edges.clone();\n let mut retail_edges = edges.clone();\n\n'+old) old=' let entry = edges.entry(arb_result.amm_name).or_insert(0.0);';assert x.count(old)==1;x=x.replace(old,' *arb_edges.get_mut(&arb_result.amm_name).unwrap() += -arb_result.profit;\n'+old) old=' let entry = edges.entry(trade.amm_name).or_insert(0.0);';assert x.count(old)==1;x=x.replace(old,' *retail_edges.get_mut(&trade.amm_name).unwrap() += trade_edge;\n'+old) old=' edges,\n';assert x.count(old)==1;x=x.replace(old,old+' arb_edges,\n retail_edges,\n');p.write_text(x) p=Path('amm_sim_rs/src/amm/cfmm.rs');x=p.read_text();old=''' if let Ok((bid_fee, ask_fee)) = self.strategy.after_swap(trade_info) { self.current_fees = FeeQuote::new(bid_fee.clamp_fee(), ask_fee.clamp_fee()); } // On error, keep current fees''';assert x.count(old)==1 x=x.replace(old,''' let (bid_fee, ask_fee) = self.strategy.after_swap(trade_info).expect("hook error during measured simulation"); self.current_fees = FeeQuote::new(bid_fee.clamp_fee(), ask_fee.clamp_fee());''');p.write_text(x) ```