This standard is an extension of the ERC-4626 spec with an identical interface and behavioral overrides for handling Ether or any native asset as the underlying.
A standard for tokenized ETH Vaults has the same benefits as ERC-4626, particularly in the case of Liquid Staking Tokens, (i.e. fungible ERC-20 wrappers around ETH staking).
Maintaining the same exact interface as ERC-4626 further amplifies the benefits as the standard will be maximally compatible with existing ERC-4626 tooling and protocols.
All ERC-7535 tokenized Vaults MUST implement ERC-4626 (and by extension ERC-20) with behavioral overrides for the methods asset
, deposit
, and mint
specified below.
assets
quantity refers to wei of Ether rather than ERC-20 balances.transfer
calls are replaced by Ether transfer (send
or call
)transferFrom
approval flows for asset
are not implementeddeposit
and mint
have state mutability payable
deposit
uses msg.value
as the primary input and MAY ignore assets
MUST return 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
per ERC-7528.
- name: asset
type: function
stateMutability: view
inputs: []
outputs:
- name: assetTokenAddress
type: address
Mints shares
Vault shares to receiver
by depositing exactly msg.value
of Ether.
MUST have state mutability of payable
.
MUST use msg.value
as the primary input parameter for calculating the shares
output. I.e. MAY ignore assets
parameter as an input.
MUST emit the Deposit
event.
MUST revert if all of msg.value
cannot be deposited (due to deposit limit being reached, slippage, etc).
- name: deposit
type: function
stateMutability: payable
inputs:
- name: assets
type: uint256
- name: receiver
type: address
outputs:
- name: shares
type: uint256
Mints exactly shares
Vault shares to receiver
by depositing assets
of ETH.
MUST have state mutability of payable
.
MUST emit the Deposit
event.
MUST revert if all of shares
cannot be minted (due to deposit limit being reached, slippage, the user not sending a large enough msg.value
of Ether to the Vault contract, etc).
- name: mint
type: function
stateMutability: payable
inputs:
- name: shares
type: uint256
- name: receiver
type: address
outputs:
- name: assets
type: uint256
The event usage MUST be identical to ERC-4626.
Any ERC-4626 Vault that uses a Wrapped ETH ERC-20 as the asset
MUST NOT implement ERC-7535. ERC-7535 only applies to native ETH.
This standard was designed to maximize compatibility with ERC-4626 while minimizing additional opinionated details on the interface. Examples of this decision rationale are described below:
assets
input to the deposit
function while making its usage optionalmsg.value
and assets
in a mint
callfallback
/__default__
methods, payability on additional vault functions, or handling ETH forcibly sent to the contractAll breaking implementation level changes with ERC-4626 are purely to accomodate for the usage of Ether or any native asset instead of an ERC-20 token.
msg.value
must always be passed anyway to fund a deposit
, therefore it may as well be treated as the primary input number. Allowing assets
to be used either forces a strict equality and extra unnecessary gas overhead for redundancy, or allows different values which could cause footguns and undefined behavior.
The last option which could work is to require that assets
MUST be 0, but this still requires gas to enforce at the implementation level and can more easily be left unspecified, as the input is functionally ignorable in the spec as written.
There may be many cases where a user deposits slightly too much Ether in a mint
call. In these cases, enforcing msg.value
to equal assets
would cause unnecessary reversions. It is up to the vault implementer to decide whether to refund or absorb any excess Ether, and up to depositors to deposit as close to the exact amount as possible.
ERC-7535 is fully backward compatible with ERC-4626 at the function interface level. Certain implementation behaviors are different due to the fact that ETH is not ERC-20 compliant, such as the priority of msg.value
over assets
.
It has no known compatibility issues with other standards.
In addition to all security considerations of ERC-4626, there are security implications of having ETH as the Vault asset.
call
vs send
Contracts should take care when using call
to transfer ETH, as this allows additional reentrancy vulnerabilities and arbitrary code execution beyond what is possible with trusted ERC-20 tokens.
It is safer to simply send
ETH with a small gas stipend.
Implementers should take extra precautions when deciding how to transfer ETH.
ETH can be forced into any Vault through the SELFDESTRUCT
opcode. Implementers should validate that this does not disrupt Vault accounting in any way.
Similarly, any additional payable
methods should be checked to ensure they do not disrupt Vault accounting.
Smart contract systems which implement ERC-4626 should consider only supporting ERC-20 underlying assets, and default to using a Wrapped ETH ERC-20 instead of implementing ERC-7535 for handling ETH.
The subtle differences between ERC-4626 and ERC-7535 can introduce code fragmentation and security concerns.
Cleaner use cases for ERC-7535 are ETH exclusive, such as Wrapped ETH and Liquid Staking Tokens.
Copyright and related rights waived via CC0.