ERC-5568 A Signal Standard for Notifying Wallets of Required Actions (Well-Known Format for Required Actions)
Review · Accounts & wallets · created 2022-08-31
A standard by which a smart contract notifies a wallet, in a machine-readable format via defined functions and revert reasons, of actions the user must take first.
Why it is needed
There are often things a user must do before using a smart contract. For example, to swap tokens on an exchange contract, the user must first approve that contract to spend their tokens. Until now, this kind of guidance has been hardcoded into each service's web frontend. As a result, the frontend has had to know and handle all prerequisite actions in advance, which complicates the code, and contracts have had no way to signal on their own what a wallet needs to do. This standard lets a contract directly signal the required action through defined functions and revert reasons. A variety of actions, such as requesting a token approval, sending an HTTP request, or requesting a key rotation after a certain period has passed, can be conveyed along with up to 64kB of arbitrary data, and the design allows other ERCs introduced later to extend it by layering on new instruction formats.
What to implement
function walletSignal24(bytes32 selector, bytes function_data) view returns (uint24 instruction_id, bytes instruction_data);: A function the wallet calls before sending a transaction. If an action is required, it returns a nonzero instruction_id along with that instruction's data; if not, it returns an instruction_id of 0.error WalletSignal24(uint24 instruction_id, bytes instruction_data): If execution proceeds without the required action having been taken, the contract reverts with this custom error to signal that the action was not performed.
In depth
Querying required actions via the walletSignal24 function
The contract implements the view function walletSignal24(bytes32 selector, bytes function_data), which returns (uint24 instruction_id, bytes instruction_data). If an action is required, it returns a nonzero instruction_id and instruction_data; if not, it sets instruction_id to 0 (in which case instruction_data can be any value). instruction_id must be the number of the ERC that defines that instruction, and no other number may be used except in exceptional circumstances. A single ERC must define exactly zero or one instruction_id, and the structure of the corresponding instruction_data is defined by the ERC that defines that instruction_id. The instruction data can hold up to 64kB of arbitrary parameters.
A Custom Revert Signaling That an Action Was Not Taken
To signal that a required action has not been taken, a contract following this standard must revert with error WalletSignal24(uint24 instruction_id, bytes instruction_data). Here too, instruction_id must be the number of the ERC that defines that instruction, a single ERC must define exactly zero or one instruction_id, and the structure of instruction_data is defined by the ERC that defines that instruction_id. Both paths, the function return and the custom error, use the same (instruction_id, instruction_data) format.
The Processing Procedure Wallets Must Follow
Before submitting a transaction to the mempool, a wallet must locally simulate walletSignal24. In doing so, it must treat this function as if it were a non-view function capable of changing state (a CALL to a non-view function is also permitted). If the simulation result has a nonzero instruction_id, an action is required. The instruction_id and instruction_data must be taken from this simulation result, and it is recommended that the instruction be evaluated according to that ERC's rules. If the wallet does not support the instruction, it must display an error informing the user of this fact, and must then re-evaluate the transaction. However, if the instruction explicitly prohibits re-evaluation, it must not be re-evaluated. If the instruction is invalid or the instruction_id and instruction_data cannot be interpreted, an error must be displayed, and in this case the transaction must not be re-evaluated.
A Design Optimized for Deployment Gas Cost and Simplicity
This standard is explicitly optimized for deployment gas cost and simplicity. It does not use ERC-165 for signaling interface support, because the interface is simple enough to detect just by calling the function directly. The source notes that it expects libraries to be built later to make this easier for developers to use.
Relationship to ERC-3668
ERC-3668, which fetches off-chain data, can be used together with this standard but uses a different mechanism from it. The compatibility issue with human-readable string revert messages is addressed in the Revert Reason Collision section of the security considerations.
A Proposal Still in Review Status
This ERC's status is Review, meaning it is a proposal that is not yet finalized and whose content may change. It is advisable to check the latest source before implementing.
Things to watch out for
- Revert Reason Collision: It is unlikely that this standard's custom error signature will accidentally coincide with another custom error already in use. Even if it does coincide, it causes no harm unless that data happens to be interpreted as a valid instruction, which is even rarer.