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 ERC: Fractional Reserve Token #644

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Changes from 6 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
180 changes: 180 additions & 0 deletions ERCS/erc-7761.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
---
eip: 7761
yaronvel marked this conversation as resolved.
Show resolved Hide resolved
title: Fractional Reserve Token
description: An interface for fractional reserve tokens.
author: Yaron Velner (@yaronvel)
discussions-to: https://ethereum-magicians.org/t/fractional-reserve-token-standard/21103
yaronvel marked this conversation as resolved.
Show resolved Hide resolved
status: Draft
type: Standards Track
category: ERC
created: 2024-09-17
requires: 20
---


## Abstract
We propose a new token standard for synthetic assets that are only partially redeemable to their underlying asset, but fully backed by other collateral assets.

The standard defines an interface to mint fractional reserve assets, and a standard to reflect economical risk related data to the token holders and lenders.

## Motivation
The Cambrian explosion of new L1s and L2s gave rise to bridged assets which are synthetic by nature. Indeed, ETH on Arbitrum L2, or WETH on Binance Smart Chain are not fully fungible with their mainnet counterpart. However, these assets are fully backed by their mainnet counterpart and guaranteed to be redeemable to their mainnet underlying asset, albeit with certain time delay.

Fractional reserve tokens can allow an ecosystem (chains, L2s, and other networks of economic activity) to increase its supply by allowing users to mint the asset not only by bridging it to the ecosystem, but also by borrowing it (typically against a collateral).

As an example, consider a fractional reserve token, namely, frDAI, that represents a synthetic DAI.
Such token will allow users to mint 1 frDAI upon deposit of 1 DAI, or by providing a collateral that worth more than 1 DAI.
Quick redemption of frDAI to DAI is available as long as there is still some DAI balance in the frDAI token, and otherwise, the price of frDAI may temporarily fluctuate until borrowers repay their debt.

Fractional reserve tokens may delegate minting capabilities for multiple risk curators and lending markets. Hence, a uniform standard for fractional reserve minting is needed.
Fractional reserve banking does not come without risks, such as insolvency or a bank run.
This standard does not aim to dictate economic risk management practices, but rather to have a standard on how to reflect the risk to token holders.

## Specification
The proposed standard has the following requirements:
* **MUST** be [ERC-20](../erc-20.md) compatible.
### Interface
```
interface IERCXXX is IERC20 {
// events
event MintFractionalReserve(address indexed minter, address to, uint256 amount);
event BurnFractionalReserve(address indexed burner, address from, uint256 amount);
event SetSegregatedAccount(address account, bool segregated);

// functions
// setters
function fractionalReserveMint(address _to, uint256 _amount) external;
function fractionalReserveBurn(address _from, uint256 _amount) external;

// getters
function totalBorrowedSupply() external view returns (uint256);
function requiredReserveRatio() external view returns (uint256);
function segregatedAccount(address _account) external view returns (bool);
function totalSegregatedSupply() external view returns (uint256);
}
```
### Reserve ratio
The reserve ratio reflects the ratio between the token that is available as cash, i.e., available for an immediate redemption (or alternatively, a token that was not minted via a fractional reserve minting), and the total supply of the token. Segregated accounts **MUST** be subtracted from the cash balance.
Lower reserve ratio gives rise to higher capital efficiency, however it increases the **likelihood** of depeg or a run on the bank, where token holders cannot immediately redeem their synthetic token.

Formally, the reserve ratio is denoted by $$\frac{totalSupply() - totalBorrowedSupply() - \sum_{a \in \text{Segregated Accounts}} \text{balanceOf}(a)}{totalSupply()}$$.
Additional fractional reserve minting **MUST NOT** occur when the reserve ratio, multiplied by `1e18` is lower than `requiredReserveRatio()`.

### Mint and burn functionality
The `fractionalReserveMint` and `fractionalReserveBurn` functions **SHOULD** be called by permissioned addresses, e.g., risk curators or lending markets. These entities **SHOULD** mint new tokens only to addresses that already locked collateral in a dedicated contract.

The reserve ratio is denoted by $$\frac{totalSupply() - \sum_{a \in \text{Segregated Accounts}} \text{balanceOf}(a)}{totalSupply() + totalBorrowedSupply()}$$.
`fractionalReserveMint` **MUST** revert if the reserve ratio, multiplied by `e18` exceeds `requiredReserveRatio()`.

A successful call to `fractionalReserveMint(_to, _amount)` **MUST** increase the value of `totalSupply()`, `totalBorrowedSupply()`, and the token balance of address `_to`, by `_amount` units.
A call to `fractionalReserveMint` **MUST** emit a `MintFractionalReserve` event.
A call to `fractionalReserveMint` **MUST** revert if after the mint the reserve ratio, multiplied by `1e18` exceeds the value of `requiredReserveRatio()`.

