Alert Source Discuss
Standards Track: ERC

ERC-7575: 多资产 ERC-4626 金库

扩展了 ERC-4626 接口,支持多资产金库

Authors Jeroen Offerijns (@hieronx), Alina Sinelnikova (@ilinzweilin), Vikram Arun (@vikramarun), Joey Santoro (@joeysantoro), Farhaan Ali (@0xfarhaan)
Created 2023-12-11
Requires EIP-20, EIP-165, EIP-2771, EIP-4626

摘要

以下标准调整了 ERC-4626,以支持同一份额代币的多个资产或入口点。这也使得金库能够支持不具有真实份额代币,而是在两个任意外部代币之间进行转换的情况。

它向金库添加了一个新的 share 方法,以允许外部化 ERC-20 依赖项。

它还向份额代币添加了金库到份额的查找功能。

最后,它强制执行对金库和份额代币的 ERC-165 支持。

动机

ERC-4626 不支持的一个缺失用例是具有多个资产或入口点(如流动性提供者 (LP) 代币)的金库。由于 ERC-4626 本身需要是一个 ERC-20,因此这些通常难以处理或不符合标准。

规范

定义:

ERC-4626 中的现有定义适用。此外,本规范定义:

  • 多资产金库:具有多个资产/入口点的金库。多资产金库是指 ERC-7575 合约的集合,这些合约具有特定资产的入口点,并链接到一个通用的 share 代币。
  • 管道(Pipe):一种从一种代币到另一种代币的转换器(单向或双向)

方法

所有 ERC-7575 金库必须实现 ERC-4626,但不包括 ERC-20 方法和事件。

share

存入金库时收到的底层 share 的地址。必须返回金库的 ERC-20 份额表示的地址。

share 可以返回金库本身的地址。

如果 share 返回一个外部代币,即 share != address(this)

  • 进入函数必须将 receivershare 余额增加 shares 的数量。即 share.balanceOf(receiver) += shares
  • 退出函数必须将 ownershare 余额减少 shares 的数量。即 share.balanceOf(owner) -= shares

必须_不_回退。

- name: share
  type: function
  stateMutability: view

  inputs: []
  outputs:
    - name: shareTokenAddress
      type: address

多资产金库

多资产金库与多个入口点共享一个 share 代币,这些入口点以不同的 asset 代币计价。

多资产金库必须在每个入口点上实现 share 方法。入口点不应该是 ERC-20

管道(Pipes)

管道在单个 assetshare 之间转换,它们都是金库外部的 ERC-20 代币。

管道可以是单向的也可以是双向的。

单向管道应仅实现进入函数 deposit 和/或 mint,而不实现 redeem 和/或 withdraw

入口点应锁定或销毁来自 msg.senderasset,并将 share 铸造或转移到 receiver。对于双向管道,退出点应锁定或销毁来自 ownershare,并将 asset 铸造或转移到 receiver

份额到金库的查找

shareERC-20 实现应实现一个 vault 方法,该方法返回特定 asset 的金库地址。

当链接到份额的金库发生更改时,应该发出 VaultUpdate 事件。

- name: vault
  type: function
  stateMutability: view

  inputs: 
    - name: asset
      type: address
    
  outputs:
    - name: vault
      type: address

ERC-165 支持

实现 ERC-7575 的金库必须实现 ERC-165supportsInterface 函数。如果通过 interfaceID 参数传递 0x2f0a18c5,则金库合约必须返回常量值 true

份额合约应该实现 ERC-165supportsInterface 函数。如果通过 interfaceID 参数传递 0xf815c03d,则份额代币必须返回常量值 true

事件

VaultUpdate

链接到份额的金库已更新。

- name: VaultUpdate
  type: event

  inputs:
    - name: asset
      indexed: true
      type: address
    - name: vault
      indexed: false
      type: address

理由

本标准有意保持灵活性,通过引入一个新方法来轻松支持现有的 ERC-4626 金库,并通过允许单独的份额代币来支持新的用例。

能够外部化 ERC-20 依赖项

通过允许 share != address(this),金库可以拥有一个外部合约来管理份额的 ERC-20 功能。在多资产的情况下,这避免了如果每个金库本身都需要是一个 ERC-20 可能引起的混淆,这可能会使集成商和前端感到困惑。

这种方法还可以创建新型金库,例如管道,这些管道有助于在两个外部 ERC-20 代币之间进行转换。这些管道可以是单向的(即仅用于通过存款/铸造将资产转换为份额,或通过赎回/提取将份额转换为资产),也可以是双向的,用于进入和退出流程。

可选择地包括“份额到金库”的查找

vault 方法的包含是为了通过其 asset 查找 share 的金库,结合 VaultUpdate 事件和 ERC-165 支持。这使得集成可以轻松查询多资产金库。

这是可选的,以保持与 share 是现有已部署合约的用例的向后兼容性。

向后兼容性

ERC-7575 金库与 ERC-4626 不完全兼容,因为 ERC-20 功能已被删除。

参考实现

    // This code snippet is incomplete pseudocode used for example only and is no way intended to be used in production or guaranteed to be secure
    // 此代码片段是不完整的伪代码,仅用于示例,绝不能用于生产或保证安全

    contract Share is ERC20 {
        mapping (address asset => address) vault;

        function updateVault(address asset, address vault_) public {
            vault[asset] = vault_;
            emit UpdateVault(asset, vault_);
        }

        function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
            return interfaceId == 0xf815c03d || interfaceId == 0x01ffc9a7;
        }
    }

    contract TokenAVault is ERC7575 {
        address public share = address(Share);
        address public asset = address(TokenA);

        // ERC4626 implementation
        // ERC4626 实现

        function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
            return interfaceId == 0x2f0a18c5 || interfaceId == 0x01ffc9a7;
        }
    }

    contract TokenBVault is ERC7575 {
        address public share = address(Share);
        address public asset = address(TokenB);

        // ERC4626 implementation
        // ERC4626 实现

        function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
            return interfaceId == 0x2f0a18c5 || interfaceId == 0x01ffc9a7;
        }
    }

安全考虑

ERC-20 非兼容金库必须注意支持 owner 不是 msg.sender 的赎回流程,因为如果金库和份额是单独的合约,则 ERC-20 批准流程本身不起作用。可以通过使用 ERC-2771 将金库设置为份额代币的可信转发器来解决这个问题。

版权

版权及相关权利通过 CC0 放弃。

Citation

Please cite this document as:

Jeroen Offerijns (@hieronx), Alina Sinelnikova (@ilinzweilin), Vikram Arun (@vikramarun), Joey Santoro (@joeysantoro), Farhaan Ali (@0xfarhaan), "ERC-7575: 多资产 ERC-4626 金库," Ethereum Improvement Proposals, no. 7575, December 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7575.