Skip to content

Commit

Permalink
Merge f5160c8 into e9588ae
Browse files Browse the repository at this point in the history
  • Loading branch information
Joeysantoro authored Dec 18, 2023
2 parents e9588ae + f5160c8 commit 075440a
Showing 1 changed file with 155 additions and 0 deletions.
155 changes: 155 additions & 0 deletions ERCS/erc-7575.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
---
eip: 7575
title: Partial and Extended ERC-4626 Vaults
description: Modular ERC-4626 Interface enabling Multi-Vault, Pipes, Partial and Alternative Vaults
author: Jeroen Offerijns (@hieronx), Alina Sinelnikova (@ilinzweilin), Vikram Arun (@vikramarun), Joey Santoro (@joeysantoro), Farhaan Ali (@0xfarhaan)
discussions-to: https://ethereum-magicians.org/t/erc-7575-partial-and-extended-erc-4626-vaults/17274
status: Draft
type: Standards Track
category: ERC
created: 2023-12-11
requires: 20, 165, 2771, 4626
---

## Abstract

The following standard adapts [ERC-4626](./eip-4626.md) into several modular components which can be used in isolation or combination to unlock new use cases.

New functionality includes multiple assets or entry points for the same share token, conversions between arbitrary tokens, and implementations which use partial entry/exit flows from ERC-4626.

This standard adds nomenclature for the different components/interfaces of the base ERC-4626 standard including `ERC7575MinimalVaultInterface` and an interface for each entry/exit function.

It adds a new `share` method to allow the [ERC-20](./eip-20.md) dependency to be externalized.

Lastly, it enforces [ERC-165](./eip-165.md) support for Vaults.

## Motivation

[ERC-4626](./eip-4626.md) represents a "complete" and symmetrical standard for a Tokenized Vault pattern. Certain use cases may want to borrow functionality from 4626 to maintain some interface compatibility without wanting the entire standard.

One major use case are Vaults which have multiple assets or entry points such as LP Tokens. These are generally unwieldy or non-compliant due to the requirement of ERC-4626 to itself be an ERC-20.

Another are Vaults which don't have a true share token but rather convert between two arbitrary external tokens.

Some Vaults always have a 1:1 conversion rate between `assets` and `shares` and would benefit from being able to implement only one entry or exit function from the Vault rather than both.

There are so many customizeable use cases that it is beneficial to modularize the Vault standard.

## Specification

### Definitions:

The existing definitions from [ERC-4626](./eip-4626.md) apply.

- Multi-Vault: A Vault which has multiple assets/entry points
- Pipe: A converter from one token to another (unidirectional or bidirectional)
- Entry Function: A Vault function which converts `asset` to `shares`. Either `deposit` or `mint` in ERC-4626
- Exit Function: A Vault function which converts `shares` to `assets`. Either `withdraw` or `redeem` in ERC-4626
- Partial Vault: A Vault which implements only one Entry or Exit function from ERC-4626

First the standard defines a new `share` function which is useful for many configurable use cases, and then goes into detail on the requirements for different configurations.

### Methods

#### share

The address of the underlying `share` received on deposit into the Vault. MUST return an address of an ERC-20 share representation of the Vault.

`share` MAY return the address of the Vault itself.

If the `share` returns an external token i.e. `share != address(this)`:
* entry functions MUST increase the `share` balance of the `receiver` by the `shares` amount. i.e. `share.balanceOf(receiver) += shares`
* exit functions MUST decrease the `share` balance of the `owner` by the `shares` amount. i.e. `share.balanceOf(owner) -= shares`

MUST _NOT_ revert.

```yaml
- name: share
type: function
stateMutability: view

inputs: []
outputs:
- name: shareTokenAddress
type: address
```
### `ERC7575MinimalVault` Interface
The Minimal Vault Interface consists of the methods which are required for any `share` based Vault with a corresponding deposit `asset`.

It is defined as the following ERC-4626 methods (and `share` described above):
- `asset`
- `share`
- `convertToAssets`
- `convertToShares`
- `totalAssets`

It also includes the `Deposit` and `Withdraw` events.

