---
eip: 5007
title: Time NFT, ERC-721 Time Extension
description: Add start time and end time to ERC-721 tokens.
author: Anders (@0xanders), Lance (@LanceSnow), Shrug <shrug@emojidao.org>
discussions-to: https://ethereum-magicians.org/t/eip-5007-eip-721-time-extension/8924
status: Final
type: Standards Track
category: ERC
created: 2022-04-13
requires: 165, 721
---

## Abstract

This standard is an extension of [ERC-721](./eip-721.md). It proposes some additional functions (`startTime`, `endTime`) to help with on-chain time management.

## Motivation

Some NFTs have a defined usage period and cannot be used outside of that period. With traditional NFTs that do not include time information, if you want to mark a token as invalid or enable it at a specific time, you need to actively submit a transaction—a process both cumbersome and expensive.

Some existing NFTs contain time functions, but their interfaces are not consistent, so it is difficult to develop third-party platforms for them.

By introducing these functions (`startTime`, `endTime`), it is possible to enable and disable NFTs automatically on chain.

## 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.

```solidity
/**
 * @dev the ERC-165 identifier for this interface is 0xf140be0d.
 */
interface IERC5007 /* is IERC721 */ {
    /**
     * @dev Returns the start time of the NFT as a UNIX timestamp.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function startTime(uint256 tokenId) external view returns (uint64);
    
    /**
     * @dev Returns the end time of the NFT as a UNIX timestamp.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function endTime(uint256 tokenId) external view returns (uint64);

}
```

The **composable extension** is OPTIONAL for this standard. This allows your NFT to be minted from an existing NFT or to merge two NFTs into one NFT.

```solidity
/**
 * @dev the ERC-165 identifier for this interface is 0x75cf3842.
 */
interface IERC5007Composable /* is IERC5007 */ {
    /**
     * @dev Returns the asset id of the time NFT.
     * Only NFTs with same asset id can be merged.
     * 
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function assetId(uint256 tokenId) external view returns (uint256);

    /**
     * @dev Split an old token to two new tokens.
     * The assetId of the new token is the same as the assetId of the old token
     *
     * Requirements:
     *
     * - `oldTokenId` must exist.
     * - `newToken1Id` must not exist.
     * - `newToken1Owner` cannot be the zero address.
     * - `newToken2Id` must not exist.
     * - `newToken2Owner` cannot be the zero address.
     * - `splitTime`  require(oldToken.startTime <= splitTime && splitTime < oldToken.EndTime)
     */
    function split(
        uint256 oldTokenId,
        uint256 newToken1Id,
        address newToken1Owner,
        uint256 newToken2Id,
        address newToken2Owner,
        uint64 splitTime
    ) external;

    /**
     * @dev Merge the first token and second token into the new token.
     *
     * Requirements:
     *
     * - `firstTokenId` must exist.
     * - `secondTokenId` must exist.
     * - require((firstToken.endTime + 1) == secondToken.startTime)
     * - require((firstToken.assetId()) == secondToken.assetId())
     * - `newTokenOwner` cannot be the zero address.
     * - `newTokenId` must not exist.
     */
    function merge(
        uint256 firstTokenId,
        uint256 secondTokenId,
        address newTokenOwner,
        uint256 newTokenId
    ) external;
}
```

## Rationale

### Time Data Type

The max value of `uint64` is 18,446,744,073,709,551,615. As a timestamp, 18,446,744,073,709,551,615 is about year 584,942,419,325. `uint256` is too big for C, C++, Java, Go, etc, and `uint64` is natively supported by mainstream programming languages.

## Backwards Compatibility

This standard is fully ERC-721 compatible.

## Test Cases

Test cases are included in [test.js](../assets/eip-5007/test/test.js). 

Run in terminal:

```shell
cd ../assets/eip-5007
npm install truffle -g
npm install
truffle test
```
 
## Reference Implementation

See [`ERC5007.sol`](../assets/eip-5007/contracts/ERC5007.sol).

## Security Considerations

No security issues found.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
