{
  "item": "a",
  "title": "Two-step continuation value overlay for V10 fee control",
  "status": "design only; no market simulation, search, confirmation-seed access, Solidity candidate, or gas measurement was performed",
  "candidate": {
    "code": null,
    "sha256": null,
    "reason": "This item specifies an implementable overlay, not a compiled candidate. Supplying invented source or a hash would be misleading."
  },
  "paired": {"n": 0, "mean_diff": null, "se": null, "worst": null},
  "gas": null,
  "retail_edge_delta": null,
  "arb_edge_delta": null,
  "source_references": {
    "V10": {"url": "https://api.imdnotdead.fun/artifacts/33f54e81f3372088e9eced52c0174f310ac348af98ef5727b73785c088679194", "path": "artifact code", "lines": "48-53, 56-92, 137-153, 179-226, 268-279", "use": "baseline state, posterior inputs, fee construction, and returned-fee timing assumptions"},
    "rules": {"url": "https://api.imdnotdead.fun/artifacts/ddbbaac58282566e0505d895c83daf348487cc322e8c482e61d4d87e6e4628de", "path": "step_order, arb_rule, retail_split, fee_semantics, retail_size", "lines": "not line-addressed JSON fields", "use": "pinned-commit interpretation cross-checked against the raw files below"},
    "engine": {"url": "https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/simulation/engine.rs", "path": "amm_sim_rs/src/simulation/engine.rs", "lines": "136-161", "use": "price, one arb attempt per AMM, then sequential retail, and execution-edge accounting"},
    "router": {"url": "https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/market/router.rs", "path": "amm_sim_rs/src/market/router.rs", "lines": "35-74, 77-116, 180-247, 266-281", "use": "exact two-pool split and sequential execution"},
    "arb": {"url": "https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/market/arbitrageur.rs", "path": "amm_sim_rs/src/market/arbitrageur.rs", "lines": "35-146", "use": "opening arbitrage objective and closed-form sizes"},
    "cfmm": {"url": "https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/amm/cfmm.rs", "path": "amm_sim_rs/src/amm/cfmm.rs", "lines": "115-295", "use": "fee-on-input reserve maps, separated fees, and callback-after-reserve-update"},
    "retail": {"url": "https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/amm_sim_rs/src/market/retail.rs", "path": "amm_sim_rs/src/market/retail.rs", "lines": "43-99", "use": "Poisson arrivals and lognormal size generator"},
    "base": {"url": "https://raw.githubusercontent.com/benedictbrady/amm-challenge/6b6921f8d463314aa7c96234e1be25a25245f704/contracts/src/AMMStrategyBase.sol", "path": "contracts/src/AMMStrategyBase.sol", "lines": "14-24, 30-33, 39-52, 80-85", "use": "WAD units, fee bounds, arithmetic helpers, and storage limit"}
  },
  "problem_and_causal_claim": {
    "claim": "A fee returned after a callback changes the routing and therefore the post-retail spot before the next step. The next step has an arbitrage attempt before retail. Thus a fee can have continuation value through next-opening arbitrage edge even when its local/greedy retail-edge derivative is zero.",
    "why_this_is_distinct": "The state variable is the endpoint spot induced by the router, not a new price estimator, static flow damping, or a same-trade router-share reward. The overlay values the induced endpoint only through the simulator's next opening arbitrage execution edge; it does not value terminal inventory.",
    "scope": "This is a proposed mechanism, not a performance claim. Its table coefficients and all action choices require the offline procedure below."
  },
  "timing_and_observable_state": {
    "update_order": [
      "The engine advances fair price, tries one arb on each pool, generates retail orders, and routes them sequentially (engine lines 136-161).",
      "A CFMM changes reserves, puts the fee outside liquidity, then invokes afterSwap; a returned fee is used by later executions (cfmm lines 199-295).",
      "At an afterSwap call, the deployed controller observes only TradeInfo (post-trade own reserves, gross amounts, isBuy, timestamp) and its own V10 slots. It computes V10's ordinary fee pair first, then may add a bounded table correction."
    ],
    "deployed_inputs": [
      "x=trade.reserveX, y=trade.reserveY, s=y/x and k=x*y, all own-pool quantities",
      "timestamp and pre-call own last timestamp / stepTradeCount; firstInStep is derived exactly as V10 does from those values",
      "trade.isBuy, trade.amountX, trade.amountY, and the previous own fees",
      "V10-owned slots: pHat (5), sigmaHat (6), lambdaHat (7), sizeHat (8), toxEma (9), stepTradeCount (10), direction (3), posterior variance (13), and fastHat (14)",
      "the static compiled table indexed by bounded transforms of those own values"
    ],
    "explicitly_not_deployed": [
      "fair price, a trader/arb label, normalizer reserves or fees, future price shocks, future orders, order count remaining in the current step, random seeds, and terminal inventory/PnL",
      "Normaliser state and latent fair price may be used only while constructing an offline conditional expectation; they are integrated out before the table is embedded."
    ],
    "first_callback_issue": "A first callback can be an arb or a retail trade, and TradeInfo has no label. Do not pretend otherwise. The offline cells condition on the observable tuple (firstInStep, isBuy, clipped amount/reserve ratio, implied-price residual, V10 posterior cell); their weights mix the two latent causes. The deployed branch uses this tuple only, never a label."
  },
  "exact_model": {
    "units": "x is X liquidity, y and p are Y and Y/X, f is a dimensionless fraction (WAD in Solidity), gamma=1-f, k=xy. All R, A, G, C, and Q values below are execution edge in Y, not PnL.",
    "constant_product_and_trade_maps": [
      "For a sell-X input q (AMM buys X) at bid gamma_b: x'=x+gamma_b q, y'=k/x', Yout=y-y'. Its execution edge is R_sell=pq-Yout.",
      "For a buy-X gross Y input z (AMM sells X) at ask gamma_a: y'=y+gamma_a z, x'=k/y', Xout=x-x'. Its execution edge is R_buy=z-p Xout.",
      "Fees are not reinvested, so these maps preserve k. This is the simulator accounting, not an approximation (cfmm lines 119-193 and 199-272)."
    ],
    "router": [
      "For a buy order total gross Y T, with normalizer state (x2,y2), gamma2=0.997 and own gamma1=1-f_ask: r=sqrt(x gamma1 y)/sqrt(x2 gamma2 y2); z=clamp((r(y2+gamma2 T)-y)/(gamma1+r gamma2),0,T).",
      "For a sell order whose Y-notional is S, T=S/p X is gross input; with own gamma1=1-f_bid: r=sqrt(y gamma1 x)/sqrt(y2 gamma2 x2); q=clamp((r(x2+gamma2 T)-x)/(gamma1+r gamma2),0,T).",
      "These are the router's exact formulas (router lines 35-116). Both legs are calculated before execution; subsequent orders recompute from updated reserves (router lines 180-281)."
    ],
    "opening_arb_edge": [
      "Let s=y/x. If s< p, use ask gamma_a. q=min(x-sqrt(k/(gamma_a p)),0.99x); Yin=(k/(x-q)-y)/gamma_a. If q>0 and p q-Yin>0, A=-[p q-Yin], otherwise A=0.",
      "If s>p, use bid gamma_b. q=(sqrt(k gamma_b/p)-x)/gamma_b; Yout=y-k/(x+gamma_b q). If q>0 and Yout-pq>0, A=-[Yout-pq], otherwise A=0.",
      "A is the AMM's next-opening arbitrage execution edge. It is non-positive by construction. The 99% cap is retained exactly (arb lines 50-146)."
    ],
    "bellman_correction": [
      "Let h be the complete own V10 state just before the returned fee is stored, o the observable callback tuple, f0=F10(h,o) the unmodified V10 pair, and a=f-f0 a small permitted perturbation.",
      "Define Q_h,o(f)=G_h,o(f)+C_h,o(f). G is expected execution edge from all retail executions whose routing can still use f. C=E[A(X_next,Y_next,P_next,F10(H_next,O_next)) | h,o,f]. The expectation follows the exact maps above through the unobserved remaining current-step retail sequence and then the next step's opening arb. If no trade follows the callback before the next opening, f itself is the fee in A.",
      "The outer expectation integrates the V10 working posterior for current latent P, a one-step GBM shock for P_next, N~Poisson(lambdaHat), lognormal size with mean sizeHat and shape 1.2 (or a calibrated shape), 50/50 side, and the offline conditional distribution of normalizer state and remaining-order count given (h,o). V10's slot 13 is treated as a relative-uncertainty coordinate; fitting its quadrature mapping is an offline calibration parameter, not a claim that V10 implements a Gaussian posterior.",
      "The table stores a discrete argmax a*=argmax_{a in Agrid} Q_h,o(f0+a), with identity included. Equivalently, near a greedy interior f0 where G_f(f0)=0, a* is driven by C_f: 0≈G_ff(f0)a+C_f(f0), hence a≈-C_f/G_ff. This is the Bellman correction."
    ],
    "surviving_term": [
      "For a single routed buy with own gross share z(f), ln(s')=2 ln(y+gamma_a z)-ln k, so d ln(s')/d f_ask=2(gamma_a z_f-z)/(y+gamma_a z). For a routed sell with own gross share q(f), ln(s')=ln k-2 ln(x+gamma_b q), so d ln(s')/d f_bid=2(q-gamma_b q_f)/(x+gamma_b q).",
      "Therefore C_f contains A_ln_s times either expression, plus terms from subsequent policy/state updates. Neither expression contains the greedy same-trade derivative G_f. Router competition normally makes z_f and q_f negative, so this endpoint term need not vanish when a greedy shadow overlay does."
    ]
  },
  "offline_table_design": {
    "action_grid": "Evaluate identity (0,0) plus six symmetric signed WAD perturbations: (±0.25 bps,0), (0,±0.25 bps), (±0.5 bps,0), (0,±0.5 bps), and two protective pairs chosen by direction. Reject any action whose clamped result differs from its requested value. The ranges are starting ranges to test, not tuned constants.",
    "cells": "Use a compact 3x3x3x2 grid: u=clip(ln(s/staleHat),[-0.04,0.04]) in 3 bins; v=clip(sqrt(slot13),[0,0.01]) in 3 bins; l=clip(lambdaHat*sizeHat/y,[0,0.02]) in 3 bins; and firstInStep in 2 bins. For firstInStep cells append the two-bit observable event bucket from side and clipped gross-size ratio. This conditions only on own observables.",
    "integration": "For each cell/action, use fixed Gauss-Hermite nodes for the working posterior and next price shock; sum Poisson probabilities through n=20 (residual must be recorded; increase cutoff until below 1e-12 for the configured lambda cap); use 7 lognormal quadrature nodes per retail order; and integrate a weighted offline corpus of hidden normalizer/remaining-order states. The corpus is generated only by the public pinned dynamics and keyed by the observable cell. It is not copied into Solidity.",
    "table_output": "Store only each winning signed bid/ask delta in signed quarter-bps plus a confidence/curvature flag. At deployment, use identity if cell support, estimated Q margin, or curvature gate fails. Do not embed Q values, latent prices, normalizer data, or a fitted price estimator.",
    "bounded_polynomial_variant": "Instead of a table, fit odd/even symmetry-constrained Chebyshev polynomials for deltaAsk(u,v,l) and deltaBid(-u,v,l), degree (3,2,2), then quantize coefficients to quarter-bps and clip to ±0.5 bps. It must be compared against the table on the same offline cells; no extrapolation beyond the table box."
  },
  "structural_alternatives": [
    {"name": "A: V10 identity", "rule": "Return F10 exactly; no continuation correction.", "purpose": "mandatory control and fallback for every unsupported/low-margin cell."},
    {"name": "B: two-step table argmax", "rule": "Return F10 plus the table's bounded bid/ask perturbation using only the observable cell.", "mechanism": "direct discrete Bellman comparison of current retail edge plus next-opening arb edge."},
    {"name": "C: continuation-gradient / curvature overlay", "rule": "Store C_f and a negative lower-bounded G_ff per cell, then apply clip(-C_f/G_ff, ±0.5 bps) only when both finite-difference signs agree at 0.25 and 0.5 bps.", "mechanism": "same continuation target with fewer constants; less robust to noisy curvature."},
    {"name": "D: endpoint-only protective action", "rule": "Ignore G and use only the sign of the tabulated A_ln_s times the exact endpoint derivative, with a one-quarter-bps correction and an identity dead zone.", "mechanism": "a falsifiable minimal ablation that isolates the proposed causal channel."}
  ],
  "solidity_pseudocode_and_layout": {
    "layout": "Keep V10 slots 0-14 unchanged. No persistent storage is required for a literal table; static bytecode constants are preferred. If diagnostics are desired, slots 15-16 can hold a saturating table-hit counter and low-margin fallback counter; neither is needed for the decision.",
    "pseudocode": "function afterSwap(TradeInfo calldata t) external returns (uint256 bid,uint256 ask) {\n  bool first = (slots[10] == 0);                 // before V10 increments it\n  uint256 priorTs = uint64(slots[2]);\n  uint256 ratio = t.reserveY == 0 ? 0 : wdiv(t.amountY,t.reserveY);\n  (bid,ask) = _v10CoreAndStoreAllState(t);       // exact refactor of V10\n  uint256 stale = wmul(slots[5],7e17)+wmul(slots[14],3e17);\n  uint256 u = stale == 0 ? 0 : wdiv(absDiff(wdiv(t.reserveY,t.reserveX),stale),stale);\n  uint256 v = _isqrt(slots[13]*WAD);\n  uint256 l = t.reserveY == 0 ? 0 : wdiv(wmul(slots[7],slots[8]),t.reserveY);\n  Cell c = _cell(first, t.isBuy, ratio, u, v, l, t.timestamp > priorTs);\n  (int256 db,int256 da,bool safe) = _continuationDelta(c);\n  if (safe) { bid=_addSignedAndClamp(bid,db); ask=_addSignedAndClamp(ask,da); }\n  slots[0]=bid; slots[1]=ask;                    // overwrite V10 returned pair only\n  return (bid,ask);\n}",
    "safety": "_addSignedAndClamp must avoid uint underflow and call clampFee. Static deltas are signed quarter-bps integers converted by BPS/4. The V10 core must be preserved byte-for-byte in behavior before the final fee overwrite; no callback may read competitor data."
  },
  "runtime_and_gas": {
    "design": "One fixed-bin index, one constant lookup, two signed bounded additions, and V10's existing calculations. No loops, square roots, exponentials, posterior quadrature, or external calls are added on-chain.",
    "estimate": "Unmeasured. The added path should be constant-time and small relative to V10, but no gas number or OOG claim is made. Measure max_ok and OOG with amm_sim_rs.gas_stats() before considering any result valid."
  },
  "static_calculations_and_checks": {
    "label": "These are algebraic calculations only, not market simulations or benchmark results.",
    "example": "At x=100, y=10000, p=100, normalizer fee=30 bps, own bid=40 bps, a single buy order T=100 Y, and own ask varied about 40 bps, the exact router/map/arb equations give: ask 39/40/41 bps -> own z=47.7456828879/47.4949511234/47.2441688897 Y; end spot=100.9534513981/100.9483371867/100.9432231025; next-opening A=-0.0752630600/-0.0738782716/-0.0725063062 Y. Central C_f is +13.7837689652 Y per unit fee. This demonstrates a nonzero endpoint channel in a static one-retail construction; it is not an expected gain estimate.",
    "checks": [
      {"name": "constant-product identity", "result": "For both maps, x'y'=k algebraically; the prototype asserts this to 1e-10 for buy and sell examples."},
      {"name": "router symmetry", "result": "With identical pools and identical 30-bps relevant fees, the formula gives own buy share 10.000000000000256 of T=20 (rounding), i.e. 1/2."},
      {"name": "zero-flow limit", "result": "For N=0 and a next price within the no-arb band, A=0 and Q(f)-Q(f0)=0 for every f; the prototype asserts this."},
      {"name": "flat-price/no-retail limit", "result": "At s=p with N=0, neither strict arb condition holds, so continuation correction is exactly zero."},
      {"name": "sign check", "result": "In the stated static example, raising ask reduces routed z and end spot, and makes A less negative; finite-difference C_f is positive, agreeing with d ln(s')/d f_ask<0 and A increasing as this overpricing is reduced."},
      {"name": "fee-bound check", "result": "Every requested grid action is rejected unless both resulting fees remain in [0,0.1], the base contract's declared valid range."}
    ]
  },
  "offline_python_prototype_source": "import math\n\ndef clamp(x, lo, hi): return max(lo, min(hi, x))\ndef router_buy(x,y,f,x2,y2,f2,T):\n    g,g2=1-f,1-f2; r=math.sqrt(x*g*y)/math.sqrt(x2*g2*y2)\n    return clamp((r*(y2+g2*T)-y)/(g+r*g2),0,T)\ndef router_sell(x,y,f,x2,y2,f2,T):\n    g,g2=1-f,1-f2; r=math.sqrt(y*g*x)/math.sqrt(y2*g2*x2)\n    return clamp((r*(x2+g2*T)-x)/(g+r*g2),0,T)\ndef buy_map(x,y,f,z):\n    k=x*y; yy=y+(1-f)*z; return k/yy,yy\ndef sell_map(x,y,f,q):\n    k=x*y; xx=x+(1-f)*q; return xx,k/xx\ndef opening_arb(x,y,bid,ask,p):\n    k=x*y; s=y/x\n    if s<p:\n        g=1-ask; q=clamp(x-math.sqrt(k/(g*p)),0,.99*x)\n        yin=(k/(x-q)-y)/g if q else 0.; return -max(p*q-yin,0.)\n    if s>p:\n        g=1-bid; q=max((math.sqrt(k*g/p)-x)/g,0.)\n        yout=y-k/(x+g*q) if q else 0.; return -max(yout-p*q,0.)\n    return 0.\ndef poisson_p(n,lam): return math.exp(-lam)*lam**n/math.factorial(n)\ndef q_value(state, action, posterior_nodes, price_nodes, retail_nodes, policy):\n    # state=(x,y,hidden_x2,hidden_y2,f0bid,f0ask,lambda). Hidden values are offline-only.\n    x,y,x2,y2,b0,a0,lam=state; db,da=action; bid,ask=b0+db,a0+da\n    total=0.\n    for p,wp in posterior_nodes:\n      for shock,ws in price_nodes:\n       pn=p*math.exp(shock)\n       for n in range(21):\n        # This kernel is exact for a supplied finite retail path; production table\n        # construction averages paths/cells and uses a larger cutoff if needed.\n        prob=wp*ws*poisson_p(n,lam)\n        xx,yy,bb,aa=x,y,bid,ask\n        for j in range(n):\n         side,T,wt=retail_nodes[j % len(retail_nodes)]\n         if side=='buy':\n          z=router_buy(xx,yy,aa,x2,y2,.003,T); xx,yy=buy_map(xx,yy,aa,z)\n         else:\n          q=router_sell(xx,yy,bb,x2,y2,.003,T/p); xx,yy=sell_map(xx,yy,bb,q)\n         bb,aa=policy(xx,yy,bb,aa,side,T) # offline mirror of V10 after this callback\n        total += prob*opening_arb(xx,yy,bb,aa,pn)\n    return total\n\ndef checks():\n    assert abs(router_buy(100,10000,.003,100,10000,.003,20)-10)<1e-9\n    x,y=buy_map(100,10000,.004,20); assert abs(x*y-1_000_000)<1e-10\n    x,y=sell_map(100,10000,.004,.2); assert abs(x*y-1_000_000)<1e-10\n    assert opening_arb(100,10000,.004,.004,100)==0\n    vals=[]\n    for f in [.0039,.004,.0041]:\n      z=router_buy(100,10000,f,100,10000,.003,100); x,y=buy_map(100,10000,f,z)\n      vals.append(opening_arb(x,y,.004,.004,100))\n    slope=(vals[2]-vals[0])/.0002; assert slope>0\n    return vals,slope\nif __name__=='__main__': print(checks())\n",
  "implementation_search_plan_minutes": [
    {"minutes": "0-5", "work": "Mirror V10 exactly in a reviewable pure offline function; freeze pinned simulator and V10 hashes; implement formula/unit tests above."},
    {"minutes": "5-15", "work": "Implement the integration kernel, posterior quadrature calibration interface, exact Poisson/lognormal nodes, and the observable-cell encoder. Verify identities, probability mass, symmetry and fee-bound checks."},
    {"minutes": "15-28", "work": "Generate offline conditional cell data only from permitted tuning seeds 10000..999999; calculate A/B/C/D actions with common random numbers. Retain action-level retail and arb execution-edge components."},
    {"minutes": "28-38", "work": "Fit table and polynomial, impose support/margin/curvature fallbacks to identity, and run structural ablations. Do not use confirmation seeds for choices."},
    {"minutes": "38-48", "work": "Implement the smallest passing overlay on an exact V10 copy; unit-test index boundaries, signed arithmetic, and that disabled table is byte-for-byte V10 fee behavior."},
    {"minutes": "48-55", "work": "Run tuning evaluation and gas counters; reject any OOG/revert. Freeze one pre-registered action family before any fresh >=2000-seed STACK comparison; report paired mean, SE, worst, and retail/arb deltas only then."}
  ],
  "required_inputs_and_falsification": {
    "required_inputs": [
      "The V10 source artifact and its SHA-256 cd9bdb45ab0537ad25c4fd90ca8618898cef6386de3df65f192eaef65fbca245.",
      "Pinned simulator commit 6b6921f8d463314aa7c96234e1be25a25245f704 and public normalizer behavior.",
      "A reviewed Python mirror of V10 callback state transitions, plus a declared mapping from slot-13 uncertainty to offline quadrature.",
      "Tuning-only trajectories sufficient to estimate hidden-state conditional distributions and per-cell action margins; these values never enter deployed state."
    ],
    "objective": "Maximize mean paired execution-edge difference to STACK on tuning seeds, with identity as a candidate in every cell. Decompose each difference into retail and arb execution-edge deltas. Do not optimize PnL or final inventory.",
    "parameter_ranges": "Table deltas ±0.25 and ±0.5 bps initially; u clip ±4%, sqrt(uncertainty) clip 0..1%, lambdaHat*sizeHat/y clip 0..2%; Poisson cutoff starts at 20 and must meet residual-mass tolerance. Wider ranges require a new ablation rather than silent expansion.",
    "falsification_tests": [
      "Identity vs B: if B has no stable tuning improvement after cell-support and multiple-testing controls, stop; do not carry it to confirmation.",
      "B vs D: if endpoint-only D matches B, the claimed extra two-step/interaction machinery is unnecessary; simplify or reject B.",
      "C vs B: if the polynomial changes action signs or loses value on held-out tuning cells, use the table or reject both.",
      "Set C=0 while retaining every other table/action detail. Any apparent benefit remaining is not evidence for continuation value.",
      "Permute endpoint spot within an observable cell while retaining current retail reward. A materially unchanged result falsifies the proposed endpoint channel.",
      "Run no-retail and fixed-price synthetic checks. Any nonzero correction there is a model/implementation error.",
      "Require zero OOG/revert/other halt and report gas_stats; any failure invalidates the candidate regardless of score."
    ]
  },
  "limitations": [
    "The deployed controller cannot identify an arb, observe the fair price, or observe the normalizer. The proposal explicitly averages those quantities offline; its quality is empirical and unmeasured here.",
    "Slot 13 is used by V10 as an uncertainty state but is not documented as a calibrated probability variance. The posterior quadrature mapping must be selected and ablated on tuning data.",
    "The static example deliberately has one retail order and fixed fair price. It establishes a nonzero algebraic channel only; it says nothing about expected board performance."
  ]
}
