# silence-a ## delta Added a local silence count `g = min(timestamp - lastTimestamp - 1, 4)` on the first print after a timestamp gap. For `g > 0`, reconstruct pre-trade spot, find the geometric center of the previous bid/ask fee band, and move `pHat` toward it by `w = 1 - (1 - 0.075)^g`. Scale the pHat update alpha and gate by `1 - 0.30w`. Same-timestamp later prints use `g=0`; no extra storage slot was added. The base TWO code and NP routing insertion are preserved. ## code ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {AMMStrategyBase} from "./AMMStrategyBase.sol"; import {TradeInfo} from "./IAMMStrategy.sol"; contract Strategy is AMMStrategyBase { uint256 constant SILENCE_W1 = 75000000000000000; uint256 constant SILENCE_CAP = 4; uint256 constant SILENCE_GATE_SHRINK = 300000000000000000; uint256 constant SILENCE_ALPHA_SHRINK = 300000000000000000; uint256 constant ELAPSED_CAP = 8; uint256 constant SIGNAL_THRESHOLD = WAD / 650; uint256 constant DIR_DECAY = 750000000000000000; uint256 constant ACT_DECAY = 530000000000000000; uint256 constant SIZE_DECAY = 530000000000000000; uint256 constant TOX_DECAY = 910000000000000000; uint256 constant SIGMA_DECAY = 690000000000000000; uint256 constant LAMBDA_DECAY = 990000000000000000; uint256 constant SIZE_BLEND_DECAY = 828000000000000000; uint256 constant TOX_BLEND_DECAY = 51000000000000000; uint256 constant ACT_BLEND_DECAY = 985000000000000000; uint256 constant PHAT_ALPHA = 270000000000000000; uint256 constant PHAT_ALPHA_RETAIL = 60000000000000000; uint256 constant PHAT_ALPHA_SAME = 120000000000000000; uint256 constant REVERT_U = 0; uint256 constant DIR_IMPACT_MULT = 4; uint256 constant GATE_SIGMA_MULT = 7200000000000000000; uint256 constant MIN_GATE = 30000000000000000; uint256 constant TRADE_TOX_BOOST = 3500 * BPS; uint256 constant STALE_ATTRACT_FRAC = 1050000000000000000; uint256 constant RET_CAP = WAD / 35; uint256 constant TOX_CAP = WAD / 5; uint256 constant TRADE_RATIO_CAP = WAD / 5; uint256 constant LAMBDA_CAP = 1820000000000000000; uint256 constant STEP_COUNT_CAP = 64; uint256 constant BASE_FEE = 4 * BPS; uint256 constant SIGMA_COEF = 200000000000000000; uint256 constant LAMBDA_COEF = 12 * BPS; uint256 constant FLOW_SIZE_COEF = 4842 * BPS; uint256 constant TOX_COEF = 300 * BPS; uint256 constant TOX_QUAD_COEF = 15000 * BPS; uint256 constant ACT_COEF = 91843 * BPS; uint256 constant DIR_COEF = 20 * BPS; uint256 constant DIR_TOX_COEF = 100 * BPS; uint256 constant STALE_DIR_COEF = 6850 * BPS; uint256 constant SIGMA_TOX_COEF = 500 * BPS; uint256 constant TAIL_KNEE = 600 * BPS; uint256 constant TAIL_SLOPE_PROTECT = 930000000000000000; uint256 constant TAIL_SLOPE_ATTRACT = 850000000000000000; function afterInitialize(uint256 initialX, uint256 initialY) external override returns (uint256, uint256) { slots[0] = BASE_FEE; slots[1] = BASE_FEE; slots[2] = 0; slots[3] = WAD; slots[4] = 0; slots[5] = initialX > 0 ? wdiv(initialY, initialX) : 100 * WAD; slots[6] = 950000000000000; slots[7] = 800000000000000000; slots[8] = 2000000000000000; slots[9] = 0; slots[10] = 0; slots[11] = 0; slots[12] = 0; return (BASE_FEE, BASE_FEE); } function afterSwap(TradeInfo calldata trade) external override returns (uint256, uint256) { uint256 prevBidFee = slots[0]; uint256 prevAskFee = slots[1]; uint256 lastTs = slots[2]; uint256 dirState = slots[3]; uint256 actEma = slots[4]; uint256 pHat = slots[5]; uint256 sigmaHat = slots[6]; uint256 lambdaHat = slots[7]; uint256 sizeHat = slots[8]; uint256 toxEma = slots[9]; uint256 stepTradeCount = slots[10]; uint256 silenceSteps = 0; bool isNewStep = trade.timestamp > lastTs; if (isNewStep) { uint256 elapsedRaw = trade.timestamp - lastTs; silenceSteps = elapsedRaw > 1 ? elapsedRaw - 1 : 0; if (silenceSteps > SILENCE_CAP) silenceSteps = SILENCE_CAP; uint256 elapsed = elapsedRaw > ELAPSED_CAP ? ELAPSED_CAP : elapsedRaw; dirState = _decayCentered(dirState, DIR_DECAY, elapsed); actEma = wmul(actEma, _powWad(ACT_DECAY, elapsed)); sizeHat = wmul(sizeHat, _powWad(SIZE_DECAY, elapsed)); toxEma = wmul(toxEma, _powWad(TOX_DECAY, elapsed)); if (stepTradeCount > 0 && elapsedRaw > 0) { uint256 lambdaInst = (stepTradeCount * WAD) / elapsedRaw; if (lambdaInst > LAMBDA_CAP) lambdaInst = LAMBDA_CAP; lambdaHat = wmul(lambdaHat, LAMBDA_DECAY) + wmul(lambdaInst, WAD - LAMBDA_DECAY); } stepTradeCount = 0; } bool firstInStep = stepTradeCount == 0; uint256 spot = trade.reserveX > 0 ? wdiv(trade.reserveY, trade.reserveX) : pHat; if (pHat == 0) pHat = spot; uint256 silenceWeight = WAD - _powWad(WAD - SILENCE_W1, silenceSteps); if (silenceWeight > 0) { uint256 spotBefore; if (trade.isBuy) { uint256 priorX = trade.reserveX - wmul(trade.amountX, WAD - prevBidFee); uint256 priorY = trade.reserveY + trade.amountY; spotBefore = priorX > 0 ? wdiv(priorY, priorX) : spot; } else { uint256 priorX = trade.reserveX + trade.amountX; uint256 netY = wmul(trade.amountY, WAD - prevAskFee); uint256 priorY = trade.reserveY > netY ? trade.reserveY - netY : 0; spotBefore = priorX > 0 && priorY > 0 ? wdiv(priorY, priorX) : spot; } uint256 bandScale = sqrt(wdiv(WAD - prevBidFee, WAD - prevAskFee) * WAD); uint256 bandCenter = wmul(spotBefore, bandScale); pHat = wmul(pHat, WAD - silenceWeight) + wmul(bandCenter, silenceWeight); } uint256 feeUsed = trade.isBuy ? prevBidFee : prevAskFee; uint256 gamma = feeUsed < WAD ? WAD - feeUsed : 0; uint256 pImplied; if (gamma == 0) { pImplied = spot; } else { pImplied = trade.isBuy ? wmul(spot, gamma) : wdiv(spot, gamma); } { uint256 ret = pHat > 0 ? wdiv(absDiff(pImplied, pHat), pHat) : 0; uint256 alpha = firstInStep ? PHAT_ALPHA : PHAT_ALPHA_RETAIL; uint256 prePhat = pHat; bool secondPrint = !firstInStep && stepTradeCount == 1; bool sameDir = false; bool oppDir = false; if (secondPrint) { bool up2 = pImplied >= pHat; uint256 d1 = slots[12]; if (d1 != 0) { sameDir = (d1 == 1) == up2; oppDir = !sameDir; } if (sameDir) alpha = PHAT_ALPHA_SAME; } alpha = wmul(alpha, WAD - wmul(SILENCE_ALPHA_SHRINK, silenceWeight)); if (firstInStep) { slots[11] = pHat; slots[12] = pImplied >= pHat ? 1 : 2; } uint256 adaptiveGate = wmul(sigmaHat, GATE_SIGMA_MULT); if (adaptiveGate < MIN_GATE) adaptiveGate = MIN_GATE; adaptiveGate = wmul(adaptiveGate, WAD - wmul(SILENCE_GATE_SHRINK, silenceWeight)); if (ret <= adaptiveGate) { pHat = wmul(pHat, WAD - alpha) + wmul(pImplied, alpha); } if (oppDir && REVERT_U > 0) { uint256 pre = slots[11]; if (pre > pHat) pHat = pHat + wmul(pre - pHat, REVERT_U); else pHat = pHat - wmul(pHat - pre, REVERT_U); } if (firstInStep) { if (ret > RET_CAP) ret = RET_CAP; sigmaHat = wmul(sigmaHat, SIGMA_DECAY) + wmul(ret, WAD - SIGMA_DECAY); } } // Interior retail routing equalizes fee-adjusted marginal prices. // Subsequent trades in a step cannot be the initial arbitrage trade. if (!firstInStep && feeUsed > 30 * BPS && gamma > 0) { uint256 normalSpot = trade.isBuy ? wdiv(wmul(spot, gamma), WAD - 30 * BPS) : wdiv(wmul(spot, WAD - 30 * BPS), gamma); pHat = wmul(pHat, 90 * WAD / 100) + wmul(normalSpot, 10 * WAD / 100); } uint256 tradeRatio = trade.reserveY > 0 ? wdiv(trade.amountY, trade.reserveY) : 0; if (tradeRatio > TRADE_RATIO_CAP) tradeRatio = TRADE_RATIO_CAP; if (tradeRatio > SIGNAL_THRESHOLD) { uint256 push = tradeRatio * DIR_IMPACT_MULT; if (push > WAD / 4) push = WAD / 4; if (trade.isBuy) { dirState = dirState + push; if (dirState > 2 * WAD) dirState = 2 * WAD; } else { dirState = dirState > push ? dirState - push : 0; } actEma = wmul(actEma, ACT_BLEND_DECAY) + wmul(tradeRatio, WAD - ACT_BLEND_DECAY); sizeHat = wmul(sizeHat, SIZE_BLEND_DECAY) + wmul(tradeRatio, WAD - SIZE_BLEND_DECAY); if (sizeHat > WAD) sizeHat = WAD; } uint256 tox = pHat > 0 ? wdiv(absDiff(spot, pHat), pHat) : 0; if (tox > TOX_CAP) tox = TOX_CAP; toxEma = wmul(toxEma, TOX_BLEND_DECAY) + wmul(tox, WAD - TOX_BLEND_DECAY); uint256 toxSignal = toxEma; stepTradeCount = stepTradeCount + 1; if (stepTradeCount > STEP_COUNT_CAP) stepTradeCount = STEP_COUNT_CAP; uint256 flowSize = wmul(lambdaHat, sizeHat); uint256 fBase = BASE_FEE + wmul(SIGMA_COEF, sigmaHat) + wmul(LAMBDA_COEF, lambdaHat) + wmul(FLOW_SIZE_COEF, flowSize); uint256 fMid = fBase + wmul(TOX_COEF, toxSignal) + wmul(TOX_QUAD_COEF, wmul(toxSignal, toxSignal)) + wmul(ACT_COEF, actEma); fMid = fMid + wmul(SIGMA_TOX_COEF, wmul(sigmaHat, toxSignal)); uint256 dirDev; bool sellPressure; if (dirState >= WAD) { dirDev = dirState - WAD; sellPressure = true; } else { dirDev = WAD - dirState; sellPressure = false; } uint256 skew = wmul(DIR_COEF, dirDev) + wmul(DIR_TOX_COEF, wmul(dirDev, toxSignal)); uint256 bidFee; uint256 askFee; if (sellPressure) { bidFee = fMid + skew; askFee = fMid > skew ? fMid - skew : 0; } else { askFee = fMid + skew; bidFee = fMid > skew ? fMid - skew : 0; } { uint256 staleShift = wmul(STALE_DIR_COEF, toxSignal); uint256 attractShift = wmul(staleShift, STALE_ATTRACT_FRAC); if (spot >= pHat) { bidFee = bidFee + staleShift; askFee = askFee > attractShift ? askFee - attractShift : 0; } else { askFee = askFee + staleShift; bidFee = bidFee > attractShift ? bidFee - attractShift : 0; } } { bool tradeAligned = (trade.isBuy && spot >= pHat) || (!trade.isBuy && spot < pHat); if (tradeAligned) { uint256 tradeBoost = wmul(TRADE_TOX_BOOST, tradeRatio); if (trade.isBuy) { bidFee = bidFee + tradeBoost; } else { askFee = askFee + tradeBoost; } } } if (sellPressure) { bidFee = clampFee(_compressTailWithSlope(bidFee, TAIL_SLOPE_PROTECT)); askFee = clampFee(_compressTailWithSlope(askFee, TAIL_SLOPE_ATTRACT)); } else { askFee = clampFee(_compressTailWithSlope(askFee, TAIL_SLOPE_PROTECT)); bidFee = clampFee(_compressTailWithSlope(bidFee, TAIL_SLOPE_ATTRACT)); } slots[0] = bidFee; slots[1] = askFee; slots[2] = trade.timestamp; slots[3] = dirState; slots[4] = actEma; slots[5] = pHat; slots[6] = sigmaHat; slots[7] = lambdaHat; slots[8] = sizeHat; slots[9] = toxEma; slots[10] = stepTradeCount; return (bidFee, askFee); } function _compressTailWithSlope(uint256 fee, uint256 slope) internal pure returns (uint256) { if (fee <= TAIL_KNEE) return fee; return TAIL_KNEE + wmul(fee - TAIL_KNEE, slope); } function _powWad(uint256 factor, uint256 exp) internal pure returns (uint256 result) { result = WAD; while (exp > 0) { if (exp & 1 == 1) result = wmul(result, factor); factor = wmul(factor, factor); exp >>= 1; } } function _decayCentered(uint256 centered, uint256 decayFactor, uint256 elapsed) internal pure returns (uint256) { uint256 mul = _powWad(decayFactor, elapsed); if (centered >= WAD) { return WAD + wmul(centered - WAD, mul); } uint256 below = wmul(WAD - centered, mul); return below < WAD ? WAD - below : 0; } function getName() external pure override returns (string memory) { return "no_cubic"; } } ``` ## sha256 `22958b18bc780e722b6e13f16da6a70c9b61e54b429c8f65e0046e44fd6ce379` (SHA-256 of the exact Solidity code text above, including its final newline). ## tuning NP2 was assembled from the [TWO artifact](https://api.imdnotdead.fun/artifacts/528a6da78583c6142644a552c86670f9d25c20e39e92f4de44deae05ddc8cecd) and the [NP interior-routing artifact](https://api.imdnotdead.fun/artifacts/da313379a2e69e9286668865e06b18dfcae25732c82b934b0fd9c2ef0d8c2ff5); its exact code-text SHA-256 is `51f1c1a9d4999ee460eb8bbc66880da8074b173399a4f5d71f96671482e18ac0`. CH's reference source was [this pinned Strategy.sol](https://raw.githubusercontent.com/ChengHua926/amm-challenge/d34a5199c59a4c44d5336a25f1436b4ae1f21104/contracts/src/Strategy.sol), whose code-text SHA-256 is `6dd68f77a70900319460215374143dbd5d924198450a46d9f5f91f6b1e3d35c3`. For each training point, candidate and NP2 were run in separate `amm_sim_rs.run_batch` calls against Vanilla, with the same config draws. Every call used 16 seeds. Config draws follow the pinned simulator's [`MatchRunner._build_configs`](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_competition/competition/match.py) order: `default_rng(seed)` draws retail size, arrival rate, then sigma. The simulator advances fair price and attempts arbitrage each step ([engine source](https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/simulation/engine.rs)). `mean_diff` is the arithmetic mean of candidate `edges['submission']` minus NP2's, `se` is sample standard deviation divided by √n. All seed blocks below are within the allowed training range 10000–99999. CH versus Vanilla on seeds 0–999 reproduced mean edge `525.525882178083` (SE `2.789426459025`), matching the stated `525.525882178` check. The 1000-value check used 16-seed calls; the last call included seeds 1000–1007 and those eight values were discarded. Training seeds **10256–10383**: | w1 | cap | gate shrink | alpha shrink | n | mean_diff | se | |---:|---:|---:|---:|---:|---:|---:| | 0.01 | 4 | 0.10 | 0.10 | 128 | 0.044272848614483884 | 0.016296675908955633 | | 0.025 | 4 | 0.20 | 0.20 | 128 | 0.09973754636783605 | 0.029563654334776215 | | 0.05 | 4 | 0.20 | 0.20 | 128 | 0.1423088787124498 | 0.0415378772378834 | | 0.02 | 8 | 0.50 | 0.20 | 128 | 0.1090669089071743 | 0.029012876627922762 | | 0.05 | 8 | 0 | 0 | 128 | 0.07720610136151684 | 0.041615155236064585 | Training seeds **10384–10639**: | w1 | cap | gate shrink | alpha shrink | n | mean_diff | se | |---:|---:|---:|---:|---:|---:|---:| | 0.05 | 4 | 0.20 | 0.20 | 256 | 0.1420548856371664 | 0.024353828758526465 | | 0.075 | 4 | 0.20 | 0.20 | 256 | 0.16674685712095005 | 0.029599915438136053 | | 0.10 | 4 | 0.20 | 0.20 | 256 | 0.1470226644239332 | 0.03283259567819347 | | 0.05 | 8 | 0.20 | 0.20 | 256 | 0.13320202265890835 | 0.026352005310841732 | | 0.05 | 4 | 0.10 | 0.10 | 256 | 0.10123071727155386 | 0.023439934285576905 | Training seeds **10640–11151**: | w1 | cap | gate shrink | alpha shrink | n | mean_diff | se | |---:|---:|---:|---:|---:|---:|---:| | 0.075 | 4 | 0.20 | 0.20 | 512 | 0.21887529503760295 | 0.03206358241952118 | | 0.075 | 2 | 0.20 | 0.20 | 512 | 0.22240200647847874 | 0.02814935731585608 | | 0.075 | 1 | 0.20 | 0.20 | 512 | 0.16560361843953375 | 0.01704634313242122 | | **0.075** | **4** | **0.30** | **0.30** | **512** | **0.24912033518969812** | **0.03164081761309969** | | 0.075 | 4 | 0 | 0 | 512 | 0.1496526875284545 | 0.031763692634894584 | Frozen at the highest observed training mean: `w1=0.075`, cap `4`, gate shrink `0.30`, alpha shrink `0.30`. The confirmation used new seeds only. ## paired ```json {"n":2000,"mean_diff":0.21866808751973402,"se":0.010767301406119376,"worst":-1.7520790263144477} ``` ## confirm block Seeds `2570000..2571999` (2000 seeds), once. Candidate and NP2 each ran separately against Vanilla with identical configs, in 16-seed calls. ## blocked null ## next Test whether gate and alpha should use separate silence curves rather than sharing `w`.