Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-Fungible Token with usage rights #4512

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
272 changes: 272 additions & 0 deletions EIPS/eip-4512.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
---
eip: 4512
title: Non-Fungible Token with usage rights
description: Separation of Non-Fungible Token ownership and usage rights , Truly in line with real life.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: Separation of Non-Fungible Token ownership and usage rights , Truly in line with real life.
description: ERC721 NFTs with a separate user role

status: Draft
type: Standards Track
author: KKimos (@KKimos), KKimos <[email protected]>
category: ERC
created: 2021-12-01
requires: 165, 721
---

## Abstract

This standard adds a new right of Non-Fungible Token that the right to use. Through this standard, you can achieve :

- Separation of the right to use and ownership of Non-Fungible Token
- Non-secured lease Non-Fungible Token
- You can continue to use it after you mortgage the Non-Fungible Token
- Metaverse sharing economy

It is precisely because of the separation of ownership and use right that the utilization rate of assets can be greater. You must distinguish between the rights of the user and the owner.

## Motivation

Uber, Airbnb, and WeWork promote the development of the sharing economy. In the blockchain , the ERC721-based leasing system has encountered great bottlenecks. For example, excess assets need to be mortgaged for leasing, The increase in NFT prices will lead to defaults ,You cannot continue to use it during NFT in mortgages. As a result, a new NFT standard is proposed, which is fully compatible with ERC-721. Separate the right to use and own the NFT.

Different from EIP-2615, we only added a right to use, so that we can get all the functions of EIP-2615, and reduce many unnecessary operations in EIP-2615. The explanation is as follows:
KKimos marked this conversation as resolved.
Show resolved Hide resolved

- The owner should not use some of the ownership rights when mortgage NFT, such as transfer, AXS-like breeding or weapon upgrade, because it is likely to change the status of the original NFT, so when the user mortgages the NFT, the ownership must be mortgaged in the contract middle.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you clarify what you mean by this? I suspect you're discussing a case where the owner (Alice) of an NFT is mortgaging the NFT via another party (Bob). Who is the owner now? Is Alice now theuser and Bob the owner? What is the "contract middle"?

I think is also laying down some guidelines for what a user can and cannot do, but I wasn't able to understand.

- In the case of mortgage or transaction, the owner has the right to continue to use it before returning the ransom or selling it
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the concept of a ransom elsewhere in the EIP. Maybe it would be beneficial if you outlined the flow of mortgaging and then paying off the mortgage of an NFT using this EIP?


## Specification

This standard adds the user role, and users can transfer their own usage rights.

### ERC-4512 Interface

```solidity
/**
* @dev Emitted when `tokenId` tokenUser is transferred from `from` to `to`.
*/
event TransferUser(address from,address to,uint256 tokenId);

/**
* @dev Emitted when `user` enables `approved` to manage the `tokenId` tokenUser.
*/
event ApprovalUser(address indexed user, address indexed approved, uint256 indexed tokenId);

/**
* @dev Returns the number of usable token in ``user``'s account.
*/
function balanceOfUser(address user) external view returns (uint256 balance);

/**
* @dev Returns the user of tokenId token
* Requirements:
*
* - `tokenId` must exist.
KKimos marked this conversation as resolved.
Show resolved Hide resolved
*/
function userOf(uint256 tokenId) external view returns (address user);

/**
* @dev Safely transfers `tokenId` tokenUser from `from` to `to`
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be used or owned by 'from'
* - If the caller is not `from`, it must be approved to move this tokenUser by {approve} or {setApprovalForAll} or {approveUser}.
*
* Emits a {TransferUser} event.
*/
function safeTransferUserFrom(
address from,
address to,
uint256 tokenId
) external;

/**
* @dev Safely transfers `tokenId` tokenUser from `from` to `to`
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be used or owned by 'from'
* - If the caller is not `from`, it must be approved to move this tokenUser by {approve} or {setApprovalForAll} or {approveUser}.
*
* Emits a {TransferUser} event.
*/
function safeTransferUserFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;

/**
* @dev Safely transfers `tokenId` token and tokenUser from `from` to `to`
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by 'from'
* - If the caller is not `from`, it must be approved to move this tokenUser by {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} and a {TransferUser} event.
*/
function safeTransferAllFrom(
address from,
address to,
uint256 tokenId
) external;

/**
* @dev Safely transfers `tokenId` token and tokenUser from `from` to `to`
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by 'from'
* - If the caller is not `from`, it must be approved to move this tokenUser by {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} and a {TransferUser} event.
*/
function safeTransferAllFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;

/**
* @dev Gives permission to `to` to transfer `tokenId` tokenUser to another account.
* The approval is cleared when the tokenUser is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must be tokenUser or be an approvedUser operator.
* - `tokenId` must exist.
*
* Emits an {ApprovalUser} event.
*/
function approveUser(address to, uint256 tokenId) external;

/**
* @dev Returns the approvedUser for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApprovedUser(uint256 tokenId) external view returns (address operator);
```

