Alert Source Discuss
⚠️ Draft Standards Track: ERC

ERC-7887: 取消 ERC-7540 代币化金库

支持取消的 ERC-7540 扩展

Authors Jeroen Offerijns (@hieronx), Vikram Arun (@vikramarun)
Created 2025-02-18
Discussion Link https://ethereum-magicians.org/t/erc-7887-cancelation-for-erc-7540-tokenized-vaults/22906
Requires EIP-165, EIP-7540

摘要

以下标准通过添加对异步取消流程的支持来扩展 ERC-7540

添加了新方法来异步取消存款或赎回请求,查看取消请求的状态,并声明因取消请求而产生的资产或份额。

动机

为请求锁定的股份或资产可能会卡在“待处理”状态。 对于某些用例,例如从长期真实世界资产池中赎回,这可能需要相当长的时间。

此标准通过添加取消支持来扩展异步 ERC-7540 金库的范围。

规范

本文档中使用的关键词“必须 (MUST)”,“禁止 (MUST NOT)”,“必需 (REQUIRED)”,“应该 (SHALL)”,“不应该 (SHALL NOT)”,“推荐 (SHOULD)”,“不推荐 (SHOULD NOT)”,“可以 (MAY)”,和“可选 (OPTIONAL)”按照 RFC 2119 和 RFC 8174 中的描述进行解释。

定义

ERC-7540 中的现有定义适用。

取消生命周期

提交后,取消请求将经历“待处理”、“可声明”和“已声明”阶段。 下表可视化了一个存款取消请求的示例生命周期。

状态 用户 金库
待处理 cancelDepositRequest(requestId, controller) pendingCancelDepositRequest[controller] = true
可声明   内部取消履行pendingCancelDepositRequest[controller] = false; claimableCancelDepositRequest[controller] = assets
已声明 claimCancelDepositRequest(requestId, receiver, controller) claimableDepositRequest[controller] -= assets; asset.balanceOf[receiver] += assets

pendingCancelDepositRequestclaimableCancelDepositRequest方法 部分中定义。

请求不得跳过或以其他方式短路“已声明”状态。换句话说,要启动和声明请求,用户必须分别调用 cancel* 和相应的 Claim 函数,即使在同一个区块中也是如此。金库在发出请求后不得“推送”代币给用户,用户必须通过 Claim 函数“拉取”代币。

在同步取消流程的情况下,请求可能会直接从“待处理”跳到“可声明”阶段。

在存款取消请求处于“待处理”状态时,新的存款请求将被阻止。同样,在赎回取消请求处于“待处理”状态时,新的赎回请求将被阻止。

方法

cancelDepositRequest

提交异步存款取消的请求。这会将请求置于“待处理”状态,并相应增加 pendingCancelDepositRequest,金额为待处理存款请求的全部金额。

当取消处于“待处理”状态时,新的存款请求将被阻止,并且 requestDeposit 必须还原。

当取消处于“可声明”状态时,claimableCancelDepositRequest 将为 controller 增加。claimCancelDepositRequest 随后可以由 controller 调用以接收 assets。请求可能会直接过渡到“可声明”状态,但不得跳过“可声明”状态。

controller 必须等于 msg.sender,除非 controller 已批准 msg.sender 作为操作员。

必须发出 CancelDepositRequest 事件。

- name: cancelDepositRequest
  type: function
  stateMutability: nonpayable

  inputs:
    - name: requestId
      type: uint256
    - name: controller
      type: address
  outputs:

pendingCancelDepositRequest

给定的 requestIdcontroller 是否有待处理的存款取消请求。

不得显示任何取决于调用者的变化。

除非由于不合理的大输入而导致的整数溢出,否则不得恢复。

- name: pendingCancelDepositRequest
  type: function
  stateMutability: view

  inputs:
    - name: requestId
      type: uint256
    - name: controller
      type: address

  outputs:
    - name: isPending
      type: bool

claimableCancelDepositRequest

controller 可声明的“可声明”取消状态中的 assets 金额。

不得显示任何取决于调用者的变化。

除非由于不合理的大输入而导致的整数溢出,否则不得恢复。

- name: claimableCancelDepositRequest
  type: function
  stateMutability: view

  inputs:
    - name: requestId
      type: uint256
    - name: controller
      type: address

  outputs:
    - name: assets
      type: uint256

claimCancelDepositRequest

声明具有 requestIdcontroller 的存款取消请求。

assets转移到 receiver

controller 必须等于 msg.sender,除非 controller 已批准 msg.sender 作为操作员。

必须发出 ClaimCancelDepositRequest 事件。

- name: claimCancelDepositRequest
  type: function
  stateMutability: nonpayable

  inputs:
    - name: requestId
      type: uint256
    - name: receiver
      type: address
    - name: controller
      type: address
  outputs:

cancelRedeemRequest

提交异步赎回取消的请求。这会将请求置于“待处理”状态,并相应增加 pendingCancelRedeemRequest,金额为待处理赎回请求的全部金额。

当取消处于“待处理”状态时,新的赎回请求将被阻止,并且 requestRedeem 必须还原。

当取消处于“可声明”状态时,claimableCancelRedeemRequest 将为 controller 增加。claimCancelRedeemRequest 随后可以由 controller 调用以接收 shares。请求可能会直接过渡到“可声明”状态,但不得跳过“可声明”状态。

