forked from DecentralizedClimateFoundation/DCIPs
177 lines
6.9 KiB
Markdown
177 lines
6.9 KiB
Markdown
|
---
|
||
|
eip: 5380
|
||
|
title: ERC-721 Entitlement Extension
|
||
|
description: Allows token owners to grant the ability for others to use specific properties of those tokens
|
||
|
author: Gavin John (@Pandapip1), Tim Daubenschütz (@TimDaub)
|
||
|
discussions-to: https://ethereum-magicians.org/t/pr-5380-eip-4907-alternative-design/10190
|
||
|
status: Final
|
||
|
type: Standards Track
|
||
|
category: ERC
|
||
|
created: 2022-03-11
|
||
|
requires: 165, 721, 1046
|
||
|
---
|
||
|
|
||
|
## Abstract
|
||
|
|
||
|
This EIP proposes a new interface that allows [ERC-721](./eip-721.md) token owners to grant limited usage of those tokens to other addresses.
|
||
|
|
||
|
## Motivation
|
||
|
|
||
|
There are many scenarios in which it makes sense for the owner of a token to grant certain properties to another address. One use case is renting tokens. If the token in question represents a trading card in an on-chain TCG (trading card game), one might want to be able to use that card in the game without having to actually buy it. Therefore, the owner might grant the renter the "property" of it being able to be played in the TCG. However, this property should only be able to be assigned to one person at a time, otherwise a contract could simply "rent" the card to everybody. If the token represents usage rights instead, the property of being allowed to use the associated media does not need such a restriction, and there is no reason that the property should be as scarce as the token.
|
||
|
|
||
|
## Specification
|
||
|
|
||
|
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
|
||
|
|
||
|
### Base
|
||
|
|
||
|
Compliant entitlement contracts MUST implement the following Solidity interface:
|
||
|
|
||
|
```solidity
|
||
|
/// SPDX-License-Identifier: CC0-1.0
|
||
|
pragma solidity ^0.8.0;
|
||
|
|
||
|
interface ERC5380Entitlement is ERC165 {
|
||
|
/// @notice Emitted when the amount of entitlement a user has changes. If user is the zero address, then the user is the owner
|
||
|
event EntitlementChanged(address indexed user, address indexed contract, uint256 indexed tokenId);
|
||
|
|
||
|
/// @notice Set the user associated with the given ERC-721 token as long as the owner is msg.sender.
|
||
|
/// @dev SHOULD NOT revert if the owner is not msg.sender.
|
||
|
/// @param user The user to grant the entitlement to
|
||
|
/// @param contract The property to grant
|
||
|
/// @param tokenId The tokenId to grant the properties of
|
||
|
function entitle(address user, address contract, uint256 tokenId) external;
|
||
|
|
||
|
/// @notice Get the maximum number of users that can receive this entitlement
|
||
|
/// @param contract The contract to query
|
||
|
/// @param tokenId The tokenId to query
|
||
|
function maxEntitlements(address contract, uint256 tokenId) external view (uint256 max);
|
||
|
|
||
|
/// @notice Get the user associated with the given contract and tokenId.
|
||
|
/// @dev Defaults to maxEntitlements(contract, tokenId) assigned to contract.ownerOf(tokenId)
|
||
|
/// @param user The user to query
|
||
|
/// @param contract The contract to query
|
||
|
/// @param tokenId The tokenId to query
|
||
|
function entitlementOf(address user, address contract, uint256 tokenId) external view returns (uint256 amt);
|
||
|
}
|
||
|
```
|
||
|
|
||
|
`supportsInterface` MUST return true when called with `ERC5380Entitlement`'s interface ID.
|
||
|
|
||
|
### Enumerable Extension
|
||
|
|
||
|
This OPTIONAL Solidity interface is RECOMMENDED.
|
||
|
|
||
|
```solidity
|
||
|
/// SPDX-License-Identifier: CC0-1.0
|
||
|
pragma solidity ^0.8.0;
|
||
|
|
||
|
interface ERC5380EntitlementEnumerable is ERC5380Entitlement { // Also implicitly supports ERC-165
|
||
|
/// @notice Enumerate tokens with nonzero entitlement assigned to a user
|
||
|
/// @dev Throws if the index is out of bounds or if user == address(0)
|
||
|
/// @param user The user to query
|
||
|
/// @param index A counter
|
||
|
function entitlementOfUserByIndex(address user, uint256 index) external view returns (address contract, uint256 tokenId);
|
||
|
}
|
||
|
```
|
||
|
|
||
|
`supportsInterface` MUST return true when called with `ERC5380EntitlementEnumerable`'s interface ID.
|
||
|
|
||
|
### Metadata Extension
|
||
|
|
||
|
This OPTIONAL Solidity interface is RECOMMENDED.
|
||
|
|
||
|
This extension uses [ERC-1046](./eip-1046.md) for `tokenURI` compatibility.
|
||
|
|
||
|
```solidity
|
||
|
/// SPDX-License-Identifier: CC0-1.0
|
||
|
pragma solidity ^0.8.0;
|
||
|
|
||
|
interface ERC5380EntitlementMetadata is ERC5380Entitlement { // Also implicitly supports ERC-165
|
||
|
/// @notice ERC-1046 token URI
|
||
|
/// @dev See ERC-1046 and the metadata schema below
|
||
|
function tokenURI() external view returns (string);
|
||
|
}
|
||
|
```
|
||
|
|
||
|
`supportsInterface` MUST return true when called with `ERC5380EntitlementMetadata`'s interface ID.
|
||
|
|
||
|
#### Interoperability Metadata Extension
|
||
|
|
||
|
ERC-1046's `InteroperabilityMetadata` is extended with the following TypeScript interface:
|
||
|
|
||
|
```typescript
|
||
|
/**
|
||
|
* ERC-5380's extension to ERC-1046's Interoperability metadata.
|
||
|
*/
|
||
|
interface ERC5380InteroperabilityMetadata is InteroperabilityMetadata {
|
||
|
/**
|
||
|
* This MUST be true if this is ERC-5380 Token Metadata, otherwise, this MUST be omitted.
|
||
|
* Setting this to true indicates to wallets that the address should be treated as an ERC-5380 entitlement.
|
||
|
**/
|
||
|
erc5380?: boolean | undefined;
|
||
|
}
|
||
|
```
|
||
|
|
||
|
#### `tokenURI` Metadata Schema
|
||
|
|
||
|
The resolved `tokenURI` data MUST conform to the following TypeScript interface:
|
||
|
|
||
|
```typescript
|
||
|
/**
|
||
|
* ERC-5380 Asset Metadata
|
||
|
* Can be extended
|
||
|
*/
|
||
|
interface ERC5380TokenMetadata {
|
||
|
/**
|
||
|
* Interoperabiliy, to differentiate between different types of tokens and their corresponding URIs.
|
||
|
**/
|
||
|
interop: ERC5380InteroperabilityMetadata;
|
||
|
|
||
|
/**
|
||
|
* The name of the ERC-5380 token.
|
||
|
*/
|
||
|
name?: string;
|
||
|
|
||
|
/**
|
||
|
* The symbol of the ERC-5380 token.
|
||
|
*/
|
||
|
symbol?: string;
|
||
|
|
||
|
/**
|
||
|
* Provides a short one-paragraph description of the ERC-5380 token, without any markup or newlines.
|
||
|
*/
|
||
|
description?: string;
|
||
|
|
||
|
/**
|
||
|
* One or more URIs each pointing to a resource with mime type `image/*` that represents this token.
|
||
|
* If an image is a bitmap, it SHOULD have a width between 320 and 1080 pixels
|
||
|
* Images SHOULD have an aspect ratio between 1.91:1 and 4:5 inclusive.
|
||
|
*/
|
||
|
images?: string[];
|
||
|
|
||
|
/**
|
||
|
* One or more URIs each pointing to a resource with mime type `image/*` that represent an icon for this token.
|
||
|
* If an image is a bitmap, it SHOULD have a width between 320 and 1080 pixels, and MUST have a height equal to its width
|
||
|
* Images MUST have an aspect ratio of 1:1, and use a transparent background
|
||
|
*/
|
||
|
icons?: string[];
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Rationale
|
||
|
|
||
|
[ERC-20](./eip-20.md) and [ERC-1155](./eip-1155.md) are unsupported as partial ownership is much more complex to track than boolean ownership.
|
||
|
|
||
|
## Backwards Compatibility
|
||
|
|
||
|
No backward compatibility issues were found.
|
||
|
|
||
|
## Security Considerations
|
||
|
|
||
|
The security considerations of [ERC-721](./eip-721.md) and [ERC-1046](./eip-1046.md) apply.
|
||
|
|
||
|
## Copyright
|
||
|
|
||
|
Copyright and related rights waived via [CC0](../LICENSE.md).
|