forked from DecentralizedClimateFoundation/DCIPs
94 lines
4.4 KiB
Markdown
94 lines
4.4 KiB
Markdown
---
|
||
eip: 5744
|
||
title: Latent Fungible Token
|
||
description: An interface for tokens that become fungible after a period of time.
|
||
author: Cozy Finance (@cozyfinance), Tony Sheng (@tonysheng), Matt Solomon (@mds1), David Laprade (@davidlaprade), Payom Dousti (@payomdousti), Chad Fleming (@chad-js), Franz Chen (@Dendrimer)
|
||
discussions-to: https://ethereum-magicians.org/t/eip-5744-latent-fungible-token/11111
|
||
status: Draft
|
||
type: Standards Track
|
||
category: ERC
|
||
created: 2022-09-29
|
||
requires: 20, 2612
|
||
---
|
||
|
||
## Abstract
|
||
|
||
The following standard is an extension of [EIP-20](./eip-20.md) that enables tokens to become fungible after some initial non-fungible period.
|
||
Once minted, tokens are non-fungible until they reach maturity.
|
||
At maturity, they become fungible and can be transferred, traded, and used in any way that a standard EIP-20 token can be used.
|
||
|
||
## Motivation
|
||
|
||
Example use cases include:
|
||
|
||
- Receipt tokens that do not become active until a certain date or condition is met. For example, this can be used to enforce minimum deposit durations in lending protocols.
|
||
- Vesting tokens that cannot be transferred or used until the vesting period has elapsed.
|
||
|
||
## Specification
|
||
|
||
All latent fungible tokens MUST implement EIP-20 to represent the token.
|
||
The `balanceOf` and `totalSupply` return quantities for all tokens, not just the matured, fungible tokens.
|
||
A new method called `balanceOfMatured` MUST be added to the ABI.
|
||
This method returns the balance of matured tokens for a given address:
|
||
|
||
```solidity
|
||
function balanceOfMatured(address user) external view returns (uint256);
|
||
```
|
||
|
||
An additional method called `getMints` MUST be added, which returns an array of all mint metadata for a given address:
|
||
|
||
```solidity
|
||
struct MintMetadata {
|
||
// Amount of tokens minted.
|
||
uint256 amount;
|
||
// Timestamp of the mint, in seconds.
|
||
uint256 time;
|
||
// Delay in seconds until these tokens mature and become fungible. When the
|
||
// delay is not known (e.g. if it's dependent on other factors aside from
|
||
// simply elapsed time), this value must be `type(uint256).max`.
|
||
uint256 delay;
|
||
}
|
||
|
||
function getMints(address user) external view returns (MintMetadata[] memory);
|
||
```
|
||
|
||
Note that the implementation does not require that each of the above metadata parameters are stored as a `uint256`, just that they are returned as `uint256`.
|
||
|
||
An additional method called `mints` MAY be added.
|
||
This method returns the metadata for a mint based on its ID:
|
||
|
||
```solidity
|
||
function mints(address user, uint256 id) external view returns (MintMetadata memory);
|
||
```
|
||
|
||
The ID is not prescriptive—it may be an index in an array, or may be generated by other means.
|
||
|
||
The `transfer` and `transferFrom` methods MAY be modified to revert when transferring tokens that have not matured.
|
||
Similarly, any methods that burn tokens MAY be modified to revert when burning tokens that have not matured.
|
||
|
||
All latent fungible tokens MUST implement EIP-20’s optional metadata extensions.
|
||
The `name` and `symbol` functions MUST reflect the underlying token’s `name` and `symbol` in some way.
|
||
|
||
## Rationale
|
||
|
||
The `mints` method is optional because the ID is optional. In some use cases such as vesting where a user may have a maximum of one mint, an ID is not required.
|
||
|
||
Similarly, vesting use cases may want to enforce non-transferrable tokens until maturity, whereas lending receipt tokens with a minimum deposit duration may want to support transfers at all times.
|
||
|
||
It is possible that the number of mints held by a user is so large that it is impractical to return all of them in a single `eth_call`.
|
||
This is unlikely so it was not included in the spec.
|
||
If this is likely for a given use case, the implementer may choose to implement an alternative method that returns a subset of the mints, such as `getMints(address user, uint256 startId, uint256 endId)`.
|
||
However, if IDs are not sequential, a different signature may be required, and therefore this was not included in the specification.
|
||
|
||
## Backwards Compatibility
|
||
|
||
This proposal is fully backward compatible with the EIP-20 standard and has no known compatibility issues with other standards.
|
||
|
||
## Security Considerations
|
||
|
||
Iterating over large arrays of mints is not recommended, as this is very expensive and may cause the protocol, or just a user's interactions with it, to be stuck if this exceeds the block gas limit and reverts. There are some ways to mitigate this, with specifics dependent on the implementation.
|
||
|
||
## Copyright
|
||
|
||
Copyright and related rights waived via [CC0](../LICENSE.md).
|