### Partial Vault Interfaces
A Partial Vault omits at least one of the ERC-4626 entry or exit functions.

A Partial Vault MUST implement both the `preview*` and `max*` methods associated with any implemented entry/exit functions.

Partial Vaults SHOULD prefer implementing `deposit` and `redeem` over `mint` and `withdraw`, respectively.

A Partial Vault MAY implement none of the ERC-4626 entry or exit functions and instead use a bespoke entry/exit. In this case it still MUST implement `ERC7575MinimalVault` interface. Any bespoke entry/exit from the Vault MUST emit `Deposit` or `Withdraw`, respectively.

This standard defines four modular interfaces beyond the Minimal Vault Interface:
- `ERC7575DepositVault` - `deposit`, `previewDeposit`, `maxDeposit`
- `ERC7575MintVault` - `mint`, `previewMint`, `maxMint`
- `ERC7575RedeemVault` - `redeem`, `previewRedeem`, `maxRedeem`
- `ERC7575WithdrawVault` - `withdraw`, `previewWithdraw`, `maxWithdraw`

### Multi-Vaults
Multi-vaults share a single `share` token with multiple entry points denominated in different `asset` tokens.

Multi-vaults MUST implement the `share` method on each entry point. The entry points SHOULD NOT be ERC-20.

### Pipes
Pipes convert between a single `asset` and `share` which are both ERC-20 tokens outside the Vault.

A Pipe MAY be either unidirectional or bidirectional.

If the exchange rate is fixed, the Pipe SHOULD be a Partial Vault implementing only `deposit` and/or `redeem`.

A unidirectional Pipe SHOULD implement only the entry function(s) `deposit` and/or `mint`.

### [ERC-165](./eip-165.md) support

Smart contracts implementing any of the above Vault interfaces MUST implement the [ERC-165](./eip-165.md) `supportsInterface` function.

`ERC7575MinimalVault` MUST return the constant value `true` if `0x50a526d6` is passed through the `interfaceID` argument.

`ERC7575DepositVault` MUST return the constant value `true` if `0xc1f329ef` is passed through the `interfaceID` argument.

`ERC7575MintVault` MUST return the constant value `true` if `0xe1550342 ` is passed through the `interfaceID` argument.

`ERC7575RedeemVault` MUST return the constant value `true` if `0x2fd7d42a ` is passed through the `interfaceID` argument.

`ERC7575WithdrawVault` MUST return the constant value `true` if `0x70dec094 ` is passed through the `interfaceID` argument.

If a Vault implements all 5 interfaces, it MUST also return the constant value `true` if `0x2f0a18c5` is passed through the `interfaceID` argument. This value is the chained XOR of all 5 interfaces, i.e. the [ERC-165](./eip-165.md) compliant `interfaceID` for the complete [ERC-7575](./eip-7575.md) implementation.

## Rationale

This standard is intentionally flexible to support both existing [ERC-4626](./eip-4626.md) Vaults easily by the introduction of a single new method, but also flexible to support new use cases by allowing separate share tokens.

### Ability to externalize ERC20 Dependency
By allowing share != address(this), the Vault can have an external contract managing the ERC20 functionality of the Share. In the case of Multi-Vaults, this avoids the confusion that might arise if each Vault itself were required to be an ERC20, which could cause confusion for integrators and front-ends. This approach also enables the creation of new types of Vaults, such as Pipes, which facilitate the conversion between two external ERC20 tokens.


## Backwards Compatibility

Existing [ERC-4626](./eip-4626.md) Vaults can be made compatible with ERC-x by adding a single `share` method that returns the address of the Vault.

## Reference Implementation

N/A
## Security Considerations

[ERC-20](./eip-20.md) non-compliant Vaults must take care with supporting a redeem flow where `owner` is not `msg.sender`, since the [ERC-20](./eip-20.md) approval flow does not by itself work if the Vault and share are separate contracts. It can work by setting up the Vault as a Trusted Forwarder of the share token, using [ERC-2771](./eip-2771.md).

## Copyright

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

0 comments on commit 075440a

Please sign in to comment.