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

Add EIP-1238.md #4966

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
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
152 changes: 152 additions & 0 deletions EIPS/eip-1238.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
---
eip: 1238
TimDaub marked this conversation as resolved.
Show resolved Hide resolved
title: Non-Transferrable Non-Fungible Tokens (Soulbound Tokens)
TimDaub marked this conversation as resolved.
Show resolved Hide resolved
author: Nicola Greco, Tim Daubenschütz <tim@daubenschuetz.de>
TimDaub marked this conversation as resolved.
Show resolved Hide resolved
discussions-to: https://github.com/ethereum/eips/issues/1238
TimDaub marked this conversation as resolved.
Show resolved Hide resolved
type: Standards Track
category: ERC
status: Draft
created: 2022-04-01
requires: 165, 721
---

## Simple Summary

A standard interface for non-transferrable non-fungible tokens, also known as
"soulbound tokens" (short "SBT").

TimDaub marked this conversation as resolved.
Show resolved Hide resolved
## Abstract

The following standard allows for the implementation of a standard API for SBTs
within smart contracts. This standard provides basic functionality to gift,
mint and track SBTs.

## Motivation

`ERC1238` tokens inhert their metadata model from `ERC721`'s metadata. Wallets
can differentiate between `ERC1238` and transferrable `ERC721` tokens through
`ERC165`'s `supportsInterface(bytes4 interfaceID);` method.

When a wallet detects support for `IERC721Metadata` (`interfaceID`:
`0x5b5e139f`), it can additonal check if transfer functionality via

- `IERC721` (`interfaceID`: `0x80ac58cd`); or
- soulbound properties via `IERC1238` (`interfaceID`: `0xad5ec850`)

are supported.

Since `ERC1238` supports `ERC721Metadata`, if implemented correctly, `ERC721` wallets
should be able to display `ERC1238` tokens without the need for any modifications
from developers. `ERC721`'s transfer functionality could be hidden from the UI if
`interfaceID` `0x80ac58cd` isn't supported or `ERC1238`'s `interfaceID` is
detected.

## Specification

The key words "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.

**Every `ERC1238` compliant contract must implement the `ERC1238`,
`ERC721Metadata` and `ERC165` interfaces** (subject to "caveats" below):

```solidity
pragma solidity ^0.8.6;

/// @title ERC-1238 Non-Transferrable Non-Fungible Token Standard
/// @dev See https://eips.ethereum.org/EIPS/eip-1238
/// Note: the ERC-165 identifier for this interface is 0xad5ec850.
interface IERC1238 /* is ERC165, ERC721Metadata */ {
/// @dev This emits when bond of any SBT is established by any mechanism.
/// This event emits when SBTs are created (`from` == 0) and destroyed
/// (`to` == 0). Exception: during contract creation, any number of SBTs
/// may be created and assigned without emitting Bond.
event Bond(address indexed _from, address indexed _to, uint256 indexed _tokenId);
/// @notice Find the address bound to an ERC1238 soulbound token (short "SBT")
/// @dev SBTs assigned to zero address are considered invalid, and queries
/// about them do throw.
/// @param _tokenId The identifier for an SBT
/// @return The address of the owner bound to the SBT
function boundTo(uint256 _tokenId) external view returns (address);
}

interface ERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceID The interface identifier, as specified in ERC-165
/// @dev Interface identification is specified in ERC-165. This function
/// uses less than 30,000 gas.
/// @return `true` if the contract implements `interfaceID` and
/// `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
/// Note: the ERC-165 identifier for this interface is 0x5b5e139f.
interface ERC721Metadata /* is ERC721 */ {
/// @notice A descriptive name for a collection of NFTs in this contract
function name() external view returns (string _name);

/// @notice An abbreviated name for NFTs in this contract
function symbol() external view returns (string _symbol);

/// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
/// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
/// 3986. The URI may point to a JSON file that conforms to the "ERC721
/// Metadata JSON Schema".
function tokenURI(uint256 _tokenId) external view returns (string);
}
```

For "ERC721 Metadata JSON Schema", see `ERC721` document.

### Caveats

No caveats known for now.

## Rationale

Since 2018, the Ethereum community has been seeking consensus for a standard
for non-transferrable non-fungible token.

For `ERC1238`, we propose:

- `event Bond(address indexed _from, address indexed _to, uint256 indexed _tokenId)`, essentially `ERC721`'s Transfer event but renamed to "Bond".
- `function boundTo(uint256 _tokenId) external view returns (address)`,
essentially `ERC721`'s `ownerOf(uint256 _tokenId)` but renamed to `boundTo`.

The benefit of using the `ERC721Metadata` interface is that implementers (e.g.
wallets) of `ERC1238` can identify transfer and tracking functionality using the
`ERC165` `supportsInterface(bytes4 interfaceID)` function.

## Backwards Compatibility

We have adopted the `ERC165` and `ERC721Metadata` functions. `ERC1238`'s
`boundTo` function is the pendant to `ERC721`'s `ownerOf` function.

## Test Cases

See "Implementations" section.

TimDaub marked this conversation as resolved.
Show resolved Hide resolved
## Implementations

- [rugpullindex/ERC1238](https://github.com/rugpullindex/ERC1238) is a minimal
implementation using `burn` and `mint` and test cases released under GNU
General Public License v3.0.

TimDaub marked this conversation as resolved.
Show resolved Hide resolved
## References

**Standards**

1. [ERC-165](./eip-165.md) Standard Interface Detection.
1. [ERC-721](https://github.com/ethereum/EIPs/issues/721) Token Standard.
1. Soulbound. https://vitalik.ca/general/2022/01/26/soulbound.html
1. RFC 2119 Key words for use in RFCs to Indicate Requirement Levels. https://www.ietf.org/rfc/rfc2119.txt

**Issues**

1. The Original ERC-1238 Issue. https://github.com/ethereum/eips/issues/1238

TimDaub marked this conversation as resolved.
Show resolved Hide resolved
## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).