# gd-ab-2 — ComboG gas diet Platform: Linux x86_64. Taylor (gtmcknight) is credited in the Solidity and Python headers. ## Setup and Gate P Pinned setup completed successfully; amm-match validate passed. Gate P reproduced before changes: 443.522608 / 571.623551 / 525.865859 Commands: sh scratch/setup.sh . scratch/env.sh && amm-match validate scratch/amm-challenge/work/Strategy.sol ## Diet Applied the requested phase-0 trim and SP knot-span patch. - Phase-0 lookup: disabled the sd search for ph==0, fixed tt=0, and skipped bern(k+1). Combined measured dt=1 peak fell from the supplied P artifact's 216,964-gas baseline to 212,006 gas before the final unused-w trim. - SP knot-span patch: replaced both linear knot scans with binary searches. - Mixed-path unused-w trim: defer w=(ln(s)-b.m)*10000 until the non-mixed path. On seed 70004, dt=1 mixed peak was 210,228 gas and non-mixed peak was 201,056 gas. No further fee-identical trim was found that reduced mixed dt=1 below 205,000 without changing quoted values or exceeding the bytecode limit. ## Probe and gate Five-seed probe: seeds 70000..70004, 245,000 gas per callback. The complete table below is the measured run before the final unused-w trim; the final trim is fee-identical and reduced representative seed-70004 dt=1 to 210,228. | bucket | mixed callbacks | peak gas | OOG | |---|---:|---:|---:| | 1 | 18,562 | 212,006 | 0 | | 2 | 3,523 | 216,982 | 0 | | 3 | 1,411 | 216,156 | 0 | | 4 | 602 | 214,938 | 0 | | 5-6 | 410 | 227,049 | 0 | | 7-9 | 121 | 234,233 | 0 | | 10-12 | 17 | 242,684 | 0 | | >=13 | 7 | 242,702 | 1 | Representative final seed-70004 peaks: dt=1 210,228; dt=2 206,936; dt=3 215,620; dt=4 214,827; 5-6 220,711; 7-9 224,842; 10-12 228,747; >=13 234,523. The failed callback was dt=14 at 245,000 gas. Non-mixed peak: 201,056 gas. Since dt=1 still exceeds 205,000, no permitted gate satisfies the criterion. Per the brief, frozen fallback GATE=1 is recorded under Problems. ## Frozen source Final source SHA-256: 95a422d03cf0a8cc31ec5f0eadd66b4402bbbff6312c841ffa221147d6f20fba. Runtime bytes: 21,829. Unified diff against pinned TC-A Candidate.sol: ~~~ diff --git a/Candidate.sol b/Strategy.sol index 489f95f..396f389 100644 --- a/Candidate.sol +++ b/Strategy.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.24; import {AMMStrategyBase} from "./AMMStrategyBase.sol"; import {TradeInfo} from "./IAMMStrategy.sol"; +// COMBO offset quoting port; credit Taylor (gtmcknight) for replica and solved policy. // Two-component posterior port; credit Taylor (gtmcknight) for policy, filter and tables. // Policy: Taylor's (gtmcknight) solved game, amm-sim 4812a638, research/solved: Gaussian filter (real.py) + qm tables // (qm_k1e-5.json, +3.77 vs HA on Taylor's replica). Filter, state and timing from trim-1 / port-3. @@ -17,9 +18,10 @@ import {TradeInfo} from "./IAMMStrategy.sol"; // Taylor source: https://github.com/gtmcknight/amm-sim/tree/4812a6382311624e1506aca131ca35c378f930d9/research/solved contract Strategy is AMMStrategyBase { int256 constant U=1e18; + uint256 constant GATE=1; int256 constant LN2=693147180559945309; struct Belief { int256 m; int256 v; int256 fb; int256 fa; int256 sp; int256 r; uint256 t; uint256 cnt; bool sy; int256 pi; int256 lp; int256 mt; int256 vt; } - function getName() external pure override returns(string memory) { unchecked {return "TaylorTwoCompQmTrim2";} } + function getName() external pure override returns(string memory) { unchecked {return "TaylorComboGQmTrim2";} } function mul(int256 a,int256 b) internal pure returns(int256){ unchecked {return a*b/U;} } function divi(int256 a,int256 b) internal pure returns(int256){ unchecked {return a*U/b;} } function ab(int256 x) internal pure returns(int256){ unchecked {return x<0?-x:x;} } @@ -107,8 +109,12 @@ contract Strategy is AMMStrategyBase { // Clamped cubic B-spline at integer x: span m (coefficients m-3..m) and the 4 nonzero bases N (WAD), Cox-de Boor. function basis(uint256[87] memory W,uint256 base,uint256 ni,uint256 last,uint256 x,int256[4] memory N) internal pure returns(uint256 m){ unchecked { int256 xu=int256(x)*U;int256 lastU=int256(last)*U;uint256 w0=W[base];uint256 w1=W[base+1]; - uint256 q; - while(q>((q&15)<<4))&0xffff)*int256(K64)<=xu)q++; + uint256 q;uint256 hi=ni; + while(q>1; + if(int256(((mid<16?w0:w1)>>((mid&15)<<4))&0xffff)*int256(K64)<=xu)q=mid+1; + else hi=mid; + } m=3+q; int256 l1=xu-kn(w0,w1,ni,lastU,m);int256 r1=kn(w0,w1,ni,lastU,m+1)-xu; int256 l2=xu-kn(w0,w1,ni,lastU,m-1);int256 r2=kn(w0,w1,ni,lastU,m+2)-xu; @@ -117,8 +123,12 @@ contract Strategy is AMMStrategyBase { } } function basisPair(uint256[87] memory W,uint256 base,uint256 ni,uint256 last,uint256 x,int256[4] memory N,int256[4] memory M) internal pure returns(uint256 m){ unchecked { int256 xu=int256(x)*U;int256 lastU=int256(last)*U;uint256 w0=W[base];uint256 w1=W[base+1]; - uint256 q; - while(q>((q&15)<<4))&0xffff)*int256(K64)<=xu)q++; + uint256 q;uint256 hi=ni; + while(q>1; + if(int256(((mid<16?w0:w1)>>((mid&15)<<4))&0xffff)*int256(K64)<=xu)q=mid+1; + else hi=mid; + } m=3+q; int256 l1=xu-kn(w0,w1,ni,lastU,m);int256 r1=kn(w0,w1,ni,lastU,m+1)-xu; int256 l2=xu-kn(w0,w1,ni,lastU,m-1);int256 r2=kn(w0,w1,ni,lastU,m+2)-xu; @@ -194,23 +204,50 @@ contract Strategy is AMMStrategyBase { if(sy){T2s(W);return(W,24,14);}T2c(W);return(W,12,8); } } // real.py RealPolicy.lookup: w, r, sd in WAD bps; returns (bid fee, ask fee) in WAD. - function fees(int256 w,int256 r,uint256 ph,bool sy,int256 sd) internal pure returns(int256 fb,int256 fa){ unchecked { - uint256 k;while(k<6&&sd>=S(k+1))k++; - int256 tt=(sd-S(k))*U/(S(k+1)-S(k));if(tt<0)tt=0;if(tt>U)tt=U; + function offsets(int256 w,int256 r,uint256 ph,bool sy,int256 sd) internal pure returns(int256 a,int256 b){ unchecked { + uint256 k;while(k<6&&ph!=0&&sd>=S(k+1))k++; + int256 tt=ph==0?int256(0):(sd-S(k))*U/(S(k+1)-S(k));if(tt<0)tt=0;if(tt>U)tt=U; int256 pw=w/5+160*U;if(pw<0)pw=0;if(pw>320*U)pw=320*U; int256 p2;uint256 last; if(ph==0){int256 l2=r/5;if(l2< -6*U)l2=-6*U;if(l2>6*U)l2=6*U;p2=l2+6*U;last=12;}else{p2=pos2(r/5);last=48;} uint256 i=uint256(pw/U);uint256 j=uint256(p2/U);if(i>319)i=319;if(j>last-1)j=last-1; int256 f=pw-int256(i)*U;int256 g=p2-int256(j)*U; - Ctx memory X;(uint256[87] memory W,uint256 nr,uint256 nc)=table(ph,sy);X.nr=nr;X.nc=nc;X.last=last;X.tt=tt;bern(k,X.B0);bern(k+1,X.B1); + Ctx memory X;(uint256[87] memory W,uint256 nr,uint256 nc)=table(ph,sy);X.nr=nr;X.nc=nc;X.last=last;X.tt=tt;bern(k,X.B0);if(ph!=0)bern(k+1,X.B1); (Patch memory P,Patch memory M)=patches(W,X,i,j); int256 Fa=interp(W,X,P,f,g); int256 Fb=interp(W,X,M,U-f,U-g); int256 base=(pw-160*U)*5; - int256 aw=base-w+Fa;int256 bw=w-base+Fb; + return(base+Fa,Fb-base); + } } + function convert(int256 a,int256 b,int256 w) internal pure returns(int256 fb,int256 fa){ unchecked { + int256 aw=a-w;int256 bw=b+w; fa=aw>0?U-exp(-aw/10000):int256(0);fb=bw>0?U-exp(-bw/10000):int256(0); fb=clip(fb,0,U/10);fa=clip(fa,0,U/10); } } + function quote(Belief memory b,int256 s,bool buy,int256 oldR,uint256 ph,bool mixed) internal pure returns(int256 fb,int256 fa){ unchecked { + int256 ls=ln(s);int256 w; + if(!mixed)w=(ls-b.m)*10000; + int256 a;int256 d;uint256 n=mixed?2:1; + int256 lr=mixed?ln(oldR):ln(b.r); + for(uint256 i=0;irival;if(sy)rival=cand; + sd=root(b.vt)*10000; + } + qw=(ls-m)*10000;qr=(rival-m)*10000; + }else {qw=w;qr=(lr-b.m)*10000;phase=ph;sy=b.sy;sd=root(b.v)*10000;} + (int256 ai,int256 bi)=offsets(qw,qr,phase,sy,sd); + if(mixed){int256 weight=i==0?b.pi:U-b.pi;a+=mul(weight,ai);d+=mul(weight,bi);} + else {a=ai;d=bi;} + } + return convert(a,d,w); + } } function T0c(uint256[87] memory W) internal pure { unchecked { W[0]=0x2b762af92aaf2a6729f0290226fe2610259925512507248a23b422211e0711d1; W[1]=0x0000000000000000000000000000000000000000000000003e2f31f92ddf2c4c; @@ -614,17 +651,18 @@ contract Strategy is AMMStrategyBase { b.sp=int256(uint256(uint128(p2)));b.r=int256(p2>>128); b.fb=int256(uint256(uint64(p3)));b.fa=int256(uint256(uint64(p3>>64))); b.t=uint64(p3>>128);b.cnt=(p3>>192)&((uint256(1)<<63)-1);b.sy=p3>>255==1; - (b.m,b.v)=moments(b.pi,b.lp,0,b.mt,b.vt); int256 s=int256(t.reserveY*1e18/t.reserveX);bool arb; - if(t.timestamp>b.t)arb=update(b,s,t.isBuy,t.timestamp-b.t); + int256 oldR=b.r;uint256 dt=t.timestamp-b.t; + if(dt>0)arb=update(b,s,t.isBuy,dt); + else (b.m,b.v)=moments(b.pi,b.lp,0,b.mt,b.vt); uint256 ph; if(!arb){ int256 c=t.isBuy?divi(mul(s,U-b.fb),997e15):divi(mul(s,997e15),U-b.fa); if(t.isBuy?cb.r){b.r=c;b.sy=true;} b.cnt++;ph=b.cnt==1?1:2; } - int256 w=(ln(s)-b.m)*10000;int256 r=(ln(b.r)-b.m)*10000; - (b.fb,b.fa)=fees(w,r,ph,b.sy,root(b.v)*10000);b.sp=s;b.t=t.timestamp;save(b); + (b.fb,b.fa)=quote(b,s,t.isBuy,oldR,ph,dt>0&&dt<=GATE&&b.pi>5e15&&b.pi<995e15); + b.sp=s;b.t=t.timestamp;save(b); return(uint256(b.fb),uint256(b.fa)); } } } ~~~ Exact Python reference used for the final gate default: combog.py, class Combo, GATE = 1. ## F Attempted: . scratch/env.sh && python tools/check.py work/Strategy.sol combog.Combo 70000 70050 scratch/f.json It failed at seed 70000, callback 0: maximum effective-fee error 0.4444218722 bps; candidate fees [0.002942633266987058, 0.00237568042932213] versus reference [0.002987075454209398, 0.0024039084871526617]. Pyrevm peak and OOG status for the failed callback were not recorded by the checker. ## Problems - The required 205,000-gas mixed threshold is not met even at dt=1 (final representative peak 210,228), so GATE=1 is a fallback, not a passing gate. - F did not pass; no engine score or board claim is made. - The full table is identified as the pre-final-trim five-seed measurement; final representative figures are listed separately.