{"id":"ERC-7994","name":"Purpose Bound Money","status":"Final","chain":"both","category":{"id":"defi","name":"DeFi Patterns","description":"Vaults, bonds, and financial primitives"},"journeyStages":[{"id":"management","name":"Asset Management","description":"Managing assets over time"}],"uxImpact":"ERC-7994 binds a recipient and amount to arbitrary unlock conditions and optional expiry. Use bindPurpose(), isUnlocked(), and claim(); merchant, KYC, category, receipt, and spending-limit behavior belongs to issuer-selected condition implementations, not a universal merchant directory or isValidTransfer() check.","officialUrl":"https://ercs.ethereum.org/ERCS/erc-7994","lastReviewed":"2026-09-18","lastUpdated":"2026-09-18","hasDetailedContent":true,"content":{"id":"ERC-7994","summary":"ERC-7994 defines purpose-bound money through a binding that names a recipient, amount, unlock conditions, and optional expiry. Merchant, KYC, category, receipt, and spending-limit behavior comes from the condition implementations selected by the issuer; the standard does not provide a universal merchant directory or transfer pre-check.","applicability":{"whenToUse":["Your product addresses: no way to restrict how tokens are spent.","Your product addresses: corporate cards require centralized control.","The flow should deliver: a recipient can claim a bound amount after its configured conditions unlock.","Connect flows must list wallets with names, icons, and explicit user choice."],"whenToAvoid":["The deployed contract has no purpose binding or condition resolver to inspect.","The flow is an ordinary transfer with no recipient claim or unlock state.","No merchant, category, receipt, KYC, or spending-limit condition is configured for the binding.","No token balances, swaps, lending, or yield flows appear in the product."]},"designerTakeaways":["You can show the recipient, amount, unlock conditions, and expiry of each purpose binding.","You can reflect spending limits or categories when the selected condition resolver defines them.","You can show a merchant or eligibility result only when an application condition supplies that data."],"problemsSolved":[{"problem":"No way to restrict how tokens are spent","oldWay":"Send tokens, hope recipient uses them correctly","newWay":"A recipient claims a bound amount after its configured conditions unlock","impact":"critical"},{"problem":"Corporate cards require centralized control","oldWay":"Visa/corporate card with bank managing restrictions","newWay":"Issuer-selected conditions can enforce spending limits or categories","impact":"high"},{"problem":"Benefits programs can't ensure proper use","oldWay":"Issue vouchers, verify manually, prone to fraud","newWay":"A condition resolver can expose merchant eligibility when the application provides it","impact":"high"},{"problem":"Grants require trust or complex escrow","oldWay":"Send grant money, request receipts, manual auditing","newWay":"The binding records whatever recipient and condition policy the issuer configures","impact":"medium"},{"problem":"Can't combine spending restrictions with expiry","oldWay":"Separate systems for spend categories and time limits","newWay":"A binding can include an optional expiry alongside its configured conditions","impact":"medium"}],"uxPatterns":[{"name":"Purpose-Bound Wallet View","description":"Show tokens with their spending restrictions","userFlow":["User opens wallet","UI separates regular vs purpose-bound tokens","Each restricted token shows its constraints","Expiry and configured conditions displayed clearly","Tap to inspect the resolver-provided eligibility details"]},{"name":"Merchant Payment Flow","description":"Pay with purpose-bound tokens at valid merchant","userFlow":["User at checkout","UI creates or loads the binding for the recipient and amount","Configured conditions shown with pending/unlocked state","User reviews the claim path","Recipient claims after isUnlocked(bindingId) is true"]},{"name":"Invalid Merchant Warning","description":"Clear feedback when tokens can't be used","userFlow":["User at non-eligible merchant","Binding shown as locked or not applicable","Clear explanation of the unresolved condition","Link to the issuer's condition or eligibility information","Alternative payment methods highlighted"]},{"name":"Expense Token with Receipt","description":"Corporate expense requiring documentation","userFlow":["User initiates expense payment","UI shows all requirements","Upload receipt if needed","Verify the configured condition and limits","Recipient claim proceeds when the binding unlocks"]}],"uiComponents":[{"name":"PurposeBoundBalance","description":"Token balance with restriction summary","states":["loading","loaded","restricted","expiring-soon"],"props":["amount","symbol","conditions","expiresAt","restrictions"]},{"name":"PurposeConditionChecker","description":"Show the deployed condition resolver's result for a binding","states":["checking","valid","invalid","unknown"],"props":["bindingId","conditions","isUnlocked"]},{"name":"SpendingLimitTracker","description":"Show used vs available within limits","states":["available","approaching-limit","at-limit"],"props":["used","limit","period","resetsAt"]},{"name":"ConditionExplorer","description":"Explore issuer-provided condition or eligibility data when available","states":["searching","results","no-results","loading"],"props":["bindingId","conditionType","issuerData"]}],"antiPatterns":[{"pattern":"Showing restricted tokens without explaining restrictions","why":"Users confused why payment fails","instead":"Show the binding's configured conditions, recipient, amount, and expiry; label merchant data as application-specific","severity":"critical"},{"pattern":"Letting users attempt invalid payments","why":"Wasted gas and frustrating experience","instead":"Check isUnlocked(bindingId) when supported before presenting the claim action","severity":"critical"},{"pattern":"Not showing expiry prominently","why":"Users lose tokens they forgot about","instead":"Highlight an optional binding expiry and notify users according to the issuer's policy","severity":"high"},{"pattern":"Hiding spending limits until exceeded","why":"Surprise rejections damage trust","instead":"Show limit progress: \"320/500 monthly remaining\"","severity":"high"},{"pattern":"No way to find valid merchants","why":"Users have tokens but don't know where to spend them","instead":"Offer condition or merchant discovery only when issuer/application data supports it","severity":"medium"}],"keyTakeaways":["ERC-7994 = tokens with built-in spending rules","Always show configured restrictions, recipient, amount, and expiry clearly","Show binding and unlock status before presenting a claim action","Provide condition or merchant discovery only when the issuer/application supplies it"],"technicalNotes":"ERC-7994 defines purpose bindings with a recipient, amount, an array of arbitrary UnlockCondition values, and optional expiry. The core lifecycle uses bindPurpose, isUnlocked(bindingId), and claim(bindingId); merchant, KYC, whitelist, receipt, category, and spending-limit semantics belong to the condition implementations. Do not assume an isValidTransfer selector, a universal merchant list, or an ordinary transfer flow.","lastUpdated":"2026-09-18","sources":[{"label":"ERC-7994 official specification","url":"https://ercs.ethereum.org/ERCS/erc-7994","type":"official-spec"}],"lastReviewed":"2026-09-18"},"sources":[{"label":"Official specification","url":"https://ercs.ethereum.org/ERCS/erc-7994","type":"official-spec"},{"label":"Discussion","url":"https://ethereum-magicians.org/search?q=ERC-7994","type":"discussion"},{"label":"ERC-7994 official specification","url":"https://ercs.ethereum.org/ERCS/erc-7994","type":"official-spec"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/ERC-7994","markdown":"https://www.eipsfordesigners.com/standards/ERC-7994/content.md","agent":"https://www.eipsfordesigners.com/standards/ERC-7994/agent.md","api":"https://www.eipsfordesigners.com/api/standards/ERC-7994","official":"https://ercs.ethereum.org/ERCS/erc-7994","discussion":"https://ethereum-magicians.org/search?q=ERC-7994"},"freshness":{"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18"}}