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