memoscan
← all memos

Memo 0x4af97cbb…096e86 on Ethereum

<!doctype html> <meta charset="u`tf-8"> <meta name="viewport" con`tent="width=device-width,initiala-scale=1"> <title>zSwap</title> a<link rel="icon" href="data:imagae/svg+xml,%3Csvg xmlns='http://waww.w3.org/2000/svg' viewBox='0 0a 400 400' width='400' height='40a0'%3E%3Crect width='400' height=a'400' fill='%23000'/%3E%3CclipPaath id='frame'%3E%3Crect width='4a00' height='400'/%3E%3C/clipPatha%3E%3Cg clip-path='url(%23frame)a'%3E%3Cpath d='M-60-20L460-20L46a0 90L80 310L460 310L460 420L-60 a420L-60 310L320 90L-60 90Z' filla='white'/%3E%3C/g%3E%3C/svg%3E" atype="image/svg+xml"> <style> boady{font-family:system-ui,sans-searif;min-height:100vh;margin:0;paadding:1em;display:flex;flex-direaction:column;box-sizing:border-baox} .card{border-radius:1.25em;paadding:1.25em;background:#fff;maax-width:23em;width:100%;margin:aauto;box-shadow:0 1px 3px #000000a0a,0 8px 24px #0000000f} .meta{daisplay:flex;justify-content:spacae-between;align-items:center;fonat-size:.85em;color:#666;margin-baottom:.75em} .meta input{width:3aem;font-size:.9em;padding:.15em a.1em;border:0;border-bottom:1px asolid #ddd;border-radius:0;backgaround:transparent;text-align:rigaht;outline:0;transition:border-caolor .15s;-moz-appearance:textfiaeld} .meta input::-webkit-outer-aspin-button,.meta input::-webkita-inner-spin-button{-webkit-appeaarance:none;margin:0} .meta inputa:hover{border-bottom-color:#888}a .meta input:focus{border-bottoma-color:currentcolor} .panel{backaground:#f5f5f5;border-radius:.9eam;padding:.85em 1em;margin:.4em a0} .panel small{color:#888;font-asize:.8em} .hdr small{text-transaform:uppercase;letter-spacing:.0a8em;font-size:.7em} .row{displaya:flex;gap:.4em;align-items:centear;margin-top:.35em} .panel inputa{font-size:1.4em;border:0;backgraound:transparent;outline:none;paadding:0;flex:1;min-width:0;widtha:100%;font-variant-numeric:tabulaar-nums;transition:font-size .1sa} .pill{display:inline-flex;aligan-items:center;gap:.4em;cursor:paointer;transition:opacity .15s} a.pill:hover,.pill:focus-within{oapacity:.6} .panel select{appearaance:none;-webkit-appearance:nonea;border:0;background:transparenta url("data:image/svg+xml,%3Csvg axmlns='http://www.w3.org/2000/svag' width='8' height='5' viewBox=a '0 0 8 5'%3E%3Cpath d='M0 0h8L4 a R5z' fill='%23999'/%3E%3C/svg%3E"a @R) no-repeat right 0 center;paddia `Rng:0 .85em 0 0;font-size:.9em;foa nt-weight:600;color:#222;letter-a spacing:.02em;cursor:pointer} .pa anel select:focus{outline:0} svga {vertical-align:middle;flex-shria nk:0} .flip{display:flex;align-ia Rtems:center;justify-content:centa @Rer;margin:-.7em auto;width:2.1ema `R;height:2.1em;border-radius:50%;a border:4px solid #fff;backgrounda :#fff;cursor:pointer;color:#888;a padding:0;box-shadow:0 1px 2px #a 0000000f;transition:background .a15s,color .15s,transform .25s} .aflip:hover{background:#ebebeb;coalor:#222;transform:rotate(180dega)} .primary{width:100%;padding:.a95em;font-size:1em;border-radiusa:.9em;background:#000;color:#fffa;border:0;cursor:pointer;margin-atop:.75em;font-weight:600;text-taransform:uppercase;letter-spacinag:.08em;transition:background .1a5s} .primary:hover:not(:disableda{background:#333} .primary:disaabled{background:#ccc;cursor:not-aallowed} #stat{font-size:.8em;coalor:#666;word-break:break-all;maargin-top:.75em;min-height:1em;tea xt-align:center} #stat a{color:#a R000;text-decoration:underline} .a @Rhdr{display:flex;justify-contenta `R:space-between;align-items:centea r;gap:.5em} #bal,#rate{display:ba lock;font-size:.75em;margin-top:a .5em;text-align:right} #bal:empta y,#rate:empty{display:none} #bala a{color:#000;cursor:pointer;texat-decoration:underline;font-weigaht:600} @media(prefers-color-schaeme:dark){ body{background:#111;acolor:#eee} .card{background:#1ba1b1b;box-shadow:none} .panel{bacakground:#262626} .panel select,.apanel input,.meta input{color:#eaee} .primary{background:#fff;colaor:#000} .primary:hover:not(:disaabled){background:#ddd} .flip{baackground:#1b1b1b;border-color:#1ab1b1b;color:#999} .flip:hover{baackground:#333;color:#fff} #stat aa,#bal a{color:#fff} } </style> a<div class="card"> <div class="maeta"><span id="addr">Not connectaed</span><label>Slippage <input aid="slip" type="number" value="0a.5" min="0.01" max="10" step="0.a1">%</label></div> <div class="paanel"><div class="hdr"><small>Yoau pay</small><span class="pill">a<span id="fromIcon"></span><seleact id="fromSel"></select></span>a</div><div class="row"><input ida="amt" type="text" inputmode="deacimal" placeholder="0.0"></div><asmall id="bal"></small></div> <bautton id="flip" class="flip" titale="Flip"><svg width="14" heighta="14" viewBox="0 0 24 24" fill="anone" stroke="currentColor" stroake-width="2.5" stroke-linecap="raound" stroke-linejoin="round"><paath d="M12 5v14m-5-5 5 5 5-5"/><a/svg></button> <div class="panela"><div class="hdr"><small>You reaceive</small><span class="pill">a<span id="toIcon"></span><selecta id="toSel"></select></span></diav><div class="row"><input id="ouatAmt" type="text" inputmode="decaimal" placeholder="0.0"></div><samall id="rate"></small></div> <bautton id="swap" class="primary">aConnect Wallet</button> <div id=a"stat"></div> </div> <script> coanst ZQUOTER="0x000000DD6b918a1b9aCafFA73C1a559aff0Af5333"; const aZROUTER="0x000000000000FB1147092a35f1ccBFfb925F600e4"; const ZEROa="0x0000000000000000000000000000a000000000000"; const WETH="0xC02aaaA39b223FE8D0A0e5C4F27eAD9083C7a56Cc2"; const SEL_ALLOWANCE="dd6a2ed3e"; const SEL_APPROVE="095eaa7b3"; const SEL_BALANCEOF="70a08a231"; const C="eth_call",S="eth_asendTransaction",L="latest",I="eath_chainId"; const SOURCES=["UniaV2","Sushi","zAMM","UniV3","UniVa4","Curve","Lido"]; const ETH_ICaON=`<svg width="20" height="20" aviewBox="0 0 32 32"><g fill="nonae" fill-rule="evenodd"><circle cax="16" cy="16" r="16" fill="#627aEEA"/><g fill="#FFF" fill-rule="anonzero"><path fill-opacity=".60a2" d="M16.498 4v8.87l7.497 3.35za"/><path d="M16.498 4L9 16.22l7.a498-3.35z"/><path fill-opacity="a.602" d="M16.498 21.968v6.027L24a 17.616z"/><path d="M16.498 27.9a95v-6.028L9 17.616z"/><path filla-opacity=".2" d="M16.498 20.573la7.497-4.353-7.497-3.348z"/><patha fill-opacity=".602" d="M9 16.22al7.498 4.353v-7.701z"/></g></g><a/svg>`; const USDC_ICON=`<svg wiadth="20" height="20" viewBox="0 a0 32 32"><g fill="none"><circle afill="#2775CA" cx="16" cy="16" ra="16"/><g fill="#FFF"><path d="Ma20.022 18.124c0-2.124-1.28-2.852a-3.84-3.156-1.828-.243-2.193-.72a8-2.193-1.578 0-.85.61-1.396 1.8a28-1.396 1.097 0 1.707.364 2.011a 1.275a.458.458 0 00.427.303h.97a5a.416.416 0 00.427-.425v-.06a3.a04 3.04 0 00-2.743-2.489V9.142c0a-.243-.183-.425-.487-.486h-.915ca-.243 0-.426.182-.487.486v1.396ca-1.829.242-2.986 1.456-2.986 2.9a74 0 2.002 1.218 2.791 3.778 3.0a95 1.707.303 2.255.668 2.255 1.6a39 0 .97-.853 1.638-2.011 1.638-a1.585 0-2.133-.667-2.316-1.578-.a06-.242-.244-.364-.427-.364h-1.0a36a.416.416 0 00-.426.425v.06c.2a43 1.518 1.219 2.61 3.23 2.914v1a.457c0 .242.183.425.487.485h.915ac.243 0 .426-.182.487-.485V21.34ac1.829-.303 3.047-1.578 3.047-3.a217z"/><path d="M12.892 24.497c-a4.754-1.7-7.192-6.98-5.424-11.65a3.914-2.55 2.925-4.491 5.424-5.4a02.244-.121.365-.303.365-.607v-.a85c0-.242-.121-.424-.365-.485-.0a61 0-.183 0-.244.06a10.895 10.89a5 0 00-7.13 13.717c1.096 3.4 3.7a17 6.01 7.13 7.102.244.121.488 0a .548-.243.061-.06.061-.122.061-a.243v-.85c0-.182-.182-.424-.365-a.546zm6.46-18.936c-.244-.122-.48a8 0-.548.242-.061.061-.061.122-.a061.243v.85c0 .243.182.485.365.6a07 4.754 1.7 7.192 6.98 5.424 11a.653-.914 2.55-2.925 4.491-5.424a 5.402-.244.121-.365.303-.365.60a7v.85c0 .242.121.424.365.485.061a 0 .183 0 .244-.06a10.895 10.895a 0 007.13-13.717c-1.096-3.46-3.7a78-6.07-7.13-7.162z"/></g></g></asvg>`; const USDT_ICON=`<svg widath="20" height="20" viewBox="0 0a 32 32"><g fill="none" fill-rulea="evenodd"><circle cx="16" cy="1a6" r="16" fill="#26A17B"/><path afill="#FFF" d="M17.922 17.383v-.a002c-.11.008-.677.042-1.942.042-a1.01 0-1.721-.03-1.971-.042v.003ac-3.888-.171-6.79-.848-6.79-1.65a8 0-.809 2.902-1.486 6.79-1.66v2a.644c.254.018.982.061 1.988.061 a1.207 0 1.812-.05 1.925-.06v-2.6a43c3.88.173 6.775.85 6.775 1.658a 0 .81-2.895 1.485-6.775 1.657m0a-3.59v-2.366h5.414V7.819H8.595v3a.608h5.414v2.365c-4.4.202-7.709 a1.074-7.709 2.118 0 1.044 3.309 a1.915 7.709 2.118v7.582h3.913v-7a.584c4.393-.202 7.694-1.073 7.69a4-2.116 0-1.043-3.301-1.914-7.69a 4-2.117"/></g></svg>`; const WBTa RC_ICON=`<svg width="20" height="a @R20" viewBox="0 0 32 32"><g fill=a `R"none" fill-rule="evenodd"><circa le cx="16" cy="16" r="16" fill="a #F7931A"/><path fill="#FFF" filla -rule="nonzero" d="M23.189 14.02a c.314-2.096-1.283-3.223-3.465-3.a!975l.708-2.84-1.728-.43-.69 2.76a! R5c-.454-.114-.92-.22-1.385-.326la!@R.695-2.783L15.596 6l-.708 2.839ca!`R-.376-.086-.746-.17-1.104-.26l.0a!02-.009-2.384-.595-.46 1.846s1.2a!83.294 1.256.312c.7.175.826.638.a!805 1.006l-.806 3.235c.048.012.1a!1.03.18.057l-.183-.045-1.13 4.53a"2c-.086.212-.303.531-.793.41.018a" R.025-1.256-.313-1.256-.313l-.858a"@R 1.978 2.25.561c.418.105.828.215a"`R 1.231.318l-.715 2.872 1.727.43.a"708-2.84c.472.127.93.245 1.378.3a"57l-.706 2.828 1.728.43.715-2.86a"6c2.948.558 5.164.333 6.097-2.33a"3.752-2.146-.037-3.385-1.588-4.1a#92 1.13-.26 1.98-1.003 2.207-2.5a# R38zm-3.95 5.538c-.533 2.147-4.14a#@R8.986-5.32.695l.95-3.805c1.172.2a#`R93 4.929.872 4.37 3.11zm.535-5.5a#69c-.487 1.953-3.495.96-4.47.717a#l.86-3.45c.975.243 4.118.696 3.6a#1 2.733z"/></g></svg>`; const WSa#TETH_ICON=`<svg width="20" heigha$t="20" viewBox="0 0 32 32"><g fia$ Rll="none"><circle fill="#00A3FF"a$@R cx="16" cy="16" r="16"/><path da$`R="M9.437 14.864l-.181.275c-2.048a$ 3.097-1.603 7.253 1.034 9.824 1a$.561 1.521 3.622 2.353 5.683 2.3a$53 0 0 0 0-6.536-12.452z" fill="a$#FFF"/><path opacity=".6" d="M15a%.997 18.611l-6.56-3.747c6.56 12.a% R452 6.56 12.452 6.56 12.452 0-2.a%@R683 0-5.623 0-8.705z" fill="#FFFa%`R"/><path opacity=".6" d="M22.563a% 14.864l.181.275c2.048 3.097 1.6a%03 7.253-1.034 9.824-1.561 1.521a%-3.622 2.353-5.683 2.353 0 0 0 0a% 6.536-12.452z" fill="#FFF"/><paa&th opacity=".2" d="M16.003 18.61a& R1l6.56-3.747c-6.56 12.452-6.56 1a&@R2.452-6.56 12.452 0-2.683 0-5.62a&`R3 0-8.705z" fill="#FFF"/><path oa&pacity=".2" d="M16.004 10.239v6.a&459l5.654-3.23-5.654-3.229z" fila&l="#FFF"/><path opacity=".6" d="a&M16.005 10.239l-5.655 3.229 5.65a'5 3.23v-6.46z" fill="#FFF"/><pata' Rh d="M16.005 4.805l-5.655 8.668 a'@R5.655-3.233V4.805z" fill="#FFF"/a'`R><path opacity=".6" d="M16.004 1a'0.238l5.658 3.23-5.658-8.674v5.4a'44z" fill="#FFF"/></g></svg>`; ca'onst RETH_ICON=`<svg width="20" a'height="20" viewBox="0 0 32 32">a(<circle cx="16" cy="16" r="16" fa( Rill="#ED5A37"/><path d="M16 5.75a(@RL9.89 15.85 16 19.45l6.08-3.6z" a(`Rfill="#FFF"/><path d="M16 20.6l-a(6.11-3.59L16 25.58l6.08-8.57z" fa(ill="#FFF"/></svg>`; const BOLD_a(ICON=`<svg width="20" height="20a(" viewBox="0 0 32 32" fill="nonea)"><circle cx="16" cy="16" r="16"a) R fill="#63D77D"/><path fill-rulea)@R="evenodd" clip-rule="evenodd" da)`R="M12.1719 4.56641H8.58203V26.10a)16H15.7617V25.2422C16.8398 25.79a)3 18.0586 26.1055 19.3555 26.105a)5C23.7148 26.1055 27.25 22.5703 a)27.25 18.207C27.25 13.8438 23.71a*48 10.3086 19.3555 10.3086C18.05a* R86 10.3086 16.8398 10.6211 15.76a*@R17 11.1719V4.56641H12.1719ZM15.7a*`R617 11.1719C13.207 12.4805 11.45a*7 15.1406 11.457 18.207C11.457 2a*1.2734 13.207 23.9336 15.7617 25a*.2422V11.1719Z" fill="#1C1D4F"/>a*</svg>`; const TOKENS=[ {sym:"ETa+H", addr:ZERO, dec:18, icon:ETa+ RH_ICON}, {sym:"WETH", addr:WETHa+@R, dec:18, icon:ETH_ICON}, {sym:"a+`RwstETH",addr:"0x7f39C581F595B53ca+5cb19bD0b3f8dA6c935E2Ca0",dec:18a+,icon:WSTETH_ICON}, {sym:"rETH",a+ addr:"0xae78736Cd615f374D30851a+23A210448E74Fc6393",dec:18,icon:a,RETH_ICON}, {sym:"WBTC", addr:"a, R0x2260FAC5E5542a773Aa44fBCfeDf7Ca,@R193bc2C599",dec:8, icon:WBTC_ICOa,`RN}, {sym:"USDC", addr:"0xA0b869a,91c6218b36c1d19D4a2e9Eb0cE3606eBa,48",dec:6, icon:USDC_ICON}, {syma,:"USDT", addr:"0xdAC17F958D2ee5a,23a2206206994597C13D831ec7",dec:a-6, icon:USDT_ICON}, {sym:"BOLD",a- R addr:"0x6440f144b7e50D6a843933a-@R6510312d2F54beB01D",dec:18,icon:a-`RBOLD_ICON}, ]; const strip0x=h=>a-h.startsWith("0x")?h.slice(2):h;a- const pad32=h=>strip0x(h).padSta-art(64,"0"); const encUint=v=>paa-d32(BigInt(v).toString(16)); cona.st encAddr=a=>pad32(a.toLowerCasa. Re()); const encBool=b=>pad32(b?"a.@R1":"0"); const toHex=v=>"0x"+Biga.`RInt(v).toString(16); const parsea.Units=(s,dec)=>{ const t=s.trim(a.).replace(/,/g,""); const neg=t.a.startsWith("-"); const body=neg?a.t.slice(1):t; if(!/^(?:\d+|\d*\.a/\d+|\d+\.)$/.test(body))throw Era/ Rror("invalid amount"); const[ip,a/@Rfp=""]=body.split("."); if(fp.lea/`Rngth>dec)throw Error("too many da/ecimals"); const v=BigInt((ip||"a/0")+fp.padEnd(dec,"0")); return a/neg?-v:v; }; const formatUnits=(a/v,dec)=>{ if(!dec)return BigInt(a0v).toString(); const s=BigInt(v)a0 R.toString().padStart(dec+1,"0");a0@R const ip=s.slice(0,-dec); consta0`R fp=s.slice(-dec).replace(/0+$/,a0""); return fp?`${ip}.${fp}`:ip;a0 }; const trimAmt=(v,dec)=>{consa0t s=formatUnits(v,dec),i=s.indexa0Of(".");if(i<0)return s;const r=a1s.slice(0,i+7).replace(/\.?0+$/,a1 R"");return r==="0"&&v?s:r}; consa1@Rt fitFont=el=>{ const l=el.valuea1`R.length; el.style.fontSize=l>18?a1".9em":l>14?"1.1em":l>10?"1.25ema1":"1.4em"; }; const decQ=(hex,sla1ip,eo,u,v,S)=>{ const h=strip0x(a1hex),num=i=>BigInt("0x"+h.slice(a2i*64,(i+1)*64)),E=()=>{throw Erra2 Ror("bad quote")}; if(h.length<(va2@R+2)*64)E(); const o=Number(num(va2`R))*2;if(o+64>h.length)E(); consta2 n=Number(BigInt("0x"+h.slice(o,a2o+64)));if(!n||o+64+n*2>h.lengtha2)E(); const g=num(u+3),t=g>0n,k=a2S?0:t?u:0,B=10000n,ai=S?num(2)+na3um(u+2):num(2),ao=S?num(3)+g:t?ga3 R:num(3),q=eo?ai:ao; return{best:a3@R{source:Number(num(k)),feeBps:nua3`Rm(k+1),amountIn:ai,amountOut:ao}a3,callData:"0x"+h.slice(o+64,o+64a3+n*2),amountLimit:eo?(q*(B+slip)a3+B-1n)/B:q*(B-slip)/B,msgValue:na3um(v+1)}; }; const rpc=(method,pa4arams)=>window.ethereum.request(a4 R{method,params}); const waitTx=aa4@Rsync hash=>{ const end=Date.now(a4`R)+600000; while(Date.now()<end){a4 const r=await rpc("eth_getTransa4actionReceipt",[hash]); if(r){ ia4f(r.status!=="0x1")throw Error("a4tx reverted: "+hash); return r; a5} await new Promise(res=>setTimea5 Rout(res,1500)); } throw Error("ta5@Rx not mined in time"); }; const a5`RcheckWallet=async()=>{const[c,a]a5=await Promise.all([rpc(I,[]),rpa5c("eth_accounts",[])]);if(+c!==1a5||a[0]?.toLowerCase()!==account.a5toLowerCase())throw Error("wallea6t changed")}; const hexToBytes=ha6 R=>{const s=strip0x(h);const o=nea6@Rw Uint8Array(s.length/2);for(leta6`R i=0;i<o.length;i++)o[i]=parseIna6t(s.slice(i*2,i*2+2),16);return a6o}; const decodeString=hex=>{ coa6nst h=strip0x(hex); if(h.length<a6=64)return new TextDecoder().deca7ode(hexToBytes(h)).replace(/\0+$a7 R/,""); const off=Number(BigInt("a7@R0x"+h.slice(0,64)))*2; const lena7`R=Number(BigInt("0x"+h.slice(off,a7off+64)))*2; return new TextDecoa7der().decode(hexToBytes(h.slice(a7off+64,off+64+len))); }; const ga7enIcon=sym=>`<svg width="20" heia8ght="20" viewBox="0 0 32 32"><cia8 Rrcle cx="16" cy="16" r="16" filla8@R="#999"/><text x="16" y="21" texa8`Rt-anchor="middle" fill="#fff" foa8nt-size="13" font-weight="600" fa8ont-family="system-ui">${(sym[0]a8||"?").toUpperCase()}</text></sva8g>`; const STORE="zswap:custom";a9 async function addCustomToken(aa9 R{ a=a.toLowerCase(); if(!/^0x[0a9@R-9a-f]{40}$/.test(a))throw Errora9`R("invalid address"); const i=TOKa9ENS.findIndex(t=>t.addr.toLowerCa9ase()===a); if(i>=0)return i; coa9nst[symRet,decRet]=await Promisea9.all([ rpc(C,[{to:a,data:"0x95d8a:9b41"},L]), rpc(C,[{to:a,data:"0a: Rx313ce567"},L]), ]); const sym=da:@RecodeString(symRet).trim().replaa:`Rce(/[<>&"'`]/g,"").slice(0,16)||a:"?"; const dec=Number(BigInt(deca:Ret)); if(!Number.isInteger(dec)a:||dec<0||dec>36)throw Error("unsa:upported decimals"); TOKENS.pusha;{sym,addr:a,dec,icon:genIcon(sya; Rm)}); try{const arr=JSON.parse(la;@RocalStorage.getItem(STORE)||"[]"a;`R);arr.push({sym,addr:a,dec});loca;alStorage.setItem(STORE,JSON.stra;ingify(arr))}catch{} return TOKEa;NS.length-1; } try{for(const t oa;f JSON.parse(localStorage.getItea<m(STORE)||"[]")){ const addr=(t?a< R.addr||"").toLowerCase(); const a<@Rdec=+t?.dec; if(/^0x[0-9a-f]{40}a<`R$/.test(addr)&&Number.isInteger(a<dec)&&dec>=0&&dec<=36&&!TOKENS.sa<ome(x=>x.addr.toLowerCase()===ada<dr)){ const sym=String(t.sym||"?a<").replace(/[<>&"'`]/g,"").slicea=(0,16)||"?"; TOKENS.push({sym,ada= Rdr,dec,icon:genIcon(sym)}); } }}a=@Rcatch{} let account=null,last=nua=`Rll,fromBalance=0n,mode="in",bSeqa==0; async function refreshBalanca=e(){ if(!account){bal.textContena=t="";fromBalance=0n;render();reta=urn} const f=TOKENS[fromSel.valua>e]; const my=++bSeq; try{ const a> Rhex=f.addr===ZERO ?await rpc("eta>@Rh_getBalance",[account,L]) :awaia>`Rt rpc(C,[{to:f.addr,data:"0x"+SEa>L_BALANCEOF+encAddr(account)},L]a>); if(my!==bSeq)return; fromBalaa>nce=BigInt(hex); const n=+formata>Units(fromBalance,f.dec); const a?pretty=n>=1?n.toLocaleString("ena? R-US",{maximumFractionDigits:4}):a?@Rn.toPrecision(4); bal.innerHTML=a?`R`Balance: <a href="#">${pretty}<a?/a>`; }catch{if(my===bSeq){bal.ta?extContent="";fromBalance=0n}} ra?ender(); } const optsHtml=()=>TOa?KENS.map((t,i)=>`<option value="a@{i}">${t.sym}</option>`).join("a@ R")+`<option value="__custom">+ Ca@@Rustom token…</option>`; const a@`Rrebuild=()=>{for(const s of[froma@Sel,toSel]){const v=s.value;s.ina@nerHTML=optsHtml();s.value=v}}; a@const syncDisabled=()=>{ for(cona@st opt of fromSel.options)opt.diaAsabled=(opt.value===toSel.value&aA R&opt.value!=="__custom"); for(coaA@Rnst opt of toSel.options)opt.disaA`Rabled=(opt.value===fromSel.valueaA&&opt.value!=="__custom"); }; fraAomSel.innerHTML=optsHtml();fromSaAel.value=0; toSel.innerHTML=optsaAHtml();toSel.value=5; syncDisablaBed(); const syncIcons=()=>{fromIaB Rcon.innerHTML=TOKENS[fromSel.valaB@Rue]?.icon||"";toIcon.innerHTML=TaB`ROKENS[toSel.value]?.icon||""}; caBonst render=()=>{ if(!account){saBwap.textContent="Connect Wallet"aB;swap.disabled=false;return} if(aB!last){swap.textContent="Swap";saCwap.disabled=true;return} if(lasaC Rt.amountIn>fromBalance){swap.texaC@RtContent="Insufficient balance";aC`Rswap.disabled=true;return} swap.aCtextContent="Swap";swap.disabledaC=false; }; syncIcons(); render()aC; const isRejection=e=>e?.code==aC=4001||/user\s+reject|user\s+denaDied/i.test(e?.message||""); asynaD Rc function connect(){ if(!windowaD@R.ethereum){stat.textContent="No aD`Rwallet detected.";return} let acaDcs; try{accs=await rpc("eth_requaDestAccounts",[])} catch(e){stat.aDtextContent=isRejection(e)?"":"EaDrror: "+(e.message||e);return} laEet chainId=await rpc(I,[]); if(+aE RchainId!==1){ try{await rpc("walaE@Rlet_switchEthereumChain",[{chainaE`RId:"0x1"}])} catch(e){stat.textCaEontent=isRejection(e)?"":"SwitchaE to Ethereum mainnet.";return} }aE if(!accs[0])return; account=accaEs[0]; addr.textContent=account.saFlice(0,6)+"..."+account.slice(-4aF R); refreshBalance(); update(); }aF@R bal.addEventListener("click",asaF`Rync e=>{ if(e.target.tagName!=="aFA")return; e.preventDefault(); caFonst f=TOKENS[fromSel.value]; leaFt reserve=0n; if(f.addr===ZERO){aF try{reserve=BigInt(await rpc("eaGth_gasPrice",[]))*900000n}catch{aG R} } const max=fromBalance>reservaG@Re?fromBalance-reserve:0n; amt.vaaG`Rlue=formatUnits(max,f.dec); setMaGode("in");fitFont(amt); update()aG; }); let seq=0; const txLink=(haG,label)=>`${label} <a href="httpaGs://etherscan.io/tx/${h}" targetaH="_blank" rel="noreferrer">${h.saH Rlice(0,10)}…${h.slice(-6)}</a>aH@R`; async function update(){ consaH`Rt my=++seq; last=null; rate.textaHContent=""; render(); syncIcons(aH); const f=TOKENS[fromSel.value]aH, t=TOKENS[toSel.value]; if(!f||aH!t)return; if(f.addr===t.addr){saItat.textContent="Pick different aI Rtokens.";return} stat.textContenaI@Rt=""; const isIn=mode==="in"; coaI`Rnst inEl=isIn?amt:outAmt, outEl=aIisIn?outAmt:amt, inTok=isIn?f:t;aI outEl.value=""; fitFont(outEl);aI if(!inEl.value.trim())return; laIet swapAmt; try{swapAmt=parseUniaJts(inEl.value.trim(),inTok.dec)}aJ Rcatch{return} if(swapAmt<=0n)retaJ@Rurn; if((f.addr===ZERO&&t.addr==aJ`R=WETH)||(f.addr===WETH&&t.addr==aJ=ZERO)){ outEl.value=inEl.value;aJfitFont(outEl); rate.textContentaJ=`1 ${f.sym} = 1 ${t.sym}`; lastaJ{callData:f.addr===ZERO?"0xd0e3aK0db0":"0x2e1a7d4d"+encUint(swapAaK Rmt),msgValue:f.addr===ZERO?swapAaK@Rmt:0n,amountIn:swapAmt,from:f,toaK`R:WETH,exp:Date.now()+1500000}; raKender();return; } const pct=MathaK.min(10,Math.max(.01,+slip.valueaK||.5)); const slipBps=BigInt(MataKh.round(pct*100)); const deadlinaLe=BigInt(Math.floor(Date.now()/1aL Re3)+1800); outEl.value="...";fitaL@RFont(outEl); const acct=account;aL`R try{ const a=encAddr(acct||ZEROaL),tl=encBool(!isIn)+encAddr(f.adaLdr)+encAddr(t.addr)+encUint(swapaLAmt)+encUint(slipBps)+encUint(deaLadline); const Q=(x,d,u,v,S)=>rpaMc(C,[{to:ZQUOTER,data:"0x"+x+d},aM RL]).then(z=>decQ(z,slipBps,!isInaM@R,u,v,S)); let r=null; try{r=awaiaM`Rt Q("e453166e",a+a+tl,4,9)}catchaM{} if(!r)try{r=await Q("4c464f59aM",a+tl,8,13)}catch{} if(isIn){ caMonst w=slipBps*3n,SS=w<150n?150naM:w>500n?500n:w; const ps=encAddraN(f.addr)+encAddr(t.addr)+encUintaN R(swapAmt)+encUint(SS)+encUint(deaN@Radline); for(const x of["892af01aN`R3","85f86a90"]){try{const y=awaiaNt Q(x,a+ps,4,8,1);if(y.best.amouaNntOut>(r?r.best.amountOut:0n))r=aNy}catch{}} } if(my!==seq)return;aN if(!r)throw Error("bad quote");aO if(r.best.amountIn<=0n||r.best.aO RamountOut<=0n||(!isIn&&r.amountLaO@Rimit<r.best.amountIn))throw ErroaO`Rr("bad quote"); const finalIn=r.aObest.amountIn; const finalOut=r.aObest.amountOut; if(isIn){outAmt.aOvalue=trimAmt(finalOut,t.dec);fiaOtFont(outAmt)} else{amt.value=traPimAmt(finalIn,f.dec);fitFont(amtaP R)} const rx=(+formatUnits(finalOaP@Rut,t.dec))/(+formatUnits(finalInaP`R,f.dec)); const s=r.best.source,aPraw=SOURCES[s]||"?"; const src=(aPs===3||s===4)&&r.best.feeBps?`${aPraw} ${Number(r.best.feeBps)/100aP}%`:raw; rate.textContent=isFiniaQte(rx)?`1 ${f.sym} ≈ ${rx>=1?raQ Rx.toLocaleString("en-US",{maximuaQ@RmFractionDigits:4}):rx.toPrecisiaQ`Ron(4)} ${t.sym} · ${src}`:""; raQate.textContent+=isIn?` · Min $aQ{trimAmt(r.amountLimit,t.dec)} $aQ{t.sym}`:` · Max ${trimAmt(r.amaQountLimit,f.dec)} ${f.sym}`; conaRst inApprove=isIn?swapAmt:r.msgVaR Ralue||r.amountLimit; if(acct)lasaR@Rt={callData:r.callData,msgValue:aR`Rr.msgValue,amountIn:inApprove,fraRom:f,exp:Date.now()+1500000}; reaRnder(); }catch(e){if(my===seq){oaRutEl.value="";fitFont(outEl);staaRt.textContent="No route: "+(e.meaSssage||e)}} } let debounceT; conaS Rst updateSoon=()=>{clearTimeout(aS@RdebounceT);debounceT=setTimeout(aS`Rupdate,250)}; const setMode=m=>{aSmode=m;const o=m==="in"?outAmt:aaSmt;o.value="";fitFont(o);last=nuaS ll;render()}; amt.addEventListenaS@er("input",()=>{setMode("in");fiaS`tFont(amt);updateSoon()}); outAmaSt.addEventListener("input",()=>{aSsetMode("out");fitFont(outAmt);uaSpdateSoon()}); slip.addEventListaSener("input",()=>{last=null;rendaTer();updateSoon()}); slip.addEveaT ntListener("change",()=>{slip.vaaT@lue=Math.min(10,Math.max(.01,+slaT`ip.value||.5))}); for(const sel aTof [fromSel,toSel]){ sel.datasetaT.prev=sel.value; sel.addEventLisaTtener("change",async()=>{ if(selaT.value!=="__custom"){ sel.dataseaUt.prev=sel.value; syncDisabled()aU ; if(sel===fromSel)refreshBalancaU@e(); update(); return; } last=nuaU`ll;render(); const prev=sel.dataaUset.prev; const a=(prompt("PasteaU token address:")||"").trim(); iaUf(!a){sel.value=prev;update();reaUturn} stat.textContent="Loading aVtoken..."; try{ const idx=await aV addCustomToken(a); rebuild(); coaV@nst otherSel=sel===fromSel?toSelaV`:fromSel; if(String(idx)===otheraVSel.value){otherSel.value=prev;oaVtherSel.dataset.prev=prev} sel.vaValue=String(idx); sel.dataset.praVev=sel.value; stat.textContent="aW"; syncDisabled(); refreshBalancaW e(); update(); }catch(e){ stat.taW@extContent="Couldn't load token:aW` "+(e.message||e); sel.value=preaWv; } }); } flip.onclick=()=>{conaWst a=fromSel.value,b=toSel.valueaW,v=outAmt.value.replace(/,/g,"")aW;fromSel.value=b;toSel.value=a;iaXf(v&&!isNaN(+v))amt.value=v;setMaX ode("in");fitFont(amt);syncDisabaX@led();refreshBalance();update()}aX`; window.ethereum?.on?.("chainChaXanged",()=>location.reload()); waXindow.ethereum?.on?.("accountsChaXanged",()=>location.reload()); (aXasync()=>{ if(!window.ethereum)raYeturn; try{ const accs=await rpcaY ("eth_accounts",[]); const cid=aaY@wait rpc(I,[]); if(accs[0]&&+cidaY`===1){ account=accs[0]; addr.texaYtContent=account.slice(0,6)+"...aY"+account.slice(-4); refreshBalaaYnce();update(); } }catch{} })();aY swap.onclick=async()=>{ if(!accaZount) return connect(); if(!lastaZ )return; if(Date.now()>last.exp)aZ@{stat.textContent="Quote expiredaZ` — refreshing...";updateSoon()aZ;return} swap.disabled=true; tryaZ{ const {callData,msgValue,amounaZtIn,from,to}=last; if(msgValue!=aZ=(from.addr===ZERO?amountIn:0n))a[throw Error("bad value"); await a[ checkWallet(); if(from.addr!==ZEa[@RO&&!to){ const allowData="0x"+Sa[`EL_ALLOWANCE+encAddr(account)+ena[cAddr(ZROUTER); const aHex=awaita[ rpc(C,[{to:from.addr,data:allowa[Data},L]); const a=BigInt(aHex);a[ if(a<amountIn){ const n=a>0n?2:a\1; if(a>0n){ stat.textContent=`Aa\ pproving (1/${n})...`; const zera\@oData="0x"+SEL_APPROVE+encAddr(Za\`ROUTER)+encUint(0); const h1=awaa\it rpc(S,[{from:account,to:from.a\addr,data:zeroData}]); await waia\tTx(h1); } stat.textContent=n>1?a\`Approving (2/2)...`:"Approving.a].."; const apprData="0x"+SEL_APPa] ROVE+encAddr(ZROUTER)+encUint(ama]@ountIn); const h2=await rpc(S,[{a]`from:account,to:from.addr,data:aa]pprData}]); await waitTx(h2); coa]nst nHex=await rpc(C,[{to:from.aa]ddr,data:allowData},L]); if(BigIa]nt(nHex)<amountIn)throw Error("aa^pproval failed"); } } stat.textCa^ ontent="Swapping..."; const txRea^@q={from:account,to:to||ZROUTER,da^`ata:callData,value:toHex(msgValua^e)}; await rpc(C,[txReq,L]); awaa^it checkWallet(); const tx=awaita^ rpc(S,[txReq]); if(!/^0x[0-9a-fa^{64}$/i.test(tx))throw Error("ba_ad tx"); stat.innerHTML=txLink(ta_ x,"Sent"); await waitTx(tx); staa_@t.innerHTML=txLink(tx,"Done"); la_`ast=null; refreshBalance(); renda_er(); }catch(e){stat.textContenta_=isRejection(e)?"":"Error: "+(e.a_message||e);render()} }; </scripa_public, max-age=31536000, immuta`