{"code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\nimport {AMMStrategyBase} from \"./AMMStrategyBase.sol\";\nimport {TradeInfo} from \"./IAMMStrategy.sol\";\n\ncontract Strategy is AMMStrategyBase {\n    uint256 constant GAP_SLOPE = 650000000000000000;\n    uint256 constant COMMON_SCALE = 1000000000000000000;\n    uint256 constant SIZE_COEF = 350000000000000000;\n    uint256 constant UNCERTAINTY_COEF = 0;\n    uint256 constant GAP_TAIL = 950000000000000000;\n    uint256 constant ATTRACT_SLOPE = 720000000000000000;\n\n    uint256 constant ELAPSED_CAP = 8;\n    uint256 constant SIGNAL_THRESHOLD = WAD / 650;\n    uint256 constant SIZE_DECAY = 530000000000000000;\n    uint256 constant SIGMA_DECAY = 690000000000000000;\n    uint256 constant LAMBDA_DECAY = 990000000000000000;\n    uint256 constant SIZE_BLEND_DECAY = 828000000000000000;\n    uint256 constant PHAT_ALPHA = 270000000000000000;\n    uint256 constant PHAT_ALPHA_RETAIL = 60000000000000000;\n    uint256 constant PHAT_ALPHA_SAME = 120000000000000000;\n    uint256 constant REVERT_U = 0;\n    uint256 constant GATE_SIGMA_MULT = 7200000000000000000;\n    uint256 constant MIN_GATE = 30000000000000000;\n    uint256 constant RET_CAP = WAD / 35;\n    uint256 constant TOX_CAP = WAD / 5;\n    uint256 constant TRADE_RATIO_CAP = WAD / 5;\n    uint256 constant LAMBDA_CAP = 1820000000000000000;\n    uint256 constant STEP_COUNT_CAP = 64;\n    uint256 constant BASE_FEE = 4 * BPS;\n    uint256 constant SIGMA_COEF = 200000000000000000;\n    uint256 constant LAMBDA_COEF = 12 * BPS;\n    uint256 constant FLOW_SIZE_COEF = 4842 * BPS;\n\n    function afterInitialize(uint256 initialX, uint256 initialY) external override returns (uint256, uint256) {\n        slots[0] = BASE_FEE; slots[1] = BASE_FEE; slots[2] = 0;\n        slots[5] = initialX > 0 ? wdiv(initialY, initialX) : 100 * WAD;\n        slots[6] = 950000000000000; slots[7] = 800000000000000000; slots[8] = 2000000000000000;\n        slots[13] = 902500000000; slots[14] = slots[5]; slots[15] = 0; slots[10] = 0; slots[11] = 0; slots[12] = 0;\n        return (BASE_FEE, BASE_FEE);\n    }\n\n    function afterSwap(TradeInfo calldata trade) external override returns (uint256, uint256) {\n        uint256 prevBidFee = slots[0]; uint256 prevAskFee = slots[1]; uint256 lastTs = slots[2];\n        uint256 pHat = slots[5];\n        uint256 sigmaHat = slots[6]; uint256 lambdaHat = slots[7]; uint256 sizeHat = slots[8];\n        uint256 stepTradeCount = slots[10];\n\n        uint256 sigmaForFast = sigmaHat;\n        uint256 fastHat = slots[14];\n        uint256 uncertainty = slots[13];\n        uint256 silent = trade.timestamp > lastTs ? trade.timestamp - lastTs : 0;\n        bool isNewStep = trade.timestamp > lastTs;\n        if (isNewStep) {\n            uint256 elapsedRaw = trade.timestamp - lastTs;\n            uint256 elapsed = elapsedRaw > ELAPSED_CAP ? ELAPSED_CAP : elapsedRaw;\n            sizeHat = wmul(sizeHat, _powWad(SIZE_DECAY, elapsed));\n            if (stepTradeCount > 0 && elapsedRaw > 0) {\n                uint256 lambdaInst = (stepTradeCount * WAD) / elapsedRaw;\n                if (lambdaInst > LAMBDA_CAP) lambdaInst = LAMBDA_CAP;\n                lambdaHat = wmul(lambdaHat, LAMBDA_DECAY) + wmul(lambdaInst, WAD - LAMBDA_DECAY);\n            }\n            uncertainty += wmul(sigmaForFast, sigmaForFast) * elapsedRaw;\n            if (uncertainty > 100000000000000) uncertainty = 100000000000000;\n            stepTradeCount = 0;\n        }\n\n        bool firstInStep = stepTradeCount == 0;\n        uint256 spot = trade.reserveX > 0 ? wdiv(trade.reserveY, trade.reserveX) : pHat;\n        if (pHat == 0) pHat = spot;\n\n        uint256 feeUsed = trade.isBuy ? prevBidFee : prevAskFee;\n        uint256 gamma = feeUsed < WAD ? WAD - feeUsed : 0;\n        uint256 pImplied;\n        if (gamma == 0) { pImplied = spot; }\n        else { pImplied = trade.isBuy ? wmul(spot, gamma) : wdiv(spot, gamma); }\n\n        // S: infer a no-trade interval center from the last post-trade spot.\n        uint256 silenceScale = WAD;\n        if (firstInStep && silent > 1) {\n            uint256 g = silent - 1;\n            if (g > 1) g = 1;\n            uint256 w = WAD - _powWad(800000000000000000, g);\n            uint256 s = slots[16];\n            if (s == 0) s = pHat;\n            uint256 c = (wmul(s, WAD - prevBidFee) + wdiv(s, WAD - prevAskFee)) / 2;\n            if (c >= pHat) pHat += wmul(w, c - pHat);\n            else pHat -= wmul(w, pHat - c);\n            silenceScale = WAD - wmul(300000000000000000, w);\n        }\n\n        {\n            uint256 ret = pHat > 0 ? wdiv(absDiff(pImplied, pHat), pHat) : 0;\n            uint256 alpha = firstInStep ? PHAT_ALPHA : PHAT_ALPHA_RETAIL;\n            uint256 prePhat = pHat;\n            bool secondPrint = !firstInStep && stepTradeCount == 1;\n            bool sameDir = false; bool oppDir = false;\n            if (secondPrint) {\n                bool up2 = pImplied >= pHat;\n                uint256 d1 = slots[12];\n                if (d1 != 0) { sameDir = (d1 == 1) == up2; oppDir = !sameDir; }\n                if (sameDir) alpha = PHAT_ALPHA_SAME;\n            }\n            if (firstInStep) { slots[11] = pHat; slots[12] = pImplied >= pHat ? 1 : 2; }\n            uint256 adaptiveGate = wmul(sigmaHat, GATE_SIGMA_MULT);\n            if (adaptiveGate < MIN_GATE) adaptiveGate = MIN_GATE;\n            alpha = wmul(alpha, silenceScale);\n            adaptiveGate = wmul(adaptiveGate, silenceScale);\n            if (ret <= adaptiveGate) { pHat = wmul(pHat, WAD - alpha) + wmul(pImplied, alpha); }\n            if (oppDir && REVERT_U > 0) {\n                uint256 pre = slots[11];\n                if (pre > pHat) pHat = pHat + wmul(pre - pHat, REVERT_U);\n                else pHat = pHat - wmul(pHat - pre, REVERT_U);\n            }\n            if (firstInStep) {\n                if (ret > RET_CAP) ret = RET_CAP;\n                sigmaHat = wmul(sigmaHat, SIGMA_DECAY) + wmul(ret, WAD - SIGMA_DECAY);\n            }\n        }\n\n        // Interior retail routing equalizes fee-adjusted marginal prices.\n        // Subsequent trades in a step cannot be the initial arbitrage trade.\n        if (!firstInStep && feeUsed > 30 * BPS && gamma > 0) {\n            uint256 normalSpot = trade.isBuy\n                ? wdiv(wmul(spot, gamma), WAD - 30 * BPS)\n                : wdiv(wmul(spot, WAD - 30 * BPS), gamma);\n            pHat = wmul(pHat, 90 * WAD / 100) + wmul(normalSpot, 10 * WAD / 100);\n        }\n\n        {\n            uint256 ret = fastHat > 0 ? wdiv(absDiff(pImplied, fastHat), fastHat) : 0;\n            uint256 alpha;\n            if (firstInStep) {\n                uint256 processSigma = sigmaForFast;\n                uint256 obsVar = uncertainty + wmul(processSigma, processSigma);\n                uint256 probArb;\n                uint256 z2 = wdiv(wmul(ret, ret), obsVar);\n                uint256 density = _powWad(wdiv(WAD, WAD + z2 / 16), 8);\n                uint256 sigmaObs = sqrt(obsVar * WAD);\n                uint256 odds = wmul(density, wdiv(6700000000000000, sigmaObs));\n                bool arbFlag = ret <= wmul(sigmaForFast, 1220000000000000000);\n                uint256 prior = arbFlag ? 650000000000000000 : 400000000000000000;\n                uint256 tr = trade.reserveY > 0 ? wdiv(trade.amountY, trade.reserveY) : 0;\n                if (tr > 3000000000000000) prior = wmul(prior, 6 * WAD / 10);\n                if (silent > 1) prior = wmul(prior, 8 * WAD / 10);\n                odds = wmul(odds, wdiv(prior, WAD - prior));\n                probArb = wdiv(odds, WAD + odds);\n                alpha = wmul(probArb, 600000000000000000) + wmul(WAD - probArb, 80000000000000000);\n                slots[15] = pImplied >= fastHat ? 1 : 2;\n                uncertainty = wmul(uncertainty, WAD - alpha);\n            } else {\n                if ((slots[15] == 1) == (pImplied >= fastHat)) alpha = PHAT_ALPHA_RETAIL;\n            }\n            uint256 gate = wmul(sigmaHat, GATE_SIGMA_MULT);\n            if (gate < MIN_GATE) gate = MIN_GATE;\n            if (ret <= gate) fastHat = wmul(fastHat, WAD - alpha) + wmul(pImplied, alpha);\n            slots[13] = uncertainty;\n        }\n\n        if (!firstInStep && feeUsed > 30 * BPS && gamma > 0) {\n            uint256 normalObs = trade.isBuy\n                ? wdiv(wmul(spot, gamma), WAD - 30 * BPS)\n                : wdiv(wmul(spot, WAD - 30 * BPS), gamma);\n            if ((slots[15] == 1) == (normalObs >= fastHat)) {\n                fastHat = wmul(fastHat, 9 * WAD / 10) + wmul(normalObs, WAD / 10);\n            }\n        }\n        slots[14] = fastHat;\n        uint256 tradeRatio = trade.reserveY > 0 ? wdiv(trade.amountY, trade.reserveY) : 0;\n        if (tradeRatio > TRADE_RATIO_CAP) tradeRatio = TRADE_RATIO_CAP;\n\n        if (tradeRatio > SIGNAL_THRESHOLD) {\n            sizeHat = wmul(sizeHat, SIZE_BLEND_DECAY) + wmul(tradeRatio, WAD - SIZE_BLEND_DECAY);\n            if (sizeHat > WAD) sizeHat = WAD;\n        }\n\n        stepTradeCount = stepTradeCount + 1;\n        if (stepTradeCount > STEP_COUNT_CAP) stepTradeCount = STEP_COUNT_CAP;\n\n        uint256 fair = wmul(pHat, 7 * WAD / 10) + wmul(fastHat, 3 * WAD / 10);\n        uint256 gap = wdiv(absDiff(spot, fair), fair);\n        if (gap > TOX_CAP) gap = TOX_CAP;\n        uint256 width = sqrt(uncertainty * WAD);\n        uint256 common = BASE_FEE + wmul(SIGMA_COEF, sigmaHat) + wmul(LAMBDA_COEF, lambdaHat)\n            + wmul(FLOW_SIZE_COEF, wmul(lambdaHat, sizeHat));\n        common = wmul(common, COMMON_SCALE) + wmul(width, UNCERTAINTY_COEF);\n        // Sparse hinge basis: signed-gap sides, a 40bp knee, and bounded size/uncertainty interactions.\n        uint256 sizeLeg = tradeRatio < 50 * BPS ? tradeRatio : 50 * BPS;\n        uint256 gapLeg = gap < 40 * BPS ? gap : 40 * BPS;\n        uint256 protection = wmul(gapLeg, GAP_SLOPE);\n        if (gap > gapLeg) protection += wmul(gap - gapLeg, GAP_TAIL);\n        protection += wmul(gapLeg, wdiv(sizeLeg, 50 * BPS)) / 8;\n        uint256 uLeg = width < 20 * BPS ? width : 20 * BPS;\n        protection += wmul(gapLeg, wdiv(uLeg, 20 * BPS)) / 8;\n        uint256 attraction = wmul(gap, ATTRACT_SLOPE);\n        uint256 bidFee; uint256 askFee;\n        uint256 aligned = ((trade.isBuy && spot >= fair) || (!trade.isBuy && spot < fair))\n            ? wmul(sizeLeg, SIZE_COEF) : 0;\n        uint256 protectFee = common + protection + aligned;\n        uint256 attractFee = common > attraction ? common - attraction : 0;\n        if (spot >= fair) { bidFee = clampFee(protectFee); askFee = clampFee(attractFee); }\n        else { askFee = clampFee(protectFee); bidFee = clampFee(attractFee); }\n\n        slots[0] = bidFee; slots[1] = askFee; slots[2] = trade.timestamp;\n        slots[5] = pHat;\n        slots[6] = sigmaHat; slots[7] = lambdaHat; slots[8] = sizeHat;\n        slots[16] = spot;\n        slots[10] = stepTradeCount;\n\n        return (bidFee, askFee);\n    }\n\n    function _powWad(uint256 factor, uint256 exp) internal pure returns (uint256 result) {\n        result = WAD;\n        while (exp > 0) {\n            if (exp & 1 == 1) result = wmul(result, factor);\n            factor = wmul(factor, factor);\n            exp >>= 1;\n        }\n    }\n\n    function getName() external pure override returns (string memory) { return \"interaction_0\"; }\n}\n","sha256":"881293cf9a361312120637649f05f584514745707c2bdd31fab554d628a543ee","paired":{"n":0,"mean_diff":null,"se":null,"worst":[]},"gas":{"max_ok":223263,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":320,"deploy_max_ok":1268222,"name_max_ok":21536,"executions":2618102},"baseline_gas":{"max_ok":243554,"init_max_ok":236377,"oog":14,"reverts":0,"other_halts":0,"init_successes":320,"deploy_max_ok":1560600,"name_max_ok":21545,"executions":3290824},"valid":false,"blocked":{"step":"V2 gas-validity prerequisite","error":"Exact requested V2 incurred OutOfGas under the unchanged 250000 afterSwap gas limit. The 64-seed screening baseline alone recorded 4 OOG halts. By the task rule every such result is invalid; no accepted paired estimate or confirmation is claimed."},"tuning":{"status":"diagnostic only; every paired comparison invalid because baseline has OOG","parameters":[{"GAP_SLOPE":0.65,"COMMON_SCALE":1,"SIZE_COEF":0.35,"UNCERTAINTY_COEF":0,"GAP_TAIL":0.95,"ATTRACT_SLOPE":0.72},{"GAP_SLOPE":0.8,"COMMON_SCALE":1,"SIZE_COEF":0.35,"UNCERTAINTY_COEF":0,"GAP_TAIL":0.95,"ATTRACT_SLOPE":0.72},{"GAP_SLOPE":0.95,"COMMON_SCALE":1,"SIZE_COEF":0.35,"UNCERTAINTY_COEF":0,"GAP_TAIL":0.95,"ATTRACT_SLOPE":0.72},{"GAP_SLOPE":0.8,"COMMON_SCALE":0.85,"SIZE_COEF":0.2,"UNCERTAINTY_COEF":0.1,"GAP_TAIL":0.95,"ATTRACT_SLOPE":0.72},{"GAP_SLOPE":0.8,"COMMON_SCALE":1.15,"SIZE_COEF":0.2,"UNCERTAINTY_COEF":0.1,"GAP_TAIL":0.95,"ATTRACT_SLOPE":0.72},{"GAP_SLOPE":0.95,"COMMON_SCALE":1,"SIZE_COEF":0.15,"UNCERTAINTY_COEF":0.2,"GAP_TAIL":0.95,"ATTRACT_SLOPE":0.72}],"screening":[{"label":"C0","paired":{"n":64,"mean_diff":-13.026796437419929,"se":0.7201000676663198,"worst":[{"seed":10014,"diff":-39.0744786355549,"edge":543.4863118986457,"v2_edge":582.5607905342006},{"seed":10022,"diff":-23.266285109996375,"edge":615.2845165162288,"v2_edge":638.5508016262252},{"seed":10023,"diff":-23.13666509630093,"edge":590.2440161785762,"v2_edge":613.3806812748771},{"seed":10003,"diff":-22.598665764350358,"edge":629.107650373861,"v2_edge":651.7063161382114},{"seed":10005,"diff":-21.850988302669577,"edge":435.4816263816822,"v2_edge":457.33261468435177}]},"gas":{"max_ok":223206,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":64,"deploy_max_ok":1268222,"name_max_ok":21536,"executions":520700},"valid":false},{"label":"C1","paired":{"n":64,"mean_diff":-21.1899751263553,"se":0.9662127392617562,"worst":[{"seed":10014,"diff":-59.05252561684301,"edge":523.5082649173576,"v2_edge":582.5607905342006},{"seed":10003,"diff":-36.377931857298904,"edge":615.3283842809125,"v2_edge":651.7063161382114},{"seed":10022,"diff":-34.39868495805467,"edge":604.1521166681705,"v2_edge":638.5508016262252},{"seed":10023,"diff":-30.928579676621325,"edge":582.4521015982558,"v2_edge":613.3806812748771},{"seed":10053,"diff":-29.702376970511523,"edge":646.1174587904468,"v2_edge":675.8198357609583}]},"gas":{"max_ok":223206,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":64,"deploy_max_ok":1268222,"name_max_ok":21536,"executions":442040},"valid":false},{"label":"C2","paired":{"n":64,"mean_diff":-31.09923049156219,"se":1.0760571851714,"worst":[{"seed":10014,"diff":-70.4120837765496,"edge":512.148706757651,"v2_edge":582.5607905342006},{"seed":10022,"diff":-47.01846575186346,"edge":591.5323358743617,"v2_edge":638.5508016262252},{"seed":10028,"diff":-45.0650727682048,"edge":588.1809326565833,"v2_edge":633.2460054247881},{"seed":10003,"diff":-41.80276538883959,"edge":609.9035507493718,"v2_edge":651.7063161382114},{"seed":10040,"diff":-40.839095768755556,"edge":558.1533460239772,"v2_edge":598.9924417927327}]},"gas":{"max_ok":223236,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":64,"deploy_max_ok":1265214,"name_max_ok":21536,"executions":371972},"valid":false},{"label":"C3","paired":{"n":64,"mean_diff":-24.201073977241634,"se":0.7755294965451306,"worst":[{"seed":10022,"diff":-36.76232872848402,"edge":601.7884728977411,"v2_edge":638.5508016262252},{"seed":10014,"diff":-36.26943293788156,"edge":546.291357596319,"v2_edge":582.5607905342006},{"seed":10028,"diff":-34.152692035152654,"edge":599.0933133896355,"v2_edge":633.2460054247881},{"seed":10053,"diff":-32.964178440141495,"edge":642.8556573208168,"v2_edge":675.8198357609583},{"seed":10034,"diff":-32.24949465112081,"edge":477.41508548399764,"v2_edge":509.66458013511846}]},"gas":{"max_ok":223175,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":64,"deploy_max_ok":1287032,"name_max_ok":21536,"executions":401681},"valid":false},{"label":"C4","paired":{"n":64,"mean_diff":-43.392641142749255,"se":1.341568514380973,"worst":[{"seed":10014,"diff":-89.19092606328553,"edge":493.36986447091505,"v2_edge":582.5607905342006},{"seed":10028,"diff":-64.302436830862,"edge":568.9435685939261,"v2_edge":633.2460054247881},{"seed":10052,"diff":-63.18609111671162,"edge":462.36424257922044,"v2_edge":525.5503336959321},{"seed":10003,"diff":-57.954631847200176,"edge":593.7516842910112,"v2_edge":651.7063161382114},{"seed":10031,"diff":-57.81786009471847,"edge":401.96940071258524,"v2_edge":459.7872608073037}]},"gas":{"max_ok":223175,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":64,"deploy_max_ok":1287044,"name_max_ok":21536,"executions":293446},"valid":false},{"label":"C5","paired":{"n":64,"mean_diff":-62.471753823530804,"se":1.6225884389954985,"worst":[{"seed":10014,"diff":-115.32856320731429,"edge":467.2322273268863,"v2_edge":582.5607905342006},{"seed":10028,"diff":-88.80999798371533,"edge":544.4360074410728,"v2_edge":633.2460054247881},{"seed":10025,"diff":-87.48850115493849,"edge":608.2901971048836,"v2_edge":695.7786982598221},{"seed":10052,"diff":-85.5159021684347,"edge":440.03443152749736,"v2_edge":525.5503336959321},{"seed":10034,"diff":-81.70036980845856,"edge":427.9642103266599,"v2_edge":509.66458013511846}]},"gas":{"max_ok":223234,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":64,"deploy_max_ok":1268666,"name_max_ok":21536,"executions":218534},"valid":false}],"top2":[{"label":"C0","paired":{"n":256,"mean_diff":-13.67129772938019,"se":0.39971389657829237,"worst":[{"seed":11049,"diff":-42.50483072065845,"edge":352.26135443625964,"v2_edge":394.7661851569181},{"seed":11083,"diff":-40.6214520373444,"edge":573.975595748688,"v2_edge":614.5970477860324},{"seed":11153,"diff":-33.17605329116043,"edge":665.3205930193324,"v2_edge":698.4966463104928},{"seed":11043,"diff":-32.97216571840244,"edge":402.86751792824566,"v2_edge":435.8396836466481},{"seed":11146,"diff":-31.624579096811658,"edge":622.3405643323599,"v2_edge":653.9651434291716}]},"gas":{"max_ok":223263,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":320,"deploy_max_ok":1268222,"name_max_ok":21536,"executions":2618102},"valid":false},{"label":"C1","paired":{"n":256,"mean_diff":-22.0044876355421,"se":0.5225279213677078,"worst":[{"seed":11049,"diff":-80.36063546985275,"edge":314.40554968706533,"v2_edge":394.7661851569181},{"seed":11083,"diff":-52.66348291454108,"edge":561.9335648714913,"v2_edge":614.5970477860324},{"seed":11148,"diff":-47.463787005494055,"edge":558.9251819487814,"v2_edge":606.3889689542755},{"seed":11146,"diff":-44.913623012096764,"edge":609.0515204170748,"v2_edge":653.9651434291716},{"seed":11153,"diff":-44.68262059097651,"edge":653.8140257195163,"v2_edge":698.4966463104928}]},"gas":{"max_ok":223263,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":320,"deploy_max_ok":1268222,"name_max_ok":21536,"executions":2221338},"valid":false}],"selected":"C0","runs":[{"label":"C0","start":10000,"n":64,"gas":{"max_ok":223206,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":64,"deploy_max_ok":1268222,"name_max_ok":21536,"executions":520700},"sha256":"881293cf9a361312120637649f05f584514745707c2bdd31fab554d628a543ee","seconds":9.598562955856323},{"label":"C0","start":11000,"n":256,"gas":{"max_ok":223263,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":320,"deploy_max_ok":1268222,"name_max_ok":21536,"executions":2618102},"sha256":"881293cf9a361312120637649f05f584514745707c2bdd31fab554d628a543ee","seconds":32.44664645195007},{"label":"C1","start":10000,"n":64,"gas":{"max_ok":223206,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":64,"deploy_max_ok":1268222,"name_max_ok":21536,"executions":442040},"sha256":"46d78972635373703cdf45c27af3c9f9775d4a34049ef2d14171ffbc63d425ba","seconds":8.444768190383911},{"label":"C1","start":11000,"n":256,"gas":{"max_ok":223263,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":320,"deploy_max_ok":1268222,"name_max_ok":21536,"executions":2221338},"sha256":"46d78972635373703cdf45c27af3c9f9775d4a34049ef2d14171ffbc63d425ba","seconds":30.230759382247925},{"label":"C2","start":10000,"n":64,"gas":{"max_ok":223236,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":64,"deploy_max_ok":1265214,"name_max_ok":21536,"executions":371972},"sha256":"c073918fbfc91ffc5054f84e22c06dc4f1e33c0248f9875f8f8942076f52f933","seconds":8.154226064682007},{"label":"C3","start":10000,"n":64,"gas":{"max_ok":223175,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":64,"deploy_max_ok":1287032,"name_max_ok":21536,"executions":401681},"sha256":"41b671e5ac0fa5e0361d11f48d5a4dcfd1f4fc4c7c4925e7c36dcf9794e7d92a","seconds":9.614863395690918},{"label":"C4","start":10000,"n":64,"gas":{"max_ok":223175,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":64,"deploy_max_ok":1287044,"name_max_ok":21536,"executions":293446},"sha256":"03b1c0c2ebefb64fc09e87bd9788f810f91bb260dc074ac148808b8702bda3bb","seconds":5.99585485458374},{"label":"C5","start":10000,"n":64,"gas":{"max_ok":223234,"init_max_ok":209855,"oog":0,"reverts":0,"other_halts":0,"init_successes":64,"deploy_max_ok":1268666,"name_max_ok":21536,"executions":218534},"sha256":"d36ca73a0ec0552f6ddced33d8de513806be59c5b9b896a92003d605d8fb632d","seconds":5.045394659042358},{"label":"V2","start":10000,"n":64,"gas":{"max_ok":243554,"init_max_ok":236377,"oog":4,"reverts":0,"other_halts":0,"init_successes":64,"deploy_max_ok":1560600,"name_max_ok":21545,"executions":652798},"sha256":"28417e116f57f1029fdd1803832e852574902c1ae7253c05657f317db76da4ab","seconds":11.650298595428467},{"label":"V2","start":11000,"n":256,"gas":{"max_ok":243554,"init_max_ok":236377,"oog":14,"reverts":0,"other_halts":0,"init_successes":320,"deploy_max_ok":1560600,"name_max_ok":21545,"executions":3290824},"sha256":"28417e116f57f1029fdd1803832e852574902c1ae7253c05657f317db76da4ab","seconds":40.810362577438354}]},"seeds":{"screening":[10000,10063],"top2":[11000,11255],"reserved_confirmation":[4030000,4031999],"confirmation_used":false},"notes":["Nothing fabricated. Main paired.n is zero because the method prerequisite failed. Diagnostic statistics below are actual observed edges with fallback-affected V2 and are NOT valid estimates of fee-rule gains.","Six sparse hinge rules replace all old fee mapping, trade boost, and tail compression. Removed direction, activity and toxicity estimators and storage writes; retained pHat, fastHat, sigma, uncertainty, lambda and size estimators. Inputs are observable trade/reserve/timestamp/state only.","No recommendation to deploy. The diagnostic candidate differences were negative; the experiment does not establish improvement.","The exact requested V2 source hash was verified before any run. No baseline repair or gas-limit increase was made. The reserved confirmation block remains unused because it cannot yield an admissible comparison with this baseline.","Tuning process already scheduled six screen variants and top two validation; these completed only as invalid diagnostics. Code was frozen afterward and never retuned. Candidate gas totals include every run of that source in this process. Synthetic counter tests ran in a separate process and are not charged to candidate or V2.","Metrics max_ok is highest successful afterSwap gas, init_max_ok is separate; deploy/name have separate maxima. Counters aggregate every top-level revm ExecutionResult before error propagation, including ignored update_fees failures; matching OutOfGas variant counts all OOG subtypes. EVM transaction-construction errors would abort runs, not be interpreted as successes. No custom external calls or child frames are introduced by candidates.","Local measurements are supported by embedded executable harness and counter patch, not by external sources. Online dependency installation is required to reproduce setup; no dependency/vendor tree is delivered. Both requested output files are ordinary untracked files."],"reproduce":{"commit":"6b6921f8d463314aa7c96234e1be25a25245f704","baseline_url":"https://api.imd.fun/artifacts/1f4f14f040b309e004904672ec6e2bb051f97b8d1195602d36b35a54c05d6c0f","baseline_sha256":"28417e116f57f1029fdd1803832e852574902c1ae7253c05657f317db76da4ab","baseline_replacements":[["if (g > 4) g = 4;","if (g > 1) g = 1;"],["_powWad(925000000000000000, g)","_powWad(800000000000000000, g)"]],"commands":["git clone https://github.com/benedictbrady/amm-challenge checkout","cd checkout","git checkout 6b6921f8d463314aa7c96234e1be25a25245f704","mkdir -p scratch; materialize embedded scripts into scratch/; fetch baseline_url via curl -sS -A Mozilla/5.0; save response as scratch/baseline-response.json; apply baseline_replacements to code and verify baseline_sha256; save scratch/V2.sol","sh scratch/setup.sh (once)",". scratch/env.sh && python scratch/instrument.py",". scratch/env.sh && maturin develop --release --uv --manifest-path amm_sim_rs/Cargo.toml",". scratch/env.sh && python scratch/make_candidates.py",". scratch/env.sh && python scratch/check_counter.py",". scratch/env.sh && python -u scratch/experiment.py tune","Do not run confirm while any baseline/candidate OOG is nonzero. The confirm branch is provided for method completeness; it was not executed."],"scripts":{"setup.sh":"set -eu;R=$PWD/scratch;mkdir -p $R/tmp $R/bin $R/solcx\necho \"export TMPDIR=$R/tmp XDG_CACHE_HOME=$R/xc UV_CACHE_DIR=$R/uvc UV_PYTHON_INSTALL_DIR=$R/uvpy RUSTUP_HOME=$R/rustup CARGO_HOME=$R/cargo SOLCX_BINARY_PATH=$R/solcx VIRTUAL_ENV=$PWD/.venv PATH=$PWD/.venv/bin:$R/bin:$R/cargo/bin:\\$PATH\" >$R/env.sh;. $R/env.sh\ncommand -v uv >/dev/null||{ curl -LsSf https://github.com/astral-sh/uv/releases/latest/download/uv-x86_64-unknown-linux-gnu.tar.gz|tar --no-same-owner -xz -C $R/tmp;cp $R/tmp/uv-*/uv $R/bin/;}\ncc --version >/dev/null 2>&1||{ curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest -o $R/tmp/mm.tbz;python3 -c \"import sys,tarfile;tarfile.open(sys.argv[1]).extract('bin/micromamba',sys.argv[2])\" $R/tmp/mm.tbz $R;MAMBA_ROOT_PREFIX=$R/mamba $R/bin/micromamba create -yq -p $R/cenv -c conda-forge gcc;ln -sf $(ls $R/cenv/bin/*gcc|head -n1) $R/bin/cc;}\ncommand -v cargo >/dev/null||{ curl -sSf https://sh.rustup.rs|sh -s -- -y --profile minimal --no-modify-path;}\nuv venv --python 3.12 .venv;uv pip install -e . maturin\nmaturin develop --release --uv --manifest-path amm_sim_rs/Cargo.toml\namm-match validate contracts/src/StarterStrategy.sol\n","instrument.py":"from pathlib import Path\np=Path('amm_sim_rs/src/evm/strategy.rs');s=p.read_text();s='''use std::sync::{Mutex, OnceLock};\nuse std::collections::HashMap;\nuse std::hash::{Hash, Hasher};\nstatic METRICS: OnceLock<Mutex<HashMap<u64, [u64; 9]>>> = OnceLock::new();\npub fn metric_id(code: &[u8]) -> u64 { let mut h = std::collections::hash_map::DefaultHasher::new(); code.hash(&mut h); h.finish() }\npub fn metrics() -> Vec<(u64, Vec<u64>)> { METRICS.get_or_init(Default::default).lock().unwrap().iter().map(|(k,v)| (*k,v.to_vec())).collect() }\nfn record(id: u64, phase: usize, r: &ExecutionResult) {\n let mut m = METRICS.get_or_init(Default::default).lock().unwrap(); let a = m.entry(id).or_insert([0;9]); a[8]+=1;\n match r {\n ExecutionResult::Success {gas_used,..} => { a[phase]=a[phase].max(*gas_used); if phase==1 {a[5]+=1;} },\n ExecutionResult::Revert {..} => a[3]+=1,\n ExecutionResult::Halt {reason,..} => if matches!(reason,revm::primitives::HaltReason::OutOfGas(_)) {a[2]+=1;} else {a[4]+=1;}\n }\n}\n''' +s.replace('//!','//')\ns=s.replace('    name: String,','    name: String,\\n    metric_id: u64,',1).replace('            name: default_name,','            metric_id: metric_id(&bytecode),\\n            name: default_name,',1)\ns=s.replace('            match result {','            record(self.metric_id, 6, &result);\\n            match result {',1)\ns=s.replace('        match result {','        record(self.metric_id, if calldata.len()==196 {0} else if gas_limit==GAS_LIMIT_INIT {1} else {7}, &result);\\n        match result {',1) if False else s\n# insert at final match, not deployment\npos=s.index('        match result {',s.index('    fn call('));s=s[:pos]+'        record(self.metric_id, if calldata.len()==196 {0} else if gas_limit==GAS_LIMIT_INIT {1} else {7}, &result);\\n'+s[pos:];p.write_text(s)\np=Path('amm_sim_rs/src/lib.rs');s=p.read_text();s=s.replace('/// Python module definition','#[pyfunction]\\nfn gas_metrics() -> Vec<(u64, Vec<u64>)> { crate::evm::strategy::metrics() }\\n#[pyfunction]\\nfn gas_id(code: Vec<u8>) -> u64 { crate::evm::strategy::metric_id(&code) }\\n\\n/// Python module definition');s=s.replace('    m.add_function(wrap_pyfunction!(run_batch, m)?)?;','    m.add_function(wrap_pyfunction!(gas_metrics, m)?)?;\\n    m.add_function(wrap_pyfunction!(gas_id, m)?)?;\\n    m.add_function(wrap_pyfunction!(run_batch, m)?)?;');p.write_text(s)\n","make_candidates.py":"from pathlib import Path\ns=Path('scratch/V2.sol').read_text()\ns=s.replace('uint256 dirState = slots[3]; uint256 actEma = slots[4]; uint256 pHat = slots[5];','uint256 pHat = slots[5];').replace('uint256 toxEma = slots[9]; uint256 stepTradeCount = slots[10];','uint256 stepTradeCount = slots[10];')\nfor line in ['            dirState = _decayCentered(dirState, DIR_DECAY, elapsed);\\n','            actEma = wmul(actEma, _powWad(ACT_DECAY, elapsed));\\n','            toxEma = wmul(toxEma, _powWad(TOX_DECAY, elapsed));\\n']:\n s=s.replace(line,'')\na=s.index('        if (tradeRatio > SIGNAL_THRESHOLD)');b=s.index('        stepTradeCount = stepTradeCount + 1;',a)\ns=s[:a]+'''        if (tradeRatio > SIGNAL_THRESHOLD) {\n            sizeHat = wmul(sizeHat, SIZE_BLEND_DECAY) + wmul(tradeRatio, WAD - SIZE_BLEND_DECAY);\n            if (sizeHat > WAD) sizeHat = WAD;\n        }\n\n'''+s[b:]\na=s.index('        uint256 flowSize');b=s.index('        slots[0] = bidFee;',a)\ns=s[:a]+'''        uint256 fair = wmul(pHat, 7 * WAD / 10) + wmul(fastHat, 3 * WAD / 10);\n        uint256 gap = wdiv(absDiff(spot, fair), fair);\n        if (gap > TOX_CAP) gap = TOX_CAP;\n        uint256 width = sqrt(uncertainty * WAD);\n        uint256 common = BASE_FEE + wmul(SIGMA_COEF, sigmaHat) + wmul(LAMBDA_COEF, lambdaHat)\n            + wmul(FLOW_SIZE_COEF, wmul(lambdaHat, sizeHat));\n        common = wmul(common, COMMON_SCALE) + wmul(width, UNCERTAINTY_COEF);\n        // Sparse hinge basis: signed-gap sides, a 40bp knee, and bounded size/uncertainty interactions.\n        uint256 sizeLeg = tradeRatio < 50 * BPS ? tradeRatio : 50 * BPS;\n        uint256 gapLeg = gap < 40 * BPS ? gap : 40 * BPS;\n        uint256 protection = wmul(gapLeg, GAP_SLOPE);\n        if (gap > gapLeg) protection += wmul(gap - gapLeg, GAP_TAIL);\n        protection += wmul(gapLeg, wdiv(sizeLeg, 50 * BPS)) / 8;\n        uint256 uLeg = width < 20 * BPS ? width : 20 * BPS;\n        protection += wmul(gapLeg, wdiv(uLeg, 20 * BPS)) / 8;\n        uint256 attraction = wmul(gap, ATTRACT_SLOPE);\n        uint256 bidFee; uint256 askFee;\n        uint256 aligned = ((trade.isBuy && spot >= fair) || (!trade.isBuy && spot < fair))\n            ? wmul(sizeLeg, SIZE_COEF) : 0;\n        uint256 protectFee = common + protection + aligned;\n        uint256 attractFee = common > attraction ? common - attraction : 0;\n        if (spot >= fair) { bidFee = clampFee(protectFee); askFee = clampFee(attractFee); }\n        else { askFee = clampFee(protectFee); bidFee = clampFee(attractFee); }\n\n'''+s[b:]\ns=s.replace('        slots[3] = dirState; slots[4] = actEma; slots[5] = pHat;','        slots[5] = pHat;').replace('        slots[9] = toxEma; slots[10] = stepTradeCount;','        slots[10] = stepTradeCount;')\na=s.index('    function _compressTailWithSlope');b=s.index('    function _powWad',a);s=s[:a]+s[b:]\na=s.index('    function _decayCentered');b=s.index('    function getName',a);s=s[:a]+s[b:]\ns=s.replace('slots[2] = 0; slots[3] = WAD; slots[4] = 0;','slots[2] = 0;').replace('slots[9] = 0; ','')\n# Remove constants unused after replacing mapping.\nimport re,json\nfor name in re.findall(r'uint256 constant (\\w+) =',s):\n if len(re.findall(r'\\b'+name+r'\\b',s))==1:\n  s=re.sub(r'    uint256 constant '+name+r' = [^;]+;\\n','',s)\nparams=[]\nfor i,(slope,scale,size,u) in enumerate([(0.65,1,.35,0),(0.8,1,.35,0),(0.95,1,.35,0),(0.8,.85,.2,.1),(0.8,1.15,.2,.1),(0.95,1,.15,.2)]):\n p=dict(GAP_SLOPE=slope,COMMON_SCALE=scale,SIZE_COEF=size,UNCERTAINTY_COEF=u,GAP_TAIL=0.95,ATTRACT_SLOPE=.72)\n out=s.replace('contract Strategy is AMMStrategyBase {','contract Strategy is AMMStrategyBase {\\n'+''.join(f'    uint256 constant {k} = {round(v*10**18)};\\n' for k,v in p.items())).replace('\"no_cubic\"',f'\"interaction_{i}\"')\n Path(f'scratch/C{i}.sol').write_text(out);params.append(p)\nPath('scratch/parameters.json').write_text(json.dumps(params))\n","experiment.py":"import json,hashlib,time,sys\nfrom pathlib import Path\nimport numpy as np\nimport amm_sim_rs as sim\nfrom amm_competition.evm.compiler import SolidityCompiler\nfrom amm_competition.competition.config import build_config\ncompiler=SolidityCompiler()\n\ndef compile_code(code,name='Strategy'):\n r=compiler.compile(code,contract_name=name)\n if not r.success: raise RuntimeError(str(r.errors))\n return list(r.bytecode)\nvanilla=compile_code(Path('contracts/src/VanillaStrategy.sol').read_text(),'VanillaStrategy')\n\ndef configs(start,n):\n out=[]\n for seed in range(start,start+n):\n  rng=np.random.default_rng(seed)\n  size=rng.uniform(19,21); rate=rng.uniform(.6,1); sigma=rng.uniform(.000882,.001008)\n  out.append(build_config(seed=seed,gbm_sigma=sigma,retail_arrival_rate=rate,retail_mean_size=size))\n return out\n\ndef metrics(bytecode):\n a=dict(sim.gas_metrics()).get(sim.gas_id(bytecode),[0]*9)\n return dict(max_ok=a[0],init_max_ok=a[1],oog=a[2],reverts=a[3],other_halts=a[4],init_successes=a[5],deploy_max_ok=a[6],name_max_ok=a[7],executions=a[8])\n\ndef run(label,start,n):\n code=Path(f'scratch/{label}.sol').read_text(); bytecode=compile_code(code)\n t=time.time();res=sim.run_batch(bytecode,vanilla,configs(start,n),8)\n edges=[r.edges['submission'] for r in res.results]\n assert len(edges)==n\n # Rust results are collected in config order (indexed parallel iterator).\n data=dict(label=label,start=start,n=n,edges=edges,gas=metrics(bytecode),sha256=hashlib.sha256(code.encode()).hexdigest(),seconds=time.time()-t)\n Path(f'scratch/{label}-{start}.json').write_text(json.dumps(data))\n print(json.dumps({k:v for k,v in data.items() if k!='edges'}),flush=True)\n return data\n\ndef paired(a,b):\n d=np.array(a['edges'])-np.array(b['edges']); ix=np.argsort(d)[:5]\n return dict(n=len(d),mean_diff=float(d.mean()),se=float(d.std(ddof=1)/np.sqrt(len(d))),worst=[dict(seed=a['start']+int(i),diff=float(d[i]),edge=a['edges'][i],v2_edge=b['edges'][i]) for i in ix])\n\nif __name__=='__main__':\n mode=sys.argv[1]\n if mode=='tune':\n  b=run('V2',10000,64);summaries=[]\n  for i in range(6):\n   a=run(f'C{i}',10000,64);p=paired(a,b); print('PAIRED',i,p,flush=True);summaries.append(dict(label=f'C{i}',paired=p,gas=a['gas']))\n  Path('scratch/tuning1.json').write_text(json.dumps(summaries))\n  top=sorted([x for x in summaries if x['gas']['oog']==0 and x['gas']['reverts']==0 and x['gas']['other_halts']==0],key=lambda x:x['paired']['mean_diff'],reverse=True)[:2]\n  b=run('V2',11000,256);second=[]\n  for x in top:\n   a=run(x['label'],11000,256);p=paired(a,b);print('TOP2',x['label'],p,flush=True);second.append(dict(label=x['label'],paired=p,gas=a['gas']))\n  Path('scratch/tuning2.json').write_text(json.dumps(second))\n  win=max([x for x in second if x['gas']['oog']==0 and x['gas']['reverts']==0 and x['gas']['other_halts']==0],key=lambda x:x['paired']['mean_diff'])\n  Path('scratch/frozen.json').write_text(json.dumps(win));Path('scratch/Frozen.sol').write_text(Path('scratch/'+win['label']+'.sol').read_text())\n elif mode=='confirm':\n  # Code already frozen; exactly one reserved block comparison.\n  b=run('V2',4030000,2000); a=run('Frozen',4030000,2000)\n  Path('scratch/confirmation.json').write_text(json.dumps(dict(paired=paired(a,b),gas=a['gas'],baseline_gas=b['gas'],sha256=a['sha256'])))\n","check_counter.py":"import sys\nsys.path.insert(0,'scratch')\nfrom experiment import *\ns=Path('contracts/src/StarterStrategy.sol').read_text()\ns=s.replace('contract StarterStrategy','contract Strategy')\na=s.index('    function afterSwap(');b=s.index('    function getName(',a)\ns=s[:a]+'''    function afterSwap(TradeInfo calldata t) external pure override returns (uint256, uint256) {\n        uint256 v = t.amountY;\n        while (v != 0) { assembly { v := add(v, 1) } }\n        return (FEE, FEE);\n    }\n\n'''+s[b:]\nbc=compile_code(s)\nc=configs(10000,1)[0];c.n_steps=3\nsim.run_batch(bc,vanilla,[c],8)\nm=metrics(bc);assert m['oog']>0,m\nprint(json.dumps(m))\n# Separate deliberately reverting code exercises revert counter and fallback path.\ns=s[:s.index('    function afterSwap(')]+'''    function afterSwap(TradeInfo calldata) external pure override returns (uint256, uint256) { revert(\"test\"); }\n    function getName() external pure override returns (string memory) { return \"revert_test\"; }\n}\n'''\nbc=compile_code(s);sim.run_batch(bc,vanilla,[c],8);m=metrics(bc);assert m['reverts']>0,m;print(json.dumps(m))\n"},"counter_check":"{\"max_ok\": 0, \"init_max_ok\": 21796, \"oog\": 1, \"reverts\": 0, \"other_halts\": 0, \"init_successes\": 1, \"deploy_max_ok\": 195984, \"name_max_ok\": 21526, \"executions\": 4}\n{\"max_ok\": 0, \"init_max_ok\": 21796, \"oog\": 0, \"reverts\": 1, \"other_halts\": 0, \"init_successes\": 1, \"deploy_max_ok\": 195408, \"name_max_ok\": 21526, \"executions\": 4}\n","compiler_settings":"            # Build compile_standard input\n            input_json = {\n                \"language\": \"Solidity\",\n                \"sources\": sources,\n                \"settings\": {\n                    \"optimizer\": {\n                        \"enabled\": True,\n                        \"runs\": 200,\n                    },\n                    \"viaIR\": True,\n                    \"evmVersion\": \"paris\",\n                    \"outputSelection\": {\n                        \"*\": {\n                            \"*\": [\n                                \"abi\",\n                                \"evm.bytecode.object\",\n                                \"evm.deployedBytecode.object\",\n                                \"storageLayout\",\n                            ],\n                        },\n                    },\n                },\n            }\n\n            # Compile\n","coverage":"Deployment + getName + afterInitialize + every afterSwap; Mutex-protected cumulative counters keyed by creation-bytecode DefaultHasher ID (all observed IDs distinct). Tests provoke one swallowed OOG and one swallowed revert at original limits; each is detected. All candidate and V2 initializations succeeded. No gas limits modified; no failures removed from diagnostics.","final_validation":{"command":". scratch/env.sh && amm-match validate scratch/Frozen.sol","exit_code":0,"stdout":"Validating strategy...\nCompiling strategy...\nStrategy 'interaction_0' validated successfully!\n"}}}