memoscan
← all memos

Memo 0x95b2af0d…ffc260 on Ethereum

0xacfba7ce…4082·#25,829,672·view on Etherscan
<!doctype html><html lang=en><head> <meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,viewport-fit=cover"> <meta name=theme-color id=tc content="#7ba7e8"> <title>poidh — pics or it didn't happen</title> <meta name=description content="Onchain front end for the POIDH bounty market on Ethereum mainnet. Post a bounty, fund one together, claim it with a picture."> <link rel=icon href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='.9em' font-size='90'%3E%F0%9F%93%B8%3C/text%3E%3C/svg%3E"> <style> /* POIDH — the first poidh wore a cornflower field, coral accents and big friendly type, and centred everything that mattered. That is kept. What is borrowed from zFi is the discipline underneath it: hairlines instead of boxes, no shadows, no gradients, and micro-labels that say what a thing is rather than decorating it. */ :root{ color-scheme:light; --bg:#7ba7e8; /* the cornflower */ --fg:#fff; --mut:rgba(255,255,255,.74); --dim:rgba(255,255,255,.52); --line:rgba(255,255,255,.34); --line2:rgba(255,255,255,.18); --sunk:rgba(255,255,255,.10); --hov:rgba(255,255,255,.16); --accent:#ff5b57; /* the coral */ --on-accent:#fff; --k:#fff;--kf:#5b8fd8; --good:#eafff0;--bad:#fff0ef} .d{ color-scheme:dark; --bg:#101725; --fg:#eef3fb; --mut:rgba(238,243,251,.68); --dim:rgba(238,243,251,.44); --line:rgba(238,243,251,.26); --line2:rgba(238,243,251,.14); --sunk:rgba(238,243,251,.06); --hov:rgba(238,243,251,.12); --accent:#ff6b66; --on-accent:#101725; --k:#7ba7e8;--kf:#0b1020; --good:#9ff0bb;--bad:#ffb4b1} *{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent} :focus-visible{outline:2px solid var(--accent);outline-offset:3px} @media(prefers-reduced-motion:reduce){*{transition:none!important}} body{background:var(--bg);color:var(--fg);line-height:1.5; font:16px/1.5 system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif; -webkit-font-smoothing:antialiased;padding:0 0 90px;overflow-x:hidden} a{color:inherit;text-underline-offset:3px;text-decoration-thickness:1px} a:hover{color:var(--accent)} .wrap{max-width:780px;margin:0 auto;padding:0 20px} .mut{color:var(--mut)}.dim{color:var(--dim)}.hide{display:none!important} .num{font-variant-numeric:tabular-nums} .ctr{text-align:center} .lbl{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--mut);font-weight:600} /* ------------------------------------------------------------------ bar */ .bar{position:sticky;top:0;z-index:20;background:var(--bg);border-bottom:1px solid var(--line2)} .bar .wrap{display:flex;align-items:center;gap:12px;height:62px} .brand{font-size:19px;font-weight:800;letter-spacing:.2em;text-decoration:none;flex:0 0 auto} .brand:hover{color:inherit} .tagline{font-size:13px;color:var(--mut);flex:1;min-width:0;font-weight:500; overflow:hidden;text-overflow:ellipsis;white-space:nowrap} @media(max-width:620px){.tagline{display:none}.brand{flex:1}} .trail{display:flex;align-items:center;gap:8px} .chip{border:2px solid var(--fg);background:none;color:var(--fg);cursor:pointer; font:inherit;font-size:13px;font-weight:700;padding:7px 13px;border-radius:999px; display:inline-flex;align-items:center;gap:7px;max-width:min(15rem,46vw)} .chip:hover{background:var(--fg);color:var(--bg)} .chip b{font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0} .chip.on{border-color:var(--accent);color:var(--accent)} .chip.on:hover{background:var(--accent);color:var(--on-accent)} /* The burger, and the X it becomes — coral, top right, exactly where the first poidh put them. */ /* The one control that changes nothing but how this looks, so it is the quietest thing in the bar: no border, no fill, half a disc, and it only comes up to full strength under the cursor. */ .themeb{width:30px;height:30px;border:0;background:none;padding:4px;cursor:pointer; opacity:.5;transition:opacity .15s;flex:0 0 auto;line-height:0} .themeb:hover,.themeb:focus-visible{opacity:1} .themeb svg{width:22px;height:22px;display:block} .themeb circle{fill:none;stroke:var(--fg);stroke-width:1.6} .themeb path{fill:var(--fg)} .burger{width:34px;height:34px;border:0;background:none;cursor:pointer;padding:6px; display:flex;flex-direction:column;justify-content:center;gap:5px;flex:0 0 auto} .burger i{display:block;height:3px;background:var(--accent);border-radius:2px} .navov{position:fixed;inset:0;z-index:50;background:var(--bg); display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px; padding:70px 20px} .navov a,.navov button{background:none;border:0;color:var(--fg);font:inherit; font-size:25px;font-weight:500;padding:11px 18px;cursor:pointer;text-decoration:none} .navov a:hover,.navov button:hover{color:var(--accent)} .navx{position:absolute;top:20px;right:22px;width:38px;height:38px;border:0;background:none; color:var(--accent);font-size:32px;line-height:1;cursor:pointer;font-weight:400;padding:0} /* ----------------------------------------------------------------- hero */ .hero{padding:44px 0 30px;text-align:center} h1.big{font-size:40px;line-height:1.06;font-weight:800;letter-spacing:-.02em} @media(min-width:640px){h1.big{font-size:52px}} .hero p{margin:16px auto 0;max-width:34rem;font-size:16px;color:var(--mut)} .hero .stats{margin-top:20px;display:flex;flex-wrap:wrap;gap:8px 26px;justify-content:center; font-size:13px;color:var(--mut);font-weight:600} .hero .stats b{color:var(--fg);font-weight:800} /* ----------------------------------------------------------------- tabs */ .tabs{display:flex;justify-content:center;gap:4px;margin:6px 0 4px} .tabs button{background:none;border:0;color:var(--mut);font:inherit;font-size:13px; font-weight:700;letter-spacing:.14em;text-transform:uppercase;padding:10px 16px; cursor:pointer;border-bottom:3px solid transparent} .tabs button:hover{color:var(--fg)} .tabs button.on{color:var(--fg);border-bottom-color:var(--accent)} /* ----------------------------------------------------------------- bits */ .btn{display:inline-flex;align-items:center;justify-content:center;gap:7px; border:2px solid var(--fg);border-radius:999px;background:none;color:var(--fg);font:inherit; font-size:14px;font-weight:700;padding:10px 20px;cursor:pointer;text-decoration:none; white-space:nowrap} .btn:hover:not(:disabled){background:var(--fg);color:var(--bg)} .btn:disabled{opacity:.4;cursor:not-allowed} .btn-pri{background:var(--accent);border-color:var(--accent);color:var(--on-accent)} .btn-pri:hover:not(:disabled){background:var(--accent);color:var(--on-accent);opacity:.85} .btn-sm{padding:6px 14px;font-size:13px;border-width:2px} .btn-block{width:100%} .row{display:flex;flex-wrap:wrap;gap:10px} .ctr .row,.row.ctr{justify-content:center} input,textarea{background:rgba(255,255,255,.10);color:var(--fg);border:2px solid var(--line); border-radius:10px;font:inherit;font-size:16px;padding:11px 13px;width:100%} .d input,.d textarea{background:rgba(255,255,255,.05)} input::placeholder,textarea::placeholder{color:var(--dim)} input:focus,textarea:focus{border-color:var(--accent);outline:0} textarea{min-height:104px;resize:vertical} /* Inputs at 780px are hard to scan and harder to aim at. The heading stays centred with the rest of the page; the controls get a column. */ .form{max-width:30rem;margin:0 auto;text-align:left} main{min-height:56vh;padding-bottom:26px} .empty{text-align:center;padding:34px 0 46px;max-width:32rem;margin:0 auto} .empty p{font-size:18px;font-weight:600} .owed{font-size:26px;font-weight:800;letter-spacing:-.02em} .owed.none{font-size:17px;font-weight:600;color:var(--mut);letter-spacing:0} .empty .sub{margin:12px 0 22px;font-size:14px;font-weight:400;color:var(--mut)} .field{margin:18px 0} .field .lbl{display:block;margin-bottom:7px} .seg{display:flex;gap:8px} .seg button{flex:1;background:none;border:2px solid var(--line);border-radius:999px; color:var(--mut);font:inherit;font-size:13px;font-weight:700;padding:9px 6px;cursor:pointer} .seg button.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)} #stat{margin:16px 0 0;font-size:14px;font-weight:600;word-break:break-word} #stat:not(:empty){padding:11px 14px;border:2px solid var(--line);border-radius:10px} #stat.err{border-color:var(--accent);color:var(--bad)} #stat.ok{border-color:#fff;color:var(--good)} /* -------------------------------------------------------------- bounties */ .b{display:block;width:100%;text-align:left;background:none;color:var(--fg);font:inherit; cursor:pointer;border:0;border-bottom:1px solid var(--line2);padding:18px 4px} .b:hover{background:var(--sunk)} .box .b{padding-left:0;padding-right:0} .box .b:last-child{border-bottom:0;padding-bottom:2px} .b-hd{display:flex;gap:12px;align-items:baseline} .b-id{font-size:13px;color:var(--dim);font-weight:700;flex:0 0 auto} .b-t{font-weight:700;font-size:19px;line-height:1.25;flex:1;min-width:0;overflow-wrap:anywhere} .b-amt{font-weight:800;font-size:16px;flex:0 0 auto} .b-meta{margin-top:9px;display:flex;flex-wrap:wrap;gap:7px 12px;align-items:center; font-size:13px;color:var(--mut);font-weight:500} .pill{font-size:11px;letter-spacing:.1em;text-transform:uppercase;font-weight:800; border:2px solid var(--line);border-radius:999px;padding:1px 9px} .pill.live{border-color:var(--fg);color:var(--fg)} .pill.dead{border-color:var(--line2);color:var(--dim)} .pill.paid{background:var(--fg);border-color:var(--fg);color:var(--bg)} .pill.vote,.pill.new{background:var(--accent);border-color:var(--accent);color:var(--on-accent)} .prov{color:var(--dim)} .spent{color:var(--dim);font-weight:600} /* The pinned bounty, given the room the first poidh gave a bounty: centred, large, and saying the one number that matters. */ .feat{border:3px solid var(--accent);border-radius:16px;padding:26px 22px;margin:8px 0 6px; text-align:center} .feat .lbl{color:var(--accent);margin-bottom:12px} .feat h2{font-size:27px;line-height:1.2;font-weight:800;overflow-wrap:anywhere} .feat .pot{margin-top:14px;font-size:32px;font-weight:800;letter-spacing:-.02em} .feat .pot span{font-size:16px;font-weight:600;color:var(--mut)} .feat .b-meta{justify-content:center;margin-top:12px} .feat p{margin-top:14px;color:var(--mut);font-size:15px;max-width:36rem; margin-left:auto;margin-right:auto} .feat .row{margin-top:18px;justify-content:center} /* ---------------------------------------------------------------- detail */ .back{background:none;border:0;color:var(--mut);font:inherit;font-size:13px;font-weight:700; letter-spacing:.1em;text-transform:uppercase;cursor:pointer;padding:18px 0 0} .back:hover{color:var(--accent)} h1.t{font-size:32px;line-height:1.15;font-weight:800;letter-spacing:-.02em;margin:14px 0 0; overflow-wrap:anywhere} /* The column is centred; the prose inside it is not. A bounty description runs to paragraphs, and centred paragraphs give the eye no left edge to return to - the one place the first poidh's look had to give way to reading. */ .desc{margin:20px auto 0;max-width:38rem;white-space:pre-wrap;overflow-wrap:anywhere; color:var(--mut);font-size:15px;line-height:1.7;text-align:left} .desc a{color:var(--fg);text-decoration:underline} .pot-big{margin-top:22px;font-size:42px;font-weight:800;letter-spacing:-.03em;line-height:1} .pot-big span{font-size:17px;font-weight:600;color:var(--mut);letter-spacing:0} .byline{margin-top:10px;font-size:14px;color:var(--mut);font-weight:500} .facts{margin:26px auto 0;max-width:100%} .fact{display:flex;justify-content:space-between;gap:16px;padding:11px 2px; border-bottom:1px solid var(--line2);font-size:14px;text-align:left} .fact:first-child{border-top:1px solid var(--line2)} .fact span{color:var(--mut);flex:0 0 auto;font-weight:500} .fact b{font-weight:700;text-align:right;overflow-wrap:anywhere;min-width:0} .box{border:2px solid var(--line);border-radius:14px;padding:20px;margin-top:22px;text-align:left} .box.hot{border-color:var(--accent)} .box.thin{padding:16px 20px} .box.thin h3{margin-bottom:6px} .box h3{font-size:12px;letter-spacing:.16em;text-transform:uppercase;font-weight:800; margin-bottom:14px;color:var(--mut)} .box.hot h3{color:var(--accent)} .bars{display:flex;height:12px;border-radius:999px;overflow:hidden;background:var(--line2); margin:10px 0 8px} .bars i{display:block;background:var(--accent)} .bars i.no{background:transparent} /* The claim card is the whole point of poidh, so it looks like the one the first one drew: a coral frame, the picture, and who took it. */ .claims{display:grid;gap:16px;grid-template-columns:1fr} @media(min-width:560px){.claims{grid-template-columns:1fr 1fr}} .claim{border:3px solid var(--accent);border-radius:10px;overflow:hidden; display:flex;flex-direction:column} .claim.win{border-color:var(--fg)} .claim .shot{background:var(--sunk);min-height:120px;display:flex;align-items:center; justify-content:center;padding:16px} .claim .shot img{display:block;width:100%;height:auto} .claim .body{padding:13px 15px 15px} .claim .who{display:flex;align-items:center;justify-content:space-between;gap:10px} .claim .who b{font-weight:800;font-size:15px;overflow-wrap:anywhere} .claim .cd{margin-top:8px;font-size:13px;color:var(--mut);white-space:pre-wrap; overflow-wrap:anywhere} .claim .b-meta{margin-top:10px;font-size:12px} .plist{font-size:14px} .plist a,.byline a{text-decoration:none} .plist a:hover,.byline a:hover{text-decoration:underline} .plist div{display:flex;justify-content:space-between;gap:12px;padding:7px 0; border-bottom:1px solid var(--line2)} .plist div:last-child{border-bottom:0} .you{font-size:10px;letter-spacing:.1em;font-weight:800;background:var(--accent); color:var(--on-accent);border-radius:999px;padding:1px 7px;margin-left:7px} /* --------------------------------------------------------------- modals */ .modal{position:fixed;inset:0;z-index:60;background:rgba(16,23,37,.72);display:flex; align-items:center;justify-content:center;padding:20px;backdrop-filter:blur(4px)} .sheet{background:var(--bg);border:3px solid var(--accent);border-radius:16px; max-width:380px;width:100%;padding:22px;max-height:88vh;overflow:auto} .sheet-hd{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px} .sheet-hd h3{font-size:13px;letter-spacing:.16em;text-transform:uppercase;font-weight:800} .x{background:none;border:0;color:var(--accent);font:inherit;font-size:26px;cursor:pointer; line-height:1;padding:0 4px} .wrow{display:flex;align-items:center;gap:12px;width:100%;background:none;color:var(--fg); border:2px solid var(--line);border-radius:12px;margin-top:9px;padding:12px 14px;font:inherit; font-size:15px;font-weight:600;cursor:pointer;text-align:left} .wrow:hover{border-color:var(--accent)} .wrow img,.wki{width:24px;height:24px;flex:0 0 auto;display:block} .wki svg{width:24px;height:24px;display:block} #wcQR{margin:0 auto;max-width:270px;background:#fff;padding:10px;border-radius:10px} #readOpts button{width:100%;justify-content:flex-start;margin-top:9px;text-transform:none; letter-spacing:0} /* --------------------------------------------------------------- footer */ /* `footer.wrap`, NOT `footer`. Every one of these is also a `.wrap`, and `.wrap{margin:0 auto}` sets margin-top to zero at a higher specificity than a bare type selector - so the footer's top margin was being discarded and its rule was drawn hard against whatever the page ended on. */ footer.wrap{margin-top:64px;border-top:1px solid var(--line2);padding-top:22px; font-size:13px;color:var(--mut);text-align:center} footer ul{list-style:none;display:flex;flex-wrap:wrap;gap:6px 18px;justify-content:center} footer a{text-decoration:underline} footer p{margin-top:12px;max-width:36rem;margin-left:auto;margin-right:auto;color:var(--dim)} </style> </head><body> <header class=bar><div class=wrap> <a class=brand href="#" id=home>POIDH</a> <span class=tagline>pics or it didn&rsquo;t happen</span> <div class=trail> <button class=themeb id=theme title="Light or dark" aria-label="Switch between light and dark"> <svg viewBox="0 0 20 20" aria-hidden="true"><circle cx="10" cy="10" r="7.5"/><path d="M10 2.5a7.5 7.5 0 0 1 0 15z"/></svg></button> <button class=chip id=connect><b>connect</b></button> <button class=burger id=burger aria-label="Menu"><i></i><i></i><i></i></button> </div></div></header> <!-- The first poidh put everything but the bounty behind a full-screen menu. It keeps the page in front of you and the plumbing out of the way. --> <div class="navov hide" id=navov> <button class=navx id=navx aria-label="Close">&times;</button> <a href="#" data-nav=list>bounties</a> <a href="#new" data-nav=new>post a bounty</a> <a href="#mine" data-nav=mine>my bounties</a> <button id=node>read node</button> <a href="https://etherscan.io/address/0xE731dFadBFf20542E10D09D26Fc71445C70d4232#code" target=_blank rel=noreferrer>contract</a> <a href="https://docs.poidh.xyz" target=_blank rel=noreferrer>how it works</a> <a href="https://poidh.xyz" target=_blank rel=noreferrer>poidh.xyz</a> </div> <main class=wrap> <section class=hero id=hero> <h1 class=big>pics or it didn&rsquo;t happen</h1> <p>Put money on something you want to see done. Whoever does it posts the picture, and the money is theirs.</p> <div class=stats id=heroStats></div> </section> <div id=stat></div> <nav class=tabs> <button id=tList class=on>Bounties</button> <button id=tNew>Post</button> <button id=tMine>Mine</button> </nav> <!-- ------------------------------------------------------------- LIST --> <section id=pList> <div id=feature></div> <div id=list style="margin-top:18px"></div> <div class="row ctr" style="margin:26px 0 4px"><button class="btn btn-sm" id=more>Load older</button></div> </section> <!-- -------------------------------------------------------------- POST --> <section id=pNew class=hide> <h2 class="big ctr" style="font-size:30px;margin:26px 0 6px">post a bounty</h2> <p class="mut ctr" style="max-width:30rem;margin:0 auto 6px;font-size:14px">Say what you want to see, put money behind it, and let whoever does it show you.</p> <div class=form> <div class=field><span class=lbl>Kind</span> <div class=seg id=kind> <button data-k=open class=on>Open &mdash; anyone may fund</button> <button data-k=solo>Solo &mdash; you fund it</button> </div> <p class="mut" style="margin-top:8px;font-size:12px" id=kindNote></p></div> <div class=field><label class=lbl for=nTitle>Title</label> <input id=nTitle maxlength=200 placeholder="What must be proved?"></div> <div class=field><label class=lbl for=nDesc>Description</label> <textarea id=nDesc placeholder="Say exactly what a picture has to show for this to be paid. A link to a longer spec is fine."></textarea></div> <div class=field><label class=lbl for=nAmt>Amount (ETH)</label> <input id=nAmt inputmode=decimal placeholder="0.1" class=num> <p class="mut" style="margin-top:7px;font-size:13px" id=nUsd></p> <p class="mut" style="margin-top:5px;font-size:13px" id=nMin></p></div> <button class="btn btn-pri btn-block" id=doNew>Post bounty</button> <p class="mut" style="margin-top:12px;font-size:13px">Bounties may only be posted from an ordinary account &mdash; the contract refuses contract callers, so a Safe or a smart account cannot issue one.</p> </div> </section> <!-- -------------------------------------------------------------- MINE --> <section id=pMine class=hide> <h2 class="big ctr" style="font-size:30px;margin:26px 0 18px">my bounties</h2> <div id=mineIntro></div> <div id=mineBody></div> </section> <!-- ------------------------------------------------------------ DETAIL --> <section id=pB class=hide> <button class=back id=back>&larr; all bounties</button> <div id=bBody class=ctr></div> </section> </main> <footer class=wrap> <ul> <li id=addrLi></li> <li id=pgLi></li> <li id=newerLi class=hide><a id=newerLink href="#">a newer version exists &rarr;</a></li> <li><a href="https://poidh.xyz" target=_blank rel=noreferrer>poidh.xyz</a></li> <li><a href="https://docs.poidh.xyz" target=_blank rel=noreferrer>docs</a></li> </ul> <p style="margin-top:10px">This page reads the bounty contract directly and talks to nothing else. Claim pictures live on IPFS and are fetched only when you ask for one.</p> </footer> <!-- --------------------------------------------------------------- MODALS --> <div class="modal hide" id=wpick><div class=sheet> <div class=sheet-hd><h3>Connect</h3><button class=x id=wpX>&times;</button></div> <div id=wpList></div><p class="mut" id=wpNone style="font-size:12px"></p> </div></div> <div class="modal hide" id=wcm><div class=sheet> <div class=sheet-hd><h3>WalletConnect</h3><button class=x id=wcX>&times;</button></div> <div id=wcQR></div> <button class="btn btn-sm btn-block" id=wcCopy style="margin-top:14px">copy link</button> </div></div> <div class="modal hide" id=readPick><div class=sheet> <div class=sheet-hd><h3>Read node</h3><button class=x id=rpX>&times;</button></div> <p class="mut" style="font-size:12px;margin-bottom:12px">No wallet is connected, so this page has nowhere to read from. Pick a node &mdash; it is remembered, and the globe icon takes any URL.</p> <div id=readOpts></div> </div></div> <script> "use strict"; /* ------------------------------------------------------------ CONSTANTS */ /* PoidhV3 and its claim NFT, on Ethereum mainnet. Both immutable, both read directly: there is no indexer, no API and no event log in the read path, which is what makes this view possible from a page that can never be updated. */ const POIDH="0xe731dfadbff20542e10d09d26fc71445c70d4232"; const NFT="0x9c5f45d5e1382e4058d334d93c6c01442012a4d9"; const MC3="0xca11bde05977b3631167028862be2a173976ca11"; const ZERO="0x0000000000000000000000000000000000000000"; const CHAIN=1; const C="eth_call",S="eth_sendTransaction",L