{"id":"ERC-7439","name":"Prevent Ticket Touting","status":"Draft","chain":"both","category":{"id":"security","name":"Security & Trust","description":"Helping users verify, control, and protect their assets"},"journeyStages":[{"id":"specialized","name":"Specialized Interactions","description":"Physical items, AI, social, gaming"}],"uxImpact":"Event tickets can only be transferred through authorized resellers — prevents scalping, enables price caps on secondary sales. Design implications: show 'Official Resale Only' indicator, direct to authorized resale channels, display ticket status (Sold/Resell/Void/Redeemed). Design decisions: how to handle unauthorized transfer attempts — educational messaging about why blocked, clear path to legitimate resale options.","hasDetailedContent":true,"content":{"id":"ERC-7439","sources":[{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/erc-7439","type":"official-spec"}],"lastReviewed":"2026-05-25","lastUpdated":"2026-05-25","summary":"Event tickets can only be transferred through authorized resellers — prevents scalping, enables price caps on secondary sales.","designerTakeaways":["You can badge Official resale only on every ticket before first purchase.","Your transfer UI can route fans to authorized resale instead of a disabled send button with no path.","You can show ticket lifecycle status so fans know if a pass is valid, listed, or already scanned."],"applicability":{"whenToUse":["Event tickets are NFTs with anti-scalping policy.","Primary issuer controls authorized resale network.","Transfer restrictions are enforced on-chain."],"whenToAvoid":["Collectible tickets meant to trade freely on open marketplaces.","Contract does not implement ERC-7439 transfer hooks.","Jurisdiction forbids transfer restrictions you must disclose."]},"prototypeFirst":[{"screen":"Ticket purchase with resale policy","why":"Fans must accept resale rules before paying.","covers":["Policy summary","Authorized partners"],"include":["Official resale only badge","Price cap explanation","Partner marketplace links"]},{"screen":"Blocked peer transfer","why":"The most rage-inducing moment needs education, not silence.","covers":["Transfer blocked","Education modal"],"include":["Why blocked copy","Go to official resale CTA","Support link"]},{"screen":"Official resale listing","why":"Legitimate resale must feel easier than gray market.","covers":["List for resale","Cap enforced","Sold through partner"],"include":["Max price display","Partner picker","Listing confirmation"]},{"screen":"Venue redemption scan","why":"Door staff and fans need Redeemed vs Valid at a glance.","covers":["Valid","Redeemed","Void"],"include":["Large status badge","QR display","Scan timestamp"]}],"mentalModel":[{"label":"Ticket NFT","description":"A token representing event entry with lifecycle state, not just art."},{"label":"Authorized resale","description":"Only approved marketplaces can change ownership — caps and fees apply."},{"label":"Transfer block","description":"Wallet-to-wallet sends revert; this is policy, not a bug."},{"label":"Redemption","description":"Scanning at venue marks ticket used — resale typically ends."},{"label":"Void state","description":"Cancelled or fraudulent tickets must show unusable clearly."}],"statesToDesign":[{"state":"Valid — not yet used","trigger":"Ticket owned, event upcoming.","userNeed":"See date, seat, and resale options.","designResponse":"Valid badge with Resell officially CTA if allowed."},{"state":"Listed on official resale","trigger":"User listed through partner.","userNeed":"Track listing without losing entry proof.","designResponse":"Listed for resale status with cancel listing action."},{"state":"Transfer blocked","trigger":"User attempts unauthorized send.","userNeed":"Understand why and what to do.","designResponse":"Modal explaining policy with partner link."},{"state":"Redeemed at venue","trigger":"Ticket scanned.","userNeed":"Confirm entry used; no false hope of resale.","designResponse":"Redeemed badge; gray card in wallet."},{"state":"Void or cancelled","trigger":"Event cancelled or ticket invalidated.","userNeed":"Know refund or replacement path.","designResponse":"Void badge with issuer message and refund CTA if applicable."}],"designDecisions":[{"question":"How to handle unauthorized transfer attempts?","recommendation":"Block with educational modal and official resale link, never silent disabled button.","rationale":"Fans blame the app unless policy is explained at failure moment."},{"question":"Show price caps in UI?","recommendation":"Display max resale price before listing.","rationale":"Cap surprises cause abandoned listings and support load."},{"question":"Peer-to-peer send button at all?","recommendation":"Hide or replace with Resell officially; do not show broken Send.","rationale":"Visible but disabled Send feels like a bug."}],"problemsSolved":[{"problem":"Scalpers arbitrage fan tickets","oldWay":"Open transfers to highest bidder instantly","newWay":"Authorized resale with price caps and audit trail","impact":"critical"},{"problem":"Fans buy invalid or duplicate tickets","oldWay":"Gray market with no issuer verification","newWay":"On-chain status shows Valid, Listed, or Redeemed","impact":"high"},{"problem":"Surprise blocks at transfer time","oldWay":"Marketplaces allow list then fail on chain","newWay":"Policy visible at purchase and resale entry","impact":"high"}],"uxPatterns":[{"name":"Official Resale Router","description":"Replace send with partner resale flow.","mockup":"concept/reactions","components":["ResaleBadge","PartnerLink","PriceCapLabel"],"userFlow":["User taps Resell","Sees cap and partner","Lists officially","Buyer purchases through channel"]},{"name":"Transfer Block Education","description":"Explain policy when unauthorized send attempted.","mockup":"concept/verify-safety","components":["BlockModal","PolicySummary","ResaleCTA"],"userFlow":["User tries send","Modal explains","Routes to resale","User lists instead"]}],"seenInTheWild":[{"app":"Ticketmaster","url":"https://www.ticketmaster.com/","note":"Official resale and face-value cap patterns fans already understand."},{"app":"GET Protocol","url":"https://www.get-protocol.io/","note":"NFT ticketing with controlled secondary market."},{"app":"SeatGeek","url":"https://seatgeek.com/","note":"Ticket status and verified resale UX reference."},{"app":"Coachella NFT","url":"https://www.coachella.com/","note":"Festival NFT experiments inform redemption status display."}],"antiPatterns":[{"pattern":"Disabled Send with no explanation","why":"Users think wallet is broken","instead":"Official resale only label and guided resale CTA","severity":"critical"},{"pattern":"Allowing OpenSea list then on-chain fail","why":"Wasted gas and rage quits","instead":"Pre-check transfer rights before listing UI","severity":"critical"},{"pattern":"Hiding resale caps until checkout","why":"Fans abandon when cap lower than expected","instead":"Show max resale price on ticket detail","severity":"high"}],"vocabulary":[{"use":"Official resale","avoid":"Whitelisted transfer destination","why":"Fan-friendly policy language."},{"use":"Ticket used","avoid":"Redeemed state flag","why":"Venue language over enum names."},{"use":"Face-value cap","avoid":"Max transfer price parameter","why":"Policy users understand from traditional ticketing."}],"onMonad":[{"aspect":"Redemption speed","ethereum":"Scan confirmation may lag","monad":"Fast finality updates Valid → Redeemed instantly at gate","designImplication":"Gate apps can show live status without refresh anxiety."},{"aspect":"Resale listing cost","ethereum":"Listing gas adds friction","monad":"Lower fees make official resale competitive with gray market","designImplication":"Emphasize free or cheap official resale in copy."}],"technicalNotes":"ERC-7439 is draft; surface resale policy before primary sale and pre-check transfers before marketplace listing.","relatedStandards":[{"id":"ERC-721","relationship":"Ticket represented as NFT with transfer hooks"},{"id":"ERC-6454","relationship":"Transfer restriction detection complement"}]},"sources":[{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/erc-7439","type":"official-spec"},{"label":"Discussion","url":"https://ethereum-magicians.org/search?q=ERC-7439","type":"discussion"},{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/erc-7439","type":"official-spec"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/ERC-7439","markdown":"https://www.eipsfordesigners.com/standards/ERC-7439/content.md","agent":"https://www.eipsfordesigners.com/standards/ERC-7439/agent.md","api":"https://www.eipsfordesigners.com/api/standards/ERC-7439","official":"https://eips.ethereum.org/EIPS/erc-7439","discussion":"https://ethereum-magicians.org/search?q=ERC-7439"},"freshness":{"lastReviewed":"2026-05-25","lastUpdated":"2026-05-25"}}