# net-1: port-3 + fixed-net MLP (2-pass) Strategy **Summary.** Shipped the **2-pass** version: the fixed-net MLP is evaluated at (w,R,phase) for ask and at (-w,-R,phase) for bid, in place of port-3's coarse table. On engine seeds 9522000..9522127 (n=128), port minus t03 = **+1.228371011** (SE 0.103213544, port ahead on 108/128 seeds). Port minus IB = **+2.009225389** (SE 0.115152456). Gate F passes: max |fee diff| is 3.181e-09 bps over 100,000 callbacks. **Limit breach:** the real-engine afterSwap peak was **245,377 gas**. That is 377 gas over the brief's 245,000 limit, though the engine recorded 0 OutOfGas. The 8-pass version was much heavier (pyrevm peak 357,552) and was not shipped. **Gate Q for the 2-pass version was not completed** (see Problems). Deployed size is **16,368 bytes**. All figures are local measurements, not independent certification. Credit: Taylor (gtmcknight) for the solved policy, filter and replica: [amm-sim research/solved @4812a638](https://github.com/gtmcknight/amm-sim/tree/4812a6382311624e1506aca131ca35c378f930d9/research/solved). The filter, math and fee rule come from port-3 ([artifact](https://api.imd.fun/artifacts/0dbcc10af41b3c3467ff0d9b9cb64c81328fcf18295f9be06b2d81bb98874067)). The network payload and integer rules come from fixed-net ([artifact](https://api.imd.fun/artifacts/cc8778a3d8f1f86ffbfc77e971b5ed598b27fee68d61c338e8f3cb2057a363d0)). ## Setup | Step | Result | |---|---| | Clone amm-challenge @ 6b6921f8d463314aa7c96234e1be25a25245f704 (under the workspace's test/scratch/) | passed | | Save port-3's setup script verbatim as scratch/setup.sh; `sh scratch/setup.sh` | exit 0; wheel sha256 check OK; ends with `Strategy 'StarterStrategy' validated successfully!` | | Taylor amm-sim @ 4812a638 research/solved (sparse fetch) | passed | | Gate P: `python3 -I gates.py` (unmodified) | reproduced every printed digit (below) | | port-3 Strategy.sol extracted from artifact | sha256 62930b8e68277c69fc1acfba18de781e684d7fc6daac8dc562b8210dc3932ac1, matches port-3 | | fixed-net payload decoded | 2,730 bytes, sha256 9727ecc8acf6d31732793d1836c60cd637133b800bbe61b19098bfee7d17e0f6, matches; fixed-net's decoder reproduces canonical JSON sha256 068ee67f3219df2aaf9ab9f8e93d29dc79ad313afa17771d818f062609a1cec6; my Python forward pass equals the decoder on 300 random grid cells (max diff 0) | | t03 = zlib(base64(code_zb64)) | sha256 cb6d945511e1e10af78baa64c2a6cb25806f0998403ce6440654bfc3c70092d9 | | IB likewise | sha256 301941829a44bb60977bb28181a5e4bfa6544f3696763f987054789b2611d686 | | `amm-match validate` on both generated versions | `validated successfully` | Gate P output: ```text seed perfect-info gaussian+plain gaussian+qm lattice+qm 10000 448.261189 443.455598 443.522608 443.663520 10001 576.779199 571.463409 571.623551 571.977293 10002 531.886497 525.168028 525.865859 526.411631 ``` ## Implementation - Filter, state, ln/exp/pdf/cdf/sqrt and the fee rule (`fee = 1-exp(-(offset∓w)/1e4)`, clamped to [0,10%]) are port-3's, unchanged. Only `fees()` is replaced. The coarse TABLE, knot, lookup and blend code is removed. The init fee constant is recomputed for net(0,0,0) = 28.74755859375 bps, giving 2870627705508484 WAD. - Integer rules follow fixed-net. Inputs are `x = nearest(16384·[w/100, R/100, phase])`; the sd input is omitted because all of its weights are 0. Each layer computes `floor((bias + Σ w·x) / 2^shift)` with shifts 12, 10, 12, using arithmetic right shifts (floor, not truncation). Hidden layers apply ReLU. Offset = z·100/16384 bps, exactly z·6103515625000000 in WAD. Arithmetic is 256-bit. - **Data layout.** Each model word is a Solidity hex literal, compiled as a PUSH32 immediate, so the data sits in 33-byte PUSH32-prefixed blocks. This differs from port-3, which reads a `bytes constant` byte by byte. Without assembly, byte-wise reads cost too much gas. Each hidden-layer word packs 4 outputs in 64-bit lanes as the exact integer Σ v·2^(64m) mod 2^256. The bias words carry +2^63 per lane. Then `Z = bias + Σ_i P_i·x_i (mod 2^256)` gives every lane exactly as bias+2^63+Σw·x, because every true lane value lies in [0, 2^64). Max |accumulator| is about 2.8e9, far below 2^63. This needs one MUL per 4 outputs. Zero ReLU inputs are skipped. Layer 2 uses 16-bit lanes. The whole data set is derived from the 2,730-byte payload by gen.py (below). - **2-pass rule.** w is clamped to [-800,800]. R is clamped to [-30,30] in phase 0 and to [-800,800] in phases 1 and 2. ask offset = net(wc,Rc,ph); bid offset = net(-wc,-Rc,ph), which is the table reflection B[i][j]=A[320-i][n-1-j]. The fee uses the unclamped w, as in Taylor's DPPolicy._fees. - **8-pass rule** (built and measured, not shipped). It evaluates the net at the four grid corners for ask and the four reflected corners for bid. It then applies exactly Taylor's grid clamping, binary search over W2L and bilinear interpolation. W2L is stored as 16-bit lanes. ## Version shipped and why (gas) | Version | Deployed bytes | pyrevm afterSwap peak | pyrevm mean | Fee parity vs its Python reference | |---|---:|---:|---:|---| | 8-pass | 17,459 | **357,552** (seed 70000; 350,947 on seed 70001), run with a 3,000,000 gas cap | ≈281k | max 1.70e-10 bps (2 runs × 2,000 callbacks) | | 2-pass (shipped) | 16,368 | 197,653 (50 Gate F runs) | 105,179.6 | max 3.18e-09 bps (Gate F) | The 8-pass peak is far above 240,000, so the 2-pass version ships, as the brief instructs. These pyrevm numbers exclude the engine's per-call overhead. On the real engine the 2-pass peak is 245,377 (see Gas). ## Gate Q (2-pass) — NOT completed The Python integer reference (`netref.Net2`, below) versus the full tables (`RealPolicy(pol_mid.json, {'soft':1})`) costs about 10 s per seed pair per process on this 6-core machine. 3,072 seeds would take about 85 minutes, which did not fit in the time left after the engine runs and Gate F. A 180-seed report subset (10000..10179) was started and was killed by the 470 s command timeout before it wrote any output. The only completed pairs are a timing probe on choose seeds 60000 and 60001: full−net = 0.2058 and 0.5312 edge (n=2, not a statistic). Nothing was chosen on the choose set because there was only one candidate. **The replica loss of the 2-pass (continuous) policy against the full tables is unmeasured.** fixed-net's −0.0397 loss applies to the 8-pass grid policy only, not to this version. ## Gate F (2-pass, shipped) Replica seeds 70000..70049. In each run, `netref.Net2` drives Taylor's replica2 and the first 2,000 own-pool callbacks and fees are recorded; the replica is then stopped. Those callbacks are replayed in order on a fresh pyrevm deployment, with amounts and reserves converted by int(float·1e18), the init call at 100/10,000, and **gas=245,000 per call**. All 100,000 calls succeeded. - 50 runs, 100,000 callbacks, 200,000 fee comparisons - max |fee diff| **3.181e-09 bps**; mean 1.910e-10 bps; init max 1.561e-13 bps. The target was ≤ 0.01 bps: **pass**. - pyrevm peak 197,653; mean 105,179.6 - SHA-256 of the concatenated per-run trace hashes: 69a2953871d5ee0da047d4561312deffdeb8ca813ee0fc4de41d17b15ecfaa59 ## Size Deployed runtime **16,368 / 24,576 bytes**. Strategy.sol sha256 `5c40c67a9c5c3c2cb3f1aea95d6f605ef110a87b7674759b65836b5c9ec1609f` (34202 bytes of source). ## Gas (real engine, `amm_sim_rs.gas_stats()`, Submission role) Stats were reset before each 32-seed chunk and summed over the 4 chunks. Peak is the maximum over chunks; mean is sum_ok_gas/ok. revert, other_halt, tx_error and bad_return were all 0. | Strategy | Callback | Calls | OOG | Peak | Mean | |---|---|---:|---:|---:|---:| | port (2-pass) | afterInitialize | 128 | 0 | 141,962 | 141,962.00 | | port (2-pass) | afterSwap | 1,389,773 | 0 | **245,377** | 141,140.96 | | port (2-pass) | getName | 128 | 0 | 21,538 | 21,538.00 | | t03 | afterInitialize | 128 | 0 | 243,234 | 243,234.00 | | t03 | afterSwap | 1,392,407 | 0 | 237,611 | 135,529.03 | | t03 | getName | 128 | 0 | 21,742 | 21,742.00 | | IB | afterInitialize | 128 | 0 | 243,227 | 243,227.00 | | IB | afterSwap | 1,381,968 | 0 | 237,040 | 135,184.13 | | IB | getName | 128 | 0 | 21,735 | 21,735.00 | The port's first chunk (9522000..9522031) peaked at 235,879. The 245,377 peak appeared in a later chunk. The engine reported 0 OutOfGas, so its own per-call limit was evidently not 245,000 for this metric. **The stated limit, afterSwap peak ≤ 245,000, is still not met.** ## Paired results (engine) Each strategy ran alone against the 30 bps VanillaStrategy via `amm_sim_rs.run_batch(X, VanillaStrategy, configs, 8)`. Configs follow port-3's transcription of MatchRunner._build_configs with seed i. Only seeds 9522000..9522127 were used, in 4 chunks of 32. These seeds were not used for tuning, and none were rerun. Mean submission edge: port 526.439528660, t03 525.211157649, IB 524.430303270. | Pair | n | mean_diff | se | worst5 (seed, diff) | |---|---:|---:|---:|---| | port − t03 | 128 | **+1.228371011** | 0.103213544 | (9522100, −1.682760066), (9522091, −1.131634696), (9522115, −1.076202058), (9522059, −0.985105541), (9522092, −0.683785675) | | port − IB | 128 | **+2.009225389** | 0.115152456 | (9522100, −1.104893790), (9522115, −0.718558082), (9522091, −0.698284662), (9522054, −0.182632093), (9522042, −0.079437268) | The port is ahead of t03 on 108/128 seeds and ahead of IB on 122/128. SE is the sample SD of the differences divided by √n. ## Problems 1. **Real-engine afterSwap peak is 245,377, which is over the 245,000 limit** (0 OOG recorded). The 2-pass version therefore does not meet the brief's peak limit as measured. Possible fixes, none of them tried: cut the filter's 12-silent-step trunc cost, which is port-3's peak path; cap ReLU-active columns; or cache layer-0 work shared by the ask and bid passes. Any fix needs fresh engine seeds. 2. **Gate Q was not run to completion** (time). The replica quality of the 2-pass policy against the full tables is unknown. The engine result above is the only evidence of its quality. 3. Data storage differs from port-3's single `bytes constant`: the model words are PUSH32 immediates in code. They are still PUSH32-prefixed 33-byte blocks, and there is no assembly. 4. Gate F stops each replica run after 2,000 callbacks; only those callbacks are compared. ## Strategy.sol (shipped, verbatim; sha256 5c40c67a9c5c3c2cb3f1aea95d6f605ef110a87b7674759b65836b5c9ec1609f) ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {AMMStrategyBase} from "./AMMStrategyBase.sol"; import {TradeInfo} from "./IAMMStrategy.sol"; // Gaussian solved policy by Taylor (gtmcknight), amm-sim 4812a638; filter ported from port-3. // Offsets: fixed-net 4-32-32-1 int16 MLP (payload sha256 9727ecc8...), integer forward pass, // shifts 12,10,12, Q14 activations, arithmetic-shift floor. 2 passes: ask net(w,R,phase), bid net(-w,-R,phase), inputs clamped to the grid. // Model data: PUSH32 immediates (33-byte blocks); hidden layers as 4x64-bit lanes per word, // lane = bias + 2^63 + sum(w*x), exact mod 2^256. // Taylor source: https://github.com/gtmcknight/amm-sim/tree/4812a6382311624e1506aca131ca35c378f930d9/research/solved contract Strategy is AMMStrategyBase { int256 constant U=1e18; int256 constant LN2=693147180559945309; struct Belief { int256 m; int256 v; int256 fb; int256 fa; int256 sp; int256 r; uint256 t; uint256 cnt; } function getName() external pure override returns(string memory) { unchecked {return "TaylorGaussianPlainNet2";} } 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;} } function clip(int256 x,int256 a,int256 b) internal pure returns(int256){ unchecked {return xb?b:x);} } function ln(int256 x) internal pure returns(int256 z){ unchecked { require(x>0); int256 k; while(x< U){x*=2;k--;} while(x>=2*U){x/=2;k++;} int256 y=divi(x-U,x+U); int256 y2=mul(y,y); int256 q=y; z=y; for(int256 n=3;n<=29;n+=2){q=mul(q,y2);z+=q/n;} return 2*z+k*LN2; } } function exp(int256 x) internal pure returns(int256){ unchecked { if(x< -42*U)return 0; require(x<60*U); int256 k=(x>=0?x+LN2/2:x-LN2/2)/LN2; int256 r=x-k*LN2; int256 r2=mul(r,r); int256 even=665280*U+mul(r2,75600*U+mul(r2,840*U+r2)); int256 odd=mul(r,332640*U+mul(r2,10080*U+mul(r2,42*U))); int256 s=divi(even+odd,even-odd); return k>=0?s*int256(uint256(1)<>128>0){z>>=128;r<<=64;} if(z>>64>0){z>>=64;r<<=32;} if(z>>32>0){z>>=32;r<<=16;} if(z>>16>0){z>>=16;r<<=8;} if(z>>8>0){z>>=8;r<<=4;} if(z>>4>0){z>>=4;r<<=2;} if(z>>2>0){r<<=1;} for(uint256 i=0;i<7;i++)r=(r+n/r)/2; return int256(r10*U)return 0;return divi(exp(-mul(x,x)/2),2506628274631000200);} } // Hart rational normal tail approximation; erf(x)=2*Phi(x*sqrt(2))-1. function cdf(int256 x,int256 density) internal pure returns(int256){ unchecked { int256 y=ab(x);if(y>8*U)return x>0?U:int256(0); int256 n=35262496599891000; n=mul(n,y)+700383064443688000;n=mul(n,y)+6373962203531650000; n=mul(n,y)+33912866078383000000;n=mul(n,y)+112079291497871000000; n=mul(n,y)+221213596169931000000;n=mul(n,y)+220206867912376000000; int256 d=88388347648318400; d=mul(d,y)+1755667163182640000;d=mul(d,y)+16064177579207000000; d=mul(d,y)+86780732202946100000;d=mul(d,y)+296564248779674000000; d=mul(d,y)+637333633378831000000;d=mul(d,y)+793826512519948000000; d=mul(d,y)+440413735824752000000; int256 tail=mul(mul(density,2506628274631000200),divi(n,d));return x>0?U-tail:tail; } } function trunc(int256 m,int256 v,int256 lo,int256 hi) internal pure returns(int256 Z,int256 mt,int256 vt){ unchecked { if(v<=0)return (lo<=m&&m<=hi?U:int256(0),m,0); int256 sd=root(v);int256 a=divi(lo-m,sd);int256 b=divi(hi-m,sd); int256 pa=pdf(a);int256 pb=pdf(b); Z=cdf(b,pb)-cdf(a,pa); if(Z<1e6)return(Z,m>2]>>((j&3)*64)&M64)-int256(OFF))>>sh;if(v>0)h[j]=uint256(v);} } } function l1a(uint256[32] memory h,uint256[8] memory Z) internal pure { unchecked { uint256 z0=0x800000000006123180000000003472d880000000005317db8000000000000000;uint256 z1=0x80000000001757687fffffffffe760cc7fffffffffd9ca8e800000000021ed28;uint256 v; v=h[0];if(v!=0){z0+=0x0000000000000016fffffffffffffe3800000000000001000000000000000400*v;z1+=0x0000000000000015fffffffffffff1a80000000000000099ffffffffffffffeb*v;} v=h[1];if(v!=0){z0+=0x000000000000009d00000000000000cbffffffffffffffd20000000000000000*v;z1+=0xffffffffffffffd7ffffffffffffff8a000000000000000effffffffffffffc9*v;} v=h[2];if(v!=0){z0+=0x0000000000000091ffffffffffffff7600000000000000790000000000000000*v;z1+=0x000000000000000000000000000000ab00000000000000edffffffffffffffb7*v;} v=h[3];if(v!=0){z0+=0xffffffffffffff99ffffffffffffff3800000000000000d40000000000000000*v;z1+=0xffffffffffffff5100000000000000e7ffffffffffffff3efffffffffffffd71*v;} v=h[4];if(v!=0){z0+=0x00000000000000a9000000000000013500000000000001370000000000000000*v;z1+=0xffffffffffffff86fffffffffffffffa000000000000004dffffffffffffffac*v;} v=h[5];if(v!=0){z0+=0xffffffffffffff6effffffffffffff49fffffffffffffe520000000000000000*v;z1+=0x00000000000000ac00000000000000dfffffffffffffff8effffffffffffffcd*v;} v=h[6];if(v!=0){z0+=0x000000000000004affffffffffffff1800000000000000320000000000000000*v;z1+=0xffffffffffffff79000000000000007f00000000000000a9ffffffffffffffdd*v;} v=h[7];if(v!=0){z0+=0xffffffffffffff95ffffffffffffff1efffffffffffffab80000000000000000*v;z1+=0x0000000000000004fffffffffffffe8d000000000000014f0000000000000127*v;} v=h[8];if(v!=0){z0+=0xffffffffffffffcb000000000000006cfffffffffffffcef0000000000000000*v;z1+=0xffffffffffffffecffffffffffffffe200000000000000eeffffffffffffffe4*v;} v=h[9];if(v!=0){z0+=0x0000000000000067000000000000005600000000000001420000000000000000*v;z1+=0xffffffffffffffc900000000000000cb00000000000000180000000000000042*v;} v=h[10];if(v!=0){z0+=0x0000000000000048ffffffffffffff2600000000000000f70000000000000000*v;z1+=0xffffffffffffffe6ffffffffffffff6dffffffffffffff6000000000000000a8*v;} v=h[11];if(v!=0){z0+=0x000000000000005fffffffffffffffd300000000000000d20000000000000000*v;z1+=0xfffffffffffffffc00000000000000bcffffffffffffff6affffffffffffff5d*v;} v=h[12];if(v!=0){z0+=0x000000000000005b00000000000000b000000000000000830000000000000000*v;z1+=0x0000000000000003000000000000002cffffffffffffff13000000000000007e*v;} v=h[13];if(v!=0){z0+=0xfffffffffffffff3fffffffffffffe99ffffffffffffeb070000000000000000*v;z1+=0xfffffffffffffff3ffffffffffffff0e00000000000002caffffffffffffffcf*v;} v=h[14];if(v!=0){z0+=0xffffffffffffffedffffffffffffffde000000000000018e0000000000000000*v;z1+=0xffffffffffffff6ffffffffffffffff20000000000000010ffffffffffffffd0*v;} v=h[15];if(v!=0){z0+=0x000000000000007cffffffffffffff59ffffffffffffff820000000000000000*v;z1+=0xffffffffffffffdcffffffffffffff4b000000000000009e0000000000000047*v;} v=h[16];if(v!=0){z0+=0x000000000000001300000000000001a100000000000002e50000000000000000*v;z1+=0xffffffffffffff6f0000000000000077ffffffffffffff57fffffffffffffc1a*v;} v=h[17];if(v!=0){z0+=0xffffffffffffff2e000000000000004dfffffffffffffce40000000000000000*v;z1+=0xffffffffffffff5d0000000000000012000000000000012c0000000000000126*v;} v=h[18];if(v!=0){z0+=0xffffffffffffff90ffffffffffffff6e00000000000000680000000000000000*v;z1+=0x0000000000000012ffffffffffffff4effffffffffffffe20000000000000214*v;} v=h[19];if(v!=0){z0+=0xffffffffffffffa4000000000000005900000000000003ce0000000000000000*v;z1+=0xffffffffffffff92ffffffffffffff97fffffffffffffffb0000000000000097*v;} v=h[20];if(v!=0){z0+=0xffffffffffffff7b00000000000000b8ffffffffffffff200000000000000000*v;z1+=0x000000000000000ffffffffffffff5e10000000000000054000000000000007b*v;} v=h[21];if(v!=0){z0+=0x000000000000016e0000000000000085ffffffffffffff050000000000000000*v;z1+=0x0000000000000055fffffffffffffed1ffffffffffffffb3ffffffffffffffc5*v;} v=h[22];if(v!=0){z0+=0xffffffffffffff86000000000000007700000000000000070000000000000000*v;z1+=0xffffffffffffff9d0000000000000119ffffffffffffff89ffffffffffffffe6*v;} v=h[23];if(v!=0){z0+=0x00000000000000ef0000000000000134fffffffffffffeaa0000000000000000*v;z1+=0xffffffffffffff6dffffffffffffffb7ffffffffffffff62ffffffffffffff82*v;} v=h[24];if(v!=0){z0+=0xffffffffffffff5cffffffffffffff32fffffffffffffbcf0000000000000000*v;z1+=0x0000000000000099ffffffffffffffeb00000000000000cf0000000000000138*v;} v=h[25];if(v!=0){z0+=0xfffffffffffffff2000000000000000d000000000000010b0000000000000000*v;z1+=0x0000000000000024fffffffffffffe2affffffffffffff690000000000000001*v;} v=h[26];if(v!=0){z0+=0x0000000000000026ffffffffffffffe000000000000000e30000000000000000*v;z1+=0xffffffffffffff8affffffffffffffbb00000000000000130000000000000051*v;} v=h[27];if(v!=0){z0+=0xfffffffffffffebbfffffffffffffebffffffffffffffff50000000000000000*v;z1+=0xffffffffffffff66000000000000015400000000000001410000000000000052*v;} v=h[28];if(v!=0){z0+=0x000000000000002dffffffffffffff8800000000000000920000000000000000*v;z1+=0xffffffffffffffa5ffffffffffffff63000000000000005b0000000000000013*v;} v=h[29];if(v!=0){z0+=0xffffffffffffff610000000000000126000000000000008c0000000000000000*v;z1+=0xffffffffffffffb4000000000000005500000000000000140000000000000007*v;} v=h[30];if(v!=0){z0+=0x00000000000000b100000000000000d200000000000001370000000000000000*v;z1+=0x000000000000002300000000000000d3ffffffffffffff3d00000000000000bb*v;} v=h[31];if(v!=0){z0+=0xffffffffffffffe0000000000000008700000000000000cb0000000000000000*v;z1+=0x0000000000000059ffffffffffffffddfffffffffffffff1ffffffffffffff61*v;} Z[0]=z0;Z[1]=z1; } } function l1b(uint256[32] memory h,uint256[8] memory Z) internal pure { unchecked { uint256 z2=0x80000000000a369e8000000000213d6f7fffffffffcc127d7ffffffffff6c278;uint256 z3=0x800000000004039f8000000000058c4480000000001f872880000000001b4632;uint256 v; v=h[0];if(v!=0){z2+=0x000000000000008afffffffffffffe71ffffffffffffff81000000000000005f*v;z3+=0x00000000000001060000000000000087ffffffffffffff39000000000000000e*v;} v=h[1];if(v!=0){z2+=0xfffffffffffffcefffffffffffffffe900000000000000a1fffffffffffffe6b*v;z3+=0x0000000000000002fffffffffffffe65ffffffffffffff85000000000000008b*v;} v=h[2];if(v!=0){z2+=0xffffffffffffffba0000000000000080ffffffffffffffb8ffffffffffffff2a*v;z3+=0x00000000000000a2fffffffffffffdd300000000000000030000000000000193*v;} v=h[3];if(v!=0){z2+=0xffffffffffffff0f0000000000000042fffffffffffffffeffffffffffffff8d*v;z3+=0xfffffffffffffffc00000000000000db000000000000007bfffffffffffffeaf*v;} v=h[4];if(v!=0){z2+=0xfffffffffffffff6ffffffffffffff6fffffffffffffff26fffffffffffffdc5*v;z3+=0xffffffffffffffd8fffffffffffffb63fffffffffffffd03ffffffffffffffef*v;} v=h[5];if(v!=0){z2+=0x0000000000000123000000000000001700000000000000640000000000000110*v;z3+=0x000000000000003a00000000000000b6ffffffffffffff340000000000000016*v;} v=h[6];if(v!=0){z2+=0xfffffffffffffdacfffffffffffffef0000000000000002ffffffffffffffe8c*v;z3+=0x000000000000007ffffffffffffffee3000000000000000dffffffffffffffb0*v;} v=h[7];if(v!=0){z2+=0xffffffffffffe7a2ffffffffffffff4b0000000000000147ffffffffffffe6f3*v;z3+=0x0000000000000026fffffffffffffe71fffffffffffffc2100000000000000ae*v;} v=h[8];if(v!=0){z2+=0x000000000000007afffffffffffffff4000000000000013a00000000000000bc*v;z3+=0x000000000000003800000000000000affffffffffffffcf9ffffffffffffff6b*v;} v=h[9];if(v!=0){z2+=0x000000000000000c0000000000000031000000000000004300000000000000b5*v;z3+=0xffffffffffffff8a000000000000004f00000000000000c6000000000000008a*v;} v=h[10];if(v!=0){z2+=0xffffffffffffff0c000000000000008b0000000000000048fffffffffffffe8d*v;z3+=0x000000000000001d000000000000011affffffffffffff9400000000000000ce*v;} v=h[11];if(v!=0){z2+=0xffffffffffffffbc00000000000000c8ffffffffffffffca000000000000005c*v;z3+=0xffffffffffffffd6ffffffffffffffc2000000000000018affffffffffffff77*v;} v=h[12];if(v!=0){z2+=0x000000000000004000000000000000c4ffffffffffffff50ffffffffffffff11*v;z3+=0x00000000000000dbffffffffffffff9b0000000000000026000000000000000e*v;} v=h[13];if(v!=0){z2+=0xffffffffffffffc4fffffffffffff7ed0000000000000170000000000000007f*v;z3+=0xffffffffffffff6b00000000000000e1fffffffffffff95f000000000000000f*v;} v=h[14];if(v!=0){z2+=0x000000000000013c0000000000000067fffffffffffffd7700000000000000cf*v;z3+=0x000000000000001b000000000000010400000000000000b90000000000000026*v;} v=h[15];if(v!=0){z2+=0xffffffffffffff4affffffffffffff09fffffffffffffffdffffffffffffff39*v;z3+=0x0000000000000049ffffffffffffffe600000000000000650000000000000091*v;} v=h[16];if(v!=0){z2+=0xfffffffffffffc560000000000000033fffffffffffffdf7fffffffffffffd38*v;z3+=0x000000000000001efffffffffffffeb8000000000000009e00000000000000b9*v;} v=h[17];if(v!=0){z2+=0xffffffffffffffe0fffffffffffffeaa00000000000001e3000000000000014d*v;z3+=0xffffffffffffff55fffffffffffffdb4ffffffffffffff2a0000000000000090*v;} v=h[18];if(v!=0){z2+=0xfffffffffffffe330000000000000165ffffffffffffffdc000000000000038d*v;z3+=0xffffffffffffffaf000000000000012d000000000000032dffffffffffffff68*v;} v=h[19];if(v!=0){z2+=0xffffffffffffff44ffffffffffffffd7000000000000007ffffffffffffffed5*v;z3+=0x0000000000000013fffffffffffffd38000000000000003f0000000000000029*v;} v=h[20];if(v!=0){z2+=0x0000000000000064ffffffffffffff20000000000000013900000000000000b1*v;z3+=0xffffffffffffff56000000000000001100000000000000d000000000000000e8*v;} v=h[21];if(v!=0){z2+=0x000000000000012effffffffffffff9200000000000000bc00000000000000e5*v;z3+=0x00000000000000a20000000000000067ffffffffffffff97ffffffffffffffa8*v;} v=h[22];if(v!=0){z2+=0x0000000000000118ffffffffffffff9f00000000000000930000000000000088*v;z3+=0xffffffffffffff140000000000000086ffffffffffffff79fffffffffffffffe*v;} v=h[23];if(v!=0){z2+=0x00000000000000d40000000000000090ffffffffffffff2900000000000001a4*v;z3+=0xffffffffffffffe900000000000000a8ffffffffffffffabffffffffffffffb9*v;} v=h[24];if(v!=0){z2+=0xfffffffffffffde2fffffffffffffe26000000000000011e00000000000000f0*v;z3+=0xffffffffffffff0a0000000000000128fffffffffffffe0c000000000000010a*v;} v=h[25];if(v!=0){z2+=0x00000000000001520000000000000124fffffffffffffcd6000000000000000f*v;z3+=0x0000000000000034000000000000006800000000000000c1ffffffffffffff6b*v;} v=h[26];if(v!=0){z2+=0xffffffffffffffe90000000000000052ffffffffffffff660000000000000031*v;z3+=0xffffffffffffffb400000000000000e30000000000000086ffffffffffffffe2*v;} v=h[27];if(v!=0){z2+=0x00000000000000cbfffffffffffffde700000000000003a1000000000000002d*v;z3+=0x0000000000000006000000000000004d00000000000000c9000000000000007e*v;} v=h[28];if(v!=0){z2+=0xfffffffffffffe7500000000000000020000000000000068fffffffffffffecb*v;z3+=0x0000000000000077ffffffffffffff9600000000000000830000000000000080*v;} v=h[29];if(v!=0){z2+=0xffffffffffffff11000000000000023affffffffffffff68ffffffffffffffc6*v;z3+=0x0000000000000077000000000000008f0000000000000097ffffffffffffff6d*v;} v=h[30];if(v!=0){z2+=0x000000000000008f00000000000000cbfffffffffffffeafffffffffffffffd6*v;z3+=0xffffffffffffffc5ffffffffffffffdd00000000000000feffffffffffffffac*v;} v=h[31];if(v!=0){z2+=0x000000000000006c000000000000001cffffffffffffff96ffffffffffffffc4*v;z3+=0x0000000000000055ffffffffffffffd9000000000000012affffffffffffffc6*v;} Z[2]=z2;Z[3]=z3; } } function l1c(uint256[32] memory h,uint256[8] memory Z) internal pure { unchecked { uint256 z4=0x7fffffffffe6afa780000000000cae11800000000027162480000000000e880c;uint256 z5=0x8000000000230d037ffffffffff492f080000000001b1520800000000016278a;uint256 v; v=h[0];if(v!=0){z4+=0x000000000000010cfffffffffffffed7000000000000021bffffffffffffffac*v;z5+=0xfffffffffffffecc0000000000000056fffffffffffffc380000000000000126*v;} v=h[1];if(v!=0){z4+=0xfffffffffffffffa000000000000003e000000000000002d0000000000000069*v;z5+=0x00000000000000090000000000000053000000000000008d0000000000000015*v;} v=h[2];if(v!=0){z4+=0x000000000000009200000000000000b9000000000000008800000000000000bf*v;z5+=0xffffffffffffff44000000000000002100000000000000f5ffffffffffffff6b*v;} v=h[3];if(v!=0){z4+=0x000000000000007cffffffffffffff8e0000000000000073000000000000003f*v;z5+=0x00000000000000ab00000000000000260000000000000134ffffffffffffff28*v;} v=h[4];if(v!=0){z4+=0xfffffffffffffff1fffffffffffffd65ffffffffffffff5dffffffffffffffbe*v;z5+=0xffffffffffffb61affffffffffffff6bffffffffffffffc8ffffffffffffff8d*v;} v=h[5];if(v!=0){z4+=0x00000000000000280000000000000014ffffffffffffff9700000000000000f6*v;z5+=0x0000000000000109ffffffffffffff2bfffffffffffffffe0000000000000139*v;} v=h[6];if(v!=0){z4+=0x000000000000006900000000000000590000000000000072ffffffffffffffba*v;z5+=0xffffffffffffff20000000000000002600000000000000c3ffffffffffffffe9*v;} v=h[7];if(v!=0){z4+=0xffffffffffffffafffffffffffffffe4ffffffffffffff4e00000000000000f3*v;z5+=0xfffffffffffffe5a00000000000000090000000000000006fffffffffffffeea*v;} v=h[8];if(v!=0){z4+=0xfffffffffffffff7000000000000012e000000000000005bffffffffffffff8c*v;z5+=0xfffffffffffffec7000000000000000efffffffffffffecb0000000000000046*v;} v=h[9];if(v!=0){z4+=0x00000000000000dbfffffffffffffe540000000000000011ffffffffffffff46*v;z5+=0x0000000000000072fffffffffffffefa00000000000000ceffffffffffffff3c*v;} v=h[10];if(v!=0){z4+=0x00000000000000e6ffffffffffffffe0000000000000010a0000000000000090*v;z5+=0x000000000000002600000000000000cbffffffffffffff97000000000000001a*v;} v=h[11];if(v!=0){z4+=0x000000000000005f00000000000000b30000000000000061ffffffffffffff92*v;z5+=0x000000000000005f00000000000000b7ffffffffffffffc4fffffffffffffffa*v;} v=h[12];if(v!=0){z4+=0xffffffffffffffb300000000000000aeffffffffffffffbaffffffffffffff9e*v;z5+=0x000000000000005e000000000000002d00000000000000e9ffffffffffffffe8*v;} v=h[13];if(v!=0){z4+=0xffffffffffffff370000000000000093ffffffffffffff8e000000000000002f*v;z5+=0xffffffffffffffb7000000000000007100000000000000b1000000000000007a*v;} v=h[14];if(v!=0){z4+=0xffffffffffffffc30000000000000134000000000000000500000000000000b4*v;z5+=0x000000000000006e00000000000000daffffffffffffffcdfffffffffffffee9*v;} v=h[15];if(v!=0){z4+=0x0000000000000099000000000000004fffffffffffffffd4000000000000001a*v;z5+=0xffffffffffffff2d00000000000000cc00000000000000000000000000000080*v;} v=h[16];if(v!=0){z4+=0x000000000000002affffffffffffffc3ffffffffffffffed00000000000000fd*v;z5+=0x000000000000016bfffffffffffffff400000000000000a600000000000000f9*v;} v=h[17];if(v!=0){z4+=0x0000000000000013000000000000000a00000000000000410000000000000098*v;z5+=0xfffffffffffffefa000000000000009500000000000001590000000000000049*v;} v=h[18];if(v!=0){z4+=0x0000000000000125ffffffffffffff72ffffffffffffff74000000000000003d*v;z5+=0x000000000000001900000000000000020000000000000045ffffffffffffff7a*v;} v=h[19];if(v!=0){z4+=0x00000000000000baffffffffffffff1100000000000000150000000000000028*v;z5+=0x00000000000000b5ffffffffffffffef0000000000000100ffffffffffffffab*v;} v=h[20];if(v!=0){z4+=0xffffffffffffffd600000000000001b5ffffffffffffff730000000000000072*v;z5+=0x00000000000001320000000000000123fffffffffffffedb00000000000000fc*v;} v=h[21];if(v!=0){z4+=0xffffffffffffffa7ffffffffffffff3fffffffffffffff5fffffffffffffff8d*v;z5+=0xffffffffffffffc2ffffffffffffffca00000000000001800000000000000036*v;} v=h[22];if(v!=0){z4+=0xffffffffffffff4cffffffffffffffc300000000000000c30000000000000012*v;z5+=0x000000000000011f00000000000000530000000000000104ffffffffffffff4f*v;} v=h[23];if(v!=0){z4+=0xffffffffffffffeb000000000000003bfffffffffffffdf10000000000000053*v;z5+=0xfffffffffffffff7ffffffffffffff50fffffffffffffbc3000000000000009f*v;} v=h[24];if(v!=0){z4+=0xffffffffffffffc2000000000000000f0000000000000023000000000000008e*v;z5+=0xffffffffffffffb10000000000000048ffffffffffffff9d00000000000000e5*v;} v=h[25];if(v!=0){z4+=0xffffffffffffff46fffffffffffffedbfffffffffffffebc0000000000000042*v;z5+=0x0000000000000012ffffffffffffff3efffffffffffffe9500000000000000ec*v;} v=h[26];if(v!=0){z4+=0x00000000000000370000000000000012ffffffffffffff7effffffffffffff3e*v;z5+=0xffffffffffffffd0ffffffffffffff70000000000000001bffffffffffffffd1*v;} v=h[27];if(v!=0){z4+=0xffffffffffffff65ffffffffffffff72ffffffffffffff830000000000000083*v;z5+=0xfffffffffffffe7fffffffffffffffadfffffffffffffecffffffffffffffebe*v;} v=h[28];if(v!=0){z4+=0xffffffffffffff2700000000000000bc00000000000000baffffffffffffffef*v;z5+=0x000000000000003e000000000000002e0000000000000137000000000000004d*v;} v=h[29];if(v!=0){z4+=0x000000000000003cfffffffffffffe2dffffffffffffff1800000000000000d5*v;z5+=0xfffffffffffffde3fffffffffffffffb00000000000000300000000000000072*v;} v=h[30];if(v!=0){z4+=0x00000000000000640000000000000056ffffffffffffffb2fffffffffffffff4*v;z5+=0xffffffffffffffdeffffffffffffff0e000000000000009fffffffffffffff27*v;} v=h[31];if(v!=0){z4+=0x00000000000000caffffffffffffff380000000000000059000000000000000f*v;z5+=0x00000000000000b40000000000000073000000000000009b0000000000000067*v;} Z[4]=z4;Z[5]=z5; } } function l1d(uint256[32] memory h,uint256[8] memory Z) internal pure { unchecked { uint256 z6=0x80000000002f0d478000000000135811800000000022e38a7fffffffffdbe00a;uint256 z7=0x7ffffffffffc7e3c7fffffffffc394bf7fffffffffd9daa280000000003b67bb;uint256 v; v=h[0];if(v!=0){z6+=0x000000000000007c00000000000000abfffffffffffffff4ffffffffffffff75*v;z7+=0xfffffffffffffffbffffffffffffffabfffffffffffffeacfffffffffffffdd9*v;} v=h[1];if(v!=0){z6+=0xffffffffffffffe4000000000000006fffffffffffffff06ffffffffffffff5a*v;z7+=0xffffffffffffffdafffffffffffffd8900000000000000850000000000000059*v;} v=h[2];if(v!=0){z6+=0x000000000000006300000000000001010000000000000014ffffffffffffff7e*v;z7+=0xffffffffffffffd3000000000000002a0000000000000080000000000000007e*v;} v=h[3];if(v!=0){z6+=0xfffffffffffffe6dffffffffffffffea000000000000004effffffffffffffd0*v;z7+=0xffffffffffffffb5000000000000007d0000000000000028000000000000009c*v;} v=h[4];if(v!=0){z6+=0x0000000000000119000000000000002500000000000000fa0000000000000049*v;z7+=0x0000000000000093ffffffffffffff85000000000000008dffffffffffffffd9*v;} v=h[5];if(v!=0){z6+=0x0000000000000071ffffffffffffff83ffffffffffffffbfffffffffffffff99*v;z7+=0xffffffffffffff8e00000000000000280000000000000102ffffffffffffff0c*v;} v=h[6];if(v!=0){z6+=0x000000000000001800000000000000080000000000000156ffffffffffffff8e*v;z7+=0xffffffffffffff78fffffffffffffc960000000000000067ffffffffffffff25*v;} v=h[7];if(v!=0){z6+=0x0000000000000045fffffffffffffee3ffffffffffffff92ffffffffffffff97*v;z7+=0xffffffffffffff77fffffffffffffd74ffffffffffffff88ffffffffffffff47*v;} v=h[8];if(v!=0){z6+=0xfffffffffffffe29fffffffffffffff50000000000000043ffffffffffffff50*v;z7+=0xffffffffffffff8dffffffffffffff24ffffffffffffff970000000000000032*v;} v=h[9];if(v!=0){z6+=0xffffffffffffffa7ffffffffffffff6dfffffffffffffeb50000000000000000*v;z7+=0xffffffffffffffac00000000000000b3000000000000014a0000000000000058*v;} v=h[10];if(v!=0){z6+=0xfffffffffffffe5500000000000000c3000000000000008bffffffffffffff6f*v;z7+=0xffffffffffffff81ffffffffffffff7affffffffffffffdbffffffffffffffe8*v;} v=h[11];if(v!=0){z6+=0x000000000000004bffffffffffffff9b000000000000005a0000000000000021*v;z7+=0xffffffffffffff6e000000000000008100000000000000c70000000000000034*v;} v=h[12];if(v!=0){z6+=0x0000000000000040000000000000004100000000000000c6ffffffffffffffa5*v;z7+=0x000000000000000a0000000000000091ffffffffffffff990000000000000057*v;} v=h[13];if(v!=0){z6+=0xffffffffffffff92ffffffffffffffa1ffffffffffffff1cffffffffffffff7e*v;z7+=0x0000000000000004fffffffffffffff400000000000000a5fffffffffffffaee*v;} v=h[14];if(v!=0){z6+=0x000000000000000fffffffffffffff5400000000000000a30000000000000012*v;z7+=0xffffffffffffff62ffffffffffffffee000000000000004f0000000000000082*v;} v=h[15];if(v!=0){z6+=0x00000000000000f0ffffffffffffffd6fffffffffffff9f20000000000000042*v;z7+=0xffffffffffffff7efffffffffffffced0000000000000001ffffffffffffff49*v;} v=h[16];if(v!=0){z6+=0x0000000000000151000000000000007200000000000000eeffffffffffffffda*v;z7+=0xffffffffffffff9a000000000000005effffffffffffff6e000000000000007b*v;} v=h[17];if(v!=0){z6+=0x000000000000000cffffffffffffff64ffffffffffffff81ffffffffffffffea*v;z7+=0xffffffffffffff5600000000000001950000000000000107fffffffffffffeb1*v;} v=h[18];if(v!=0){z6+=0x000000000000018cffffffffffffff44fffffffffffffb1cffffffffffffffac*v;z7+=0xffffffffffffffd0000000000000053effffffffffffffa70000000000000026*v;} v=h[19];if(v!=0){z6+=0x000000000000004a0000000000000018ffffffffffffffaf0000000000000039*v;z7+=0x0000000000000096ffffffffffffff8e0000000000000001fffffffffffffff3*v;} v=h[20];if(v!=0){z6+=0x0000000000000060ffffffffffffffec0000000000000209ffffffffffffff51*v;z7+=0x000000000000004ffffffffffffffdf7ffffffffffffff77fffffffffffffff0*v;} v=h[21];if(v!=0){z6+=0xffffffffffffffdeffffffffffffffaeffffffffffffff2b000000000000000d*v;z7+=0xffffffffffffff7fffffffffffffffb9fffffffffffffef6fffffffffffffff1*v;} v=h[22];if(v!=0){z6+=0xffffffffffffff45000000000000003600000000000000d60000000000000091*v;z7+=0xffffffffffffffe5ffffffffffffff5f000000000000005b0000000000000070*v;} v=h[23];if(v!=0){z6+=0x000000000000009100000000000000d5ffffffffffffff2f00000000000000a0*v;z7+=0x0000000000000091000000000000018c0000000000000046000000000000004b*v;} v=h[24];if(v!=0){z6+=0xffffffffffffffc6ffffffffffffff76000000000000002500000000000000ab*v;z7+=0xfffffffffffffff6ffffffffffffff91000000000000001bffffffffffffff01*v;} v=h[25];if(v!=0){z6+=0x0000000000000055ffffffffffffff7bffffffffffffff4effffffffffffff59*v;z7+=0xffffffffffffffda00000000000000a7ffffffffffffff6d0000000000000138*v;} v=h[26];if(v!=0){z6+=0x000000000000010300000000000000c5ffffffffffffff46000000000000002a*v;z7+=0x0000000000000016fffffffffffffe78ffffffffffffffe4000000000000004a*v;} v=h[27];if(v!=0){z6+=0xffffffffffffffc3ffffffffffffffc40000000000000035ffffffffffffff6e*v;z7+=0xffffffffffffffdf0000000000000042fffffffffffffefcfffffffffffffe33*v;} v=h[28];if(v!=0){z6+=0xffffffffffffff760000000000000055fffffffffffffdd7000000000000009a*v;z7+=0xffffffffffffff9cffffffffffffff6b000000000000002effffffffffffff92*v;} v=h[29];if(v!=0){z6+=0xfffffffffffffff600000000000000c7ffffffffffffffc2ffffffffffffffe9*v;z7+=0x000000000000001c0000000000000176fffffffffffffe410000000000000123*v;} v=h[30];if(v!=0){z6+=0x000000000000009a00000000000000840000000000000019000000000000001f*v;z7+=0xffffffffffffff97000000000000004e00000000000000200000000000000019*v;} v=h[31];if(v!=0){z6+=0xfffffffffffffffe0000000000000039ffffffffffffff4c000000000000009b*v;z7+=0xffffffffffffffc500000000000000c300000000000000f7000000000000007a*v;} Z[6]=z6;Z[7]=z7; } } function net(int256 x0,int256 x1,int256 x2) internal pure returns(int256 o){ unchecked { uint256[32] memory h=unpack(l0(uint256(x0),uint256(x1),uint256(x2)),12); uint256[8] memory Z;l1a(h,Z);l1b(h,Z);l1c(h,Z);l1d(h,Z);h=unpack(Z,10); uint256 c=0x000000000000000000000000000000000000000000000000000000000049a2b5;o=int256(int32(uint32(c)));uint256 A=0xfdd5faa709440342061e0ff1f459fa920068e66d07d30259fbcb056cf36f1000;uint256 B=0x029ef90a04790e09046902a8084e00ce0d12032bfb1efa96fd5802b803200293; for(uint256 j=0;j<16;j++){o+=int256(int16(uint16(A>>(16*j))))*int256(h[j])+int256(int16(uint16(B>>(16*j))))*int256(h[j+16]);} o=(o>>12)*6103515625000000; } } function fee(int256 a,int256 w,int256 b) internal pure returns(int256 fb,int256 fa){ unchecked { fb=b> -w?U-exp(-(b+w)/10000):int256(0);fa=a>w?U-exp(-(a-w)/10000):int256(0); fb=clip(fb,0,U/10);fa=clip(fa,0,U/10); } } function rnd(int256 v) internal pure returns(int256){ unchecked {return (v*16384/100+U/2+(int256(1)<<30)*U)/U-(int256(1)<<30);} } function fees(int256 w,int256 r,uint256 ph) internal pure returns(int256,int256){ unchecked { int256 lim=ph==0?30*U:800*U;int256 x0=rnd(clip(w,-800*U,800*U));int256 x1=rnd(clip(r,-lim,lim));int256 x2=int256(ph)*16384; return fee(net(x0,x1,x2),w,net(-x0,-x1,x2)); } } function save(Belief memory b) internal { unchecked { slots[0]=uint256(b.m);slots[1]=uint256(b.v);slots[2]=uint256(b.fb);slots[3]=uint256(b.fa); slots[4]=uint256(b.sp);slots[5]=uint256(b.r);slots[6]=b.t;slots[7]=b.cnt; } } function afterInitialize(uint256 x,uint256 y) external override returns(uint256,uint256){ unchecked { Belief memory b; b.sp=int256(y*1e18/x);b.r=b.sp;b.m=ln(b.sp); b.fb=2870627705508484;b.fa=2870627705508484;save(b);return(uint256(b.fb),uint256(b.fa)); } } struct Work {int256 lo;int256 hi;int256 m;int256 v;int256 lp;int256 la;int256 Z;int256 mt;int256 vt;int256 d;int256 pi;} function update(Belief memory b,int256 s,bool buy,uint256 dt) internal pure returns(bool arb){ unchecked { Work memory q; q.lo=ln(mul(b.sp,U-b.fb));q.hi=ln(divi(b.sp,U-b.fa));q.m=b.m;q.v=b.v; uint256 n=dt-1;if(n>12)n=12; for(uint256 i=0;i0?divi(q.la,q.la+lr):int256(0);arb=q.pi>U/2; if(q.pi>5e15&&q.pi<995e15){ b.m=mul(q.pi,q.lp)+mul(U-q.pi,q.mt); b.v=mul(q.pi,mul(q.lp-b.m,q.lp-b.m))+mul(U-q.pi,q.vt+mul(q.mt-b.m,q.mt-b.m)); }else if(arb){b.m=q.lp;b.v=0;}else{b.m=q.mt;b.v=q.vt;} int256 pe=exp(b.m);b.r=clip(b.r,mul(pe,997e15),divi(pe,997e15));b.cnt=0; } } function afterSwap(TradeInfo calldata t) external override returns(uint256,uint256){ unchecked { Belief memory b=Belief(int256(slots[0]),int256(slots[1]),int256(slots[2]),int256(slots[3]),int256(slots[4]),int256(slots[5]),slots[6],slots[7]); 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); 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.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.sp=s;b.t=t.timestamp;save(b); return(uint256(b.fb),uint256(b.fa)); } } } ``` ## Python reference (netref.py; filter imported from port-3's standalone.py `Coarse`, published in the port-3 artifact) ```python """Fixed-net (4-32-32-1 int16) policy reference on Taylor's (gtmcknight) Gaussian plain filter. Standard library only. Filter = port-3 standalone.Coarse (real.py plain, soft=1); only _fees changes. mode 8: net at the 4 grid corners (ask) + 4 reflected corners (bid), Taylor's DPPolicy._fees bilinear. mode 2: net at clamped (w,R,phase) for ask and (-w,-R,phase) for bid. """ import math, struct, sys, os sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'p3')) from standalone import Coarse def load_payload(path=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'payload.bin')): d = open(path, 'rb').read() h = d[0]; assert len(d) == 2*h*h + 18*h + 106 rg = list(struct.unpack_from('<49h', d, 4)) layers = []; at = 102 for k, (ni, no) in enumerate(((4, h), (h, h), (h, 1))): w = struct.unpack_from('<%dh' % (ni*no), d, at); at += 2*ni*no b = struct.unpack_from('<%di' % no, d, at); at += 4*no layers.append(([list(w[j*ni:(j+1)*ni]) for j in range(no)], list(b), d[1+k])) return h, rg, layers H, RG, LAYERS = load_payload() def net_q(x): """x: 4 ints (Q14). Returns final integer z (Q14 of offset/100).""" for k, (W, B, sh) in enumerate(LAYERS): x = [(B[j] + sum(wi*xi for wi, xi in zip(W[j], x))) >> sh for j in range(len(B))] if k < 2: x = [v if v > 0 else 0 for v in x] return x[0] def q14(v): # nearest-even of 16384*v/100 for float v (bps) return round(v*16384/100) def net_bps(w, r, ph): return net_q([q14(w), q14(r), ph*16384, 0])*100/16384 def net_grid(i, j, ph): # integer grid coordinates exactly as the decoder forms them w = (i-160)*5; r = (j*5-30) if ph == 0 else RG[j]*5 return net_q([round(16384*w/100), round(16384*r/100), ph*16384, 0])*100/16384 class NetPolicy(Coarse): def __init__(self, mode=2): self.mode = mode self.m = math.log(100); self.v = 0.; self.tlast = 0; self.cnt = 0; self.s2h = 100.; self.fb = self.fa = .003; self.sp = 100. def _fees(self, w, r, ph): if self.mode == 2: wc = max(-800., min(800., w)); lim = 30. if ph == 0 else 800.; rc = max(-lim, min(lim, r)) a = net_bps(wc, rc, ph); b = net_bps(-wc, -rc, ph) else: pw = max(0., min(320., w/5 + 160)); i = min(int(pw), 319); f = pw - i if ph == 0: p2 = max(-6., min(6., r/5)) + 6; n2 = 13 else: v = r/5; W = RG; n2 = 49 if v <= W[0]: p2 = 0. elif v >= W[48]: p2 = 48. else: lo, hi = 0, 48 while hi-lo > 1: mid = (lo+hi)//2 if W[mid] <= v: lo = mid else: hi = mid p2 = lo + (v-W[lo])/(W[hi]-W[lo]) j = min(int(p2), n2-2); g = p2 - j A = lambda a, b: net_grid(a, b, ph) Bf = lambda a, b: net_grid(320-a, n2-1-b, ph) a = (A(i, j)*(1-f) + A(i+1, j)*f)*(1-g) + (A(i, j+1)*(1-f) + A(i+1, j+1)*f)*g b = (Bf(i, j)*(1-f) + Bf(i+1, j)*f)*(1-g) + (Bf(i, j+1)*(1-f) + Bf(i+1, j+1)*f)*g fa = min(.1, 1-math.exp(-(a-w)*1e-4)) if a > w else 0. fb = min(.1, 1-math.exp(-(b+w)*1e-4)) if b > -w else 0. return fb, fa class Net8(NetPolicy): def __init__(self): super().__init__(8) class Net2(NetPolicy): def __init__(self): super().__init__(2) ``` ## Generator (gen.py; reads port-3 Strategy.sol and payload.bin, writes the contract; `python gen.py 2 S2.sol`) ```python """Generate Strategy.sol (mode 2 or 8) from port-3's Strategy.sol and the fixed-net payload.""" import sys, re, math from decimal import Decimal, getcontext import netref as N getcontext().prec = 60 mode = int(sys.argv[1]); out = sys.argv[2] src = open('../p3/Strategy.sol').read() M256 = 1 << 256 def hx(v): return '0x%064x' % (v % M256) def simd(vals): # 4 signed values -> sum v_m 2^(64m) mod 2^256 return sum(v << (64*m) for m, v in enumerate(vals)) % M256 def lanes16(vals): # up to 16 int16 in 16-bit two's complement lanes return sum((v & 0xffff) << (16*m) for m, v in enumerate(vals)) (W0, B0, S0), (W1, B1, S1), (W2, B2, S2) = N.LAYERS OFF = 1 << 63 words = {} for k in range(8): words['B0_%d' % k] = simd([B0[4*k+m] + OFF for m in range(4)]) words['B1_%d' % k] = simd([B1[4*k+m] + OFF for m in range(4)]) for i in range(3): words['P%d_%d' % (i, k)] = simd([W0[4*k+m][i] for m in range(4)]) for i in range(32): words['C%d_%d' % (i, k)] = simd([W1[4*k+m][i] for m in range(4)]) words['L2A'] = lanes16([W2[0][j] for j in range(16)]) words['L2B'] = lanes16([W2[0][j] for j in range(16, 32)]) words['L2C'] = B2[0] % (1 << 32) for q in range(4): words['RG%d' % q] = lanes16(N.RG[16*q:16*q+16]) L = [] L.append(' uint256 constant OFF=%d;' % OFF) L.append(' uint256 constant M64=0xffffffffffffffff;') # layer 0 L.append(' function l0(uint256 a,uint256 b,uint256 c) internal pure returns(uint256[8] memory Z){ unchecked {') for k in range(8): L.append(' Z[%d]=%s+%s*a+%s*b+%s*c;' % (k, hx(words['B0_%d' % k]), hx(words['P0_%d' % k]), hx(words['P1_%d' % k]), hx(words['P2_%d' % k]))) L.append(' } }') L.append(' function unpack(uint256[8] memory Z,uint256 sh) internal pure returns(uint256[32] memory h){ unchecked {') L.append(' for(uint256 j=0;j<32;j++){int256 v=(int256((Z[j>>2]>>((j&3)*64))&M64)-int256(OFF))>>sh;'.replace('int256((Z[j>>2]>>((j&3)*64))&M64)','int256(Z[j>>2]>>((j&3)*64)&M64)') + 'if(v>0)h[j]=uint256(v);}') L.append(' } }') for half in range(4): L.append(' function l1%s(uint256[32] memory h,uint256[8] memory Z) internal pure { unchecked {' % 'abcd'[half]) ks = range(2*half, 2*half+2) L.append(' ' + ''.join('uint256 z%d=%s;' % (k, hx(words['B1_%d' % k])) for k in ks) + 'uint256 v;') for i in range(32): L.append(' v=h[%d];if(v!=0){' % i + ''.join('z%d+=%s*v;' % (k, hx(words['C%d_%d' % (i, k)])) for k in ks) + '}') L.append(' ' + ''.join('Z[%d]=z%d;' % (k, k) for k in ks)) L.append(' } }') L.append(' function net(int256 x0,int256 x1,int256 x2) internal pure returns(int256 o){ unchecked {') L.append(' uint256[32] memory h=unpack(l0(uint256(x0),uint256(x1),uint256(x2)),%d);' % S0) L.append(' uint256[8] memory Z;l1a(h,Z);l1b(h,Z);l1c(h,Z);l1d(h,Z);h=unpack(Z,%d);' % S1) L.append(' uint256 c=%s;o=int256(int32(uint32(c)));uint256 A=%s;uint256 B=%s;' % (hx(words['L2C']), hx(words['L2A']), hx(words['L2B']))) L.append(' for(uint256 j=0;j<16;j++){o+=int256(int16(uint16(A>>(16*j))))*int256(h[j])+int256(int16(uint16(B>>(16*j))))*int256(h[j+16]);}') L.append(' o=(o>>%d)*6103515625000000;' % S2) # offset in WAD bps L.append(' } }') L.append(' function fee(int256 a,int256 w,int256 b) internal pure returns(int256 fb,int256 fa){ unchecked {') L.append(' fb=b> -w?U-exp(-(b+w)/10000):int256(0);fa=a>w?U-exp(-(a-w)/10000):int256(0);') L.append(' fb=clip(fb,0,U/10);fa=clip(fa,0,U/10);') L.append(' } }') if mode == 2: L.append(' function rnd(int256 v) internal pure returns(int256){ unchecked {return (v*16384/100+U/2+(int256(1)<<30)*U)/U-(int256(1)<<30);} }') L.append(' function fees(int256 w,int256 r,uint256 ph) internal pure returns(int256,int256){ unchecked {') L.append(' int256 lim=ph==0?30*U:800*U;int256 x0=rnd(clip(w,-800*U,800*U));int256 x1=rnd(clip(r,-lim,lim));int256 x2=int256(ph)*16384;') L.append(' return fee(net(x0,x1,x2),w,net(-x0,-x1,x2));') L.append(' } }') else: L.append(' function q(int256 b) internal pure returns(int256){ unchecked {return (8192*b+25+50*(int256(1)<<30))/50-(int256(1)<<30);} }') L.append(' function rk(uint256 j) internal pure returns(int256){ unchecked {uint256 x=j<16?%s:j<32?%s:j<48?%s:%s;return int256(int16(uint16(x>>((j&15)*16))))*5;} }' % tuple(hx(words['RG%d' % q]) for q in range(4))) L.append(' function col(uint256 j,uint256 ph) internal pure returns(int256){ unchecked {return ph==0?int256(j)*5-30:rk(j);} }') L.append(' function bil(uint256 i,uint256 j,int256 f,int256 g,uint256 ph,int256 s) internal pure returns(int256){ unchecked {') L.append(' int256 x2=int256(ph)*16384;int256 w0=s*q((int256(i)-160)*5);int256 w1=s*q((int256(i)-159)*5);int256 r0=s*q(col(j,ph));int256 r1=s*q(col(j+1,ph));') L.append(' int256 l=mul(net(w0,r0,x2),U-f)+mul(net(w1,r0,x2),f);int256 h=mul(net(w0,r1,x2),U-f)+mul(net(w1,r1,x2),f);') L.append(' return mul(l,U-g)+mul(h,g);') L.append(' } }') L.append(' function fees(int256 w,int256 r,uint256 ph) internal pure returns(int256,int256){ unchecked {') L.append(' int256 p=clip(w/5+160*U,0,320*U);uint256 i=uint256(p/U);if(i>319)i=319;int256 f=p-int256(i)*U;uint256 j;int256 g;') L.append(' if(ph==0){p=clip(r/5,-6*U,6*U)+6*U;j=uint256(p/U);if(j>11)j=11;g=p-int256(j)*U;}') L.append(' else{r=clip(r,-800*U,800*U);uint256 hi=48;while(hi-j>1){uint256 mid=(j+hi)/2;if(rk(mid)*U<=r)j=mid;else hi=mid;}g=divi(r-rk(j)*U,(rk(hi)-rk(j))*U);}') L.append(' return fee(bil(i,j,f,g,ph,1),w,bil(i,j,f,g,ph,-1));') L.append(' } }') body = '\n'.join(L) + '\n' # init fee constant a = N.net_bps(0, 0, 0) init = int((1 - Decimal(-a*1e-4).exp())*Decimal(10**18) + Decimal('0.5')) s = src s = re.sub(r' bytes constant TABLE=hex"[0-9a-f]+";\n', '', s) s = re.sub(r' function knot\(.*?(?= function save)', lambda m: body, s, flags=re.S) s = s.replace('2821013442392051', str(init)) s = s.replace('"TaylorGaussianPlainCoarse"', '"TaylorGaussianPlainNet%d"' % mode) hdr_old = s[s.index('// Gaussian solved'):s.index('contract Strategy')] hdr = ('// Gaussian solved policy by Taylor (gtmcknight), amm-sim 4812a638; filter ported from port-3.\n' '// Offsets: fixed-net 4-32-32-1 int16 MLP (payload sha256 9727ecc8...), integer forward pass,\n' '// shifts 12,10,12, Q14 activations, arithmetic-shift floor. %s\n' '// Model data: PUSH32 immediates (33-byte blocks); hidden layers as 4x64-bit lanes per word,\n' '// lane = bias + 2^63 + sum(w*x), exact mod 2^256.\n' '// Taylor source: https://github.com/gtmcknight/amm-sim/tree/4812a6382311624e1506aca131ca35c378f930d9/research/solved\n' % ('2 passes: ask net(w,R,phase), bid net(-w,-R,phase), inputs clamped to the grid.' if mode == 2 else '8 passes: net at the 4 grid corners (ask) and 4 reflected corners (bid), Taylor bilinear.')) s = s.replace(hdr_old, hdr) open(out, 'w').write(s) print('init', init, 'bytes', len(s)) ```