memoscan
← all memos

Memo 0x34895439…58b5f4 on Ethereum

0x68575b07…67c7·#25,913,369·view on Etherscan
t(":"); if(p.length!==5||p[0]!=="v1")continue; const other=p[1]==="0"?ZERO:p[1]; const hooks=p[4]==="0"?ZERO:p[4]; if(!/^0x[0-9a-f]{40}$/i.test(other)||!/^0x[0-9a-f]{40}$/i.test(hooks))continue; if(!/^\d{1,7}$/.test(p[2])||!/^\d{1,7}$/.test(p[3]))continue; const fee=Number(p[2]),ts=Number(p[3]); if(!Number.isInteger(fee)||!Number.isInteger(ts)||ts<1)continue; if(other.toLowerCase()===tokenAddr.toLowerCase())continue; const a=tokenAddr.toLowerCase(),b=other.toLowerCase(); const zeroFirst=BigInt(a)<BigInt(b); out.push({c0:zeroFirst?tokenAddr:other,c1:zeroFirst?other:tokenAddr,fee,ts,hooks}); if(out.length===8)break; } return out; } function v4PoolsFor(f,t){ const fa=f.addr.toLowerCase(),ta=t.addr.toLowerCase(); const seen=new Set(),out=[]; for(const tok of [f,t])for(const p of (tok.v4||[])){ const c0=p.c0.toLowerCase(),c1=p.c1.toLowerCase(); if(!((c0===fa&&c1===ta)||(c0===ta&&c1===fa)))continue; const id=`${c0}:${c1}:${p.fee}:${p.ts}:${p.hooks.toLowerCase()}`; if(seen.has(id))continue; seen.add(id); out.push({...p,zeroForOne:c0===fa}); } return out; } const encPoolKey=p=>encAddr(p.c0)+encAddr(p.c1)+encUint(p.fee)+encUint(p.ts)+encAddr(p.hooks); const SEL_QUOTE_BEST="2adaa389",SEL_EFFFEE="ef66de32"; let PROUTE=MB.pr; const SEL_PROUTE="5d6498e1",SEL_PCHECKPOINT="0b7c6c6c"; const SEL_PROUTEWETH="78fd78b0"; const SEL_ZAPIN="c98c2c0b"; const SEL_PREVIEW_ZAP="e7cddab0"; const encPRouteWeth=(pools,tokenOut,amountIn,minOut,to)=> "0x"+SEL_PROUTEWETH+encUint(160)+encAddr(tokenOut)+encUint(amountIn) +encUint(minOut)+encAddr(to)+encUint(pools.length)+pools.map(encAddr).join(""); const encPRoute=(pools,tokenIn,tokenOut,amountIn,minOut,to)=> "0x"+SEL_PROUTE+encUint(192)+encAddr(tokenIn)+encAddr(tokenOut)+encUint(amountIn) +encUint(minOut)+encAddr(to)+encUint(BigInt(pools.length))+pools.map(encAddr).join(""); const SEL_PAIR_COUNT="355da246"; const PPOLICY="0x00000045fc7b570Be4d71F67219508ebD295EC6D"; const SEL_ROUTABLE="9662c498",SEL_QUOTE_ALL="89941805"; const LQ_SCAN=128; const LQ_SHOW=24; const isEthLike=a=>a===ZERO||a.toLowerCase()===WETH.toLowerCase(); async function quotePrecision(f,t,amountIn,sender,block){ if(PPLENS===ZERO||PROUTE===ZERO||amountIn<=0n)return null; const nat=a=>a.toLowerCase()===WETH.toLowerCase()?ZERO:a; const vars=[]; const addVar=(a,b)=>{ const [x,y]=a.toLowerCase()<b.toLowerCase()?[a,b]:[b,a]; if(!vars.some(v=>v.c0===x&&v.c1===y&&v.tokenIn===a))vars.push({c0:x,c1:y,tokenIn:a}); }; const forms=a=>a===ZERO?[ZERO,WETH] :a.toLowerCase()===WETH.toLowerCase()?[WETH,ZERO]:[a]; for(const a of forms(f.addr))for(const b of forms(t.addr)){ if(nat(a)===nat(b))continue; addVar(a,b); } const reqs=[]; for(const v of vars)reqs.push( {to:PPLENS,data:"0x"+SEL_QUOTE_BEST+encAddr(v.c0)+encAddr(v.c1) +encAddr(sender)+encAddr(v.tokenIn)+encUint(amountIn)+encUint(0n)+encUint(BigInt(LQ_SCAN))}, {to:PFACTORY,data:"0x"+SEL_PAIR_COUNT+encAddr(v.c0)+encAddr(v.c1)}); const res=await mc3Deep(reqs,block); let pool="",out=0n,n=0,fA=f.addr,won=null; for(let i=0;i<vars.length;i++){ const q=res[i*2],c=res[i*2+1]; const b=decBest(q); if(!b)continue; if(b.out<=out)continue; pool=b.pool;out=b.out;fA=vars[i].tokenIn;won=vars[i]; try{n=c?Number(BigInt(c)):0}catch{n=0} } if(!pool||!won)return await hubHop(f,t,amountIn,sender,block); const tA=won.c0===fA?won.c1:won.c0; let fee=0n; const feeReq=p=>({to:PPLENS, data:"0x"+SEL_EFFFEE+encAddr(p)+encAddr(sender)+encAddr(fA)+encUint(amountIn)}); const [fx,rt]=await mc3Deep([feeReq(pool),routableReq([pool])],block); if(policyRefuses(rt,1)){ const alt=await bestRoutable(won.c0,won.c1,fA,amountIn,sender,block); if(!alt)return await hubHop(f,t,amountIn,sender,block); pool=alt.pool;out=alt.out; const [fx2]=await mc3Deep([feeReq(pool)],block); if(fx2)fee=BigInt(fx2); }else if(fx)fee=BigInt(fx); return {pools:[pool],out,fee,capped:n>LQ_SCAN,tokenIn:fA,tokenOut:tA, unwrap:fA===ZERO&&f.addr!==ZERO?amountIn:0n, wrap:fA!==ZERO&&f.addr===ZERO?amountIn:0n, outDiffers:(tA===ZERO)!==(t.addr===ZERO)}; } const routableReq=pools=>({to:PPOLICY, data:"0x"+SEL_ROUTABLE+encUint(32)+encUint(BigInt(pools.length))+pools.map(encAddr).join("")}); function policyRefuses(raw,n){ if(!raw)return false; const h=strip0x(raw); if(h.length<128+n*64)return false; const len=Number(BigInt("0x"+h.slice(64,128))); if(len!==n)return false; for(let i=0;i<n;i++)if(BigInt("0x"+h.slice(128+i*64,128+(i+1)*64))===0n)return true; return false; } async function bestRoutable(c0,c1,tokenIn,amountIn,sender,block){ const [raw]=await mc3Deep([{to:PPLENS,data:"0x"+SEL_QUOTE_ALL+encAddr(c0)+encAddr(c1) +encAddr(sender)+encAddr(tokenIn)+encUint(amountIn)+encUint(0n)+encUint(BigInt(LQ_SCAN))}],block); const cands=decAll(raw); if(!cands.length)return null; const [rt]=await mc3Deep([routableReq(cands.map(c=>c.pool))],block); if(!rt)return null; const h=strip0x(rt); if(h.length<128+cands.length*64)return null; let win=null; for(let i=0;i<cands.length;i++){ if(BigInt("0x"+h.slice(128+i*64,128+(i+1)*64))===0n)continue; if(!win||cands[i].out>win.out)win=cands[i]; } return win; } function decAll(raw){ if(!raw)return[]; const h=strip0x(raw); if(h.length<128)return[]; const n=Number(BigInt("0x"+h.slice(64,128))); const out=[]; for(let i=0;i<n;i++){ const b=128+i*192; if(h.length<b+192)break; const pool="0x"+h.slice(b+24,b+64),o=BigInt("0x"+h.slice(b+64,b+128)); if(o<=0n||/^0x0{40}$/i.test(pool))continue; out.push({pool,out:o}); } return out; } function decBest(raw){ if(!raw)return null; const h=strip0x(raw); if(h.length<128)return null; const pool="0x"+h.slice(24,64),out=BigInt("0x"+h.slice(64,128)); if(out<=0n||/^0x0{40}$/i.test(pool))return null; return {pool,out}; } async function hubHop(f,t,amountIn,sender,block){ if(isEthLike(f.addr)||isEthLike(t.addr))return null; const enc=(a,b,tokenIn,amt)=>{ const [c0,c1]=a.toLowerCase()<b.toLowerCase()?[a,b]:[b,a]; return [{to:PPLENS,data:"0x"+SEL_QUOTE_BEST+encAddr(c0)+encAddr(c1) +encAddr(sender)+encAddr(tokenIn)+encUint(amt)+encUint(0n)+encUint(BigInt(LQ_SCAN))}, {to:PFACTORY,data:"0x"+SEL_PAIR_COUNT+encAddr(c0)+encAddr(c1)}]}; const count=raw=>{try{return raw?Number(BigInt(raw)):0}catch{return 0}}; const hubs=[ZERO,WETH]; const legs=[]; const first=await mc3Deep(hubs.flatMap(h=>enc(f.addr,h,f.addr,amountIn)),block); for(let i=0;i<hubs.length;i++){ const b=decBest(first[i*2]); if(b)legs.push({hub:hubs[i],pool:b.pool,mid:b.out,n:count(first[i*2+1])}); } if(!legs.length)return null; const second=await mc3Deep(legs.flatMap(l=>enc(l.hub,t.addr,l.hub,l.mid)),block); let win=null; for(let i=0;i<legs.length;i++){ const b=decBest(second[i*2]); if(!b||(win&&b.out<=win.out))continue; win={pools:[legs[i].pool,b.pool],out:b.out,mid:legs[i].mid,hub:legs[i].hub, n:Math.max(legs[i].n,count(second[i*2+1]))}; } if(!win)return null; let fee=0n; const [a,b,rt]=await mc3Deep([ {to:PPLENS,data:"0x"+SEL_EFFFEE+encAddr(win.pools[0])+encAddr(sender)+encAddr(f.addr)+encUint(amountIn)}, {to:PPLENS,data:"0x"+SEL_EFFFEE+encAddr(win.pools[1])+encAddr(sender)+encAddr(win.hub)+encUint(win.mid)}, routableReq(win.pools), ],block); if(policyRefuses(rt,win.pools.length))return null; const fa=a?BigInt(a):0n,fb=b?BigInt(b):0n; fee=fa+fb-(fa*fb)/1000000n; return {pools:win.pools,out:win.out,fee,capped:win.n>LQ_SCAN, tokenIn:f.addr,tokenOut:t.addr,unwrap:0n,wrap:0n,outDiffers:false}; } const QPAIR=2; const SEL_BBS="e7798987"; const HUBS=()=>[WETH,...NUMERAIRES,"0x2260fac5e5542a773aa44fbcfedf7c193bc2c599","0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0"]; async function hubRoute(f,t,amt,sb,dl,to,rf,block){ const nf=(f.addr===ZERO?WETH:f.addr).toLowerCase(),nt=(t.addr===ZERO?WETH:t.addr).toLowerCase(); const H=HUBS().filter(h=>h.toLowerCase()!==nf&&h.toLowerCase()!==nt); if(!H.length)return null; const E=(x,i,o,n)=>({to:ZQUOTER,data:"0x"+SEL_BBS+encAddr(x)+encBool(false)+encAddr(i)+encAddr(o)+encUint(n)+encUint(sb)+encUint(dl)}); const D=h=>{try{return decQ(h,sb,false,0,4,0,6)}catch{return null}}; const L=[],r1=await mc3Deep(H.map(h=>E(ZROUTER,f.addr,h,amt)),block); for(let i=0;i<H.length;i++){const a=r1[i]&&D(r1[i]);if(a&&a.amountLimit>0n)L.push({h:H[i],a})} if(!L.length)return null; const r2=await mc3Deep(L.map(x=>E(to,x.h,t.addr,x.a.amountLimit)),block); let B=null; for(let i=0;i<L.length;i++){const b=r2[i]&&D(r2[i]); if(b&&b.best.amountOut>0n&&(!B||b.best.amountOut>B.b.best.amountOut))B={...L[i],b}} if(!B)return null; const c=[B.a.callData,B.b.callData,encSweep(B.h,0n,rf),encSweep(ZERO,0n,rf)]; const ha=B.a.best.feeBps||0n,hb=B.b.best.feeBps||0n; return{best:{source:B.b.best.source,feeBps:ha+hb-ha*hb/10000n,amountIn:amt,amountOut:B.b.best.amountOut}, callData:encCalls(c),amountLimit:B.b.amountLimit, msgValue:f.addr===ZERO?amt:0n,spender:f.addr===ZERO?null:ZROUTER}; } async function quoteV4Pools(f,t,amountIn,block){ const pools=v4PoolsFor(f,t); if(!pools.length||amountIn<=0n||V4LENS===ZERO||V4PORT===ZERO)return null; const rs=(await mc3Deep(pools.map(p=>({to:V4LENS, data:"0x"+SEL_V4QUOTE+encBool(false)+encAddr(f.addr)+encAddr(t.addr) +encUint(p.fee)+encUint(p.ts)+encAddr(p.hooks)+encUint(amountIn)})),block)) .map(h=>{try{const x=strip0x(h||"");return x.length>=128?BigInt("0x"+x.slice(64,128)):0n}catch{return 0n}}); let best=null; for(let i=0;i<pools.length;i++)if(rs[i]>0n&&(!best||rs[i]>best.amountOut)) best={pool:pools[i],amountIn,amountOut:rs[i]}; return best; } const setListNote=t=>{ const el=document.getElementById("listNote"); if(!el)return; el.textContent=t||""; if(t&&/\u2026$/.test(t)){const s=document.createElement("span");s.className="spin";el.appendChild(s)} el.classList.toggle("hide",!t)}; const setListSource=w=>setListNote(w?"Built-in token list — "+w:""); let rankFellBack=false,listLive=false; const rankedIds=async()=>{ rankFellBack=false; try{ const ids=decUintArr(await cfgRead(C,[{to:ZLISTLENS,data:"0x"+SEL_RANKEDIDS},L])); if(ids.length)return ids; }catch{} try{ const ids=decUintArr(await cfgRead(C,[{to:TOKENLIST,data:"0x"+SEL_RANKEDIDS},L])); if(ids.length)rankFellBack=true; return ids; }catch{return[]} }; const KEEP="zswap:deep"; const stickyPools=()=>{try{ return JSON.parse(LS[KEEP]||"[]").filter(x=>/^0x[0-9a-f]{40}$/i.test(x)).slice(0,LAUNCH_SHOW); }catch{return[]}}; let listJob=null,listGen=0; const loadTokenList=()=>{if(listJob)return listJob;const g=++listGen; return listJob=loadTokenListRun().finally(()=>{if(!listLive&&g===listGen)listJob=null})}; async function loadTokenListRun(){ const cid=CHAIN_ID; if(TOKENLIST===ZERO)return setListSource("registry address not set"); setListNote("Built-in token list \u2014 checking zList\u2026"); try{ const cntJob=PLAUNCH===ZERO?Promise.resolve("0x0"):rpc(C,[{to:PFACTORY,data:"0x"+SEL_BYCREATOR_N+encAddr(PLAUNCH)},L]); cntJob.catch(()=>{}); const ids=await rankedIds(); if(!ids.length)return setListSource("registry is empty"); const raw=await cfgBatch(ids.slice(0,64).map(id=>({to:TOKENLIST,data:"0x"+SEL_JSON+encUint(id)}))); const rows=raw.map(h=>{try{return h?decStr(h):null}catch{return null}}); const next=[]; for(const row of rows){ if(!row)continue; let t;try{t=JSON.parse(row)}catch{continue} if(t.k!=="eip155"||+t.c!==CHAIN_ID)continue; const std=t.p==="Native"||t.p==="ERC-20"?"ft":t.p==="ERC-721"?"nft":""; if(!std)continue; if(!/^0x[0-9a-f]{40}$/i.test(t.a||""))continue; if(!Number.isInteger(t.d)||t.d<0||t.d>36)continue; if(next.some(x=>x.addr.toLowerCase()===t.a.toLowerCase()))continue; const sym=safeSym(t.s).slice(0,12); const logo=safeDataUrl(t.l); next.push({sym,addr:t.a.toLowerCase(),dec:t.d,std,icon:logo?`<img src="${logo}" width="20" height="20" alt="">`:genIcon(sym), name:String(t.n??"").slice(0,64),desc:String(t.desc??"").slice(0,240), v4:parseV4Pools(t.e,t.a)}); } next.sort((a,b)=>(a.std==="nft")-(b.std==="nft")); if(!next.some(t=>t.std==="ft"))return setListSource("registry returned nothing swappable"); const mine=TOKENS.filter(t=>t.cust&&!next.some(x=>x.addr===t.addr.toLowerCase())); let born=[]; LAUNCHED.length=0; try{ const cnt=Number(BigInt(await cntJob||"0x0")); const take=Math.min(cnt,LAUNCH_SCAN); const raw=take?await rpc(C,[{to:PFACTORY,data:"0x"+SEL_BYCREATOR+encAddr(PLAUNCH)+encUint(BigInt(cnt-take))+encUint(BigInt(take))},L]):"0x"; const h=strip0x(raw||""),n=h.length>=128?Number(BigInt("0x"+h.slice(64,128)||"0")):0; let pools=[]; for(let i=0;i<n&&i<take;i++)pools.push("0x"+h.slice(128+i*64+24,128+(i+1)*64)); const fresh=new Set(pools.map(x=>x.toLowerCase())); const carried=stickyPools().filter(x=>!fresh.has(x.toLowerCase())); if(carried.length){ const fr=await mc3Deep(carried.map(a=>({to:a,data:"0x"+SEL_FEERECIP}))); carried.forEach((x,i)=>{let a="";try{a=("0x"+strip0x(fr[i]||"").slice(24)).toLowerCase()}catch{} if(a===PLAUNCH.toLowerCase())pools.push(x)}); } if(pools.length){ const depth=await mc3Deep(pools.map(a=>[{to:a,data:"0x"+SEL_RESERVE0}]).flat()); const byDepth=pools.map((p,i)=>{let d=0n;try{d=BigInt(depth[i]||"0x0")}catch{}return{p,d}}) .sort((x,y)=>x.d===y.d?0:(x.d<y.d?1:-1)).slice(0,LAUNCH_SHOW); pools=byDepth.map(x=>x.p); try{LS[KEEP]=JSON.stringify(byDepth.filter(x=>x.d>0n).map(x=>x.p))}catch{} const meta=await mc3Deep(pools.flatMap(a=>[{to:a,data:"0x"+SEL_TOKEN1}])); const toks=[]; meta.forEach((x,i)=>{const a=x?("0x"+strip0x(x).slice(24)).toLowerCase():""; if(/^0x[0-9a-f]{40}$/.test(a))toks.push({a,pi:i})}); const seen=new Set(next.map(x=>x.addr.toLowerCase())); const info=await mc3Deep(toks.flatMap(({a})=>[{to:a,data:"0x95d89b41"},{to:a,data:"0x"+SEL_CONTRACTURI}, {to:PLAUNCH,data:"0x"+SEL_CREATOROF+encAddr(a)}])); const taken=new Set(next.map(x=>x.sym.toLowerCase()).concat(BUILTIN.filter(b=>b.addr===ZERO||b.addr===WETH).map(x=>x.sym.toLowerCase()))); toks.forEach(({a,pi},i)=>{ if(seen.has(a))return; seen.add(a); let sym="?";try{sym=safeSym(decodeString(info[i*3]||"0x").trim()).slice(0,12)}catch{} if(!sym||sym==="?")return; if(taken.has(sym.toLowerCase()))sym+=" "+a.slice(0,6)+"…";else taken.add(sym.toLowerCase()); let art="";try{art=imgFromContractURI(decodeString(info[i*3+1]||"0x"))}catch{} if(art)logoCache[a]=art; const dep=byDepth[pi]?byDepth[pi].d:0n; let by="";try{const c="0x"+strip0x(info[i*3+2]||"").slice(24);if(/^0x[0-9a-f]{40}$/i.test(c)&&!/^0x0{40}$/i.test(c))by=short(c)}catch{} const desc=[dep>0n?`${(+formatUnits(dep,18)).toFixed(dep<10n**16n?5:3)} ETH liquidity`:"no liquidity yet", by?`by ${by}`:""].filter(Boolean).join(" \u00b7 "); born.push({sym,addr:a,dec:18,std:"ft",name:"",desc,launched:1,dep, icon:art?`<img width="20" height="20" style="border-radius:50%;object-fit:cover" src="${art}" alt="">`:genIcon(sym)}); LAUNCHED.push({addr:a,sym,pool:pools[pi]||""}); }); } }catch{} if(cid!==CHAIN_ID)return; const anchors=BUILTIN.filter(b=>(b.addr===ZERO||b.addr===WETH)&&!next.some(x=>x.addr===b.addr)); const bornAt=new Set(born.map(x=>x.addr.toLowerCase())); TOKENS.splice(0,TOKENS.length,...next,...anchors,...born, ...mine.filter(t=>!bornAt.has(t.addr.toLowerCase()))); listLive=true; setListNote(rankFellBack?"Ranked by listing order — conviction unavailable":""); }catch(e){setListSource("could not be reached")} } const strip0x=h=>h.startsWith("0x")?h.slice(2):h; const pad32=h=>{const x=strip0x(h); if(x.length>64)throw Error("ABI word overflow"); return x.padStart(64,"0")}; const encUint=v=>{const b=BigInt(v); if(b<0n||b>=(1n<<256n))throw Error("uint256 out of range"); return pad32(b.toString(16))}; const encAddr=a=>{const x=strip0x(a||ZERO).toLowerCase(); if(!/^[0-9a-f]{40}$/.test(x))throw Error("not an address"); return pad32(x)}; const isAddr=a=>/^0x[0-9a-fA-F]{40}$/.test(a||""); const decStr=hex=>{const h=strip0x(hex);const n=parseInt(h.slice(64,128),16); return new TextDecoder().decode(hexToBytes(h.slice(128,128+n*2)))}; const decUintArr=hex=>{const h=strip0x(hex);const n=parseInt(h.slice(64,128),16);const o=[]; for(let i=0;i<n;i++)o.push(BigInt("0x"+h.slice(128+i*64,192+i*64)));return o}; const encBool=b=>pad32(b?"1":"0"); const toHex=v=>"0x"+BigInt(v).toString(16); const parseUnits=(s,dec)=>{ const r=s.trim(); if(r.includes(",")&&!/^\d{1,3}(?:,\d{3})+(?:\.\d*)?$/.test(r)) throw Error(r.indexOf(",")===r.lastIndexOf(",") ?`unclear comma — for decimals write ${r.replace(",",".")}` :"unclear commas — use . for decimals"); const t=r.replace(/,/g,""); if(!/^(?:\d+|\d*\.\d+|\d+\.)$/.test(t))throw Error("invalid amount"); const[ip,fp=""]=t.split("."); if(fp.length>dec)throw Error("too many decimals"); return BigInt((ip||"0")+fp.padEnd(dec,"0")); }; const formatUnits=(v,dec)=>{ if(!dec)return BigInt(v).toString(); v=BigInt(v); const sign=v<0n?"-":""; const s=(v<0n?-v:v).toString().padStart(dec+1,"0"); const ip=sign+s.slice(0,-dec); const fp=s.slice(-dec).replace(/0+$/,""); return fp?`${ip}.${fp}`:ip; }; const trimAmt=(v,dec)=>{const s=formatUnits(v,dec),i=s.indexOf(".");if(i<0)return s;const r=s.slice(0,i+7).replace(/\.?0+$/,"");return r==="0"&&v?s:r}; const sigAmt=(v,dec,sig=6)=>{ const s=formatUnits(v,dec),i=s.indexOf("."); if(i<0||v===0n)return s; const lead=s.slice(0,i).replace(/^0+/,""); if(lead.length)return s.slice(0,i+Math.max(1,sig-lead.length)+1).replace(/\.?0+$/,"")||s.slice(0,i); const frac=s.slice(i+1); let z=0;while(z<frac.length&&frac[z]==="0")z++; const cut=s.slice(0,i+1+z+sig).replace(/0+$/,""); return cut.endsWith(".")?cut.slice(0,-1):cut; }; const maxAmt=(v,dec)=>{v=BigInt(v);if(dec<=6)return formatUnits(v,dec); const u=10n**BigInt(dec-6);return formatUnits((v+u-1n)/u,6)}; const fitFont=el=>{ const l=el.value.length,s=l>18?".9em":l>14?"1.1em":l>10?"1.25em":"1.65em"; if(el.style.fontSize!==s)el.style.fontSize=s; }; const decQ=(hex,slip,eo,u,v,S,mv)=>{ const h=strip0x(hex),num=i=>BigInt("0x"+h.slice(i*64,(i+1)*64)),E=()=>{throw Error("bad quote")}; if(h.length<Math.max(v+2,(mv||v+1)+1)*64)E(); const o=Number(num(v))*2;if(o+64>h.length)E(); const n=Number(BigInt("0x"+h.slice(o,o+64)));if(!n||o+64+n*2>h.length)E(); const g=num(u+3),t=g>0n,k=S?(num(3)>0n?0:u):t?u:0,B=10000n,ai=S?num(2)+num(u+2):num(2),ao=S?num(3)+g:t?g:num(3),q=eo?ai:ao; const src=[];for(let w=0;w<=u;w+=4)if(num(w+2)>0n||num(w+3)>0n)src.push(Number(num(w))); return{best:{source:Number(num(k)),feeBps:num(k+1),amountIn:ai,amountOut:ao},sources:src,callData:"0x"+h.slice(o+64,o+64+n*2),amountLimit:eo?(q*(B+slip)+B-1n)/B:q*(B-slip)/B,msgValue:num(mv||v+1),slipBps:slip}; }; const merge=(est,exe)=>{if(!est)return exe;if(!exe)return null;return{...exe,best:est.best}}; const NO_WALLET="No wallet detected."; let PROV=null; const prov=()=>PROV||window.ethereum; const RPC_SEED=["https://ethereum-rpc.publicnode.com","https://eth-mainnet.public.blastapi.io"]; const RPC_STORE="zswap:rpc"; const rpcPin=()=>{try{const v=localStorage.getItem(RPC_STORE); if(v&&/^https:\/\/\S+$/i.test(v))return v}catch{}return""}; let rpcPool=RPC_SEED.slice(),rpcPi=0,curated=0,curating=0,curatedTry=0; const GAS_FLOOR=3000000000n; const SEL_LIST="d77e4c79"; const decStrArr=h=>{const b=strip0x(h||"");if(b.length<128)return[]; const W=i=>parseInt(b.slice(i*64,i*64+64),16); const off=W(0)/32;if(!Number.isInteger(off))return[]; const n=W(off);if(!(n>=0&&n<=64))return[]; const out=[]; for(let k=0;k<n;k++){ const rel=W(off+1+k)/32;if(!Number.isInteger(rel))return[]; const p=off+1+rel,len=W(p);if(!(len>=0&&len<=512))return[]; let str="";const base=(p+1)*64; for(let j=0;j<len;j++)str+=String.fromCharCode(parseInt(b.slice(base+j*2,base+j*2+2),16)); out.push(str)} return out}; const httpRead=async(u,method,params)=>{ const ac=new AbortController(),kill=setTimeout(()=>ac.abort(),15000); try{ let r; try{r=await fetch(u,{method:"POST",headers:{"content-type":"application/json"}, body:JSON.stringify({id:1,jsonrpc:"2.0",method,params:params||[]}),signal:ac.signal})} catch{throw Object.assign(Error("could not reach the read node"),{retry:1})} if(!r.ok)throw Object.assign(Error("a read node answered "+r.status),{retry:1}); let j;try{j=await r.json()}catch{throw Object.assign(Error("a read node sent an unreadable answer"),{retry:1})} if(j&&j.error){const c=j.error.code; throw Object.assign(Error(j.error.message||"the read node refused"),{code:c,data:j.error.data, retry:c==null||c===-32005||c===-32603||c===-32004||c===-32002||c===-32001||c===429})} return j?j.result:null; }finally{clearTimeout(kill)}}; const loadCurated=async()=>{ if(curating||Date.now()-curatedTry<60000)return; curating=1;curatedTry=Date.now(); try{ const a=RPCS_PIN; const alt=RPC_SEED.find(u=>u!==rpcPool[rpcPi])||RPC_SEED[0]; const [a1,a2]=await Promise.all([ httpRead(rpcPool[rpcPi],"eth_call",[{to:a,data:"0x"+SEL_LIST},L]), httpRead(alt,"eth_call",[{to:a,data:"0x"+SEL_LIST},L])]); if(!a1||!a2||strip0x(a1)!==strip0x(a2))return; const urls=decStrArr(a1).map(s=>s.trim()).filter(s=>/^https:\/\/\S+$/.test(s)); if(!urls.length)return; rpcPool=[...new Set(urls.concat(rpcPool,RPC_SEED))]; curated=1; }catch{} finally{curating=0}}; const OX_ETH="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; const OKX_APPROVE={1:"0x40aA958dd87FC8305b97f2BA922CDdCa374bcD7f",8453:"0x57df6092665eb6058DE53939612413ff4B09114E"}; const bmin=(a,b)=>a<b?a:b,bmax=(a,b)=>a>b?a:b; const SEL_SLIST="e3b06401",SEL_EXEC="495c73b0",SEL_FILL="0a1b4c9f"; const SOLVERS_PIN="0x1Dfbb2f41B596F72187370469074C46de60dA2e3"; const RPCS_PIN="0x8C7348D039f58C4e9cfA936EF410eec759213b12"; let SOLVER_FILL_PIN="0x7A2f21e476cA2ADde027BC868c5a083338EEfE54"; const SOLVER_ROW_TAG="0x7A2f21e476cA2ADde027BC868c5a083338EEfE54"; let SOLVER_EXEC_PIN="0x4f6633342045C80Efa6c8CAc41b9bdc6145168C4"; const SRC_SOLVER=9; const SRC_DEEP=10; const SOLVER_DEADLINE=1500,SOLVER_STRIKES=3,SOLVER_COOL=60000; let solverLanes=null,solverFill=null,solverExec=null,solversJob=null; const _strikes=new Map(); const laneHurt=n=>{const s=_strikes.get(n),t=Date.now();_strikes.set(n,{n:(s&&t-s.t<SOLVER_COOL?s.n:0)+1,t})}; const laneDown=n=>{const s=_strikes.get(n);return!!s&&Date.now()-s.t<SOLVER_COOL&&s.n>=SOLVER_STRIKES}; const laneSaw=(n,st)=>{if(st===401||st===403||st===429)laneHurt(n)}; const laneThrew=(n,e)=>{if(!e||e.name!=="AbortError")laneHurt(n)}; const laneOk=c=>!!c&&isAddr(c.target)&&(c.spender==null||isAddr(c.spender)) &&/^0x[0-9a-fA-F]*$/.test(c.data||"")&&strip0x(c.data||"").length%2===0; const decSolvers=h=>{const b=strip0x(h||"");if(b.length<128)return[]; const W=i=>parseInt(b.slice(i*64,i*64+64),16); const str=w=>{const n=W(w);if(!(n>=0&&n<=256))return null;let o="";const base=(w+1)*64; for(let j=0;j<n;j++)o+=String.fromCharCode(parseInt(b.slice(base+j*2,base+j*2+2),16));return o}; try{ const head=W(0)/32;if(!Number.isInteger(head))return[]; const n=W(head);if(!(n>=0&&n<=64))return[]; const out=[]; for(let k=0;k<n;k++){ const rel=W(head+1+k)/32;if(!Number.isInteger(rel))return[]; const t=head+1+rel; const nameOff=W(t)/32,epOff=W(t+1)/32; if(!Number.isInteger(nameOff)||!Number.isInteger(epOff))return[]; const name=str(t+nameOff),endpoint=str(t+epOff); if(name===null||endpoint===null)return[]; const hash=endpoint.indexOf("#"); const flag=hash<0?"":endpoint.slice(hash+1); const url=hash<0?endpoint:endpoint.slice(0,hash); const m=/(?:^|;)c=([0-9,]+)/.exec(flag); const chains=m?m[1].split(",").map(Number).filter(Boolean):[1]; out.push({name,endpoint:url,chains, adapter:"0x"+b.slice((t+2)*64+24,(t+3)*64), handicapBps:BigInt(W(t+3)), enabled:W(t+4)===1}); } return out}catch{return[]}}; const loadSolvers=()=>solversJob||(solversJob=(async()=>{ try{ const list=SOLVERS_PIN; solverFill=SOLVER_FILL_PIN; const ex=await nodeRead("eth_call",[{to:solverFill,data:"0x"+SEL_EXEC},L]).catch(()=>null); const exec="0x"+strip0x(ex||"0x").slice(24); if(!isAddr(exec)){solversJob=null;return} if(exec.toLowerCase()!==SOLVER_EXEC_PIN.toLowerCase()){solverLanes=[];return} solverExec=SOLVER_EXEC_PIN; const raw=await cfgRead("eth_call",[{to:list,data:"0x"+SEL_SLIST},L]); solverLanes=decSolvers(raw).filter(x=>x.enabled &&x.adapter.toLowerCase()===SOLVER_ROW_TAG.toLowerCase() &&/^https:\/\/\S+$/.test(x.endpoint) &&SOLVER_SHAPES[x.name] &&x.chains.includes(CHAIN_ID) &&chainCfg().slvId); }catch{solversJob=null} })()); const lanePost=async(name,url,body,ms)=>{ const ac=new AbortController(),k=setTimeout(()=>ac.abort(),ms); try{const r=await fetch(url,{method:"POST",headers:{"content-type":"application/json"}, body:JSON.stringify(body),signal:ac.signal});laneSaw(name,r.status); if(!r.ok)return null;ret