### ERC-4512 Receiver

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above, imho the interface for ERC4512Receiver should be included here for reference

```solidity
function onERCXReceived(address operator, address from, uint256 itemId, uint256 layer, bytes memory data) public returns(bytes4);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function onERCXReceived(address operator, address from, uint256 itemId, uint256 layer, bytes memory data) public returns(bytes4);
function onERC4512Received(address operator, address from, uint256 itemId, uint256 layer, bytes memory data) public returns(bytes4);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, why is itemId being used instead of the usual ERC721 tokenId?

```

### ERC-4512 Extensions

Extensions here are provided to help developers build with this standard.

#### 1. ERC-4512 Enumerable

```solidity
/**
* @dev Returns a tokenId used by `user` at a given `index` of its token list.
* Use along with {balanceOfUser} to enumerate all of ``user``'s tokens.
*/
function tokenOfUserByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

/**
* @dev Returns the total amount of tokens stored by the contract.
*/
function totalSupply() external view returns (uint256);

/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

/**
* @dev Returns a tokenId at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/
function tokenByIndex(uint256 index) external view returns (uint256);
```

#### 2. ERC-721

Fully compatible with ERC-721

```solidity
interface ERC721{
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
function balanceOf(address _owner) external view returns (uint256);
function ownerOf(uint256 _tokenId) external view returns (address);
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
function approve(address _approved, uint256 _tokenId) external payable;
function setApprovalForAll(address _operator, bool _approved) external;
function getApproved(uint256 _tokenId) external view returns (address);
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
}
interface ERC165 {
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
```
Comment on lines +207 to +229
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#### 2. ERC-721
Fully compatible with ERC-721
```solidity
interface ERC721{
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
function balanceOf(address _owner) external view returns (uint256);
function ownerOf(uint256 _tokenId) external view returns (address);
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
function approve(address _approved, uint256 _tokenId) external payable;
function setApprovalForAll(address _operator, bool _approved) external;
function getApproved(uint256 _tokenId) external view returns (address);
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
}
interface ERC165 {
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
```

imho this is unnecessary




## Rationale

#### 1 . Mortgage

When mortgage NFT, you only need to mortgage the right to use into the mortgage contract, leaving the right to use.The advantage of this is that you can still use your own NFT before delivery.

#### 2 . Rent

Lease does not require any collateral. First, you mortgage the NFT ownership into the contract, and the tenantry leases the right to use.

This has the following benefits :

- No need to mortgage assets
- Don't worry about the risk of default
Comment on lines +235 to +246
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to above, I'm personally not fully understanding the intended path to leverage this EIP for NFT mortgages or rentals. The Rationale section is more for design decisions, so I don't know if this would be the right place to put it, but I think that at least for myself, if there would be more in the Motivation explaining how this EIP is intended to be leveraged, it would help me understand here.

This would also be a good section for discussing why the authors opted to create a more simplified EIP-2612, and any other alternatives that were considered but ultimately discarded in favour of the current EIP.


## Backward compatibility

This protocol is fully backward compatible with ERC721.Refer to above Specification.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This protocol is fully backward compatible with ERC721.Refer to above Specification.
This protocol is fully backward compatible with ERC721. Refer to the Specification section above for more details.




## Test Cases

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any tests - are there tests somewhere to run?

When running the tests, you need to create a test network with Ganache-CLI:

```
ganache-cli -a 15 --gasLimit=0x1fffffffffffff -e 1000000000
```

And then run the tests using Truffle:

```
truffle test -e development
```

Powered by Truffle and Openzeppelin test helper.

## Reference Implementation

[Github Reposotory](../assets/eip-4512).



## Security Considerations

When using the modified agreement, you must distinguish between the right of use and ownership. In theory, the right of use cannot change the NFT.



## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
Binary file added assets/eip-4512/LICENSE
Binary file not shown.
2 changes: 2 additions & 0 deletions assets/eip-4512/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# ERCX
Unsecured Leasing NFT Promotes the Development of Metaverse's Sharing Economy
Loading