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

Update ERC-7425: Add missing info #238

Merged
merged 9 commits into from
Feb 20, 2024
Merged
Changes from 2 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
93 changes: 65 additions & 28 deletions ERCS/erc-7425.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,47 @@

## Abstract

A proposal for a tokenized reserve mechanism. The reserve allows an audit of on-chain actions of the owner. Using [ERC-4626](../EIPS/eip-4626.md), stakeholders can create shares to show support for actions in the reserve.
This specification explains a tokenized reserve mechanism standard. Current smart contracts record transactions and are made public. The reserve will implement added functionality allowing stakeholders proactively to audit a contract. Using [ERC-4626](../ERCS/erc-4626.md), stakeholders can create shares to show support for actions in the contract.

## Motivation

Tokenized reserves are an extension of tokenized vaults. The goal is to create a reserve similar to a real world reserve an entity has as a backup in case regular funds run low. In the real world, an entity will have to meet certain criteria before accessing reserve funds. In a decentralized environment, an entity can incorporate stakeholders into their criteria. This will help entities who participate in decentralized environments to be transparent with stakeholders.
Tokenized vaults store [ERC-20](../ERCS/erc-20.md) tokens that are represented by shares within vault contracts. Implemenations can follow the [ERC-4626](../ERCS/erc-4626.md) standard to provide basic functionality for depositing, withdrawing and reading balances for a vault. As tokenization becomes increasingly popular, applications should use a form of tokenized vaults to store assests and allow all parties to track performance.

This specifcation introduces a standard for a on-chain reserve that uses tokenized vaults to represent reserve stakeholders. Core functionality, which is an extension of [ERC-4626](../ERCS/erc-4626.md), will provide stakeholders representation by depsoiting and withdrawing from the vault. The record of transactions for other [ERC-20](../ERCS/erc-20.md) assests should be easily accessicble to any party for auditing.

## Background

Check failure on line 24 in ERCS/erc-7425.md

View workflow job for this annotation

GitHub Actions / EIP Walidator

body has extra section(s)

error[markdown-order-section]: body has extra section(s) --> ERCS/erc-7425.md | 24 | ## Background | = help: see https://ethereum.github.io/eipw/markdown-order-section/

In a tokenized reserve, stakeholders are represented by minting shares from the vault. The goal is to create a reserve similar to a real-world reserve fund used as a contingency for an entity. In most cases, an entity would follow criteria like, running low on regular funds, to utilize the reserve fund. In a decentralized environment, an entity should incorporate stakeholders as criteria. Assets accioted with the reserve as well as its orgin will vary in decentralized envirnoments, so transparent auditing is needed.


## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC [2119](https://www.ietf.org/rfc/rfc2119.txt) and RFC [8174](https://www.ietf.org/rfc/rfc8174.txt).

Check failure on line 31 in ERCS/erc-7425.md

View workflow job for this annotation

GitHub Actions / EIP Walidator

non-relative link or image

