NFTs are one of the web3 products that brought a lot of adoption and recognition to the web3 ecosystem. Some NFTs are exclusive and with limited supply, and some require a large capital investment making them somewhat inaccessible.
Abstract //Non-technical
A rentable NFT is an NFT that can be rented by a different wallet address (Rentee) other than the token owner’s wallet address (Renter). Rentee gets access to its utility for a certain amount of time before its renting period expires, Rentee cannot burn or transfer the NFT and can only use it for Token Gated utilities.
Use Case: Party Pass //Non-technical
Party Pass is a ticket to enter the most exclusive Token Gated Meetups parties all around the world. Bob and Jay are 2 personas that we will use to illustrate the use case. Bob is an entrepreneur, living in NYC, who’s building his community in his specific niche industry. Bob has minted a Party Pass NFT as a utility token that gives him access to recurrent exclusive meetups with his fellow niche members in NYC and nearby. Jay is an entrepreneur in the same niche that’s living in Singapore, Meetups are also organized there, but less frequently, and it definitely doesn’t worth purchasing an entire Party Pass NFT. In this case, renting an NFT pass from Bob for a specific period of time might be a better deal for Jay. And it’s a triple-win situation here. Jay gets access to the event at a lower price, Bob gets passive income for the NFT when he’s not using it, and the meetups parties organizers increase their pass floor price.
Rentable NFTs projects can also address a larger market and open new avenues of use cases to make their NFT utility more accessible to users. Whenever it’s valuable to renting instead of buy, it’s valuable to use a rent NFT protocol.
Functioning of Rentable NFT
Here there are three main layers to the function of rental NFT
Client
Rental contract
NFT contract
The renting process goes with a three-phase process to complete
Listing
Leasing
Redeem
Technical working of rental NFTs
EIP-4907: Rental NFT (Status: Final)
EIP-4907 is an extension of the EIP721 standard. It proposes an additional role (user) that can be granted to addresses. It also specifies a time when the role is automatically revoked (expires). The user role represents permission to use the NFT, but not the ability to transfer it or set users.
Key Characteristics
NFT will not be transferable by the Rentee
Rentee can only use it for Token Gated utilities
On expiry, the Rentee can no longer access it
The NFT ownership status (Rentee has changed, Rentee has expired) can be logged thanks to the following functions
updateUser: sets the user and expires of NFT
setUser: Get the user address of an NFT
userOf: Get the user expiration of an NFT
EIP-4907 interface
interface IERC4907 {
// Logged when the user of an NFT is changed or expires is changed
/// @notice Emitted when the `user` of an NFT or the `expires` of the `user` is changed
/// The zero address for user indicates that there is no user address
event UpdateUser(uint256 indexed tokenId, address indexed user, uint64 expires);/// @notice set the user and expires of an NFT
/// @dev The zero address indicates there is no user
/// Throws if `tokenId` is not valid NFT
/// @param user The new user of the NFT
/// @param expires UNIX timestamp, The new user could use the TNFT before expires
function setUser(uint256 tokenId, address user, uint64 expires) external;
/// @notice Get the user address of an NFT
/// @dev The zero address indicates that there is no user or the user is expired
/// @param tokenId The NFT to get the user address for
/// @return The user address for this NFT
function userOf(uint256 tokenId) external view returns(address);
/// @notice Get the user expires of an NFT
/// @dev The zero value indicates that there is no user
/// @param tokenId The NFT to get the user expires for
/// @return The user expires for this NFT
function userExpires(uint256 tokenId) external view returns(uint256);
}
ERC-4907 Smart Contract
The Below code is an example of a rentable NFT smart contract ERC4907. It is a simple ERC721 token with features such as mintable, auto-increment IDs, URI storage, and access control set to ownable. On top of it, we add the above-mentioned functions : updateUser, setUser, and userOf.
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "./IERC4907.sol";
contract ERC4907 is ERC721, IERC4907 {
struct UserInfo
{
address user; // address of user role
uint64 expires; // unix timestamp, user expires
}
mapping (uint256 => UserInfo) internal _users;
constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}
/// @notice set the user and expires of an NFT
/// @dev The zero address indicates there is no user
/// Throws if `tokenId` is not valid NFT
/// @param user The new user of the NFT
/// @param expires UNIX timestamp, The new user could use the NFT before expires
function setUser(uint256 tokenId, address user, uint64 expires) public override virtual{
require(_isApprovedOrOwner(msg.sender, tokenId), "ERC4907: transfer caller is not owner nor approved");
UserInfo storage info = _users[tokenId];
// require(info.expires < block.timestamp, "Already rented to someone");
info.user = user;
info.expires = expires;
emit UpdateUser(tokenId, user, expires);
}
/// @notice Get the user address of an NFT
/// @dev The zero address indicates that there is no user or the user is expired
/// @param tokenId The NFT to get the user address for
/// @return The user address for this NFT
function userOf(uint256 tokenId) public view override virtual returns(address){
if (uint256(_users[tokenId].expires) >= block.timestamp) {
return _users[tokenId].user;
} else {
return ownerOf(tokenId);
}
}
/// @notice Get the user expires of an NFT
/// @dev The zero value indicates that there is no user
/// @param tokenId The NFT to get the user expires for
/// @return The user expires for this NFT
function userExpires(uint256 tokenId) public view override virtual returns(uint256){
if (uint256(_users[tokenId].expires) >= block.timestamp) {
return _users[tokenId].expires;
} else {
return 115792089237316195423570985008687907853269984665640564039457584007913129639935;
}
}
/// @dev See {IERC165-supportsInterface}.
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC4907).interfaceId || super.supportsInterface(interfaceId);
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override{
super._beforeTokenTransfer(from, to, tokenId);
if (from != to && _users[tokenId].user != address(0)) {
delete _users[tokenId];
emit UpdateUser(tokenId, address(0), 0);
}
}
function mint(uint256 tokenId) public {
// this is the mint function that you need to customize for yourself
_mint(msg.sender, tokenId);
}
function time() public view returns (uint256) {
return block.timestamp;
}
}
EIP-5501: Rental & Delegation NFT (Status: Draft)
EIP-5501 is another standard proposal that addresses additional user roles for EIP-721. It grants permission to use the NFT with no ability to transfer or set users, it has an expiry date, and flags if the token is borrowed or not. The owner can delegate the NFT for usage to hot wallets or lend the NFT. Terminating the borrowing requires the approval of both parties.
Key Characteristics:
No ability to transfer or set users
Expiry flag for token borrowing
Token delegation
The owner cannot access NFT in the leased period
Projects
Dobby Protocol
DOBBY protocol seeks to become the best-decentralized platform for renting, lending, and mortgaging NFTs developing a global lending and borrowing market based on the collateral-free rental of NFTs by utilizing the potential ERC 4907 & 5501 standard offers. The main objective is to make it possible for the owner to lend NFTs without having to remove the token from their wallet.
Double Protocol
Double Protocol is a fully decentralized and open-source NFT rental protocol and marketplace for Metaverse and GameFi assets.
Building a Rentable NFT Project with Zero-Code.io
Creating a Rentable NFT project can be a complex process from building a landing page with rent enablements to deploying NFT smart contracts with correct rent functionalities. Zero-Code is building a one-stop customizable solution for all your web3 needs, enabling you to create a wide selection of token standards including rentable NFTs, with a ludic and friendly experience.
Comments