{"id":"ERC-4907","name":"Rental NFT","status":"Final","chain":"both","category":{"id":"nft","name":"NFT Capabilities","description":"What NFTs can do beyond basic ownership"},"journeyStages":[{"id":"approving","name":"Approving & Permissioning","description":"Granting permissions for actions"},{"id":"management","name":"Asset Management","description":"Managing assets over time"}],"uxImpact":"ERC-4907 adds rental functionality to NFTs. The owner can rent out their NFT to a \"user\" for a set time period. The renter gets usage rights without ownership. When the rental expires, usage rights automatically revert. Perfect for game items, virtual land, or any NFT with utility that can be temporarily shared.","officialUrl":"https://ercs.ethereum.org/ERCS/erc-4907","lastReviewed":"2026-09-18","lastUpdated":"2026-09-18","kind":"proposal","hasDetailedContent":true,"content":{"id":"ERC-4907","summary":"ERC-4907 adds rental functionality to NFTs. The owner can rent out their NFT to a \"user\" for a set time period. The renter gets usage rights without ownership. When the rental expires, usage rights automatically revert. Perfect for game items, virtual land, or any NFT with utility that can be temporarily shared.","applicability":{"whenToUse":["Your product addresses: no standard way to rent NFTs.","Your product addresses: renter could sell/transfer the NFT.","The flow should deliver: set user + expiration, owner keeps ownership.","You are designing a rental listing experience with visible states and recovery paths."],"whenToAvoid":["The product requires quantity-based ERC-1155 rentals or a different custody model.","The token does not implement the user role and expiry interface.","The consuming app does not grant the intended utility to the current user."]},"designerTakeaways":["Design the flow to support set user + expiration, owner keeps ownership.","Design the flow to support owner retains ownership, only usage is delegated.","Design the flow to support simple setUser() call with expiration."],"problemsSolved":[{"problem":"No standard way to rent NFTs","oldWay":"Transfer NFT, trust renter to return it (they often don't)","newWay":"Set user + expiration, owner keeps ownership","impact":"critical"},{"problem":"Expensive to \"loan\" NFTs safely","oldWay":"Use escrow contracts, complex collateral systems","newWay":"Simple setUser() call with expiration","impact":"high"},{"problem":"Renter could sell/transfer the NFT","oldWay":"Owner loses asset if they transfer ownership for rental","newWay":"Owner retains ownership, only usage is delegated","impact":"critical"}],"uxPatterns":[{"name":"Rental Listing","description":"List NFT for rent with price and duration","userFlow":["Owner selects NFT to rent","Sets price per day","Sets maximum duration","Signs rental listing","NFT available for rent"]},{"name":"Rental Marketplace","description":"Browse and rent NFTs","userFlow":["User browses available rentals","Clicks \"Rent\" on desired item","Selects rental duration","Pays rental fee","Becomes \"user\" of NFT"]},{"name":"Active Rental Status","description":"View current rental with countdown","userFlow":["User views their rental","Sees time remaining","Progress bar shows rental period","Option to extend before expiry","Warning as expiration approaches"]}],"uiComponents":[{"name":"RentalCard","description":"NFT card with rental info","states":["available","rented-by-you","rented-by-other","your-listing"],"props":["nft","price","duration","user","expires"]},{"name":"ExpirationTimer","description":"Countdown to rental expiration","states":["plenty-of-time","expiring-soon","expired"],"props":["expiresAt","onExpire"]},{"name":"RentalDurationPicker","description":"Select how long to rent","states":["selecting","selected"],"props":["minDuration","maxDuration","pricePerDay","onChange"]},{"name":"UserRoleBadge","description":"Shows if you're owner vs user","states":["owner","user","both","neither"],"props":["owner","user","currentAccount"]}],"antiPatterns":[{"pattern":"Not showing expiration prominently","why":"User loses access unexpectedly","instead":"Always show countdown, warn as expiration approaches","severity":"critical"},{"pattern":"Confusing \"owner\" and \"user\" roles","why":"Users don't understand their rights","instead":"Clear badges: \"You OWN this\" vs \"You RENT this\"","severity":"high"},{"pattern":"Not checking userOf(tokenId) before granting access","why":"Expired rentals could still access utility","instead":"Check that userOf(tokenId) returns the requesting user at the relevant chain state. Use userExpires(tokenId) for the countdown and follow the deployed contract's expiry boundary, not a stricter comparison against the device clock.","severity":"critical"},{"pattern":"No reminder before expiration","why":"User surprised when access revoked","instead":"Notify at 24h, 1h, and near expiration","severity":"high"}],"keyTakeaways":["ERC-4907 = NFT rentals with automatic expiration","Owner keeps ownership, user gets usage rights","Always check expiration before granting access","Show clear countdown to expiration","Distinguish \"owner\" vs \"user\" roles clearly"],"specConstraints":[{"id":"user-expiry-state","constraint":"Applications should use the UpdateUser event to refresh user-address and expiry state, while keeping the user role distinct from ownership.","appliesTo":"application","normativity":"normative","specQuote":"The `UpdateUser` event MUST be emitted when a user address is changed or the user expires is changed.","specSection":"Specification / Contract Interface","specUrl":"https://ercs.ethereum.org/ERCS/erc-4907#contract-interface","designImplication":"Refresh the displayed user and expiry when this event is observed, show the owner and user as separate roles, and do not treat expiry as an ownership transfer."},{"id":"erc721-compatibility","constraint":"The rental extension is designed to remain compatible with EIP-721 when its extension functions are added.","appliesTo":"application","normativity":"backwards-compatibility","specQuote":"this standard can be fully EIP-721 compatible by adding an extension function set.","specSection":"Backwards Compatibility","specUrl":"https://ercs.ethereum.org/ERCS/erc-4907#backwards-compatibility","designImplication":"Keep ordinary NFT ownership and transfer affordances available, then layer rental status and expiry on top instead of replacing the underlying ERC-721 model."},{"id":"owner-revocation","constraint":"The owner can change the assigned NFT user and expiry at any time.","appliesTo":"application","normativity":"security-considerations","specQuote":"the owner can change the NFT user and expires at any time.","specSection":"Security Considerations","specUrl":"https://ercs.ethereum.org/ERCS/erc-4907#security-considerations","designImplication":"Make owner-controlled reassignment and expiry visible in access and rental UI; do not imply that a user-held rental cannot be replaced before its displayed end time."}],"technicalNotes":"ERC-4907 extends ERC-721 with setUser(tokenId, user, expires), userOf(tokenId), and userExpires(tokenId). The user role does not itself grant ERC-721 transfer authority. In the reference implementation, userOf returns the assigned user while expires >= block.timestamp and address(0) once block.timestamp > expires. Use the deployed contract's result for access checks. UpdateUser is emitted on assignment changes; expiration does not require a transaction. Contracts unaware of ERC-4907 still see the underlying ERC-721.","lastUpdated":"2026-09-18","sources":[{"label":"ERC-4907 official specification","url":"https://ercs.ethereum.org/ERCS/erc-4907","type":"official-spec"}],"lastReviewed":"2026-09-18"},"sources":[{"label":"Official specification","url":"https://ercs.ethereum.org/ERCS/erc-4907","type":"official-spec"},{"label":"Discussion search","url":"https://ethereum-magicians.org/search?q=ERC-4907","type":"discussion"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/ERC-4907","markdown":"https://www.eipsfordesigners.com/standards/ERC-4907/content.md","agent":"https://www.eipsfordesigners.com/standards/ERC-4907/agent.md","api":"https://www.eipsfordesigners.com/api/standards/ERC-4907","official":"https://ercs.ethereum.org/ERCS/erc-4907","discussion":"https://ethereum-magicians.org/search?q=ERC-4907"},"freshness":{"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18"}}