Similarly, a successful call to `fractionalReserveBurn(_from, _amount)` **MUST** decrease the value of `totalSupply()`,`totalBorrowedSupply()`, and the token balance of address `_from` by `_amount` units.
A call to `fractionalReserveBurn` **MUST** emit a `BurnFractionalReserve` event.
### Segregated accounts
Increasing the total supply could be a concern if a token is used for DAO votes and/or if dividends are distributed to token holders.
In order to mitigate such concerns, segregated accounts are introduced, with the premise that money in these accounts is not counted towards the reserve, and therefore, additional token supply cannot be minted against them.

At every point in time, it **MUST** hold that the sum of token balances for segregated addresses equals to `totalSegregatedSupply()`.

### Account balance
The `fractionalReserveMint` **SHOULD** be used in conjunction with a lending operation, where the minted token is borrowed. The lending operation **SHOULD** come with an interest rate, and some of the interest rate proceedings **SHOULD** be distributed to token holders that are not in segregated accounts.
This standard does not dictate how distribution should occur.

## Rationale
The proposed standard aims to standardise how multiple lending markets and risk providers can interact with a fractional reserve token. The actual lending operation should be done carefully by trusted entities, and it is the token owner's responsibility to make sure the parties who have fractional reserve minting credentials are reliable.

At the core of the coordination relies the need to understand how much additional supply is available for borrow, and at what interest rate. The additional borrowable supply is deduced from the required reserve ratio, and the total, borrowable and segregated supply.
The interest rate **SHOULD** be monotonically increasing with the current reserve ratio.

The standard does not dictate how the accrued interest rate is distributed. One possible distribution is by making the token a rebased token. An alternative way is to introduce staking, or just airdropping of proceeds.

While a fractional reserve is most useful when it is backed by a known asset, e.g., frDAI and DAI, it can also be used in isolation. In such a case, a token will have a fixed initial supply, however additional supply can be borrowed. In such cases the supply temporarily increases, but the net holdings (`totalSupply() - totalBorrowedSupply()`) remains unchanged.

## Backwards Compatibility
Fractional reserve tokens should be backwards compatible with [ERC-20](../erc-20.md).

## Reference Implementation
```
// The code below is provided only for illustration, DO NOT use it in production
contract FractionalReserveToken is ERC20, Ownable {

event MintFractionalReserve(address indexed minter, address to, uint256 amount);
event BurnFractionalReserve(address indexed burner, address from, uint256 amount);
event SetSegregatedAccount(address account, bool segregated);

/// @notice token supply in these accounts is not counted towards the reserve, and
/// therefore, additional token supply cannot be minted against them.
mapping(address => bool) public segregatedAccount;

/// @notice ratio between the token that is available as cash (immediate redemption)
/// and the total supply of the token.
uint256 public requiredReserveRatio;

uint256 public totalBorrowedSupply;

constructor(
string memory _name,
string memory _symbol
) ERC20(_name, _symbol) Ownable(msg.sender) {}

function fractionalReserveMint(address to, uint256 amount) external onlyOwner {
_mint(to, amount);
totalBorrowedSupply += amount;
emit MintFractionalReserve(msg.sender, to, amount);

uint256 reserveRatio = (totalSupply() - totalBorrowedSupply - segregatedSupply) * 1e18 / totalSupply();
require(reserveRatio >= requiredReserveRatio, "reserveRatio");
}
function fractionalReserveBurn(address from, uint256 amount) external onlyOwner {
_burn(from, amount);
totalBorrowedSupply -= amount;
emit BurnFractionalReserve(msg.sender, from, amount);
}

// ------------------------------------------------------------------------------
// Code below is not part of the proposed standard
// ------------------------------------------------------------------------------
uint256 internal segregatedSupply; // supply of segregated tokens

function _update(address from, address to, uint256 value) internal override {
// keep the reserve up to date on transfers
if (!segregatedAccount[from] && segregatedAccount[to]) {
segregatedSupply += value;
}
if (segregatedAccount[from] && !segregatedAccount[to]) {
segregatedSupply -= value;
}
ERC20._update(from, to, value);
}

function mint(address account, uint256 value) external onlyOwner {
_mint(account, value);
}

function burn(address account, uint256 value) external onlyOwner {
_burn(account, value);
}

function setSegregatedAccount(address account, bool segregated) external onlyOwner {
if (segregated) {
require(!segregatedAccount[account], "segregated");
segregatedSupply += balanceOf(account);
} else {
require(segregatedAccount[account], "!segregated");
segregatedSupply -= balanceOf(account);
}
segregatedAccount[account] = segregated;
emit SetSegregatedAccount(account, segregated);
}

function setRequiredReserveRatio(uint256 value) external onlyOwner {
requiredReserveRatio = value;
}
}
```
## Security Considerations
Fractional reserve banking comes with many economic risks. This standard does not aim to provide guidelines on how to properly mitigate them.
## Copyright
Copyright and related rights waived via [CC0](../LICENSE.md).
Loading