{"key":"gn-b","shas":{"V2":"28417e116f57f1029fdd1803832e852574902c1ae7253c05657f317db76da4ab","G":"4f0f38f89b205570a5222f2a486de7b8a8dd0a0b81c4ef9d9d6a4cc2016b3ba8","GN":"ea7093f97f03b8b1fbf6237c863cb9a5e3d7a3c106f9b821cde42d81f8701cd3","GNK":"0fb0b17da6f48555011aa59043eed9f5526ba4c28aabc71e41596a7a137cc127"},"code_GN":"// 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 MIX_M = 625000000000000000;\n    uint256 constant MIX_E_SIXTEENTHS = 2;\n    uint256 constant ELAPSED_CAP = 8;\n    uint256 constant SIGNAL_THRESHOLD = WAD / 650;\n    uint256 constant DIR_DECAY = 750000000000000000;\n    uint256 constant ACT_DECAY = 530000000000000000;\n    uint256 constant SIZE_DECAY = 530000000000000000;\n    uint256 constant TOX_DECAY = 910000000000000000;\n    uint256 constant SIGMA_DECAY = 690000000000000000;\n    uint256 constant LAMBDA_DECAY = 990000000000000000;\n    uint256 constant SIZE_BLEND_DECAY = 828000000000000000;\n    uint256 constant TOX_BLEND_DECAY = 51000000000000000;\n    uint256 constant ACT_BLEND_DECAY = 985000000000000000;\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 DIR_IMPACT_MULT = 4;\n    uint256 constant GATE_SIGMA_MULT = 7200000000000000000;\n    uint256 constant MIN_GATE = 30000000000000000;\n    uint256 constant TRADE_TOX_BOOST = 3500 * BPS;\n    uint256 constant STALE_ATTRACT_FRAC = 1050000000000000000;\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    uint256 constant TOX_COEF = 300 * BPS;\n    uint256 constant TOX_QUAD_COEF = 15000 * BPS;\n    uint256 constant ACT_COEF = 91843 * BPS;\n    uint256 constant DIR_COEF = 20 * BPS;\n    uint256 constant DIR_TOX_COEF = 100 * BPS;\n    uint256 constant STALE_DIR_COEF = 6850 * BPS;\n    uint256 constant SIGMA_TOX_COEF = 500 * BPS;\n    uint256 constant TAIL_KNEE = 600 * BPS;\n    uint256 constant TAIL_SLOPE_PROTECT = 930000000000000000;\n    uint256 constant TAIL_SLOPE_ATTRACT = 850000000000000000;\n\n    function afterInitialize(uint256 initialX, uint256 initialY) external override returns (uint256, uint256) {\n        slots[0] = BASE_FEE; slots[1] = BASE_FEE; slots[3] = WAD;\n        slots[5] = initialX > 0 ? _div(initialY, initialX) : 100 * WAD;\n        slots[6] = 950000000000000; slots[7] = 800000000000000000; slots[8] = 2000000000000000;\n        slots[13] = 902500000000; slots[14] = slots[5];\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 packed = slots[2]; uint256 lastTs = uint64(packed);\n        uint256 dirState = slots[3]; uint256 actEma = slots[4]; uint256 pHat = slots[5];\n        uint256 sigmaHat = slots[6]; uint256 lambdaHat = slots[7]; uint256 sizeHat = slots[8];\n        uint256 toxEma = slots[9]; 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            dirState = _decayCentered(dirState, DIR_DECAY, elapsed);\n            actEma = _mul(actEma, _powWad(ACT_DECAY, elapsed));\n            sizeHat = _mul(sizeHat, _powWad(SIZE_DECAY, elapsed));\n            toxEma = _mul(toxEma, _powWad(TOX_DECAY, elapsed));\n            if (stepTradeCount > 0 && elapsedRaw > 0) {\n                uint256 lambdaInst = (stepTradeCount * WAD) / elapsedRaw;\n                if (lambdaInst > LAMBDA_CAP) lambdaInst = LAMBDA_CAP;\n                lambdaHat = _mul(lambdaHat, LAMBDA_DECAY) + _mul(lambdaInst, WAD - LAMBDA_DECAY);\n            }\n            uncertainty += _mul(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 ? _div(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 ? _mul(spot, gamma) : _div(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 = packed >> 64;\n            if (s == 0) s = pHat;\n            uint256 c = (_mul(s, WAD - prevBidFee) + _div(s, WAD - prevAskFee)) / 2;\n            if (c >= pHat) pHat += _mul(w, c - pHat);\n            else pHat -= _mul(w, pHat - c);\n            silenceScale = WAD - _mul(300000000000000000, w);\n        }\n\n        {\n            uint256 ret = pHat > 0 ? _div(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[12] = pImplied >= pHat ? 1 : 2; }\n            uint256 adaptiveGate = _mul(sigmaHat, GATE_SIGMA_MULT);\n            if (adaptiveGate < MIN_GATE) adaptiveGate = MIN_GATE;\n            alpha = _mul(alpha, silenceScale);\n            adaptiveGate = _mul(adaptiveGate, silenceScale);\n            if (ret <= adaptiveGate) { pHat = _mul(pHat, WAD - alpha) + _mul(pImplied, alpha); }\n            if (oppDir && REVERT_U > 0) {\n                uint256 pre = slots[11];\n                if (pre > pHat) pHat = pHat + _mul(pre - pHat, REVERT_U);\n                else pHat = pHat - _mul(pHat - pre, REVERT_U);\n            }\n            if (firstInStep) {\n                if (ret > RET_CAP) ret = RET_CAP;\n                sigmaHat = _mul(sigmaHat, SIGMA_DECAY) + _mul(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                ? _div(_mul(spot, gamma), WAD - 30 * BPS)\n                : _div(_mul(spot, WAD - 30 * BPS), gamma);\n            pHat = _mul(pHat, 90 * WAD / 100) + _mul(normalSpot, 10 * WAD / 100);\n        }\n\n        {\n            uint256 ret = fastHat > 0 ? _div(absDiff(pImplied, fastHat), fastHat) : 0;\n            uint256 alpha;\n            if (firstInStep) {\n                uint256 processSigma = sigmaForFast;\n                uint256 obsVar = uncertainty + _mul(processSigma, processSigma);\n                uint256 probArb;\n                uint256 z2 = _div(_mul(ret, ret), obsVar);\n                uint256 density = _powWad(_div(WAD, WAD + z2 / 16), 8);\n                uint256 sigmaObs = _isqrt(obsVar * WAD);\n                uint256 odds = _mul(density, _div(6700000000000000, sigmaObs));\n                bool arbFlag = ret <= _mul(sigmaForFast, 1220000000000000000);\n                uint256 prior = arbFlag ? 650000000000000000 : 400000000000000000;\n                uint256 tr = trade.reserveY > 0 ? _div(trade.amountY, trade.reserveY) : 0;\n                if (tr > 3000000000000000) prior = _mul(prior, 6 * WAD / 10);\n                if (silent > 1) prior = _mul(prior, 8 * WAD / 10);\n                odds = _mul(odds, _div(prior, WAD - prior));\n                probArb = _div(odds, WAD + odds);\n                alpha = _mul(probArb, 600000000000000000) + _mul(WAD - probArb, 80000000000000000);\n                slots[15] = pImplied >= fastHat ? 1 : 2;\n                uncertainty = _mul(uncertainty, WAD - alpha);\n            } else {\n                if ((slots[15] == 1) == (pImplied >= fastHat)) alpha = PHAT_ALPHA_RETAIL;\n            }\n            uint256 gate = _mul(sigmaHat, GATE_SIGMA_MULT);\n            if (gate < MIN_GATE) gate = MIN_GATE;\n            if (ret <= gate) fastHat = _mul(fastHat, WAD - alpha) + _mul(pImplied, alpha);\n            slots[13] = uncertainty;\n        }\n\n        if (!firstInStep && feeUsed > 30 * BPS && gamma > 0) {\n            uint256 normalObs = trade.isBuy\n                ? _div(_mul(spot, gamma), WAD - 30 * BPS)\n                : _div(_mul(spot, WAD - 30 * BPS), gamma);\n            if ((slots[15] == 1) == (normalObs >= fastHat)) {\n                fastHat = _mul(fastHat, 9 * WAD / 10) + _mul(normalObs, WAD / 10);\n            }\n        }\n        slots[14] = fastHat;\n        uint256 tradeRatio = trade.reserveY > 0 ? _div(trade.amountY, trade.reserveY) : 0;\n        if (tradeRatio > TRADE_RATIO_CAP) tradeRatio = TRADE_RATIO_CAP;\n\n        if (tradeRatio > SIGNAL_THRESHOLD) {\n            uint256 push = tradeRatio * DIR_IMPACT_MULT;\n            if (push > WAD / 4) push = WAD / 4;\n            if (trade.isBuy) {\n                dirState = dirState + push;\n                if (dirState > 2 * WAD) dirState = 2 * WAD;\n            } else {\n                dirState = dirState > push ? dirState - push : 0;\n            }\n            actEma = _mul(actEma, ACT_BLEND_DECAY) + _mul(tradeRatio, WAD - ACT_BLEND_DECAY);\n            sizeHat = _mul(sizeHat, SIZE_BLEND_DECAY) + _mul(tradeRatio, WAD - SIZE_BLEND_DECAY);\n            if (sizeHat > WAD) sizeHat = WAD;\n        }\n\n        uint256 tox = pHat > 0 ? _div(absDiff(spot, pHat), pHat) : 0;\n        if (tox > TOX_CAP) tox = TOX_CAP;\n        toxEma = _mul(toxEma, TOX_BLEND_DECAY) + _mul(tox, WAD - TOX_BLEND_DECAY);\n        uint256 toxSignal = toxEma;\n\n        stepTradeCount = stepTradeCount + 1;\n        if (stepTradeCount > STEP_COUNT_CAP) stepTradeCount = STEP_COUNT_CAP;\n\n        uint256 flowSize = _mul(lambdaHat, sizeHat);\n        uint256 fBase = BASE_FEE + _mul(SIGMA_COEF, sigmaHat) + _mul(LAMBDA_COEF, lambdaHat) + _mul(FLOW_SIZE_COEF, flowSize);\n        uint256 fMid = fBase + _mul(TOX_COEF, toxSignal) + _mul(TOX_QUAD_COEF, _mul(toxSignal, toxSignal)) + _mul(ACT_COEF, actEma);\n        fMid = fMid + _mul(SIGMA_TOX_COEF, _mul(sigmaHat, toxSignal));\n\n        uint256 dirDev; bool sellPressure;\n        if (dirState >= WAD) { dirDev = dirState - WAD; sellPressure = true; }\n        else { dirDev = WAD - dirState; sellPressure = false; }\n\n        uint256 skew = _mul(DIR_COEF, dirDev) + _mul(DIR_TOX_COEF, _mul(dirDev, toxSignal));\n        uint256 bidFee; uint256 askFee;\n        if (sellPressure) {\n            bidFee = fMid + skew;\n            askFee = fMid > skew ? fMid - skew : 0;\n        } else {\n            askFee = fMid + skew;\n            bidFee = fMid > skew ? fMid - skew : 0;\n        }\n\n        {\n            uint256 staleHat = _mul(pHat, 700000000000000000) + _mul(fastHat, 300000000000000000);\n            uint256 staleTox = _div(absDiff(spot, staleHat), staleHat);\n            if (staleTox > TOX_CAP) staleTox = TOX_CAP;\n            uint256 staleShift = _mul(STALE_DIR_COEF, staleTox);\n            uint256 attractShift = _mul(staleShift, STALE_ATTRACT_FRAC);\n            if (spot >= staleHat) {\n                bidFee = bidFee + staleShift;\n                askFee = askFee > attractShift ? askFee - attractShift : 0;\n            } else {\n                askFee = askFee + staleShift;\n                bidFee = bidFee > attractShift ? bidFee - attractShift : 0;\n            }\n        }\n\n        {\n            bool tradeAligned = (trade.isBuy && spot >= pHat) || (!trade.isBuy && spot < pHat);\n            if (tradeAligned) {\n                uint256 tradeBoost = _mul(TRADE_TOX_BOOST, tradeRatio);\n                if (trade.isBuy) { bidFee = bidFee + tradeBoost; }\n                else { askFee = askFee + tradeBoost; }\n            }\n        }\n\n        if (sellPressure) {\n            bidFee = clampFee(_compressTailWithSlope(bidFee, TAIL_SLOPE_PROTECT));\n            askFee = clampFee(_compressTailWithSlope(askFee, TAIL_SLOPE_ATTRACT));\n        } else {\n            askFee = clampFee(_compressTailWithSlope(askFee, TAIL_SLOPE_PROTECT));\n            bidFee = clampFee(_compressTailWithSlope(bidFee, TAIL_SLOPE_ATTRACT));\n        }\n\n        // Mix the next retail quote with a defence against next-step arbitrage.\n        // The first observed print is our existing proxy for the step's arb;\n        // after it, k counts the subsequent observed retail prints.\n        {\n            uint256 q = _nextRetailProbability(lambdaHat, stepTradeCount - 1);\n            uint256 weight = _mixWeight(q);\n            uint256 defence = clampFee(_absLogRatio(spot, pHat) + _mul(MIX_M, sigmaHat));\n            if (spot >= pHat) {\n                bidFee = _mul(weight, bidFee) + _mul(WAD - weight, defence);\n            } else {\n                askFee = _mul(weight, askFee) + _mul(WAD - weight, defence);\n            }\n        }\n\n        slots[0] = bidFee; slots[1] = askFee; slots[2] = (spot << 64) | trade.timestamp;\n        slots[3] = dirState; slots[4] = actEma; slots[5] = pHat;\n        slots[6] = sigmaHat; slots[7] = lambdaHat; slots[8] = sizeHat;\n        slots[9] = toxEma; slots[10] = stepTradeCount;\n\n        return (bidFee, askFee);\n    }\n\n    // Floor integer square root. Power-of-two upper bound, seven Newton steps.\n    function _isqrt(uint256 x) internal pure returns (uint256 z) {\n        if (x == 0) return 0;\n        unchecked {\n            uint256 a = x; uint256 bits;\n            if (a >> 128 > 0) { a >>= 128; bits += 128; }\n            if (a >> 64 > 0) { a >>= 64; bits += 64; }\n            if (a >> 32 > 0) { a >>= 32; bits += 32; }\n            if (a >> 16 > 0) { a >>= 16; bits += 16; }\n            if (a >> 8 > 0) { a >>= 8; bits += 8; }\n            if (a >> 4 > 0) { a >>= 4; bits += 4; }\n            if (a >> 2 > 0) { a >>= 2; bits += 2; }\n            if (a >> 1 > 0) { bits += 1; }\n            z = uint256(1) << ((bits + 2) / 2);\n            z = (z + x / z) / 2; z = (z + x / z) / 2;\n            z = (z + x / z) / 2; z = (z + x / z) / 2;\n            z = (z + x / z) / 2; z = (z + x / z) / 2;\n            z = (z + x / z) / 2;\n            uint256 other = x / z;\n            return z < other ? z : other;\n        }\n    }\n\n    function _mul(uint256 x, uint256 y) internal pure returns (uint256) {\n        unchecked { return (x * y) / WAD; }\n    }\n    function _div(uint256 x, uint256 y) internal pure returns (uint256) {\n        unchecked { return (x * WAD) / y; }\n    }\n\n    // Poisson survival ratio P(N > k) / P(N >= k). Dividing both\n    // tails by P(N=k) avoids cancellation for large k. For k=0 this\n    // is exactly 1-exp(-lambda), up to fixed-point/series rounding.\n    function _nextRetailProbability(uint256 lambda, uint256 k) internal pure returns (uint256) {\n        unchecked {\n        uint256 term = WAD;\n        uint256 tail;\n        for (uint256 j = 1; j <= 24; ++j) {\n            term = ((term * lambda) / WAD) / (k + j);\n            tail += term;\n            if (term == 0) break;\n        }\n        return (tail * WAD) / (WAD + tail);\n        }\n    }\n\n    // e is an exact multiple of 1/16. Successive square roots implement\n    // the fractional bits without an external fixed-point math library.\n    function _mixWeight(uint256 q) internal pure returns (uint256 weight) {\n        weight = _powWad(q, MIX_E_SIXTEENTHS / 16);\n        uint256 fraction = MIX_E_SIXTEENTHS % 16;\n        uint256 root = q;\n        for (uint256 bit = 8; bit > 0 && fraction > 0; bit >>= 1) {\n            root = _isqrt(root * WAD);\n            if ((fraction & bit) != 0) {\n                weight = _mul(weight, root);\n                fraction -= bit;\n            }\n        }\n    }\n\n    // 2*atanh((a-b)/(a+b)) = abs(ln(a/b)). Once z >= .05,\n    // the logarithm exceeds the 10% fee cap. In the remaining domain\n    // five positive terms give <1e-15 absolute truncation error.\n    function _absLogRatio(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (a == b) return 0;\n        if (a == 0 || b == 0) return MAX_FEE;\n        uint256 z = _div(absDiff(a, b), a + b);\n        if (z >= WAD / 20) return MAX_FEE;\n        unchecked {\n        uint256 z2 = (z * z) / WAD;\n        uint256 power = z;\n        uint256 series = z;\n        for (uint256 j = 3; j <= 9; j += 2) {\n            power = (power * z2) / WAD;\n            series += power / j;\n        }\n        return 2 * series;\n        }\n    }\n\n    function _compressTailWithSlope(uint256 fee, uint256 slope) internal pure returns (uint256) {\n        if (fee <= TAIL_KNEE) return fee;\n        return TAIL_KNEE + _mul(fee - TAIL_KNEE, slope);\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 = _mul(result, factor);\n            factor = _mul(factor, factor);\n            exp >>= 1;\n        }\n    }\n\n    function _decayCentered(uint256 centered, uint256 decayFactor, uint256 elapsed) internal pure returns (uint256) {\n        uint256 mul = _powWad(decayFactor, elapsed);\n        if (centered >= WAD) { return WAD + _mul(centered - WAD, mul); }\n        uint256 below = _mul(WAD - centered, mul);\n        return below < WAD ? WAD - below : 0;\n    }\n\n    function getName() external pure override returns (string memory) { return \"no_cubic\"; }\n}\n","code_GNK":"// 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 MIX_M = 625000000000000000;\n    uint256 constant MIX_E_SIXTEENTHS = 2;\n    uint256 constant ELAPSED_CAP = 8;\n    uint256 constant SIGNAL_THRESHOLD = WAD / 650;\n    uint256 constant DIR_DECAY = 750000000000000000;\n    uint256 constant ACT_DECAY = 530000000000000000;\n    uint256 constant SIZE_DECAY = 530000000000000000;\n    uint256 constant TOX_DECAY = 910000000000000000;\n    uint256 constant SIGMA_DECAY = 690000000000000000;\n    uint256 constant LAMBDA_DECAY = 990000000000000000;\n    uint256 constant SIZE_BLEND_DECAY = 828000000000000000;\n    uint256 constant TOX_BLEND_DECAY = 51000000000000000;\n    uint256 constant ACT_BLEND_DECAY = 985000000000000000;\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 DIR_IMPACT_MULT = 4;\n    uint256 constant GATE_SIGMA_MULT = 7200000000000000000;\n    uint256 constant MIN_GATE = 30000000000000000;\n    uint256 constant TRADE_TOX_BOOST = 3500 * BPS;\n    uint256 constant STALE_ATTRACT_FRAC = 1050000000000000000;\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    uint256 constant TOX_COEF = 300 * BPS;\n    uint256 constant TOX_QUAD_COEF = 15000 * BPS;\n    uint256 constant ACT_COEF = 91843 * BPS;\n    uint256 constant DIR_COEF = 20 * BPS;\n    uint256 constant DIR_TOX_COEF = 100 * BPS;\n    uint256 constant STALE_DIR_COEF = 6850 * BPS;\n    uint256 constant SIGMA_TOX_COEF = 500 * BPS;\n    uint256 constant TAIL_KNEE = 600 * BPS;\n    uint256 constant TAIL_SLOPE_PROTECT = 930000000000000000;\n    uint256 constant TAIL_SLOPE_ATTRACT = 850000000000000000;\n\n    function afterInitialize(uint256 initialX, uint256 initialY) external override returns (uint256, uint256) {\n        slots[0] = BASE_FEE; slots[1] = BASE_FEE; slots[3] = WAD;\n        slots[5] = initialX > 0 ? _div(initialY, initialX) : 100 * WAD;\n        slots[6] = 950000000000000; slots[7] = 800000000000000000; slots[8] = 2000000000000000;\n        slots[13] = 902500000000; slots[14] = slots[5];\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 packed = slots[2]; uint256 lastTs = uint64(packed);\n        uint256 dirState = slots[3]; uint256 actEma = slots[4]; uint256 pHat = slots[5];\n        uint256 sigmaHat = slots[6]; uint256 lambdaHat = slots[7]; uint256 sizeHat = slots[8];\n        uint256 toxEma = slots[9]; 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            dirState = _decayCentered(dirState, DIR_DECAY, elapsed);\n            actEma = _mul(actEma, _powWad(ACT_DECAY, elapsed));\n            sizeHat = _mul(sizeHat, _powWad(SIZE_DECAY, elapsed));\n            toxEma = _mul(toxEma, _powWad(TOX_DECAY, elapsed));\n            if (stepTradeCount > 0 && elapsedRaw > 0) {\n                uint256 lambdaInst = (stepTradeCount * WAD) / elapsedRaw;\n                if (lambdaInst > LAMBDA_CAP) lambdaInst = LAMBDA_CAP;\n                lambdaHat = _mul(lambdaHat, LAMBDA_DECAY) + _mul(lambdaInst, WAD - LAMBDA_DECAY);\n            }\n            uncertainty += _mul(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 ? _div(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 ? _mul(spot, gamma) : _div(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 = packed >> 64;\n            if (s == 0) s = pHat;\n            uint256 c = (_mul(s, WAD - prevBidFee) + _div(s, WAD - prevAskFee)) / 2;\n            if (c >= pHat) pHat += _mul(w, c - pHat);\n            else pHat -= _mul(w, pHat - c);\n            silenceScale = WAD - _mul(300000000000000000, w);\n        }\n\n        {\n            uint256 ret = pHat > 0 ? _div(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[12] = pImplied >= pHat ? 1 : 2; }\n            uint256 adaptiveGate = _mul(sigmaHat, GATE_SIGMA_MULT);\n            if (adaptiveGate < MIN_GATE) adaptiveGate = MIN_GATE;\n            alpha = _mul(alpha, silenceScale);\n            adaptiveGate = _mul(adaptiveGate, silenceScale);\n            if (ret <= adaptiveGate) { pHat = _mul(pHat, WAD - alpha) + _mul(pImplied, alpha); }\n            if (oppDir && REVERT_U > 0) {\n                uint256 pre = slots[11];\n                if (pre > pHat) pHat = pHat + _mul(pre - pHat, REVERT_U);\n                else pHat = pHat - _mul(pHat - pre, REVERT_U);\n            }\n            if (firstInStep) {\n                if (ret > RET_CAP) ret = RET_CAP;\n                sigmaHat = _mul(sigmaHat, SIGMA_DECAY) + _mul(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                ? _div(_mul(spot, gamma), WAD - 30 * BPS)\n                : _div(_mul(spot, WAD - 30 * BPS), gamma);\n            pHat = _mul(pHat, 90 * WAD / 100) + _mul(normalSpot, 10 * WAD / 100);\n        }\n\n        {\n            uint256 ret = fastHat > 0 ? _div(absDiff(pImplied, fastHat), fastHat) : 0;\n            uint256 alpha;\n            if (firstInStep) {\n                uint256 processSigma = sigmaForFast;\n                uint256 obsVar = uncertainty + _mul(processSigma, processSigma);\n                uint256 probArb;\n                uint256 z2 = _div(_mul(ret, ret), obsVar);\n                uint256 density = _powWad(_div(WAD, WAD + z2 / 16), 8);\n                uint256 sigmaObs = _isqrt(obsVar * WAD);\n                uint256 odds = _mul(density, _div(6700000000000000, sigmaObs));\n                bool arbFlag = ret <= _mul(sigmaForFast, 1220000000000000000);\n                uint256 prior = arbFlag ? 650000000000000000 : 400000000000000000;\n                uint256 tr = trade.reserveY > 0 ? _div(trade.amountY, trade.reserveY) : 0;\n                if (tr > 3000000000000000) prior = _mul(prior, 6 * WAD / 10);\n                if (silent > 1) prior = _mul(prior, 8 * WAD / 10);\n                odds = _mul(odds, _div(prior, WAD - prior));\n                probArb = _div(odds, WAD + odds);\n                alpha = _mul(probArb, 600000000000000000) + _mul(WAD - probArb, 80000000000000000);\n                slots[15] = pImplied >= fastHat ? 1 : 2;\n                uncertainty = _mul(uncertainty, WAD - alpha);\n            } else {\n                if ((slots[15] == 1) == (pImplied >= fastHat)) alpha = PHAT_ALPHA_RETAIL;\n            }\n            uint256 gate = _mul(sigmaHat, GATE_SIGMA_MULT);\n            if (gate < MIN_GATE) gate = MIN_GATE;\n            if (ret <= gate) fastHat = _mul(fastHat, WAD - alpha) + _mul(pImplied, alpha);\n            slots[13] = uncertainty;\n        }\n\n        if (!firstInStep && feeUsed > 30 * BPS && gamma > 0) {\n            uint256 normalObs = trade.isBuy\n                ? _div(_mul(spot, gamma), WAD - 30 * BPS)\n                : _div(_mul(spot, WAD - 30 * BPS), gamma);\n            if ((slots[15] == 1) == (normalObs >= fastHat)) {\n                fastHat = _mul(fastHat, 9 * WAD / 10) + _mul(normalObs, WAD / 10);\n            }\n        }\n        slots[14] = fastHat;\n        uint256 tradeRatio = trade.reserveY > 0 ? _div(trade.amountY, trade.reserveY) : 0;\n        if (tradeRatio > TRADE_RATIO_CAP) tradeRatio = TRADE_RATIO_CAP;\n\n        if (tradeRatio > SIGNAL_THRESHOLD) {\n            uint256 push = tradeRatio * DIR_IMPACT_MULT;\n            if (push > WAD / 4) push = WAD / 4;\n            if (trade.isBuy) {\n                dirState = dirState + push;\n                if (dirState > 2 * WAD) dirState = 2 * WAD;\n            } else {\n                dirState = dirState > push ? dirState - push : 0;\n            }\n            actEma = _mul(actEma, ACT_BLEND_DECAY) + _mul(tradeRatio, WAD - ACT_BLEND_DECAY);\n            sizeHat = _mul(sizeHat, SIZE_BLEND_DECAY) + _mul(tradeRatio, WAD - SIZE_BLEND_DECAY);\n            if (sizeHat > WAD) sizeHat = WAD;\n        }\n\n        uint256 tox = pHat > 0 ? _div(absDiff(spot, pHat), pHat) : 0;\n        if (tox > TOX_CAP) tox = TOX_CAP;\n        toxEma = _mul(toxEma, TOX_BLEND_DECAY) + _mul(tox, WAD - TOX_BLEND_DECAY);\n        uint256 toxSignal = toxEma;\n\n        stepTradeCount = stepTradeCount + 1;\n        if (stepTradeCount > STEP_COUNT_CAP) stepTradeCount = STEP_COUNT_CAP;\n\n        uint256 flowSize = _mul(lambdaHat, sizeHat);\n        uint256 fBase = BASE_FEE + _mul(SIGMA_COEF, sigmaHat) + _mul(LAMBDA_COEF, lambdaHat) + _mul(FLOW_SIZE_COEF, flowSize);\n        uint256 fMid = fBase + _mul(TOX_COEF, toxSignal) + _mul(TOX_QUAD_COEF, _mul(toxSignal, toxSignal)) + _mul(ACT_COEF, actEma);\n        fMid = fMid + _mul(SIGMA_TOX_COEF, _mul(sigmaHat, toxSignal));\n\n        uint256 dirDev; bool sellPressure;\n        if (dirState >= WAD) { dirDev = dirState - WAD; sellPressure = true; }\n        else { dirDev = WAD - dirState; sellPressure = false; }\n\n        uint256 skew = 0;\n        uint256 bidFee; uint256 askFee;\n        if (sellPressure) {\n            bidFee = fMid + skew;\n            askFee = fMid > skew ? fMid - skew : 0;\n        } else {\n            askFee = fMid + skew;\n            bidFee = fMid > skew ? fMid - skew : 0;\n        }\n\n        {\n            uint256 staleHat = _mul(pHat, 700000000000000000) + _mul(fastHat, 300000000000000000);\n            uint256 staleTox = _div(absDiff(spot, staleHat), staleHat);\n            if (staleTox > TOX_CAP) staleTox = TOX_CAP;\n            uint256 staleShift = _mul(STALE_DIR_COEF, staleTox);\n            uint256 attractShift = _mul(staleShift, STALE_ATTRACT_FRAC);\n            if (spot >= staleHat) {\n                bidFee = bidFee + staleShift;\n                askFee = askFee > attractShift ? askFee - attractShift : 0;\n            } else {\n                askFee = askFee + staleShift;\n                bidFee = bidFee > attractShift ? bidFee - attractShift : 0;\n            }\n        }\n\n        {\n            bool tradeAligned = (trade.isBuy && spot >= pHat) || (!trade.isBuy && spot < pHat);\n            if (tradeAligned) {\n                uint256 tradeBoost = _mul(TRADE_TOX_BOOST, tradeRatio);\n                if (trade.isBuy) { bidFee = bidFee + tradeBoost; }\n                else { askFee = askFee + tradeBoost; }\n            }\n        }\n\n        if (sellPressure) {\n            bidFee = clampFee(_compressTailWithSlope(bidFee, TAIL_SLOPE_PROTECT));\n            askFee = clampFee(_compressTailWithSlope(askFee, TAIL_SLOPE_ATTRACT));\n        } else {\n            askFee = clampFee(_compressTailWithSlope(askFee, TAIL_SLOPE_PROTECT));\n            bidFee = clampFee(_compressTailWithSlope(bidFee, TAIL_SLOPE_ATTRACT));\n        }\n\n        // Mix the next retail quote with a defence against next-step arbitrage.\n        // The first observed print is our existing proxy for the step's arb;\n        // after it, k counts the subsequent observed retail prints.\n        {\n            uint256 q = _nextRetailProbability(lambdaHat, stepTradeCount - 1);\n            uint256 weight = _mixWeight(q);\n            uint256 defence = clampFee(_absLogRatio(spot, pHat) + _mul(MIX_M, sigmaHat));\n            if (spot >= pHat) {\n                bidFee = _mul(weight, bidFee) + _mul(WAD - weight, defence);\n            } else {\n                askFee = _mul(weight, askFee) + _mul(WAD - weight, defence);\n            }\n        }\n\n        slots[0] = bidFee; slots[1] = askFee; slots[2] = (spot << 64) | trade.timestamp;\n        slots[3] = dirState; slots[4] = actEma; slots[5] = pHat;\n        slots[6] = sigmaHat; slots[7] = lambdaHat; slots[8] = sizeHat;\n        slots[9] = toxEma; slots[10] = stepTradeCount;\n\n        return (bidFee, askFee);\n    }\n\n    // Floor integer square root. Power-of-two upper bound, seven Newton steps.\n    function _isqrt(uint256 x) internal pure returns (uint256 z) {\n        if (x == 0) return 0;\n        unchecked {\n            uint256 a = x; uint256 bits;\n            if (a >> 128 > 0) { a >>= 128; bits += 128; }\n            if (a >> 64 > 0) { a >>= 64; bits += 64; }\n            if (a >> 32 > 0) { a >>= 32; bits += 32; }\n            if (a >> 16 > 0) { a >>= 16; bits += 16; }\n            if (a >> 8 > 0) { a >>= 8; bits += 8; }\n            if (a >> 4 > 0) { a >>= 4; bits += 4; }\n            if (a >> 2 > 0) { a >>= 2; bits += 2; }\n            if (a >> 1 > 0) { bits += 1; }\n            z = uint256(1) << ((bits + 2) / 2);\n            z = (z + x / z) / 2; z = (z + x / z) / 2;\n            z = (z + x / z) / 2; z = (z + x / z) / 2;\n            z = (z + x / z) / 2; z = (z + x / z) / 2;\n            z = (z + x / z) / 2;\n            uint256 other = x / z;\n            return z < other ? z : other;\n        }\n    }\n\n    function _mul(uint256 x, uint256 y) internal pure returns (uint256) {\n        unchecked { return (x * y) / WAD; }\n    }\n    function _div(uint256 x, uint256 y) internal pure returns (uint256) {\n        unchecked { return (x * WAD) / y; }\n    }\n\n    // Poisson survival ratio P(N > k) / P(N >= k). Dividing both\n    // tails by P(N=k) avoids cancellation for large k. For k=0 this\n    // is exactly 1-exp(-lambda), up to fixed-point/series rounding.\n    function _nextRetailProbability(uint256 lambda, uint256 k) internal pure returns (uint256) {\n        unchecked {\n        uint256 term = WAD;\n        uint256 tail;\n        for (uint256 j = 1; j <= 24; ++j) {\n            term = ((term * lambda) / WAD) / (k + j);\n            tail += term;\n            if (term == 0) break;\n        }\n        return (tail * WAD) / (WAD + tail);\n        }\n    }\n\n    // e is an exact multiple of 1/16. Successive square roots implement\n    // the fractional bits without an external fixed-point math library.\n    function _mixWeight(uint256 q) internal pure returns (uint256 weight) {\n        weight = _powWad(q, MIX_E_SIXTEENTHS / 16);\n        uint256 fraction = MIX_E_SIXTEENTHS % 16;\n        uint256 root = q;\n        for (uint256 bit = 8; bit > 0 && fraction > 0; bit >>= 1) {\n            root = _isqrt(root * WAD);\n            if ((fraction & bit) != 0) {\n                weight = _mul(weight, root);\n                fraction -= bit;\n            }\n        }\n    }\n\n    // 2*atanh((a-b)/(a+b)) = abs(ln(a/b)). Once z >= .05,\n    // the logarithm exceeds the 10% fee cap. In the remaining domain\n    // five positive terms give <1e-15 absolute truncation error.\n    function _absLogRatio(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (a == b) return 0;\n        if (a == 0 || b == 0) return MAX_FEE;\n        uint256 z = _div(absDiff(a, b), a + b);\n        if (z >= WAD / 20) return MAX_FEE;\n        unchecked {\n        uint256 z2 = (z * z) / WAD;\n        uint256 power = z;\n        uint256 series = z;\n        for (uint256 j = 3; j <= 9; j += 2) {\n            power = (power * z2) / WAD;\n            series += power / j;\n        }\n        return 2 * series;\n        }\n    }\n\n    function _compressTailWithSlope(uint256 fee, uint256 slope) internal pure returns (uint256) {\n        if (fee <= TAIL_KNEE) return fee;\n        return TAIL_KNEE + _mul(fee - TAIL_KNEE, slope);\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 = _mul(result, factor);\n            factor = _mul(factor, factor);\n            exp >>= 1;\n        }\n    }\n\n    function _decayCentered(uint256 centered, uint256 decayFactor, uint256 elapsed) internal pure returns (uint256) {\n        uint256 mul = _powWad(decayFactor, elapsed);\n        if (centered >= WAD) { return WAD + _mul(centered - WAD, mul); }\n        uint256 below = _mul(WAD - centered, mul);\n        return below < WAD ? WAD - below : 0;\n    }\n\n    function getName() external pure override returns (string memory) { return \"no_cubic\"; }\n}\n","code_G":"// 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 ELAPSED_CAP = 8;\n    uint256 constant SIGNAL_THRESHOLD = WAD / 650;\n    uint256 constant DIR_DECAY = 750000000000000000;\n    uint256 constant ACT_DECAY = 530000000000000000;\n    uint256 constant SIZE_DECAY = 530000000000000000;\n    uint256 constant TOX_DECAY = 910000000000000000;\n    uint256 constant SIGMA_DECAY = 690000000000000000;\n    uint256 constant LAMBDA_DECAY = 990000000000000000;\n    uint256 constant SIZE_BLEND_DECAY = 828000000000000000;\n    uint256 constant TOX_BLEND_DECAY = 51000000000000000;\n    uint256 constant ACT_BLEND_DECAY = 985000000000000000;\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 DIR_IMPACT_MULT = 4;\n    uint256 constant GATE_SIGMA_MULT = 7200000000000000000;\n    uint256 constant MIN_GATE = 30000000000000000;\n    uint256 constant TRADE_TOX_BOOST = 3500 * BPS;\n    uint256 constant STALE_ATTRACT_FRAC = 1050000000000000000;\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    uint256 constant TOX_COEF = 300 * BPS;\n    uint256 constant TOX_QUAD_COEF = 15000 * BPS;\n    uint256 constant ACT_COEF = 91843 * BPS;\n    uint256 constant DIR_COEF = 20 * BPS;\n    uint256 constant DIR_TOX_COEF = 100 * BPS;\n    uint256 constant STALE_DIR_COEF = 6850 * BPS;\n    uint256 constant SIGMA_TOX_COEF = 500 * BPS;\n    uint256 constant TAIL_KNEE = 600 * BPS;\n    uint256 constant TAIL_SLOPE_PROTECT = 930000000000000000;\n    uint256 constant TAIL_SLOPE_ATTRACT = 850000000000000000;\n\n    function afterInitialize(uint256 initialX, uint256 initialY) external override returns (uint256, uint256) {\n        slots[0] = BASE_FEE; slots[1] = BASE_FEE; slots[3] = WAD;\n        slots[5] = initialX > 0 ? _div(initialY, initialX) : 100 * WAD;\n        slots[6] = 950000000000000; slots[7] = 800000000000000000; slots[8] = 2000000000000000;\n        slots[13] = 902500000000; slots[14] = slots[5];\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 packed = slots[2]; uint256 lastTs = uint64(packed);\n        uint256 dirState = slots[3]; uint256 actEma = slots[4]; uint256 pHat = slots[5];\n        uint256 sigmaHat = slots[6]; uint256 lambdaHat = slots[7]; uint256 sizeHat = slots[8];\n        uint256 toxEma = slots[9]; 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            dirState = _decayCentered(dirState, DIR_DECAY, elapsed);\n            actEma = _mul(actEma, _powWad(ACT_DECAY, elapsed));\n            sizeHat = _mul(sizeHat, _powWad(SIZE_DECAY, elapsed));\n            toxEma = _mul(toxEma, _powWad(TOX_DECAY, elapsed));\n            if (stepTradeCount > 0 && elapsedRaw > 0) {\n                uint256 lambdaInst = (stepTradeCount * WAD) / elapsedRaw;\n                if (lambdaInst > LAMBDA_CAP) lambdaInst = LAMBDA_CAP;\n                lambdaHat = _mul(lambdaHat, LAMBDA_DECAY) + _mul(lambdaInst, WAD - LAMBDA_DECAY);\n            }\n            uncertainty += _mul(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 ? _div(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 ? _mul(spot, gamma) : _div(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 = packed >> 64;\n            if (s == 0) s = pHat;\n            uint256 c = (_mul(s, WAD - prevBidFee) + _div(s, WAD - prevAskFee)) / 2;\n            if (c >= pHat) pHat += _mul(w, c - pHat);\n            else pHat -= _mul(w, pHat - c);\n            silenceScale = WAD - _mul(300000000000000000, w);\n        }\n\n        {\n            uint256 ret = pHat > 0 ? _div(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[12] = pImplied >= pHat ? 1 : 2; }\n            uint256 adaptiveGate = _mul(sigmaHat, GATE_SIGMA_MULT);\n            if (adaptiveGate < MIN_GATE) adaptiveGate = MIN_GATE;\n            alpha = _mul(alpha, silenceScale);\n            adaptiveGate = _mul(adaptiveGate, silenceScale);\n            if (ret <= adaptiveGate) { pHat = _mul(pHat, WAD - alpha) + _mul(pImplied, alpha); }\n            if (oppDir && REVERT_U > 0) {\n                uint256 pre = slots[11];\n                if (pre > pHat) pHat = pHat + _mul(pre - pHat, REVERT_U);\n                else pHat = pHat - _mul(pHat - pre, REVERT_U);\n            }\n            if (firstInStep) {\n                if (ret > RET_CAP) ret = RET_CAP;\n                sigmaHat = _mul(sigmaHat, SIGMA_DECAY) + _mul(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                ? _div(_mul(spot, gamma), WAD - 30 * BPS)\n                : _div(_mul(spot, WAD - 30 * BPS), gamma);\n            pHat = _mul(pHat, 90 * WAD / 100) + _mul(normalSpot, 10 * WAD / 100);\n        }\n\n        {\n            uint256 ret = fastHat > 0 ? _div(absDiff(pImplied, fastHat), fastHat) : 0;\n            uint256 alpha;\n            if (firstInStep) {\n                uint256 processSigma = sigmaForFast;\n                uint256 obsVar = uncertainty + _mul(processSigma, processSigma);\n                uint256 probArb;\n                uint256 z2 = _div(_mul(ret, ret), obsVar);\n                uint256 density = _powWad(_div(WAD, WAD + z2 / 16), 8);\n                uint256 sigmaObs = _isqrt(obsVar * WAD);\n                uint256 odds = _mul(density, _div(6700000000000000, sigmaObs));\n                bool arbFlag = ret <= _mul(sigmaForFast, 1220000000000000000);\n                uint256 prior = arbFlag ? 650000000000000000 : 400000000000000000;\n                uint256 tr = trade.reserveY > 0 ? _div(trade.amountY, trade.reserveY) : 0;\n                if (tr > 3000000000000000) prior = _mul(prior, 6 * WAD / 10);\n                if (silent > 1) prior = _mul(prior, 8 * WAD / 10);\n                odds = _mul(odds, _div(prior, WAD - prior));\n                probArb = _div(odds, WAD + odds);\n                alpha = _mul(probArb, 600000000000000000) + _mul(WAD - probArb, 80000000000000000);\n                slots[15] = pImplied >= fastHat ? 1 : 2;\n                uncertainty = _mul(uncertainty, WAD - alpha);\n            } else {\n                if ((slots[15] == 1) == (pImplied >= fastHat)) alpha = PHAT_ALPHA_RETAIL;\n            }\n            uint256 gate = _mul(sigmaHat, GATE_SIGMA_MULT);\n            if (gate < MIN_GATE) gate = MIN_GATE;\n            if (ret <= gate) fastHat = _mul(fastHat, WAD - alpha) + _mul(pImplied, alpha);\n            slots[13] = uncertainty;\n        }\n\n        if (!firstInStep && feeUsed > 30 * BPS && gamma > 0) {\n            uint256 normalObs = trade.isBuy\n                ? _div(_mul(spot, gamma), WAD - 30 * BPS)\n                : _div(_mul(spot, WAD - 30 * BPS), gamma);\n            if ((slots[15] == 1) == (normalObs >= fastHat)) {\n                fastHat = _mul(fastHat, 9 * WAD / 10) + _mul(normalObs, WAD / 10);\n            }\n        }\n        slots[14] = fastHat;\n        uint256 tradeRatio = trade.reserveY > 0 ? _div(trade.amountY, trade.reserveY) : 0;\n        if (tradeRatio > TRADE_RATIO_CAP) tradeRatio = TRADE_RATIO_CAP;\n\n        if (tradeRatio > SIGNAL_THRESHOLD) {\n            uint256 push = tradeRatio * DIR_IMPACT_MULT;\n            if (push > WAD / 4) push = WAD / 4;\n            if (trade.isBuy) {\n                dirState = dirState + push;\n                if (dirState > 2 * WAD) dirState = 2 * WAD;\n            } else {\n                dirState = dirState > push ? dirState - push : 0;\n            }\n            actEma = _mul(actEma, ACT_BLEND_DECAY) + _mul(tradeRatio, WAD - ACT_BLEND_DECAY);\n            sizeHat = _mul(sizeHat, SIZE_BLEND_DECAY) + _mul(tradeRatio, WAD - SIZE_BLEND_DECAY);\n            if (sizeHat > WAD) sizeHat = WAD;\n        }\n\n        uint256 tox = pHat > 0 ? _div(absDiff(spot, pHat), pHat) : 0;\n        if (tox > TOX_CAP) tox = TOX_CAP;\n        toxEma = _mul(toxEma, TOX_BLEND_DECAY) + _mul(tox, WAD - TOX_BLEND_DECAY);\n        uint256 toxSignal = toxEma;\n\n        stepTradeCount = stepTradeCount + 1;\n        if (stepTradeCount > STEP_COUNT_CAP) stepTradeCount = STEP_COUNT_CAP;\n\n        uint256 flowSize = _mul(lambdaHat, sizeHat);\n        uint256 fBase = BASE_FEE + _mul(SIGMA_COEF, sigmaHat) + _mul(LAMBDA_COEF, lambdaHat) + _mul(FLOW_SIZE_COEF, flowSize);\n        uint256 fMid = fBase + _mul(TOX_COEF, toxSignal) + _mul(TOX_QUAD_COEF, _mul(toxSignal, toxSignal)) + _mul(ACT_COEF, actEma);\n        fMid = fMid + _mul(SIGMA_TOX_COEF, _mul(sigmaHat, toxSignal));\n\n        uint256 dirDev; bool sellPressure;\n        if (dirState >= WAD) { dirDev = dirState - WAD; sellPressure = true; }\n        else { dirDev = WAD - dirState; sellPressure = false; }\n\n        uint256 skew = _mul(DIR_COEF, dirDev) + _mul(DIR_TOX_COEF, _mul(dirDev, toxSignal));\n        uint256 bidFee; uint256 askFee;\n        if (sellPressure) {\n            bidFee = fMid + skew;\n            askFee = fMid > skew ? fMid - skew : 0;\n        } else {\n            askFee = fMid + skew;\n            bidFee = fMid > skew ? fMid - skew : 0;\n        }\n\n        {\n            uint256 staleHat = _mul(pHat, 700000000000000000) + _mul(fastHat, 300000000000000000);\n            uint256 staleTox = _div(absDiff(spot, staleHat), staleHat);\n            if (staleTox > TOX_CAP) staleTox = TOX_CAP;\n            uint256 staleShift = _mul(STALE_DIR_COEF, staleTox);\n            uint256 attractShift = _mul(staleShift, STALE_ATTRACT_FRAC);\n            if (spot >= staleHat) {\n                bidFee = bidFee + staleShift;\n                askFee = askFee > attractShift ? askFee - attractShift : 0;\n            } else {\n                askFee = askFee + staleShift;\n                bidFee = bidFee > attractShift ? bidFee - attractShift : 0;\n            }\n        }\n\n        {\n            bool tradeAligned = (trade.isBuy && spot >= pHat) || (!trade.isBuy && spot < pHat);\n            if (tradeAligned) {\n                uint256 tradeBoost = _mul(TRADE_TOX_BOOST, tradeRatio);\n                if (trade.isBuy) { bidFee = bidFee + tradeBoost; }\n                else { askFee = askFee + tradeBoost; }\n            }\n        }\n\n        if (sellPressure) {\n            bidFee = clampFee(_compressTailWithSlope(bidFee, TAIL_SLOPE_PROTECT));\n            askFee = clampFee(_compressTailWithSlope(askFee, TAIL_SLOPE_ATTRACT));\n        } else {\n            askFee = clampFee(_compressTailWithSlope(askFee, TAIL_SLOPE_PROTECT));\n            bidFee = clampFee(_compressTailWithSlope(bidFee, TAIL_SLOPE_ATTRACT));\n        }\n\n        slots[0] = bidFee; slots[1] = askFee; slots[2] = (spot << 64) | trade.timestamp;\n        slots[3] = dirState; slots[4] = actEma; slots[5] = pHat;\n        slots[6] = sigmaHat; slots[7] = lambdaHat; slots[8] = sizeHat;\n        slots[9] = toxEma; slots[10] = stepTradeCount;\n\n        return (bidFee, askFee);\n    }\n\n    // Floor integer square root. Power-of-two upper bound, seven Newton steps.\n    function _isqrt(uint256 x) internal pure returns (uint256 z) {\n        if (x == 0) return 0;\n        unchecked {\n            uint256 a = x; uint256 bits;\n            if (a >> 128 > 0) { a >>= 128; bits += 128; }\n            if (a >> 64 > 0) { a >>= 64; bits += 64; }\n            if (a >> 32 > 0) { a >>= 32; bits += 32; }\n            if (a >> 16 > 0) { a >>= 16; bits += 16; }\n            if (a >> 8 > 0) { a >>= 8; bits += 8; }\n            if (a >> 4 > 0) { a >>= 4; bits += 4; }\n            if (a >> 2 > 0) { a >>= 2; bits += 2; }\n            if (a >> 1 > 0) { bits += 1; }\n            z = uint256(1) << ((bits + 2) / 2);\n            z = (z + x / z) / 2; z = (z + x / z) / 2;\n            z = (z + x / z) / 2; z = (z + x / z) / 2;\n            z = (z + x / z) / 2; z = (z + x / z) / 2;\n            z = (z + x / z) / 2;\n            uint256 other = x / z;\n            return z < other ? z : other;\n        }\n    }\n\n    function _mul(uint256 x, uint256 y) internal pure returns (uint256) {\n        unchecked { return (x * y) / WAD; }\n    }\n    function _div(uint256 x, uint256 y) internal pure returns (uint256) {\n        unchecked { return (x * WAD) / y; }\n    }\n\n    function _compressTailWithSlope(uint256 fee, uint256 slope) internal pure returns (uint256) {\n        if (fee <= TAIL_KNEE) return fee;\n        return TAIL_KNEE + _mul(fee - TAIL_KNEE, slope);\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 = _mul(result, factor);\n            factor = _mul(factor, factor);\n            exp >>= 1;\n        }\n    }\n\n    function _decayCentered(uint256 centered, uint256 decayFactor, uint256 elapsed) internal pure returns (uint256) {\n        uint256 mul = _powWad(decayFactor, elapsed);\n        if (centered >= WAD) { return WAD + _mul(centered - WAD, mul); }\n        uint256 below = _mul(WAD - centered, mul);\n        return below < WAD ? WAD - below : 0;\n    }\n\n    function getName() external pure override returns (string memory) { return \"no_cubic\"; }\n}\n","n":2000,"blocked":{"step":"g_identity","error":"Pinned V2 has 2 afterSwap OutOfGas halts on seeds 0..99 at the mandated 250000 gas limit. G avoids them; edges differ on seeds 96 and 99. Thus the required 1e-9 identity check does not pass. Full GN/GNK measurements are nevertheless delivered."},"g_identity":{"n":100,"max_abs_diff":0.027564380569174318,"tolerance":1e-09,"passed":false,"mismatches":[{"seed":96,"V2":527.5171558649798,"G":527.544720245549,"diff":0.027564380569174318},{"seed":99,"V2":537.0991536098833,"G":537.1056147357435,"diff":0.006461125860255379}],"mismatch_seed_gas":{"96":{"v2":{"max_ok":242865,"oog":1},"G":{"max_ok":207689,"oog":0}},"99":{"v2":{"max_ok":240766,"oog":1},"G":{"max_ok":206401,"oog":0}}},"gas_V2":{"max_ok":242865,"oog":2},"gas_G":{"max_ok":207689,"oog":0},"diagnostic_unconstrained":{"purpose":"Diagnostic only; excluded from reported full-block gas and paired measurements. Compare G at 250000 gas against pinned V2 with only afterSwap gas limit raised to 1000000 to remove baseline execution failures.","n":100,"V2_afterSwap_limit":1000000,"G_afterSwap_limit":250000,"max_abs_diff":0.0,"V2_gas":{"max_ok":266230,"oog":0}}},"gas":{"V2":{"max_ok":243881,"oog":39},"GN":{"max_ok":216494,"oog":0},"GNK":{"max_ok":216441,"oog":0}},"v2_0_999":{"n":1000,"mean_edge":526.9433475904315},"pairs":{"gn_v2":{"n":2000,"sum_d":-179.4213627451519,"sum_d2":399.19546754258306,"mean_diff":-0.08971068137257594,"se":0.009788910822815189},"gnk_v2":{"n":2000,"sum_d":-299.7421152604154,"sum_d2":530.436417107836,"mean_diff":-0.1498710576302077,"se":0.011019943597759898},"gnk_gn":{"n":2000,"sum_d":-120.32075251526351,"sum_d2":108.70300974440175,"mean_diff":-0.06016037625763175,"se":0.0050377382230096385}},"worst5_gn_v2":[{"seed":3302557,"V2":383.0270610867761,"GN":380.39177160787875,"diff":-2.6352894788973344},{"seed":3302344,"V2":787.3852724284642,"GN":785.1022411006361,"diff":-2.2830313278280983},{"seed":3302286,"V2":594.8066965542253,"GN":592.6106304856307,"diff":-2.1960660685945186},{"seed":3302648,"V2":665.1090628738074,"GN":663.0095520799446,"diff":-2.0995107938628053},{"seed":3302997,"V2":608.7643105375978,"GN":606.9121280566507,"diff":-1.8521824809471354}],"seed_2920436":{"V2":376.4307937219669,"GN":376.69815800615487,"GNK":376.7025255418257},"seconds_per_simulation":{"V2":0.21357705269684082,"GN":0.17503707172721625,"GNK":0.20210861635638866},"method":{"simulator_commit":"6b6921f8d463314aa7c96234e1be25a25245f704","seed_start":3302000,"seed_end":3303999,"n_steps":10000,"workers":8,"opponent":"VanillaStrategy (Vanilla_30bps)","batch_size":100,"compilation":"SolidityCompiler defaults: solc 0.8.24, optimizer enabled runs=200, viaIR=true, evmVersion=paris. Both GN and GNK pass amm-match validate.","configs":"For each seed s, numpy.random.default_rng(s); draw retail_mean_size uniform(19,21), retail_arrival_rate uniform(0.6,1.0), gbm_sigma uniform(0.000882,0.001008), in that order. Other values from build_config. Engine price seed=s, retail seed=s+1. Each candidate is run separately against VanillaStrategy using amm_sim_rs.run_batch(...,configs,8). Results retain configuration order.","edge":"The Rust result.edges[submission], not submission minus normalizer. Paired differences use first candidate edge minus second candidate edge. SE is sample standard deviation of paired differences / sqrt(n).","gas":"Scratch-only AtomicU64 max and OOG counters in strategy.rs, updated after transact_commit only for calldata length 196 and name != Vanilla_30bps. Max is Success gas_used; OOG increments only HaltReason::OutOfGas. No EVM input, gas limit, state or error handling is changed. Each batch resets counters; reported gas is max and sum over the full 2000-seed block.","seconds":"Wall seconds for run_batch divided by simulations, with 8 workers; excludes compilation, installation, pilots and extra seeds.","trims":"Drop afterInitialize zero writes; pack last post-trade spot in high 192 bits of slot 2 and timestamp in low 64 bits; remove unreachable slots[11] write because REVERT_U=0; use floor Newton _isqrt; bounded unchecked WAD arithmetic; unchecked Poisson and atanh series preserve original integer operations. All bounds hold over simulator inputs.","GN":"N constants and next-retail block from the pinned N artifact, inserted after tail compression before slot writes, using slow pHat. Three successive floor square roots implement q^(1/8).","GNK":"GN with skew=0 in place of DIR_COEF/DIR_TOX_COEF terms. Direction still controls tail compression as in GN.","limitations":"The 250000-gas V2 baseline can revert. Consequently paired results include the effect of eliminating baseline OOG, and do not isolate N alone. No measurements or missing values were fabricated."},"checks":{"setup":"Objective setup.sh ran once successfully, including StarterStrategy validation. Build tools and dependencies were confined to disposable test/scratch and are not delivered.","instrumentation_identity":{"n":3,"seeds":[0,1,2],"max_abs_diff":0.0},"sqrt":{"cases":10769,"python_math_isqrt_exact":true},"poisson":{"lambda_grid":"0..1.82 in increments of .001","k_grid":"0..63","decimal_precision":70,"max_abs_error":"1.08812654561298680433226040966989011289295178140627154e-17","uniform_abs_error_bound":"1.493447210577700480191529235276043549062739829387173797181867954782375e-16","bound_derivation":"Each of 24 term-rounding errors is bounded by exp(1.82) WAD units; add one WAD unit for the final ratio and discarded tail <= (1.82^25/25!)/(1-1.82/26). The probability map t/(1+t) is 1-Lipschitz for t>=0.","evaluation":"24 terms, identical integer divisions to pinned N; reference uses 99 terms at 70-digit precision."},"atanh":{"domain":"0 <= z < .05; z >= .05 returns MAX_FEE as pinned N","absolute_truncation_bound":"8.900091136933242196400091136933242196400091136933242196400091136933242e-16","rounding_bound":"3e-17","evaluation":"Same five positive odd terms as pinned N; unchecked only removes arithmetic checks."}},"reproduction_script":"import json,time,sys\nfrom pathlib import Path\nsys.path.insert(0,str(Path.cwd()))\nimport numpy as np\nimport amm_sim_rs\nfrom amm_competition.evm.compiler import SolidityCompiler\nfrom amm_competition.competition.config import build_config\n\ndef configs(seeds):\n out=[]\n for s in seeds:\n  rng=np.random.default_rng(s)\n  size=rng.uniform(19.,21.);rate=rng.uniform(.6,1.);sigma=rng.uniform(.000882,.001008)\n  out.append(build_config(seed=s,retail_mean_size=size,retail_arrival_rate=rate,gbm_sigma=sigma))\n return out\n\ndef compile_all():\n c=SolidityCompiler()\n for name in ['v2','G','GN','GNK','Vanilla']:\n  if name=='Vanilla': src=Path('contracts/src/VanillaStrategy.sol').read_text();cn='VanillaStrategy'\n  else: src=Path(f'scratch/{name}.sol').read_text();cn='Strategy'\n  r=c.compile(src,cn)\n  assert r.success,(name,r.errors)\n  Path(f'scratch/{name}.bin').write_bytes(r.bytecode)\n  print('compiled',name,len(r.bytecode),flush=True)\n\ndef batch(name,seeds,label):\n seeds=list(seeds); path=Path(f'scratch/{label}.json')\n if path.exists(): return json.loads(path.read_text())\n if hasattr(amm_sim_rs,'gas_stats'):amm_sim_rs.gas_stats(True)\n t=time.monotonic()\n r=amm_sim_rs.run_batch(list(Path(f'scratch/{name}.bin').read_bytes()),list(Path('scratch/Vanilla.bin').read_bytes()),configs(seeds),8)\n elapsed=time.monotonic()-t\n out={'name':name,'seeds':seeds,'edges':[x.edges['submission'] for x in r.results],'seconds':elapsed,'gas':amm_sim_rs.gas_stats(False) if hasattr(amm_sim_rs,'gas_stats') else None}\n assert len(out['edges'])==len(seeds)\n path.write_text(json.dumps(out))\n print(label, 'n',len(seeds),'mean',np.mean(out['edges']),'gas',out['gas'],'seconds',elapsed,flush=True)\n return out\nif __name__=='__main__':\n if sys.argv[1]=='compile':compile_all()\n elif sys.argv[1]=='pre':batch('v2',range(3),'preinstrument')\n elif sys.argv[1]=='pilot':\n  for name in ['v2','G','GN','GNK']:batch(name,range(100),'pilot_'+name)\n elif sys.argv[1]=='full':\n  for name in ['v2','GN','GNK']:\n   for start in range(3302000,3304000,100): batch(name,range(start,start+100),name+'_'+str(start))\n elif sys.argv[1]=='extra':\n  for start in range(0,1000,100):batch('v2',range(start,start+100),'v2extra_'+str(start))\n  for name in ['v2','GN','GNK']:batch(name,[2920436],'seed2920436_'+name)\n"}