error[markdown-rel-links]: non-relative link or image --> ERCS/erc-7425.md | 31 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC [2119](https://www.ietf.org/rfc/rfc2119.txt) and RFC [8174](https://www.ietf.org/rfc/rfc8174.txt). | = help: see https://ethereum.github.io/eipw/markdown-rel-links/

Check failure on line 31 in ERCS/erc-7425.md

View workflow job for this annotation

GitHub Actions / EIP Walidator

non-relative link or image

error[markdown-rel-links]: non-relative link or image --> ERCS/erc-7425.md | 31 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC [2119](https://www.ietf.org/rfc/rfc2119.txt) and RFC [8174](https://www.ietf.org/rfc/rfc8174.txt). |

### Definitions:

- owner: The creator of the reserve
- user: Stakeholders of specific proposals
- reserve: The tokenized reserve contract
- proposal: Occurs when the owner wants a withdrawal from contract
- user: Stakeholders participating proposals
- reserve: The assets held on the contract other than underlying token
- proposal: Created by owners to encourage stakeholder participation

### Constructor:

- name: ERC-20 token name
- ticker: ERC-20 ticker
- asset: ERC-4626 underlying ERC-20 address
- rAuth: Primary authorized user
- rAuth: Authorized user, for cases utilizing more than one owner
- rOwner: Owner of the Reserve

### Interface

```solidity
// SPDX-License-Identifier: CC0-1.0

pragma solidity ^0.8.0;
import "./ERC4626.sol";

interface TokenReserve is ERC4626{

/**
* @dev Event emitted after a new proposal is created
*/
Expand All @@ -56,6 +63,7 @@
uint256 indexed amount,
address recipient
);

/**
* @dev Event emitted after a new deposit is made by the owner
*/
Expand All @@ -65,46 +73,60 @@
uint256 indexed time,
uint256 count
);

/**
* @dev Get time of a deposit made to reserve with depositReserve()
* @param count Number matching deposit
* @dev Get time of a deposit made to reserve by owner
* @param count Number for deposit count
* @return block.timestamp format
*/
function depositTime(uint256 count) external view returns (uint256);

/**
* @dev Get amount deposited to reserve with depositReserve()
* @param count Number of deposit
* @return uint256 number of any asset that were deposited
* @dev Get amount deposited to reserve by owner
* @param count Number for deposit count
* @return uint256 Amount of an asset that was deposited
*/
function ownerDeposit(uint256 count) external view returns(uint256);

/**
* @dev Token type deposited to reserve with depositReserve()
* @dev Token type deposited to reserve by owner
* - MUST be an address of ERC20 token
* @param count Number of deposit
* @return address Address of ERC20 token
*/
function tokenDeposit(uint256 count) external view returns(address);

/**
* @dev Amount deposited for shares of proposal by the user
* - MUST be an ERC20 address
* @param user address of user
* @param proposal number of the proposal the user deposited
* @dev Amount deposited by the user to a proposal for shares
* - MUST be an ERC20 token
* @param user Address of user
* @param proposal Proposal number the user deposited to
* @return uint256 Amount of ERC20 deposited
*/
function userDeposit(address user, uint256 proposal) external view returns(uint256);

/**
* @dev Token used for given proposal
* - MUST be ERC20 address
* @param proposal number for requested token
* @return token address
* @param proposal Proposal number for requested used token
* @return Token address
*/
function proposalToken(uint256 proposal) external view returns(address);

/**
* @dev Amount withdrawn for given opened proposal
* @dev Amount withdrawn for given opened proposal number
* @param proposal Proposal number
* @return Amount of ERC20
*/
function proposalWithdrew(uint256 proposal) external view returns(uint256);

/**
* @dev Amount received for given closed proposal
* @dev Amount received for given proposal number
* @param proposal Proposal number
* @return Amount of ERC20
*/
function proposalDeposited(uint256 proposal) external view returns(uint256);

/**
* @dev Make a deposit to a proposal creating new shares with deposit function from ERC-4626
* - MUST be opened proposal
Expand All @@ -113,8 +135,10 @@
* @param assets Amount being deposited
* @param receiver Address of depositor
* @param proposal Number associated proposal
* @return Amount of mint shares
*/
function proposalDeposit(uint256 assets, address receiver, uint256 proposal) external virtual returns(uint256);

/**
* @dev Burn shares, receive 1 to 1 value of shares
* - MUST have closed proposalNumber
Expand All @@ -123,37 +147,45 @@
* @param receiver Address of receiver
* @param owner Address of token owner
* @param proposal Number associated proposal
* @return Amount of the asset
*/
function proposalWithdraw(uint256 assets, address receiver, address owner, uint256 proposal)external virtual returns(uint256);

/**
* @dev Issue new proposal
* - MUST create new proposal number
* - MUST account for amount withdrawn
* - MUST be owner
* - MUST emit proposals event
* @param token Address of ERC-20 token
* @param amount Token amount being withdrawn
* @param receiver Address of token recipient
* @return Proposal number
*/
function proposalOpen(address token, uint256 amount, address receiver) external virtual returns (uint256);

/**
* @dev Make deposit and/or choose to close an opened proposal
* - MUST be owner
* - MUST account for amount received
* - MUST be a proposal that is less than or equal to current proposal
* - MUST emit proposals event
* @param token Address of ERC-20 token
* @param proposal Number of desired proposal
* @param amount Token amount being deposited to the reserve
* @param close Choose to close the proposal
* @return True for closed proposal
*/
function proposalClose(address token, uint256 proposal, uint256 amount, bool close) external virtual returns (bool);

/**
* @dev Optional accounting for tokens deposited by owner
* - MUST be reserve owner
* - MUST emit depositR event
* NOTE: No shares are issued, funds can not be redeemed. Only withdrawn from proposalOpen
* @param token Address of ERC-20 token
* @param sender Address of where tokens from
* @param amount Token amount being deposited
* @param amount Token amount being deposited
*/
function depositReserve(address token, address sender, uint256 amount) external virtual;
}
Expand All @@ -162,17 +194,22 @@

## Rationale

This proposal is designed to be a basic implementation of a reserve fund interface. Other non specified conditions should be addressed on a case by case basis. Each reserve uses [ERC-20](../EIPS/eip-20.md) standard for shares, and [ERC-4626](../EIPS/eip-4626.md) for the creation of shares. The reserve token can be the underlying token in [ERC-4626](../EIPS/eip-4626.md) or the shares that are created when the underlying token is deposited in the vault.
[ERC-4626](../EIPS/eip-4626.md) is implemented to the reserve to account for user participation. There needs to be a representation for users participating in a proposal within a reserve. With vaults, the implementor could decide how to treat participation based on users entering the vault. For example, a user could be forced not to use the same tokens in multiple proposals to allow shares to be created fairly. Once the underlying token is deposited into the vault for an open proposal those tokens could not be accessible until the proposal is closed.
It is not explicitly enforced that deposited tokens that create shares cannot be withdrawn by the owner of the reserve. On a case by case basis there can be implementions to ensure those tokens are accounted for if needed.
This proposal is designed to be a core implementation of a tokenized reserve interface standard. Other non-specified conditions should be addressed on a case-by-case basis. Each reserve uses [ERC-20](../ERCS/erc-20.md) standard for shares, and [ERC-4626](../ERCS/erc-4626.md) for the creation of shares. The reserve token can be the underlying token in [ERC-4626](../ERCS/erc-4626.md) or the shares that are created when the underlying token is deposited in the vault. The use
[ERC-4626](../ERCS/erc-4626.md) is implemented to the reserve to represent stakeholders. There MUST to be a representation of interseted parties in the reserve. The implementer could decide how to treat representation based on users entering and leaving the vault. For example, a user could be forced not to use the same tokens in multiple proposals to allow shares to be distributed fairly. Once the underlying token is deposited into the vault for an open proposal, tokens cannot be accessible until the proposal is closed.

It is not explicitly enforced that deposited tokens that create shares cannot be withdrawn by the owner of the reserve. On a case-by-case basis there can be implementions to ensure those tokens are accounted for if needed.

## Backwards Compatibility

Tokenized reserves are made compatible with [ERC-20](../EIPS/eip-20.md) and [ERC-4626](../EIPS/eip-4626.md).
Tokenized reserves are made compatible with [ERC-20](../ERCS/erc-20.md) and [ERC-4626](../ERCS/erc-4626.md).

## Security Considerations

Needs discussion.
1. Assests are not secured by vaults from owner withdrawal
- Stakeholders SHOULD be aware when the underlying `asset` can be withdrawn by the owner with no restrictions like requiring an `rAuth`. Depending on the authorizing implementation, `asset` could still be withdrawn.

A RECOMMENDED implementation:
- The `proposalOpen` SHOULD explictly restrict the transfer of the underlying `asset`.

## Copyright

Expand Down
Loading