From 2081e0077d1002c5cc33360b286dfb62c5c40669 Mon Sep 17 00:00:00 2001 From: Joey Santoro Date: Tue, 28 Nov 2023 08:44:43 -0600 Subject: [PATCH 01/38] changes for rid --- ERCS/erc-7540.md | 267 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 234 insertions(+), 33 deletions(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index fe35babb4e..3f7b755532 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -15,7 +15,7 @@ requires: 20, 165, 4626 The following standard extends [ERC-4626](./eip-4626.md) by adding support for asynchronous deposit and redemption flows. The async flows are called Requests. -New methods are added to asynchronously Request a deposit or redemption, and view the pending status of the Request. The existing `deposit`, `mint`, `withdraw`, and `redeem` ERC-4626 methods are used for executing Claimable Requests. +New methods are added to asynchronously Request a deposit or redemption, and view the status of the Request. The existing `deposit`, `mint`, `withdraw`, and `redeem` ERC-4626 methods are used for executing Claimable Requests. Implementations can choose to whether to add asynchronous flows for deposits, redemptions, or both. @@ -33,12 +33,11 @@ This standard expands the utility of ERC-4626 Vaults for asynchronous use cases. The existing definitions from [ERC-4626](./eip-4626.md) apply. In addition, this spec defines: -- Request: a function call that initiates an asynchronous deposit/redemption flow +- Request: a request to enter (`requestDeposit`) or exit (`requestRedeem`) the Vault - Pending: the state where a Request has been made but is not yet Claimable - Claimable: the state where a Request is processed by the Vault enabling the user to claim corresponding `shares` (for async deposit) or `assets` (for async redeem) - Claimed: the state where a Request is finalized by the user and the user receives the output token (e.g. `shares` for a deposit Request) - Claim function: the corresponding Vault method to bring a Request to Claimed state (e.g. `deposit` or `mint` claims `shares` from `requestDeposit`). Lower case claim always describes the verb action of calling a Claim function. -- operator: the account specified by the sender of the Request which has the right to claim a given Request once it is Claimable - asynchronous deposit Vault: a Vault that implements asynchronous Requests for deposit flows - asynchronous redemption Vault: a Vault that implements asynchronous redemption flows - fully asynchronous Vault: a Vault that implements asynchronous Requests for both deposit and redemption @@ -57,7 +56,7 @@ Asynchronous deposit Vaults MUST override the ERC-4626 specification as follows: Asynchronous redeem Vaults MUST override the ERC-4626 specification as follows: 1. The `redeem` and `withdraw` methods do not transfer `shares` to the Vault, because this already happened on `requestRedeem`. -2. The `owner/operator` field of `redeem` and `withdraw` MUST be `msg.sender` to prevent the theft of requested redemptions by a non-owner/operator. +2. The `owner` field of `redeem` and `withdraw` MUST be `msg.sender` to prevent the theft of requested redemptions by a non-owner. 3. `previewRedeem` and `previewWithdraw` MUST revert for all callers and inputs. ### Request Lifecycle @@ -66,9 +65,11 @@ After submission, Requests go through Pending, Claimable, and Claimed stages. An | **State** | **User** | **Vault** | |-------------|---------------------------------|-----------| -| Pending | `requestDeposit(assets, operator)` | `asset.transferFrom(msg.sender, vault, assets)`; `pendingDepositRequest[operator] += assets` | -| Claimable | | *Internal Request fulfillment*: `pendingDepositRequest[msg.sender] -= assets`; `maxDeposit[operator] += assets` | -| Claimed | `deposit(assets, receiver)` | `maxDeposit[msg.sender] -= assets`; `vault.balanceOf[receiver] += shares` | +| Pending | `requestDeposit(assets, receiver, owner, data)` | `asset.transferFrom(msg.sender, vault, assets)`; `pendingDepositRequest[owner] += assets` | +| Claimable | | *Internal Request fulfillment*: `pendingDepositRequest[msg.sender] -= assets`; `claimableDepositRequest[owner] += assets` | +| Claimed | `deposit(assets, receiver)` | `claimableDepositRequest[msg.sender] -= assets`; `vault.balanceOf[receiver] += shares` | + +Note that `maxDeposit` increases and decreases in sync with `claimableDepositRequest`. An important Vault inequality is that following a Request(s), the cumulative requested quantity MUST be more than `pendingDepositRequest + maxDeposit - claimed`. The inequality may come from fees or other state transitions outside implemented by Vault logic such as cancellation of a Request, otherwise this would be a strict equality. @@ -76,19 +77,37 @@ Requests MUST NOT skip or otherwise short-circuit the Claim state. In other word For asynchronous Vaults, the exchange rate between `shares` and `assets` including fees and yield is up to the Vault implementation. In other words, pending redemption Requests MAY NOT be yield bearing and MAY NOT have a fixed exchange rate. +### Request Ids +The request ID (`rid`) of a request is returned by the corresponding `requestDeposit` and `requestRedeem` functions. + +Multiple requests may have the same `rid`, so a given Request is discriminated by both the `rid` and the `owner`. + +Requests of the same `rid` MUST be fungible with each other (except in the special case `rid == 0` described below). I.e. all Requests with the same `rid` MUST transition from Pending to Claimable at the same time and receive the same exchange rate between `assets` and `shares`. + +If a Request becomes partially claimable, all requests of the same `rid` MUST become claimable at the same pro rata rate. + +There are no assumptions or requirements of requests with different `rid`. I.e. they MAY transition to Claimable at different times and exchange rates with no ordering or correlation enforced in any way. + +When `rid==0`, the Vault MUST use purely the `owner` to discriminate the request state. The Pending and Claimable state of multiple requests from the same `owner` would be aggregated. If a Vault returns `0` for the `rid` of any request, it MUST return `0` for all requests. ### Methods #### requestDeposit -Transfers `assets` from `msg.sender` into the Vault and submits a Request for asynchronous `deposit/mint`. This places the Request in Pending state, with a corresponding increase in `pendingDepositRequest` for the amount `assets`. +Transfers `assets` from `msg.sender` into the Vault and submits a Request for asynchronous `deposit/mint`. This places the Request in Pending state, with a corresponding increase in `pendingDepositRequest` for the amount `assets`. + +The output `rid` is used to partially descriminate the request along with the `receiver`. See "Request Ids" section for more info. -When the Request is Claimable, `maxDeposit` and `maxMint` will be increased for the case where the `receiver` input is the `operator`. `deposit` or `mint` can subsequently be called by `operator` to receive `shares`. A Request MAY transition straight to Claimable state but MUST NOT skip the Claimable state. +If the length of `data` is not 0, the Request MUST send an `onERC7540DepositReceived` callback to `receiver` following the interface of ERC7540DepositReceiver described in "Request Callbacks" section. If the length of `data` is 0, the Request MUST NOT send a callback. + +When the Request is Claimable, `claimableDepositRequest` will be increased for the `receiver`. `deposit` or `mint` can subsequently be called by `receiver` to receive `shares`. A Request MAY transition straight to Claimable state but MUST NOT skip the Claimable state. The `shares` that will be received on `deposit` or `mint` MAY NOT be equivalent to the value of `convertToShares(assets)` at the time of Request, as the price can change between Request and Claim. MUST support [ERC-20](./eip-20.md) `approve` / `transferFrom` on `asset` as a deposit Request flow. +`owner` MUST equal `msg.sender` unless the `owner` has approved the `msg.sender` by some mechanism. + MUST revert if all of `assets` cannot be requested for `deposit`/`mint` (due to deposit limit being reached, slippage, the user not approving enough underlying tokens to the Vault contract, etc). Note that most implementations will require pre-approval of the Vault with the Vault's underlying `asset` token. @@ -103,13 +122,20 @@ MUST emit the `RequestDeposit` event. inputs: - name: assets type: uint256 - - name: operator + - name: receiver + type: address + - name: owner type: address + - name: data + type: bytes + outputs: + - name: rid + type: uint256 ``` #### pendingDepositRequest -The amount of requested `assets` in Pending state for the `operator` to `deposit` or `mint`. +The amount of requested `assets` in Pending state for the `owner` to `deposit` or `mint`. MUST NOT include any `assets` in Claimable state for `deposit` or `mint`. @@ -123,7 +149,31 @@ MUST NOT revert unless due to integer overflow caused by an unreasonably large i stateMutability: view inputs: - - name: operator + - name: owner + type: address + + outputs: + - name: assets + type: uint256 +``` + +#### claimableDepositRequest + +The amount of requested `assets` in Claimable state for the `owner` to `deposit` or `mint`. + +MUST NOT include any `assets` in Pending state for `deposit` or `mint`. + +MUST NOT show any variations depending on the caller. + +MUST NOT revert unless due to integer overflow caused by an unreasonably large input. + +```yaml +- name: claimableDepositRequest + type: function + stateMutability: view + + inputs: + - name: owner type: address outputs: @@ -135,13 +185,17 @@ MUST NOT revert unless due to integer overflow caused by an unreasonably large i Assumes control of `shares` from `owner` and submits a Request for asynchronous `redeem/withdraw`. This places the Request in Pending state, with a corresponding increase in `pendingRedeemRequest` for the amount `shares`. +The output `rid` is used to partially descriminate the request along with the `receiver`. See "Request Ids" section for more info. + MAY support either a locking or a burning mechanism for `shares` depending on the Vault implemention. If a Vault uses a locking mechanism for `shares`, those `shares` MUST be burned from the Vault balance before or upon claiming the Request. MUST support a redeem Request flow where the control of `shares` is taken from `owner` directly where `msg.sender` has ERC-20 approval over the `shares` of `owner`. -When the Request is Claimable, `maxRedeem` and `maxWithdraw` will be increased for the case where the `owner` input is the `operator`. `redeem` or `withdraw` can subsequently be called by `operator` to receive `assets`. A Request MAY transition straight to Claimable state but MUST NOT skip the Claimable state. +If the length of `data` is not 0, the Request MUST send an `onERC7540RedeemReceived` callback to `receiver` following the interface of ERC7540RedeemReceiver described in "Request Callbacks" section. If the length of `data` is 0, the Request MUST NOT send a callback. + +When the Request is Claimable, `claimableRedeemRequest` will be increased for the `receiver`. `redeem` or `withdraw` can subsequently be called by `receiver` to receive `assets`. A Request MAY transition straight to Claimable state but MUST NOT skip the Claimable state. The `assets` that will be received on `redeem` or `withdraw` MAY NOT be equivalent to the value of `convertToAssets(shares)` at time of Request, as the price can change between Pending and Claimed. @@ -159,15 +213,20 @@ MUST emit the `RequestRedeem` event. inputs: - name: shares type: uint256 - - name: operator + - name: receiver type: address - name: owner type: address + - name: data + type: bytes + outputs: + - name: rid + - type: uint256 ``` #### pendingRedeemRequest -The amount of requested `shares` in Pending state for the `operator` to `redeem` or `withdraw`. +The amount of requested `shares` in Pending state for the `owner` to `redeem` or `withdraw`. MUST NOT include any `shares` in Claimable state for `redeem` or `withdraw`. @@ -181,7 +240,31 @@ MUST NOT revert unless due to integer overflow caused by an unreasonably large i stateMutability: view inputs: - - name: operator + - name: owner + type: address + + outputs: + - name: shares + type: uint256 +``` + +#### claimableRedeemRequest + +The amount of requested `shares` in Claimable state for the `owner` to `redeem` or `withdraw`. + +MUST NOT include any `shares` in Pending state for `redeem` or `withdraw`. + +MUST NOT show any variations depending on the caller. + +MUST NOT revert unless due to integer overflow caused by an unreasonably large input. + +```yaml +- name: claimableRedeemRequest + type: function + stateMutability: view + + inputs: + - name: owner type: address outputs: @@ -193,7 +276,7 @@ MUST NOT revert unless due to integer overflow caused by an unreasonably large i #### DepositRequest -`sender` has locked `assets` in the Vault to Request a deposit. `operator` controls this Request. +`sender` has locked `assets` in the Vault to Request a deposit with request ID `rid`. `receiver` controls this Request. MUST be emitted when a deposit Request is submitted using the `requestDeposit` method. @@ -205,9 +288,12 @@ MUST be emitted when a deposit Request is submitted using the `requestDeposit` m - name: sender indexed: true type: address - - name: operator + - name: receiver indexed: true type: address + - name: rid + indexed: true + type: uint256 - name: assets indexed: false type: uint256 @@ -215,7 +301,7 @@ MUST be emitted when a deposit Request is submitted using the `requestDeposit` m #### RedeemRequest -`sender` has locked `shares`, owned by `owner`, in the Vault to Request a redemption. `operator` controls this Request. +`sender` has locked `shares`, owned by `owner`, in the Vault to Request a redemption. `receiver` controls this Request, but is not necessarily the `owner`. MUST be emitted when a redemption Request is submitted using the `requestRedeem` method. @@ -224,30 +310,107 @@ MUST be emitted when a redemption Request is submitted using the `requestRedeem` type: event inputs: - - name: sender - indexed: true - type: address - - name: operator + - name: receiver indexed: true type: address - name: owner indexed: true type: address + - name: rid + indexed: true + type: uint256 + - name: sender + indexed: false + type: uint256 - name: assets indexed: false type: uint256 ``` +### Request Callbacks + +All methods which initiate a request (including `rid==0`) include a `data` parameter, which if nonzero length MUST send a callback to the receiver. + +There are two interfaces, `ERC7540DepositReceiver` and `ERC7540RedeemReceiver` which each define the single callback method to be called. + +#### ERC7540DepositReceiver +The interface to be called on `requestDeposit`. + +`operator` is the `msg.sender` of the original `requestDeposit` call. `owner` is the `owner` of the `requestDeposit`. `rid` is the output `rid` of the `requestDeposit` and `data` is the `data` of the `requestDeposit`. + +This function MUST return `TODO` upon successful execution of the callback. + +```yaml +- name: onERC7540DepositReceived + type: function + + inputs: + - name: operator + type: address + - name: owner + type: address + - name: rid + type: uint256 + - name: data + type: bytes + outputs: + - name: interfaceId + type: bytes4 +``` + + +#### ERC7540RedeemReceiver +The interface to be called on `requestRedeem`. + +`operator` is the `msg.sender` of the original `requestRedeem` call. `owner` is the `owner` of the `requestRedeem`. `rid` is the output `rid` of the `requestRedeem` and `data` is the `data` of the `requestRedeem`. + +This function MUST return `TODO` upon successful execution of the callback. + +```yaml +- name: onERC7540RedeemReceived + type: function + + inputs: + - name: operator + type: address + - name: owner + type: address + - name: rid + type: uint256 + - name: data + type: bytes + outputs: + - name: interfaceId + type: bytes4 +``` + ### [ERC-165](./eip-165.md) support Smart contracts implementing this standard MUST implement the [ERC-165](./eip-165.md) `supportsInterface` function. -Asynchronous deposit Vaults MUST return the constant value `true` if `0xea446681` is passed through the `interfaceID` argument. +Asynchronous deposit Vaults MUST return the constant value `true` if TODO `0xea446681` is passed through the `interfaceID` argument. + +Asynchronous redemption Vaults MUST return the constant value `true` if TODO `0x2e9dd5bd` is passed through the `interfaceID` argument. -Asynchronous redemption Vaults MUST return the constant value `true` if `0x2e9dd5bd` is passed through the `interfaceID` argument. +ERC7540DepositReceiver contracts MUST return the constant value `true` if TODO is passed through the `interfaceID` argument. + +ERC7540RedeemReceiver contracts MUST return the constant value `true` if TODO is passed through the `interfaceID` argument. ## Rationale +### Including Request IDs but Not Including a Claim by ID method +Requests in an Asynchronous Vault have properties of NFTs or Semi-Fungible tokens due to their asynchronicity. However, trying to pigeonhole all ERC-7540 Vaults into supporting [ERC-721](./eip-721) or [ERC-1155](./erc-1155) for Requests would create too much interface bloat. + +Using both an id and address to discriminate Requests allows for any of these use cases to be developed at an external layer without adding too much complexity to the core interface. + +Certain Vaults especially `rid==0` cases benefit from using the underlying ERC4626 methods for claiming because there is no discrimination at the `rid` level. This standard is written primarily with those use cases in mind. A future standard can optimize for nonzero RID with support for claiming and transferring requests discriminated also with an `rid`. + +### Callbacks + +Callbacks on Request calls can be used among other things to allow Requests to become fully [ERC-721](./eip-721) or [ERC-1155](./erc-1155) compatible in an external layer. + +This can support flows where a smart contract manages the Request lifecycle on behalf of a user. + ### Symmetry and Non-inclusion of requestWithdraw and requestMint In ERC-4626, the spec was written to be fully symmetrical with respect to converting `assets` and `shares` by including deposit/withdraw and mint/redeem. @@ -284,10 +447,6 @@ The 2-step approach used in the standard may be abstracted into a 1-step approac In the case where a Request may become Claimable immediately in the same block, there can be router contracts which atomically check for Claimable amounts immediately upon Request. Frontends can dynamically route Requests in this way depending on the state and implementation of the Vault to handle this edge case. -### Operator function parameter on requestDeposit and requestRedeem - -To support flows where a smart contract manages the Request lifecycle on behalf of a user, the `operator` parameter is included in the `requestDeposit` and `requestRedeem` functions. This is not called `owner` because the `assets` or `shares` are not transferred from this account on Request submission, unlike the behaviour of an `owner` on `redeem`. It is also not called `receiver` because the `shares` or `assets` are not necessarily transferred on claiming the Request, this can be chosen by the operator when they call `deposit`, `mint`, `redeem`, or `withdraw`. - ### No Outputs for Request functions `requestDeposit` and `requestRedeem` may not have a known exchange rate that will happen when the Request becomes Claimed. Returning the corresponding `assets` or `shares` could not work in this case. @@ -300,7 +459,7 @@ The state transition of a Request from Pending to Claimable happens at the Vault ### Reversion of Preview Functions in Async Request Flows -The preview functions do not take an address parameter, therefore the only way to discriminate discrepancies in exchange rate are via the `msg.sender`. However, this could lead to integration/implementation complexities where support contracts cannot determine the output of a claim on behalf of an `operator`. +The preview functions do not take an address parameter, therefore the only way to discriminate discrepancies in exchange rate are via the `msg.sender`. However, this could lead to integration/implementation complexities where support contracts cannot determine the output of a claim on behalf of an `owner`. In addition, there is no on-chain benefit to previewing the Claim step as the only valid state transition is to Claim anyway. If the output of a Claim is undesirable for any reason, the calling contract can revert on the output of that function call. @@ -319,11 +478,53 @@ The interface is fully backwards compatible with [ERC-4626](./eip-4626.md). The ## Reference Implementation -WIP +```solidity + // 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 + + mapping(address => uint256) public pendingDepositRequest; + + mapping(address => uint256) public claimableDepositRequest; + + function requestDeposit(uint256 assets, address receiver, address owner, bytes calldata data) external returns (uint256 rid) { + require(assets != 0); + require(owner == msg.sender); + + rid = 0; // no rid associated with this request + + asset.safeTransferFrom(msg.sender, address(this), assets); // asset here is the Vault underlying asset + + pendingDepositRequest[owner] += assets; + + // Perform the callback + if (data.length != 0) { + ERC7540Receiver(receiver).onERC7540DepositReceived(msg.sender, owner, rid, data); + } + + emit DepositRequest(msg.sender, operator, rid, assets); + return rid; + } + + /** + * Include some arbitrary transition logic here from Pending to Claimable + */ + + function deposit(uint256 assets, address receiver) external returns (uint256 shares) { + require(assets != 0); + + claimableDepositRequest[msg.sender] -= assets; // underflow would revert if not enough claimable assets + + shares = convertToShares(assets); // this naive example uses the instantaneous exchange rate. It may be more common to use the rate locked in upon Claimable stage. + + balanceOf[receiver] += shares; + + emit Deposit(msg.sender, receiver, assets, shares); + } + +``` ## Security Considerations -The methods `pendingDepositRequest` and `pendingRedeemRequest` are estimates useful for display purposes, and can be outdated due to the asynchronicity. +The view methods for viewing Pending and Claimable request states (e.g. `pendingDepositRequest`) are estimates useful for display purposes, and can be outdated due to the asynchronicity. In general, asynchronicity concerns make state transitions in the Vault much more complex and vulnerable to security risks. Access control on Vault operations, clear documentation of state transitioning, and invariant checks should all be performed to mitigate these risks. @@ -331,7 +532,7 @@ In particular, shares or assets locked for Requests can be stuck in the Pending Moreover, users might not know what the final exchange rate will be on any Request due to the asynchronicity. Users therefore trust the implementation of the asynchronous Vault in the computation of the exchange rate and fulfillment of their Request. -It is worth highlighting again here that the Claim functions for any asynchronous flows MUST enforce that `msg.sender == operator/owner` to prevent theft of Claimable `assets` or `shares` +It is worth highlighting again here that the Claim functions for any asynchronous flows MUST enforce that `msg.sender == owner` to prevent theft of Claimable `assets` or `shares` ## Copyright From 94936c7c8c124762e16304e30345e68cf042bd8f Mon Sep 17 00:00:00 2001 From: Joey <31974730+Joeysantoro@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:48:41 -0600 Subject: [PATCH 02/38] Update ERCS/erc-7540.md Co-authored-by: Farhaan <59924029+0xfarhaan@users.noreply.github.com> --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 3f7b755532..a796e775e2 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -94,7 +94,7 @@ When `rid==0`, the Vault MUST use purely the `owner` to discriminate the request #### requestDeposit -Transfers `assets` from `msg.sender` into the Vault and submits a Request for asynchronous `deposit/mint`. This places the Request in Pending state, with a corresponding increase in `pendingDepositRequest` for the amount `assets`. +Transfers `assets` from `msg.sender` into the Vault and submits a Request for asynchronous `deposit`. This places the Request in Pending state, with a corresponding increase in `pendingDepositRequest` for the amount `assets`. The output `rid` is used to partially descriminate the request along with the `receiver`. See "Request Ids" section for more info. From e6a1956860194196b380c94f124b44925040ddd4 Mon Sep 17 00:00:00 2001 From: Joey <31974730+Joeysantoro@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:48:48 -0600 Subject: [PATCH 03/38] Update ERCS/erc-7540.md Co-authored-by: Farhaan <59924029+0xfarhaan@users.noreply.github.com> --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index a796e775e2..7c691ad76d 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -183,7 +183,7 @@ MUST NOT revert unless due to integer overflow caused by an unreasonably large i #### requestRedeem -Assumes control of `shares` from `owner` and submits a Request for asynchronous `redeem/withdraw`. This places the Request in Pending state, with a corresponding increase in `pendingRedeemRequest` for the amount `shares`. +Assumes control of `shares` from `owner` and submits a Request for asynchronous `redeem`. This places the Request in Pending state, with a corresponding increase in `pendingRedeemRequest` for the amount `shares`. The output `rid` is used to partially descriminate the request along with the `receiver`. See "Request Ids" section for more info. From 2aaf591048d3e23020b88607efd73a35a9b4322f Mon Sep 17 00:00:00 2001 From: Joey <31974730+Joeysantoro@users.noreply.github.com> Date: Tue, 5 Dec 2023 14:14:01 -0500 Subject: [PATCH 04/38] Update ERCS/erc-7540.md Co-authored-by: Jeroen <1748621+hieronx@users.noreply.github.com> --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 7c691ad76d..d69f9ffd01 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -65,7 +65,7 @@ After submission, Requests go through Pending, Claimable, and Claimed stages. An | **State** | **User** | **Vault** | |-------------|---------------------------------|-----------| -| Pending | `requestDeposit(assets, receiver, owner, data)` | `asset.transferFrom(msg.sender, vault, assets)`; `pendingDepositRequest[owner] += assets` | +| Pending | `requestDeposit(assets, receiver, owner, data)` | `asset.transferFrom(msg.sender, vault, assets)`; `pendingDepositRequest[receiver] += assets` | | Claimable | | *Internal Request fulfillment*: `pendingDepositRequest[msg.sender] -= assets`; `claimableDepositRequest[owner] += assets` | | Claimed | `deposit(assets, receiver)` | `claimableDepositRequest[msg.sender] -= assets`; `vault.balanceOf[receiver] += shares` | From 26466ef3e85777d1f864ab63b852c1abb035f355 Mon Sep 17 00:00:00 2001 From: Joey Santoro Date: Tue, 5 Dec 2023 14:15:06 -0500 Subject: [PATCH 05/38] sec considerations --- ERCS/erc-7540.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 7c691ad76d..de9f0322b9 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -524,15 +524,12 @@ The interface is fully backwards compatible with [ERC-4626](./eip-4626.md). The ## Security Considerations -The view methods for viewing Pending and Claimable request states (e.g. `pendingDepositRequest`) are estimates useful for display purposes, and can be outdated due to the asynchronicity. +In general, asynchronicity concerns make state transitions in the Vault much more complex and vulnerable to security risks. Access control on Vault operations, clear documentation of state transitioning, and invariant checks should all be performed to mitigate these risks. For example: -In general, asynchronicity concerns make state transitions in the Vault much more complex and vulnerable to security risks. Access control on Vault operations, clear documentation of state transitioning, and invariant checks should all be performed to mitigate these risks. +* The view methods for viewing Pending and Claimable request states (e.g. pendingDepositRequest) are estimates useful for display purposes but can be outdated. The inability to know the final exchange rate will be on any Request requires users to trust the implementation of the asynchronous Vault in the computation of the exchange rate and fulfillment of their Request. +* Shares or assets locked for Requests can be stuck in the Pending state. Vaults may elect to allow for fungibility of pending claims or implement some cancellation functionality to protect users. -In particular, shares or assets locked for Requests can be stuck in the Pending state. Vaults may elect to allow for fungibility of pending claims or implement some cancellation functionality to protect users. - -Moreover, users might not know what the final exchange rate will be on any Request due to the asynchronicity. Users therefore trust the implementation of the asynchronous Vault in the computation of the exchange rate and fulfillment of their Request. - -It is worth highlighting again here that the Claim functions for any asynchronous flows MUST enforce that `msg.sender == owner` to prevent theft of Claimable `assets` or `shares` +Lastly, it is worth highlighting again here that the Claim functions for any asynchronous flows MUST enforce that msg.sender == owner to prevent theft of Claimable assets or shares. ## Copyright From e3a1026e5ba2abd2d4ce08cdad1b42c3ad23f499 Mon Sep 17 00:00:00 2001 From: Joey Santoro Date: Tue, 5 Dec 2023 14:23:32 -0500 Subject: [PATCH 06/38] events and 165 --- ERCS/erc-7540.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index aeeaf9e733..f1c032b388 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -276,7 +276,7 @@ MUST NOT revert unless due to integer overflow caused by an unreasonably large i #### DepositRequest -`sender` has locked `assets` in the Vault to Request a deposit with request ID `rid`. `receiver` controls this Request. +`owner` has locked `assets` in the Vault to Request a deposit with request ID `rid`. `receiver` controls this Request. `sender` is the caller of the `requestDeposit` which may not be equal to the `owner`. MUST be emitted when a deposit Request is submitted using the `requestDeposit` method. @@ -285,15 +285,18 @@ MUST be emitted when a deposit Request is submitted using the `requestDeposit` m type: event inputs: - - name: sender + - name: receiver indexed: true type: address - - name: receiver + - name: owner indexed: true type: address - name: rid indexed: true type: uint256 + - name: sender + indexed: false + type: address - name: assets indexed: false type: uint256 @@ -386,16 +389,12 @@ This function MUST return `TODO` upon successful execution of the callback. ### [ERC-165](./eip-165.md) support -Smart contracts implementing this standard MUST implement the [ERC-165](./eip-165.md) `supportsInterface` function. +Smart contracts implementing this Vault standard MUST implement the [ERC-165](./eip-165.md) `supportsInterface` function. Asynchronous deposit Vaults MUST return the constant value `true` if TODO `0xea446681` is passed through the `interfaceID` argument. Asynchronous redemption Vaults MUST return the constant value `true` if TODO `0x2e9dd5bd` is passed through the `interfaceID` argument. -ERC7540DepositReceiver contracts MUST return the constant value `true` if TODO is passed through the `interfaceID` argument. - -ERC7540RedeemReceiver contracts MUST return the constant value `true` if TODO is passed through the `interfaceID` argument. - ## Rationale ### Including Request IDs but Not Including a Claim by ID method From 8387565cad7cff2c60b8454a122de9485e950e90 Mon Sep 17 00:00:00 2001 From: Joey Santoro Date: Tue, 5 Dec 2023 14:28:58 -0500 Subject: [PATCH 07/38] rid --- ERCS/erc-7540.md | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index f1c032b388..2eb153cbe5 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -78,17 +78,17 @@ Requests MUST NOT skip or otherwise short-circuit the Claim state. In other word For asynchronous Vaults, the exchange rate between `shares` and `assets` including fees and yield is up to the Vault implementation. In other words, pending redemption Requests MAY NOT be yield bearing and MAY NOT have a fixed exchange rate. ### Request Ids -The request ID (`rid`) of a request is returned by the corresponding `requestDeposit` and `requestRedeem` functions. +The request ID (`requestId`) of a request is returned by the corresponding `requestDeposit` and `requestRedeem` functions. -Multiple requests may have the same `rid`, so a given Request is discriminated by both the `rid` and the `owner`. +Multiple requests may have the same `requestId`, so a given Request is discriminated by both the `requestId` and the `owner`. -Requests of the same `rid` MUST be fungible with each other (except in the special case `rid == 0` described below). I.e. all Requests with the same `rid` MUST transition from Pending to Claimable at the same time and receive the same exchange rate between `assets` and `shares`. +Requests of the same `requestId` MUST be fungible with each other (except in the special case `requestId == 0` described below). I.e. all Requests with the same `requestId` MUST transition from Pending to Claimable at the same time and receive the same exchange rate between `assets` and `shares`. -If a Request becomes partially claimable, all requests of the same `rid` MUST become claimable at the same pro rata rate. +If a Request becomes partially claimable, all requests of the same `requestId` MUST become claimable at the same pro rata rate. -There are no assumptions or requirements of requests with different `rid`. I.e. they MAY transition to Claimable at different times and exchange rates with no ordering or correlation enforced in any way. +There are no assumptions or requirements of requests with different `requestId`. I.e. they MAY transition to Claimable at different times and exchange rates with no ordering or correlation enforced in any way. -When `rid==0`, the Vault MUST use purely the `owner` to discriminate the request state. The Pending and Claimable state of multiple requests from the same `owner` would be aggregated. If a Vault returns `0` for the `rid` of any request, it MUST return `0` for all requests. +When `requestId==0`, the Vault MUST use purely the `owner` to discriminate the request state. The Pending and Claimable state of multiple requests from the same `owner` would be aggregated. If a Vault returns `0` for the `requestId` of any request, it MUST return `0` for all requests. ### Methods @@ -96,7 +96,7 @@ When `rid==0`, the Vault MUST use purely the `owner` to discriminate the request Transfers `assets` from `msg.sender` into the Vault and submits a Request for asynchronous `deposit`. This places the Request in Pending state, with a corresponding increase in `pendingDepositRequest` for the amount `assets`. -The output `rid` is used to partially descriminate the request along with the `receiver`. See "Request Ids" section for more info. +The output `requestId` is used to partially descriminate the request along with the `receiver`. See "Request Ids" section for more info. If the length of `data` is not 0, the Request MUST send an `onERC7540DepositReceived` callback to `receiver` following the interface of ERC7540DepositReceiver described in "Request Callbacks" section. If the length of `data` is 0, the Request MUST NOT send a callback. @@ -129,7 +129,7 @@ MUST emit the `RequestDeposit` event. - name: data type: bytes outputs: - - name: rid + - name: requestId type: uint256 ``` @@ -185,7 +185,7 @@ MUST NOT revert unless due to integer overflow caused by an unreasonably large i Assumes control of `shares` from `owner` and submits a Request for asynchronous `redeem`. This places the Request in Pending state, with a corresponding increase in `pendingRedeemRequest` for the amount `shares`. -The output `rid` is used to partially descriminate the request along with the `receiver`. See "Request Ids" section for more info. +The output `requestId` is used to partially descriminate the request along with the `receiver`. See "Request Ids" section for more info. MAY support either a locking or a burning mechanism for `shares` depending on the Vault implemention. @@ -220,7 +220,7 @@ MUST emit the `RequestRedeem` event. - name: data type: bytes outputs: - - name: rid + - name: requestId - type: uint256 ``` @@ -276,7 +276,7 @@ MUST NOT revert unless due to integer overflow caused by an unreasonably large i #### DepositRequest -`owner` has locked `assets` in the Vault to Request a deposit with request ID `rid`. `receiver` controls this Request. `sender` is the caller of the `requestDeposit` which may not be equal to the `owner`. +`owner` has locked `assets` in the Vault to Request a deposit with request ID `requestId`. `receiver` controls this Request. `sender` is the caller of the `requestDeposit` which may not be equal to the `owner`. MUST be emitted when a deposit Request is submitted using the `requestDeposit` method. @@ -291,7 +291,7 @@ MUST be emitted when a deposit Request is submitted using the `requestDeposit` m - name: owner indexed: true type: address - - name: rid + - name: requestId indexed: true type: uint256 - name: sender @@ -319,7 +319,7 @@ MUST be emitted when a redemption Request is submitted using the `requestRedeem` - name: owner indexed: true type: address - - name: rid + - name: requestId indexed: true type: uint256 - name: sender @@ -332,14 +332,14 @@ MUST be emitted when a redemption Request is submitted using the `requestRedeem` ### Request Callbacks -All methods which initiate a request (including `rid==0`) include a `data` parameter, which if nonzero length MUST send a callback to the receiver. +All methods which initiate a request (including `requestId==0`) include a `data` parameter, which if nonzero length MUST send a callback to the receiver. There are two interfaces, `ERC7540DepositReceiver` and `ERC7540RedeemReceiver` which each define the single callback method to be called. #### ERC7540DepositReceiver The interface to be called on `requestDeposit`. -`operator` is the `msg.sender` of the original `requestDeposit` call. `owner` is the `owner` of the `requestDeposit`. `rid` is the output `rid` of the `requestDeposit` and `data` is the `data` of the `requestDeposit`. +`operator` is the `msg.sender` of the original `requestDeposit` call. `owner` is the `owner` of the `requestDeposit`. `requestId` is the output `requestId` of the `requestDeposit` and `data` is the `data` of the `requestDeposit`. This function MUST return `TODO` upon successful execution of the callback. @@ -352,7 +352,7 @@ This function MUST return `TODO` upon successful execution of the callback. type: address - name: owner type: address - - name: rid + - name: requestId type: uint256 - name: data type: bytes @@ -365,7 +365,7 @@ This function MUST return `TODO` upon successful execution of the callback. #### ERC7540RedeemReceiver The interface to be called on `requestRedeem`. -`operator` is the `msg.sender` of the original `requestRedeem` call. `owner` is the `owner` of the `requestRedeem`. `rid` is the output `rid` of the `requestRedeem` and `data` is the `data` of the `requestRedeem`. +`operator` is the `msg.sender` of the original `requestRedeem` call. `owner` is the `owner` of the `requestRedeem`. `requestId` is the output `requestId` of the `requestRedeem` and `data` is the `data` of the `requestRedeem`. This function MUST return `TODO` upon successful execution of the callback. @@ -378,7 +378,7 @@ This function MUST return `TODO` upon successful execution of the callback. type: address - name: owner type: address - - name: rid + - name: requestId type: uint256 - name: data type: bytes @@ -402,7 +402,7 @@ Requests in an Asynchronous Vault have properties of NFTs or Semi-Fungible token Using both an id and address to discriminate Requests allows for any of these use cases to be developed at an external layer without adding too much complexity to the core interface. -Certain Vaults especially `rid==0` cases benefit from using the underlying ERC4626 methods for claiming because there is no discrimination at the `rid` level. This standard is written primarily with those use cases in mind. A future standard can optimize for nonzero RID with support for claiming and transferring requests discriminated also with an `rid`. +Certain Vaults especially `requestId==0` cases benefit from using the underlying ERC4626 methods for claiming because there is no discrimination at the `requestId` level. This standard is written primarily with those use cases in mind. A future standard can optimize for nonzero RID with support for claiming and transferring requests discriminated also with an `requestId`. ### Callbacks @@ -484,11 +484,11 @@ The interface is fully backwards compatible with [ERC-4626](./eip-4626.md). The mapping(address => uint256) public claimableDepositRequest; - function requestDeposit(uint256 assets, address receiver, address owner, bytes calldata data) external returns (uint256 rid) { + function requestDeposit(uint256 assets, address receiver, address owner, bytes calldata data) external returns (uint256 requestId) { require(assets != 0); require(owner == msg.sender); - rid = 0; // no rid associated with this request + requestId = 0; // no requestId associated with this request asset.safeTransferFrom(msg.sender, address(this), assets); // asset here is the Vault underlying asset @@ -496,11 +496,11 @@ The interface is fully backwards compatible with [ERC-4626](./eip-4626.md). The // Perform the callback if (data.length != 0) { - ERC7540Receiver(receiver).onERC7540DepositReceived(msg.sender, owner, rid, data); + ERC7540Receiver(receiver).onERC7540DepositReceived(msg.sender, owner, requestId, data); } - emit DepositRequest(msg.sender, operator, rid, assets); - return rid; + emit DepositRequest(msg.sender, operator, requestId, assets); + return requestId; } /** From 3f0493f323f4a283a6962d4b33b76cd57a6f2916 Mon Sep 17 00:00:00 2001 From: Joey <31974730+Joeysantoro@users.noreply.github.com> Date: Wed, 6 Dec 2023 13:39:55 -0500 Subject: [PATCH 08/38] Update ERCS/erc-7540.md Co-authored-by: Jeroen <1748621+hieronx@users.noreply.github.com> --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 2eb153cbe5..212c492121 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -66,7 +66,7 @@ After submission, Requests go through Pending, Claimable, and Claimed stages. An | **State** | **User** | **Vault** | |-------------|---------------------------------|-----------| | Pending | `requestDeposit(assets, receiver, owner, data)` | `asset.transferFrom(msg.sender, vault, assets)`; `pendingDepositRequest[receiver] += assets` | -| Claimable | | *Internal Request fulfillment*: `pendingDepositRequest[msg.sender] -= assets`; `claimableDepositRequest[owner] += assets` | +| Claimable | | *Internal Request fulfillment*: `pendingDepositRequest[owner] -= assets`; `claimableDepositRequest[owner] += assets` | | Claimed | `deposit(assets, receiver)` | `claimableDepositRequest[msg.sender] -= assets`; `vault.balanceOf[receiver] += shares` | Note that `maxDeposit` increases and decreases in sync with `claimableDepositRequest`. From ae5148e0a2e79b297ee23098e3e0c55d3a2efcfe Mon Sep 17 00:00:00 2001 From: Joey <31974730+Joeysantoro@users.noreply.github.com> Date: Wed, 6 Dec 2023 13:53:03 -0500 Subject: [PATCH 09/38] Update ERCS/erc-7540.md Co-authored-by: Jeroen <1748621+hieronx@users.noreply.github.com> --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 212c492121..eba49c769d 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -391,7 +391,7 @@ This function MUST return `TODO` upon successful execution of the callback. Smart contracts implementing this Vault standard MUST implement the [ERC-165](./eip-165.md) `supportsInterface` function. -Asynchronous deposit Vaults MUST return the constant value `true` if TODO `0xea446681` is passed through the `interfaceID` argument. +Asynchronous deposit Vaults MUST return the constant value `true` if `0x1683f250` is passed through the `interfaceID` argument. Asynchronous redemption Vaults MUST return the constant value `true` if TODO `0x2e9dd5bd` is passed through the `interfaceID` argument. From 1981de35e6b3ced7f920e744caa4b3b2e2fdfea0 Mon Sep 17 00:00:00 2001 From: Joey <31974730+Joeysantoro@users.noreply.github.com> Date: Wed, 6 Dec 2023 13:53:11 -0500 Subject: [PATCH 10/38] Update ERCS/erc-7540.md Co-authored-by: Jeroen <1748621+hieronx@users.noreply.github.com> --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index eba49c769d..c9e5720096 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -393,7 +393,7 @@ Smart contracts implementing this Vault standard MUST implement the [ERC-165](./ Asynchronous deposit Vaults MUST return the constant value `true` if `0x1683f250` is passed through the `interfaceID` argument. -Asynchronous redemption Vaults MUST return the constant value `true` if TODO `0x2e9dd5bd` is passed through the `interfaceID` argument. +Asynchronous redemption Vaults MUST return the constant value `true` if `0x0899cb0b` is passed through the `interfaceID` argument. ## Rationale From c6d2bcc328102a47d488c4aeb7ae149d2a0f97b4 Mon Sep 17 00:00:00 2001 From: Joey Santoro Date: Wed, 6 Dec 2023 14:24:33 -0500 Subject: [PATCH 11/38] selectors --- ERCS/erc-7540.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index c9e5720096..4f53513712 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -341,7 +341,7 @@ The interface to be called on `requestDeposit`. `operator` is the `msg.sender` of the original `requestDeposit` call. `owner` is the `owner` of the `requestDeposit`. `requestId` is the output `requestId` of the `requestDeposit` and `data` is the `data` of the `requestDeposit`. -This function MUST return `TODO` upon successful execution of the callback. +This function MUST return `0xe74d2a41` upon successful execution of the callback. ```yaml - name: onERC7540DepositReceived @@ -367,7 +367,7 @@ The interface to be called on `requestRedeem`. `operator` is the `msg.sender` of the original `requestRedeem` call. `owner` is the `owner` of the `requestRedeem`. `requestId` is the output `requestId` of the `requestRedeem` and `data` is the `data` of the `requestRedeem`. -This function MUST return `TODO` upon successful execution of the callback. +This function MUST return `0x0102fde4` upon successful execution of the callback. ```yaml - name: onERC7540RedeemReceived From f80ad231c1179c4928b6b3dbb531c1af5277c508 Mon Sep 17 00:00:00 2001 From: Joey <31974730+Joeysantoro@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:28:39 -0500 Subject: [PATCH 12/38] Update ERCS/erc-7540.md Co-authored-by: Jeroen <1748621+hieronx@users.noreply.github.com> --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 4f53513712..9f281555e1 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -496,7 +496,7 @@ The interface is fully backwards compatible with [ERC-4626](./eip-4626.md). The // Perform the callback if (data.length != 0) { - ERC7540Receiver(receiver).onERC7540DepositReceived(msg.sender, owner, requestId, data); + require(ERC7540Receiver(receiver).onERC7540DepositReceived(msg.sender, owner, requestId, data) == ERC7540Receiver.onERC7540DepositReceived.selector, "receiver failed"); } emit DepositRequest(msg.sender, operator, requestId, assets); From 36b04d87d98a2b4359a080dca913047f751a3f93 Mon Sep 17 00:00:00 2001 From: Joey <31974730+Joeysantoro@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:28:55 -0500 Subject: [PATCH 13/38] Update ERCS/erc-7540.md Co-authored-by: Jeroen <1748621+hieronx@users.noreply.github.com> --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 9f281555e1..9bd5b442dd 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -65,7 +65,7 @@ After submission, Requests go through Pending, Claimable, and Claimed stages. An | **State** | **User** | **Vault** | |-------------|---------------------------------|-----------| -| Pending | `requestDeposit(assets, receiver, owner, data)` | `asset.transferFrom(msg.sender, vault, assets)`; `pendingDepositRequest[receiver] += assets` | +| Pending | `requestDeposit(assets, receiver, owner, data)` | `asset.transferFrom(owner, vault, assets)`; `pendingDepositRequest[receiver] += assets` | | Claimable | | *Internal Request fulfillment*: `pendingDepositRequest[owner] -= assets`; `claimableDepositRequest[owner] += assets` | | Claimed | `deposit(assets, receiver)` | `claimableDepositRequest[msg.sender] -= assets`; `vault.balanceOf[receiver] += shares` | From 37ff809e6ebf4c634b53674ff01244a512715a74 Mon Sep 17 00:00:00 2001 From: Joey <31974730+Joeysantoro@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:29:08 -0500 Subject: [PATCH 14/38] Update ERCS/erc-7540.md Co-authored-by: Jeroen <1748621+hieronx@users.noreply.github.com> --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 9bd5b442dd..c4cbc1f923 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -67,7 +67,7 @@ After submission, Requests go through Pending, Claimable, and Claimed stages. An |-------------|---------------------------------|-----------| | Pending | `requestDeposit(assets, receiver, owner, data)` | `asset.transferFrom(owner, vault, assets)`; `pendingDepositRequest[receiver] += assets` | | Claimable | | *Internal Request fulfillment*: `pendingDepositRequest[owner] -= assets`; `claimableDepositRequest[owner] += assets` | -| Claimed | `deposit(assets, receiver)` | `claimableDepositRequest[msg.sender] -= assets`; `vault.balanceOf[receiver] += shares` | +| Claimed | `deposit(assets, receiver)` | `claimableDepositRequest[owner] -= assets`; `vault.balanceOf[receiver] += shares` | Note that `maxDeposit` increases and decreases in sync with `claimableDepositRequest`. From 85001edec51d303cfe086fe00336dbd6c1e26bdc Mon Sep 17 00:00:00 2001 From: Joey <31974730+Joeysantoro@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:29:24 -0500 Subject: [PATCH 15/38] Update ERCS/erc-7540.md Co-authored-by: Jeroen <1748621+hieronx@users.noreply.github.com> --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index c4cbc1f923..41c35986b8 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -96,7 +96,7 @@ When `requestId==0`, the Vault MUST use purely the `owner` to discriminate the r Transfers `assets` from `msg.sender` into the Vault and submits a Request for asynchronous `deposit`. This places the Request in Pending state, with a corresponding increase in `pendingDepositRequest` for the amount `assets`. -The output `requestId` is used to partially descriminate the request along with the `receiver`. See "Request Ids" section for more info. +The output `requestId` is used to partially discriminate the request along with the `receiver`. See "Request Ids" section for more info. If the length of `data` is not 0, the Request MUST send an `onERC7540DepositReceived` callback to `receiver` following the interface of ERC7540DepositReceiver described in "Request Callbacks" section. If the length of `data` is 0, the Request MUST NOT send a callback. From 9961e5e6295276b11dfcb114ba5d652530acb44a Mon Sep 17 00:00:00 2001 From: Joey <31974730+Joeysantoro@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:30:53 -0500 Subject: [PATCH 16/38] Apply suggestions from code review Co-authored-by: Jeroen <1748621+hieronx@users.noreply.github.com> --- ERCS/erc-7540.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 41c35986b8..8be4dc8a0a 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -98,7 +98,7 @@ Transfers `assets` from `msg.sender` into the Vault and submits a Request for as The output `requestId` is used to partially discriminate the request along with the `receiver`. See "Request Ids" section for more info. -If the length of `data` is not 0, the Request MUST send an `onERC7540DepositReceived` callback to `receiver` following the interface of ERC7540DepositReceiver described in "Request Callbacks" section. If the length of `data` is 0, the Request MUST NOT send a callback. +If the length of `data` is not 0, the Request MUST send an `onERC7540DepositReceived` callback to `receiver` following the interface of ERC7540DepositReceiver described in [Request Callbacks](#request-callbacks) section. If the length of `data` is 0, the Request MUST NOT send a callback. When the Request is Claimable, `claimableDepositRequest` will be increased for the `receiver`. `deposit` or `mint` can subsequently be called by `receiver` to receive `shares`. A Request MAY transition straight to Claimable state but MUST NOT skip the Claimable state. @@ -185,7 +185,7 @@ MUST NOT revert unless due to integer overflow caused by an unreasonably large i Assumes control of `shares` from `owner` and submits a Request for asynchronous `redeem`. This places the Request in Pending state, with a corresponding increase in `pendingRedeemRequest` for the amount `shares`. -The output `requestId` is used to partially descriminate the request along with the `receiver`. See "Request Ids" section for more info. +The output `requestId` is used to partially discriminate the request along with the `receiver`. See [Request Ids](#request-ids) section for more info. MAY support either a locking or a burning mechanism for `shares` depending on the Vault implemention. @@ -193,7 +193,7 @@ If a Vault uses a locking mechanism for `shares`, those `shares` MUST be burned MUST support a redeem Request flow where the control of `shares` is taken from `owner` directly where `msg.sender` has ERC-20 approval over the `shares` of `owner`. -If the length of `data` is not 0, the Request MUST send an `onERC7540RedeemReceived` callback to `receiver` following the interface of ERC7540RedeemReceiver described in "Request Callbacks" section. If the length of `data` is 0, the Request MUST NOT send a callback. +If the length of `data` is not 0, the Request MUST send an `onERC7540RedeemReceived` callback to `receiver` following the interface of ERC7540RedeemReceiver described in [Request Callbacks](#request-callbacks) section. If the length of `data` is 0, the Request MUST NOT send a callback. When the Request is Claimable, `claimableRedeemRequest` will be increased for the `receiver`. `redeem` or `withdraw` can subsequently be called by `receiver` to receive `assets`. A Request MAY transition straight to Claimable state but MUST NOT skip the Claimable state. @@ -402,7 +402,7 @@ Requests in an Asynchronous Vault have properties of NFTs or Semi-Fungible token Using both an id and address to discriminate Requests allows for any of these use cases to be developed at an external layer without adding too much complexity to the core interface. -Certain Vaults especially `requestId==0` cases benefit from using the underlying ERC4626 methods for claiming because there is no discrimination at the `requestId` level. This standard is written primarily with those use cases in mind. A future standard can optimize for nonzero RID with support for claiming and transferring requests discriminated also with an `requestId`. +Certain Vaults especially `requestId==0` cases benefit from using the underlying [ERC-4626](./eip-4626) methods for claiming because there is no discrimination at the `requestId` level. This standard is written primarily with those use cases in mind. A future standard can optimize for nonzero request ID with support for claiming and transferring requests discriminated also with an `requestId`. ### Callbacks @@ -490,7 +490,7 @@ The interface is fully backwards compatible with [ERC-4626](./eip-4626.md). The requestId = 0; // no requestId associated with this request - asset.safeTransferFrom(msg.sender, address(this), assets); // asset here is the Vault underlying asset + asset.safeTransferFrom(owner, address(this), assets); // asset here is the Vault underlying asset pendingDepositRequest[owner] += assets; @@ -499,7 +499,7 @@ The interface is fully backwards compatible with [ERC-4626](./eip-4626.md). The require(ERC7540Receiver(receiver).onERC7540DepositReceived(msg.sender, owner, requestId, data) == ERC7540Receiver.onERC7540DepositReceived.selector, "receiver failed"); } - emit DepositRequest(msg.sender, operator, requestId, assets); + emit DepositRequest(receiver, owner, requestId, msg.sender, assets); return requestId; } From 2b756a71b85c80e86041567dac9eb1920e5af01b Mon Sep 17 00:00:00 2001 From: Joey <31974730+Joeysantoro@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:32:01 -0500 Subject: [PATCH 17/38] Apply suggestions from code review --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 8be4dc8a0a..6cc09713d3 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -96,7 +96,7 @@ When `requestId==0`, the Vault MUST use purely the `owner` to discriminate the r Transfers `assets` from `msg.sender` into the Vault and submits a Request for asynchronous `deposit`. This places the Request in Pending state, with a corresponding increase in `pendingDepositRequest` for the amount `assets`. -The output `requestId` is used to partially discriminate the request along with the `receiver`. See "Request Ids" section for more info. +The output `requestId` is used to partially discriminate the request along with the `receiver`. See [Request Ids](#request-ids) section for more info. If the length of `data` is not 0, the Request MUST send an `onERC7540DepositReceived` callback to `receiver` following the interface of ERC7540DepositReceiver described in [Request Callbacks](#request-callbacks) section. If the length of `data` is 0, the Request MUST NOT send a callback. From fd209e76c5ff58832c53945e60064a00127e4b5d Mon Sep 17 00:00:00 2001 From: Joey Santoro Date: Wed, 6 Dec 2023 14:39:29 -0500 Subject: [PATCH 18/38] eipw --- ERCS/erc-7540.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 6cc09713d3..15be6e1cca 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -98,7 +98,7 @@ Transfers `assets` from `msg.sender` into the Vault and submits a Request for as The output `requestId` is used to partially discriminate the request along with the `receiver`. See [Request Ids](#request-ids) section for more info. -If the length of `data` is not 0, the Request MUST send an `onERC7540DepositReceived` callback to `receiver` following the interface of ERC7540DepositReceiver described in [Request Callbacks](#request-callbacks) section. If the length of `data` is 0, the Request MUST NOT send a callback. +If the length of `data` is not 0, the Request MUST send an `onERC7540DepositReceived` callback to `receiver` following the interface of `ERC7540DepositReceiver` described in [Request Callbacks](#request-callbacks) section. If the length of `data` is 0, the Request MUST NOT send a callback. When the Request is Claimable, `claimableDepositRequest` will be increased for the `receiver`. `deposit` or `mint` can subsequently be called by `receiver` to receive `shares`. A Request MAY transition straight to Claimable state but MUST NOT skip the Claimable state. @@ -193,7 +193,7 @@ If a Vault uses a locking mechanism for `shares`, those `shares` MUST be burned MUST support a redeem Request flow where the control of `shares` is taken from `owner` directly where `msg.sender` has ERC-20 approval over the `shares` of `owner`. -If the length of `data` is not 0, the Request MUST send an `onERC7540RedeemReceived` callback to `receiver` following the interface of ERC7540RedeemReceiver described in [Request Callbacks](#request-callbacks) section. If the length of `data` is 0, the Request MUST NOT send a callback. +If the length of `data` is not 0, the Request MUST send an `onERC7540RedeemReceived` callback to `receiver` following the interface of `ERC7540RedeemReceiver` described in [Request Callbacks](#request-callbacks) section. If the length of `data` is 0, the Request MUST NOT send a callback. When the Request is Claimable, `claimableRedeemRequest` will be increased for the `receiver`. `redeem` or `withdraw` can subsequently be called by `receiver` to receive `assets`. A Request MAY transition straight to Claimable state but MUST NOT skip the Claimable state. @@ -336,7 +336,7 @@ All methods which initiate a request (including `requestId==0`) include a `data` There are two interfaces, `ERC7540DepositReceiver` and `ERC7540RedeemReceiver` which each define the single callback method to be called. -#### ERC7540DepositReceiver +#### `ERC7540DepositReceiver` The interface to be called on `requestDeposit`. `operator` is the `msg.sender` of the original `requestDeposit` call. `owner` is the `owner` of the `requestDeposit`. `requestId` is the output `requestId` of the `requestDeposit` and `data` is the `data` of the `requestDeposit`. @@ -362,7 +362,7 @@ This function MUST return `0xe74d2a41` upon successful execution of the callback ``` -#### ERC7540RedeemReceiver +#### `ERC7540RedeemReceiver` The interface to be called on `requestRedeem`. `operator` is the `msg.sender` of the original `requestRedeem` call. `owner` is the `owner` of the `requestRedeem`. `requestId` is the output `requestId` of the `requestRedeem` and `data` is the `data` of the `requestRedeem`. From 17739aac29e301046420c703afddbf904604053f Mon Sep 17 00:00:00 2001 From: Joey Santoro Date: Wed, 6 Dec 2023 14:52:32 -0500 Subject: [PATCH 19/38] html --- ERCS/erc-7540.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 15be6e1cca..f6e4cb590e 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -398,7 +398,7 @@ Asynchronous redemption Vaults MUST return the constant value `true` if `0x0899c ## Rationale ### Including Request IDs but Not Including a Claim by ID method -Requests in an Asynchronous Vault have properties of NFTs or Semi-Fungible tokens due to their asynchronicity. However, trying to pigeonhole all ERC-7540 Vaults into supporting [ERC-721](./eip-721) or [ERC-1155](./erc-1155) for Requests would create too much interface bloat. +Requests in an Asynchronous Vault have properties of NFTs or Semi-Fungible tokens due to their asynchronicity. However, trying to pigeonhole all ERC-7540 Vaults into supporting [ERC-721](./eip-721) or [ERC-1155](./eip-1155) for Requests would create too much interface bloat. Using both an id and address to discriminate Requests allows for any of these use cases to be developed at an external layer without adding too much complexity to the core interface. @@ -406,7 +406,7 @@ Certain Vaults especially `requestId==0` cases benefit from using the underlying ### Callbacks -Callbacks on Request calls can be used among other things to allow Requests to become fully [ERC-721](./eip-721) or [ERC-1155](./erc-1155) compatible in an external layer. +Callbacks on Request calls can be used among other things to allow Requests to become fully [ERC-721](./eip-721) or [ERC-1155](./eip-1155) compatible in an external layer. This can support flows where a smart contract manages the Request lifecycle on behalf of a user. From d1edffdc790d54f2833623d8166d39bf683e6d74 Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Thu, 14 Dec 2023 06:32:00 +0100 Subject: [PATCH 20/38] Add ERC7575 to ERC7540 --- ERCS/erc-7540.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index f6e4cb590e..397d37c8bd 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -8,7 +8,7 @@ status: Review type: Standards Track category: ERC created: 2023-10-18 -requires: 20, 165, 4626 +requires: 20, 165, 4626, 7575 --- ## Abstract @@ -395,6 +395,10 @@ Asynchronous deposit Vaults MUST return the constant value `true` if `0x1683f250 Asynchronous redemption Vaults MUST return the constant value `true` if `0x0899cb0b` is passed through the `interfaceID` argument. +### [ERC-7575](./eip-7575.md) support + +Smart contracts implementing this Vault standard MULT implement the [ERC-7575](./eip-7575.md) specification. + ## Rationale ### Including Request IDs but Not Including a Claim by ID method From d1119816674a8bff6c01b5318d3214d5739a8ffd Mon Sep 17 00:00:00 2001 From: Jeroen <1748621+hieronx@users.noreply.github.com> Date: Thu, 14 Dec 2023 15:48:40 +0100 Subject: [PATCH 21/38] Update ERCS/erc-7540.md Co-authored-by: Joey <31974730+Joeysantoro@users.noreply.github.com> --- ERCS/erc-7540.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 397d37c8bd..b949debdce 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -397,7 +397,9 @@ Asynchronous redemption Vaults MUST return the constant value `true` if `0x0899c ### [ERC-7575](./eip-7575.md) support -Smart contracts implementing this Vault standard MULT implement the [ERC-7575](./eip-7575.md) specification. +Smart contracts implementing this Vault standard MUST implement the [ERC-7575](./eip-7575.md) standard (in particular the `share` method). + +Contracts MAY omit `ERC7575WithdrawVault` and `ERC7575MintVault` as Partial Vaults. ## Rationale From c13dd2c149650e0c45d042e0204ca3fb960ff671 Mon Sep 17 00:00:00 2001 From: blablalf Date: Mon, 1 Jan 2024 10:47:52 +0100 Subject: [PATCH 22/38] Changed assets to shares into RedeemRequest --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 15be6e1cca..2a549ca519 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -325,7 +325,7 @@ MUST be emitted when a redemption Request is submitted using the `requestRedeem` - name: sender indexed: false type: uint256 - - name: assets + - name: shares indexed: false type: uint256 ``` From 25e454f6f16aeb92cfcd382a0fdf3fe559623384 Mon Sep 17 00:00:00 2001 From: blablalf Date: Tue, 2 Jan 2024 16:44:06 +0100 Subject: [PATCH 23/38] Changing sender param type to instead of into the event. --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 2a549ca519..b064debd36 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -324,7 +324,7 @@ MUST be emitted when a redemption Request is submitted using the `requestRedeem` type: uint256 - name: sender indexed: false - type: uint256 + type: address - name: shares indexed: false type: uint256 From 4737acf6b612374c2359a9827aea458d45c99ce6 Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Fri, 1 Mar 2024 11:52:13 +0100 Subject: [PATCH 24/38] Add missing assets/shares to callbacks --- ERCS/erc-7540.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index fd8fe818db..9987508a8c 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -339,7 +339,7 @@ There are two interfaces, `ERC7540DepositReceiver` and `ERC7540RedeemReceiver` w #### `ERC7540DepositReceiver` The interface to be called on `requestDeposit`. -`operator` is the `msg.sender` of the original `requestDeposit` call. `owner` is the `owner` of the `requestDeposit`. `requestId` is the output `requestId` of the `requestDeposit` and `data` is the `data` of the `requestDeposit`. +`operator` is the `msg.sender` of the original `requestDeposit` call. `owner` is the `owner` of the `requestDeposit`. `requestId` is the output `requestId` of the `requestDeposit`, `assets` is the transferred on `requestDeposit`, and `data` is the `data` of the `requestDeposit`. This function MUST return `0xe74d2a41` upon successful execution of the callback. @@ -354,6 +354,8 @@ This function MUST return `0xe74d2a41` upon successful execution of the callback type: address - name: requestId type: uint256 + - name: assets + type: uint256 - name: data type: bytes outputs: @@ -365,7 +367,7 @@ This function MUST return `0xe74d2a41` upon successful execution of the callback #### `ERC7540RedeemReceiver` The interface to be called on `requestRedeem`. -`operator` is the `msg.sender` of the original `requestRedeem` call. `owner` is the `owner` of the `requestRedeem`. `requestId` is the output `requestId` of the `requestRedeem` and `data` is the `data` of the `requestRedeem`. +`operator` is the `msg.sender` of the original `requestRedeem` call. `owner` is the `owner` of the `requestRedeem`. `requestId` is the output `requestId` of the `requestRedeem`, `shares` is the transferred on `requestRedeem`, and `data` is the `data` of the `requestRedeem`. This function MUST return `0x0102fde4` upon successful execution of the callback. @@ -380,6 +382,8 @@ This function MUST return `0x0102fde4` upon successful execution of the callback type: address - name: requestId type: uint256 + - name: shares + type: uint256 - name: data type: bytes outputs: From b73a4de07a6aa6aae40fba4e34220634900041fe Mon Sep 17 00:00:00 2001 From: Jeroen <1748621+hieronx@users.noreply.github.com> Date: Sat, 2 Mar 2024 08:14:57 +0100 Subject: [PATCH 25/38] Update ERCS/erc-7540.md Co-authored-by: Joey <31974730+Joeysantoro@users.noreply.github.com> --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index 9987508a8c..cdd88bd16b 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -339,7 +339,7 @@ There are two interfaces, `ERC7540DepositReceiver` and `ERC7540RedeemReceiver` w #### `ERC7540DepositReceiver` The interface to be called on `requestDeposit`. -`operator` is the `msg.sender` of the original `requestDeposit` call. `owner` is the `owner` of the `requestDeposit`. `requestId` is the output `requestId` of the `requestDeposit`, `assets` is the transferred on `requestDeposit`, and `data` is the `data` of the `requestDeposit`. +`operator` is the `msg.sender` of the original `requestDeposit` call. `owner` is the `owner` of the `requestDeposit`. `requestId` is the output `requestId` of the `requestDeposit`, `assets` is the amount transferred on `requestDeposit`, and `data` is the `data` of the `requestDeposit`. This function MUST return `0xe74d2a41` upon successful execution of the callback. From 4a9724639d47bb2280ae1d64401a682c75db3387 Mon Sep 17 00:00:00 2001 From: Jeroen <1748621+hieronx@users.noreply.github.com> Date: Sat, 2 Mar 2024 08:15:03 +0100 Subject: [PATCH 26/38] Update ERCS/erc-7540.md Co-authored-by: Joey <31974730+Joeysantoro@users.noreply.github.com> --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index cdd88bd16b..64542b2730 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -367,7 +367,7 @@ This function MUST return `0xe74d2a41` upon successful execution of the callback #### `ERC7540RedeemReceiver` The interface to be called on `requestRedeem`. -`operator` is the `msg.sender` of the original `requestRedeem` call. `owner` is the `owner` of the `requestRedeem`. `requestId` is the output `requestId` of the `requestRedeem`, `shares` is the transferred on `requestRedeem`, and `data` is the `data` of the `requestRedeem`. +`operator` is the `msg.sender` of the original `requestRedeem` call. `owner` is the `owner` of the `requestRedeem`. `requestId` is the output `requestId` of the `requestRedeem`, `shares` is the amount transferred on `requestRedeem`, and `data` is the `data` of the `requestRedeem`. This function MUST return `0x0102fde4` upon successful execution of the callback. From 258209b27ef99c4a2826c46988218e8d89f76a48 Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Mon, 4 Mar 2024 17:06:23 +0100 Subject: [PATCH 27/38] Fix callback return values --- ERCS/erc-7540.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index fd8fe818db..20ea74c5ed 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -341,7 +341,7 @@ The interface to be called on `requestDeposit`. `operator` is the `msg.sender` of the original `requestDeposit` call. `owner` is the `owner` of the `requestDeposit`. `requestId` is the output `requestId` of the `requestDeposit` and `data` is the `data` of the `requestDeposit`. -This function MUST return `0xe74d2a41` upon successful execution of the callback. +This function MUST return `0x6d7e2da0` upon successful execution of the callback. ```yaml - name: onERC7540DepositReceived @@ -367,7 +367,7 @@ The interface to be called on `requestRedeem`. `operator` is the `msg.sender` of the original `requestRedeem` call. `owner` is the `owner` of the `requestRedeem`. `requestId` is the output `requestId` of the `requestRedeem` and `data` is the `data` of the `requestRedeem`. -This function MUST return `0x0102fde4` upon successful execution of the callback. +This function MUST return `0x01a2e97e` upon successful execution of the callback. ```yaml - name: onERC7540RedeemReceived From e81354f3dbdb3506237bdc645648b9ffd9a98cd7 Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Tue, 12 Mar 2024 17:40:52 +0100 Subject: [PATCH 28/38] Fix missing assets in reference implementation --- ERCS/erc-7540.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index fd8fe818db..455825981a 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -502,7 +502,7 @@ The interface is fully backwards compatible with [ERC-4626](./eip-4626.md). The // Perform the callback if (data.length != 0) { - require(ERC7540Receiver(receiver).onERC7540DepositReceived(msg.sender, owner, requestId, data) == ERC7540Receiver.onERC7540DepositReceived.selector, "receiver failed"); + require(ERC7540Receiver(receiver).onERC7540DepositReceived(msg.sender, owner, requestId, assets, data) == ERC7540Receiver.onERC7540DepositReceived.selector, "receiver failed"); } emit DepositRequest(receiver, owner, requestId, msg.sender, assets); From dc68753dd36cd76290b49a2224f2c999f6799651 Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Tue, 19 Mar 2024 20:26:04 +0100 Subject: [PATCH 29/38] Simplify ERC7575 --- ERCS/erc-7575.md | 76 +++++------------------------------------------- 1 file changed, 7 insertions(+), 69 deletions(-) diff --git a/ERCS/erc-7575.md b/ERCS/erc-7575.md index d37cf15f97..ed5a28fabc 100644 --- a/ERCS/erc-7575.md +++ b/ERCS/erc-7575.md @@ -1,7 +1,7 @@ --- eip: 7575 -title: Partial and Extended ERC-4626 Vaults -description: Modular ERC-4626 Interface enabling Multi-Vault, Pipes, Partial and Alternative Vaults +title: Extended ERC-4626 Vaults +description: Extended ERC-4626 Interface enabling Multi-Vault 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 @@ -13,27 +13,15 @@ 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. +The following standard adapts [ERC-4626](./eip-4626.md) to support multiple assets or entry points for the same share token. 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. +Furthermore, 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 liquidity provider (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. +One missing use case that is not supported by [ERC-4626](./eip-4626.md) are Vaults which have multiple assets or entry points such as liquidity provider (LP) Tokens. These are generally unwieldy or non-compliant due to the requirement of ERC-4626 to itself be an ERC-20. ## Specification @@ -42,10 +30,6 @@ There are so many customizeable use cases that it is beneficial to modularize th 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. @@ -74,62 +58,16 @@ MUST _NOT_ revert. 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. +It MUST return the constant value `true` if `0x2f0a18c5` is passed through the `interfaceID` argument. ## Rationale @@ -141,7 +79,7 @@ By allowing `share != address(this)`, the Vault can have an external contract ma ## 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. +Existing [ERC-4626](./eip-4626.md) Vaults can be made compatible with [ERC-7575](./eip-7575.md) by adding a single `share` method that returns the address of the Vault. ## Security Considerations From af82b6244fb4396fe1fb24cda9c5bffda745ade7 Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Tue, 19 Mar 2024 20:28:50 +0100 Subject: [PATCH 30/38] Update naming --- ERCS/erc-7575.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ERCS/erc-7575.md b/ERCS/erc-7575.md index ed5a28fabc..adb443d146 100644 --- a/ERCS/erc-7575.md +++ b/ERCS/erc-7575.md @@ -1,7 +1,7 @@ --- eip: 7575 -title: Extended ERC-4626 Vaults -description: Extended ERC-4626 Interface enabling Multi-Vault Vaults +title: Multi-Asset ERC-4626 Vaults +description: Extended ERC-4626 Interface enabling Multi-Asset 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 @@ -29,7 +29,7 @@ One missing use case that is not supported by [ERC-4626](./eip-4626.md) are Vaul The existing definitions from [ERC-4626](./eip-4626.md) apply. -- Multi-Vault: A Vault which has multiple assets/entry points +- Multi-Asset Vaults: A Vault which has multiple assets/entry points 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. @@ -58,10 +58,10 @@ MUST _NOT_ revert. type: address ``` -### Multi-Vaults -Multi-vaults share a single `share` token with multiple entry points denominated in different `asset` tokens. +### Multi-Asset Vaults +Multi-Asset 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. +Multi-Asset Vaults MUST implement the `share` method on each entry point. The entry points SHOULD NOT be ERC-20. ### [ERC-165](./eip-165.md) support @@ -74,7 +74,7 @@ It MUST return the constant value `true` if `0x2f0a18c5` is passed through the ` 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 [ERC-20](./eip-20.md) Dependency -By allowing `share != address(this)`, the Vault can have an external contract managing the [ERC-20](./eip-20.md) 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 [ERC-20](./eip-20.md), 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 [ERC-20](./eip-20.md) tokens. +By allowing `share != address(this)`, the Vault can have an external contract managing the [ERC-20](./eip-20.md) functionality of the Share. In the case of Multi-Asset, this avoids the confusion that might arise if each Vault itself were required to be an [ERC-20](./eip-20.md), 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 [ERC-20](./eip-20.md) tokens. ## Backwards Compatibility From 7d5bf0a41f5d39d6b51bf2fce69a39b93f435a98 Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Tue, 19 Mar 2024 20:29:14 +0100 Subject: [PATCH 31/38] Fix --- ERCS/erc-7575.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7575.md b/ERCS/erc-7575.md index adb443d146..4d3111e187 100644 --- a/ERCS/erc-7575.md +++ b/ERCS/erc-7575.md @@ -65,7 +65,7 @@ Multi-Asset Vaults MUST implement the `share` method on each entry point. The en ### [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. +Smart contracts implementing [ERC-7575](./eip-7575.md) MUST implement the [ERC-165](./eip-165.md) `supportsInterface` function. It MUST return the constant value `true` if `0x2f0a18c5` is passed through the `interfaceID` argument. From b29e6d72c01a011ea8b059286f172ae26c124a46 Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Tue, 19 Mar 2024 20:37:45 +0100 Subject: [PATCH 32/38] Fix eipw warning --- ERCS/erc-7575.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7575.md b/ERCS/erc-7575.md index 4d3111e187..9faccff9dc 100644 --- a/ERCS/erc-7575.md +++ b/ERCS/erc-7575.md @@ -1,6 +1,6 @@ --- eip: 7575 -title: Multi-Asset ERC-4626 Vaults +title: Multi-Asset ERC-4626 Vaults description: Extended ERC-4626 Interface enabling Multi-Asset 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 From 0471876b6093c347d63ad1a876aebb1d5a3e3188 Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Wed, 20 Mar 2024 09:26:06 +0100 Subject: [PATCH 33/38] Re-add pipes --- ERCS/erc-7540.md | 2 -- ERCS/erc-7575.md | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/ERCS/erc-7540.md b/ERCS/erc-7540.md index c4fc3b07c5..d96701e938 100644 --- a/ERCS/erc-7540.md +++ b/ERCS/erc-7540.md @@ -403,8 +403,6 @@ Asynchronous redemption Vaults MUST return the constant value `true` if `0x0899c Smart contracts implementing this Vault standard MUST implement the [ERC-7575](./eip-7575.md) standard (in particular the `share` method). -Contracts MAY omit `ERC7575WithdrawVault` and `ERC7575MintVault` as Partial Vaults. - ## Rationale ### Including Request IDs but Not Including a Claim by ID method diff --git a/ERCS/erc-7575.md b/ERCS/erc-7575.md index 9faccff9dc..6c6f71db15 100644 --- a/ERCS/erc-7575.md +++ b/ERCS/erc-7575.md @@ -17,7 +17,9 @@ The following standard adapts [ERC-4626](./eip-4626.md) to support multiple asse It adds a new `share` method to allow the [ERC-20](./eip-20.md) dependency to be externalized. -Furthermore, it enforces [ERC-165](./eip-165.md) support for Vaults. +This also enables Vaults which don't have a true share token but rather convert between two arbitrary external tokens. + +Lastly, it enforces [ERC-165](./eip-165.md) support for Vaults. ## Motivation @@ -30,6 +32,7 @@ One missing use case that is not supported by [ERC-4626](./eip-4626.md) are Vaul The existing definitions from [ERC-4626](./eip-4626.md) apply. - Multi-Asset Vaults: A Vault which has multiple assets/entry points +- Pipe: A converter from one token to another (unidirectional or bidirectional) 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. @@ -63,6 +66,13 @@ Multi-Asset Vaults share a single `share` token with multiple entry points denom Multi-Asset 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. + +A unidirectional Pipe SHOULD implement only the entry function(s) `deposit` and/or `mint`. + ### [ERC-165](./eip-165.md) support Smart contracts implementing [ERC-7575](./eip-7575.md) MUST implement the [ERC-165](./eip-165.md) `supportsInterface` function. @@ -74,7 +84,9 @@ It MUST return the constant value `true` if `0x2f0a18c5` is passed through the ` 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 [ERC-20](./eip-20.md) Dependency -By allowing `share != address(this)`, the Vault can have an external contract managing the [ERC-20](./eip-20.md) functionality of the Share. In the case of Multi-Asset, this avoids the confusion that might arise if each Vault itself were required to be an [ERC-20](./eip-20.md), 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 [ERC-20](./eip-20.md) tokens. +By allowing `share != address(this)`, the Vault can have an external contract managing the [ERC-20](./eip-20.md) functionality of the Share. In the case of Multi-Asset, this avoids the confusion that might arise if each Vault itself were required to be an [ERC-20](./eip-20.md), 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 [ERC-20](./eip-20.md) tokens. These Pipes could be unidirectional (i.e. only for assets to shares via deposit/mint, or shares to assets via redeem/withdraw) or bidirectional for both entry and exit flows. ## Backwards Compatibility From c4b3488fa3b8a9cc62c9f1e5ee20b33506e873f3 Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Wed, 20 Mar 2024 14:33:21 +0100 Subject: [PATCH 34/38] Add share to vault lookup --- ERCS/erc-7575.md | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/ERCS/erc-7575.md b/ERCS/erc-7575.md index 6c6f71db15..c03a4dada2 100644 --- a/ERCS/erc-7575.md +++ b/ERCS/erc-7575.md @@ -23,7 +23,7 @@ Lastly, it enforces [ERC-165](./eip-165.md) support for Vaults. ## Motivation -One missing use case that is not supported by [ERC-4626](./eip-4626.md) are Vaults which have multiple assets or entry points such as liquidity provider (LP) Tokens. These are generally unwieldy or non-compliant due to the requirement of ERC-4626 to itself be an ERC-20. +One missing use case that is not supported by [ERC-4626](./eip-4626.md) are Vaults which have multiple assets or entry points such as liquidity provider (LP) Tokens. These are generally unwieldy or non-compliant due to the requirement of ERC-4626 to itself be an [ERC-20](./eip-20.md). ## Specification @@ -40,7 +40,7 @@ First the standard defines a new `share` function which is useful for many confi #### 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. +The address of the underlying `share` received on deposit into the Vault. MUST return an address of an [ERC-20](./eip-20.md) share representation of the Vault. `share` MAY return the address of the Vault itself. @@ -62,12 +62,14 @@ MUST _NOT_ revert. ``` ### Multi-Asset Vaults + Multi-Asset Vaults share a single `share` token with multiple entry points denominated in different `asset` tokens. -Multi-Asset Vaults MUST implement the `share` method on each entry point. The entry points SHOULD NOT be ERC-20. +Multi-Asset Vaults MUST implement the `share` method on each entry point. The entry points SHOULD NOT be [ERC-20](./eip-20.md). ### Pipes -Pipes convert between a single `asset` and `share` which are both ERC-20 tokens outside the Vault. + +Pipes convert between a single `asset` and `share` which are both [ERC-20](./eip-20.md) tokens outside the Vault. A Pipe MAY be either unidirectional or bidirectional. @@ -79,6 +81,25 @@ Smart contracts implementing [ERC-7575](./eip-7575.md) MUST implement the [ERC-1 It MUST return the constant value `true` if `0x2f0a18c5` is passed through the `interfaceID` argument. +### Share-to-Vault lookup + +The [ERC-20](./eip-20.md) implementation of `share` MAY additionally implement a `vault` method, that returns the address of the `vault` for a specific `asset`. + +```yaml +- name: vault + type: function + stateMutability: view + + inputs: + - name: asset + type: address + + outputs: + - name: vault + type: address +``` + + ## 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. @@ -88,6 +109,12 @@ By allowing `share != address(this)`, the Vault can have an external contract ma This approach also enables the creation of new types of Vaults, such as Pipes, which facilitate the conversion between two external [ERC-20](./eip-20.md) tokens. These Pipes could be unidirectional (i.e. only for assets to shares via deposit/mint, or shares to assets via redeem/withdraw) or bidirectional for both entry and exit flows. +### Including Share-to-Vault lookup optionally + +The `share` token can optionally support the `vault` method to lookup a vault for a `share` by its `asset`. This enables integrations to easily query Multi-Asset Vaults. + +This is intentionally optional, to maintain backwards compatibility with use cases where the `share` is an existing deployed contract. + ## Backwards Compatibility From 7b13b7bb8ff78ba8c32587e9f56b9a469adfb05e Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Wed, 20 Mar 2024 14:34:49 +0100 Subject: [PATCH 35/38] Update --- ERCS/erc-7575.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-7575.md b/ERCS/erc-7575.md index c03a4dada2..0e2afcdd84 100644 --- a/ERCS/erc-7575.md +++ b/ERCS/erc-7575.md @@ -83,7 +83,7 @@ It MUST return the constant value `true` if `0x2f0a18c5` is passed through the ` ### Share-to-Vault lookup -The [ERC-20](./eip-20.md) implementation of `share` MAY additionally implement a `vault` method, that returns the address of the `vault` for a specific `asset`. +The [ERC-20](./eip-20.md) implementation of `share` MAY implement a `vault` method, that returns the address of the Vault for a specific `asset`. ```yaml - name: vault @@ -111,7 +111,7 @@ This approach also enables the creation of new types of Vaults, such as Pipes, w ### Including Share-to-Vault lookup optionally -The `share` token can optionally support the `vault` method to lookup a vault for a `share` by its `asset`. This enables integrations to easily query Multi-Asset Vaults. +The `share` token can optionally support the `vault` method to lookup a Vault for a `share` by its `asset`. This enables integrations to easily query Multi-Asset Vaults. This is intentionally optional, to maintain backwards compatibility with use cases where the `share` is an existing deployed contract. From afbfa473dadfa66f8961baff1f6bded65a0298ce Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Wed, 20 Mar 2024 20:45:11 +0100 Subject: [PATCH 36/38] Update --- ERCS/erc-7575.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-7575.md b/ERCS/erc-7575.md index 0e2afcdd84..c5e45d69b8 100644 --- a/ERCS/erc-7575.md +++ b/ERCS/erc-7575.md @@ -83,7 +83,7 @@ It MUST return the constant value `true` if `0x2f0a18c5` is passed through the ` ### Share-to-Vault lookup -The [ERC-20](./eip-20.md) implementation of `share` MAY implement a `vault` method, that returns the address of the Vault for a specific `asset`. +The [ERC-20](./eip-20.md) implementation of `share` SHOULD implement a `vault` method, that returns the address of the Vault for a specific `asset`. ```yaml - name: vault @@ -111,9 +111,9 @@ This approach also enables the creation of new types of Vaults, such as Pipes, w ### Including Share-to-Vault lookup optionally -The `share` token can optionally support the `vault` method to lookup a Vault for a `share` by its `asset`. This enables integrations to easily query Multi-Asset Vaults. +T `vault` method is included to lookup a Vault for a `share` by its `asset`. This enables integrations to easily query Multi-Asset Vaults. -This is intentionally optional, to maintain backwards compatibility with use cases where the `share` is an existing deployed contract. +This is optional, to maintain backwards compatibility with use cases where the `share` is an existing deployed contract. ## Backwards Compatibility From c8624023b7ce5bc6d5712cb5319adca291705e3f Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Thu, 21 Mar 2024 09:49:46 +0100 Subject: [PATCH 37/38] Fix typos --- ERCS/erc-7575.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ERCS/erc-7575.md b/ERCS/erc-7575.md index c5e45d69b8..82570c5bf8 100644 --- a/ERCS/erc-7575.md +++ b/ERCS/erc-7575.md @@ -34,8 +34,6 @@ The existing definitions from [ERC-4626](./eip-4626.md) apply. - Multi-Asset Vaults: A Vault which has multiple assets/entry points - Pipe: A converter from one token to another (unidirectional or bidirectional) -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 @@ -111,7 +109,7 @@ This approach also enables the creation of new types of Vaults, such as Pipes, w ### Including Share-to-Vault lookup optionally -T `vault` method is included to lookup a Vault for a `share` by its `asset`. This enables integrations to easily query Multi-Asset Vaults. +The `vault` method is included to lookup a Vault for a `share` by its `asset`. This enables integrations to easily query Multi-Asset Vaults. This is optional, to maintain backwards compatibility with use cases where the `share` is an existing deployed contract. From 66d12f1737523eb3b1ee2e34ec06c326def9b642 Mon Sep 17 00:00:00 2001 From: Jeroen Offerijns Date: Thu, 21 Mar 2024 14:36:11 +0100 Subject: [PATCH 38/38] Move to review --- ERCS/erc-7575.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7575.md b/ERCS/erc-7575.md index 82570c5bf8..f6a174d99d 100644 --- a/ERCS/erc-7575.md +++ b/ERCS/erc-7575.md @@ -4,7 +4,7 @@ title: Multi-Asset ERC-4626 Vaults description: Extended ERC-4626 Interface enabling Multi-Asset 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 +status: Review type: Standards Track category: ERC created: 2023-12-11