controller 必须等于 msg.sender,除非 controller 已批准 msg.sender 作为操作员。

必须发出 CancelRedeemRequest 事件。

- name: cancelRedeemRequest
  type: function
  stateMutability: nonpayable

  inputs:
    - name: requestId
      type: uint256
    - name: controller
      type: address
  outputs:

pendingCancelRedeemRequest

给定的 requestIdcontroller 是否有待处理的赎回取消请求。

不得显示任何取决于调用者的变化。

除非由于不合理的大输入而导致的整数溢出,否则不得恢复。

- name: pendingCancelRedeemRequest
  type: function
  stateMutability: view

  inputs:
    - name: requestId
      type: uint256
    - name: controller
      type: address

  outputs:
    - name: isPending
      type: bool

claimableCancelRedeemRequest

controller 可以声明的“可声明”取消状态中的 shares 金额。

不得显示任何取决于调用者的变化。

除非由于不合理的大输入而导致的整数溢出,否则不得恢复。

- name: claimableCancelRedeemRequest
  type: function
  stateMutability: view

  inputs:
    - name: requestId
      type: uint256
    - name: controller
      type: address

  outputs:
    - name: shares
      type: uint256

claimCancelRedeemRequest

声明具有 requestIdcontroller 的赎回取消请求。

assets转移到 receiver

controller 必须等于 msg.sender,除非 controller 已批准 msg.sender 作为操作员。

必须发出 ClaimCancelRedeemRequest 事件。

- name: claimCancelRedeemRequest
  type: function
  stateMutability: nonpayable

  inputs:
    - name: requestId
      type: uint256
    - name: receiver
      type: address
    - name: owner
      type: address
  outputs:

事件

CancelDepositRequest

controller 已请求取消其请求 ID 为 requestId 的存款请求。 sendercancelDepositRequest 的调用者,可能不等于 controller

当使用 cancelDepositRequest 方法提交存款取消请求时,必须发出。

- name: CancelDepositRequest
  type: event

  inputs:
    - name: controller
      indexed: true
      type: address
    - name: requestId
      indexed: true
      type: uint256
    - name: sender
      indexed: false
      type: address

CancelDepositClaim

controller 已声明其请求 ID 为 requestId 的存款取消请求。 receiverassets 的目标。 senderclaimCancelDepositRequest 的调用者,可能不等于 controller

当使用 claimCancelDepositRequest 方法提交存款取消请求时,必须发出。

- name: CancelDepositClaim
  type: event

  inputs:
    - name: controller
      indexed: true
      type: address
    - name: receiver
      indexed: true
      type: address
    - name: requestId
      indexed: true
      type: uint256
    - name: sender
      indexed: false
      type: address
    - name: assets
      indexed: false
      type: uint256

CancelRedeemRequest

controller 已请求取消其请求 ID 为 requestId 的存款请求。 sendercancelRedeemRequest 的调用者,可能不等于 controller

当使用 cancelRedeemRequest 方法提交赎回取消请求时,必须发出。

- name: CancelRedeemRequest
  type: event

  inputs:
    - name: controller
      indexed: true
      type: address
    - name: requestId
      indexed: true
      type: uint256
    - name: sender
      indexed: false
      type: address

CancelRedeemClaim

controller 已声明其请求 ID 为 requestId 的赎回取消请求。 receivershares 的目标。 senderclaimCancelRedeemRequest 的调用者,可能不等于 controller

当使用 claimCancelRedeemRequest 方法提交赎回取消请求时,必须发出。

- name: CancelRedeemClaim
  type: event

  inputs:
    - name: controller
      indexed: true
      type: address
    - name: receiver
      indexed: true
      type: address
    - name: requestId
      indexed: true
      type: uint256
    - name: sender
      indexed: false
      type: address
    - name: shares
      indexed: false
      type: uint256

ERC-165 支持

实现此金库标准的智能合约必须实现 ERC-165 supportsInterface 函数。

如果通过 interfaceID 参数传递 0x8bf840e3,则具有取消支持的异步存款金库必须返回常量值 true

如果通过 interfaceID 参数传递 0xe76cffc7,则具有取消支持的异步赎回金库必须返回常量值 true

理由

在取消期间阻止请求

controller 调用 cancelDepositRequest 时,将阻止此 controller 的新存款请求,并且等效项适用于赎回流程。

此要求简化了实现异步取消流程的金库的可能状态。

另一种方法会创建可能的状态,其中取消挂起并触发新的存款请求,从而导致集成商难以读取当前状态。

强制支持 ERC-165

由于 ERC-7540 中定义的可选流程,因此强制执行对 ERC-165 的支持。 集成可以使用 supportsInterface 方法来检查金库是完全异步、部分异步还是完全同步(对于完全同步的金库,它只是遵循 ERC-4626),并使用单个合约来支持所有情况。

向后兼容性

该接口与 ERC-7540 完全向后兼容。

安全注意事项

ERC-7540 中现有的安全注意事项适用。

版权

CC0 下放弃版权和相关权利。

Citation

Please cite this document as:

Jeroen Offerijns (@hieronx), Vikram Arun (@vikramarun), "ERC-7887: 取消 ERC-7540 代币化金库 [DRAFT]," Ethereum Improvement Proposals, no. 7887, February 2025. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7887.