forked from Mint-Blockchain/ERCs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ERC: Validation Module Extension for ERC-7579
Merged by EIP-Bot.
- Loading branch information
Showing
1 changed file
with
193 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
--- | ||
eip: 7780 | ||
title: Validation Module Extension for ERC-7579 | ||
description: Introduces new smart account module types for signature validation and permissioning | ||
author: zeroknots (@zeroknots), Konrad Kopp (@kopy-kat), Taek Lee (@leekt), Fil Makarov (@filmakarov) | ||
discussions-to: https://ethereum-magicians.org/t/erc-7780-validation-module-extension-for-erc-7579/21273 | ||
status: Draft | ||
type: Standards Track | ||
category: ERC | ||
created: 2024-10-01 | ||
requires: 7579 | ||
--- | ||
|
||
## Abstract | ||
|
||
This proposal introduces three new module types on top of the existing modules described in [ERC-7579](./eip-7579). The modules are policy, signer and stateless validator. None of these modules are required to be implemented by accounts, but accounts can choose to implement them or other modules can choose to make use of them for additional composability. | ||
|
||
Policy modules can be used to check what a `UserOperation` or action is trying to achieve and determine if this is allowed. Signer modules can be used to validate signatures on provided hashes. Stateless validators are modules that are used to both validate signatures and compare them to a calldata-provided data blob which could, for example, include owners to check signatures against. | ||
|
||
## Motivation | ||
|
||
The modules introduced by this proposal aim to create more composability around signature and permission verification. | ||
|
||
Policy and signer modules allow an account to make direct use of such a permissioning logic rather than relying on external modules to handle this. This has the upside of lower gas cost but the downside of less flexibility for users and developers that use the account. | ||
|
||
Stateless validators enable further composability around signature validation logic. In many cases, it does not make sense to re-write signature validation for new validators, but instead to use the existing ones. However, this is usually not possible since the validators rely on a stored configuration indexed by the `msg.sender`, which is expected to be an account. Stateless validators solve this problem by not relying on state to compare signature verficiation against, but instead to compare it against a calldata-provided argument. | ||
|
||
## Specification | ||
|
||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. | ||
|
||
This standard introduces three new module types on top of the existing modules introduced by ERC-7579: | ||
|
||
- Policy (type id: 5) | ||
- Signer (type id: 6) | ||
- Stateless Validator (type id: 7) | ||
|
||
Note: A single module can be of multiple types. | ||
|
||
### Policy | ||
|
||
Policies MUST implement [ERC-7579](./eip-7579.md)'s `IModule` and the `IPolicy` interface and have module type id: `5`. | ||
|
||
```solidity | ||
interface IPolicy is IModule { | ||
/** | ||
* Checks a userOp to determine if it should be executed | ||
* | ||
* SHOULD validate the executions in the userOp against stored configurations | ||
* | ||
* @param id The id of the policy | ||
* @param userOp The user operation to check | ||
* | ||
* @return The validation data to return to the EntryPoint as specified by ERC-4337 | ||
*/ | ||
function checkUserOpPolicy( | ||
bytes32 id, | ||
PackedUserOperation calldata userOp | ||
) | ||
external | ||
payable | ||
virtual | ||
returns (uint256); | ||
/** | ||
* Checks a signature to determine if it should be executed | ||
* | ||
* SHOULD validate the hash in order to determine what the signature is used for and if it should be permitted | ||
* MAY check the sender to determine whether the signature should be permitted | ||
* | ||
* @param id The id of the policy | ||
* @param sender The sender of the transaction | ||
* @param hash The hash of the transaction | ||
* @param sig The signature of the transaction | ||
* | ||
* @return The validation data to return to the EntryPoint as specified by ERC-4337 | ||
*/ | ||
function checkSignaturePolicy( | ||
bytes32 id, | ||
address sender, | ||
bytes32 hash, | ||
bytes calldata sig | ||
) | ||
external | ||
view | ||
virtual | ||
returns (uint256); | ||
} | ||
``` | ||
|
||
### Signer | ||
|
||
Signers MUST implement the `IModule` and the `ISigner` interface and have module type id: `6`. | ||
|
||
```solidity | ||
interface ISigner is IModule { | ||
/** | ||
* Check the signature of a user operation | ||
* | ||
* @param id The id of the signer config | ||
* @param userOp The user operation | ||
* @param userOpHash The hash of the user operation | ||
* | ||
* @return The status of the signature check to return to the EntryPoint | ||
*/ | ||
function checkUserOpSignature( | ||
bytes32 id, | ||
PackedUserOperation calldata userOp, | ||
bytes32 userOpHash | ||
) | ||
external | ||
payable | ||
virtual | ||
returns (uint256); | ||
/** | ||
* Check an ERC-1271 signature | ||
* | ||
* @param id The id of the signer config | ||
* @param sender The sender of the signature | ||
* @param hash The hash to check against | ||
* @param sig The signature to validate | ||
* | ||
* @return The ERC-1271 magic value if the signature is valid | ||
*/ | ||
function checkSignature( | ||
bytes32 id, | ||
address sender, | ||
bytes32 hash, | ||
bytes calldata sig | ||
) | ||
external | ||
view | ||
virtual | ||
returns (bytes4); | ||
} | ||
``` | ||
|
||
### Stateless Validator | ||
|
||
Validators MUST implement the `IStatelessValidator` interface and have module type id: `7`. It is RECOMMENDED that all Validators (module type id `1`) also implement the Stateless Validator interface for additional composabillity. | ||
|
||
```solidity | ||
interface IStatelessValidator { | ||
/** | ||
* Validates a signature given some data | ||
* | ||
* @param hash The data that was signed over | ||
* @param signature The signature to verify | ||
* @param data The data to validate the verified signature agains | ||
* | ||
* MUST validate that the signature is a valid signature of the hash | ||
* MUST compare the validated signature against the data provided | ||
* MUST return true if the signature is valid and false otherwise | ||
*/ | ||
function validateSignatureWithData( | ||
bytes32 hash, | ||
bytes calldata signature, | ||
bytes calldata data | ||
) | ||
external | ||
view | ||
returns (bool); | ||
/** | ||
* Returns boolean value if module is a certain type | ||
* | ||
* @param moduleTypeId the module type ID according the ERC-7579 spec | ||
* | ||
* MUST return true if the module is of the given type and false otherwise | ||
*/ | ||
function isModuleType(uint256 moduleTypeId) external view returns (bool); | ||
} | ||
``` | ||
|
||
## Rationale | ||
|
||
TBD <!-- TODO --> | ||
|
||
## Backwards Compatibility | ||
|
||
No backward compatibility issues found. | ||
|
||
## Security Considerations | ||
|
||
TBD <!-- TODO --> | ||
|
||
## Copyright | ||
|
||
Copyright and related rights waived via [CC0](../LICENSE.md). |