From 86f4e167aa027fd0d6d993de707b171c3afac2b5 Mon Sep 17 00:00:00 2001 From: Andrew Raffensperger Date: Sun, 2 Mar 2025 15:15:04 -0800 Subject: [PATCH 1/6] first draft --- ensips/x.md | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100755 ensips/x.md diff --git a/ensips/x.md b/ensips/x.md new file mode 100755 index 0000000..efb3a0b --- /dev/null +++ b/ensips/x.md @@ -0,0 +1,83 @@ +--- +description: Custom Errors for ENSIP-10 +contributors: + - raffy.eth +ensip: + created: '2025-03-01' + status: draft +--- + +# ENSIP-X: Custom Errors for ENSIP-10 + +## Abstract + +This standard establishes [custom errors](https://docs.soliditylang.org/en/latest/contracts.html#custom-errors) for [ENSIP-10](./10.md) `resolve()` to improve the resolution experience and disambiguate the following situations: + +* the resolver profile (eg. `contenthash()`) is not supported +* the name (eg. `nick.eth`) does not exist +* all other resolution errors + +## Motivation + +ENS and the broader Ethereum ecosystem are becoming increasingly multichain. [ERC-3668](https://eips.ethereum.org/EIPS/eip-3668) enabled crosschain state access and ENSIP-10 allows a complete namespace to be bridged from another chain. + +Currently, it is difficult to programmatically disambiguate between resolution responses that have different end-user consequences. Clients are forced interpret `null` and resolution reverts as *this record does not exist*. There is no reliable technique to check if a name exists. + +## Specification + +An ENSIP-10 enabled contract SHOULD utilize the following errors: + +### UnknownResolverProfile + +```solidity +/// @param selector Function selector of the resolver profile that cannot be answered. +error UnknownResolverProfile(bytes4 selector); +``` + +Selector: [`0xa427eaf9`](https://adraffy.github.io/keccak.js/test/demo.html#algo=evm&s=UnknownResolverProfile%28bytes4%29&escape=1&encoding=utf8) + +This error should be raised when the selector of supplied `calldata` corresponds to an unknown resolver profile. + +### Unreachable + +```solidity +/// @param name DNS-encoded ENS name that does not exist. +error Unreachable(bytes name); +``` + +Selector: [`0x9e2fd406`](https://adraffy.github.io/keccak.js/test/demo.html#algo=evm&s=Unreachable%28bytes%29&escape=1&encoding=utf8) + +This error should be raised when the supplied `name` does not exist, which could happen for a variety of reasons: + +* `name` is encoded incorrectly +* `name` cannot be parsed — eg. `zzz.3c.reverse` where `zzz` is expected to be 40 hexadecimal characters. +* `name` does not exist — eg. `__dne.base.eth` where `__dne` is not a registered [Basename](https://www.base.org/names). + +When existence is unknown, a `null` response is preferable to a false-positive revert. + +### Revert Priority + +ENSIP-10 states *the function MUST either return valid return data for that function, or revert if it is not supported.* When both situations apply, `UnknownResolverProfile` MUST be raised before `Unreachable`. + +## Rationale + +The proposed implementation makes it possible to check for extended resolver profile support, similar to [ERC-165](https://eips.ethereum.org/EIPS/eip-165). + +When queried with a supported resolver profile, the existence of a name can be determined by the presence of `Unreachable`. + +Clients can utilize this information to improve the resolution experience. All other errors likely correspond to unexpected resolution failures. + +## Backwards Compatibility + +This proposal does not alter the resolution process, it only supplies additional error information when a name cannot be resolved. + +Resolvers that answer the equivalent of `null` when an unsupported resolver profile is queried should be redeployed. + +## Security Considerations + +None. + +## Copyright + + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 6f87501f156500c3384816c883beddda23ef5b6e Mon Sep 17 00:00:00 2001 From: Andrew Raffensperger Date: Sun, 2 Mar 2025 15:27:00 -0800 Subject: [PATCH 2/6] minor --- ensips/x.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ensips/x.md b/ensips/x.md index efb3a0b..793681c 100755 --- a/ensips/x.md +++ b/ensips/x.md @@ -49,7 +49,7 @@ Selector: [`0x9e2fd406`](https://adraffy.github.io/keccak.js/test/demo.html#algo This error should be raised when the supplied `name` does not exist, which could happen for a variety of reasons: -* `name` is encoded incorrectly +* `name` is incorrectly encoded * `name` cannot be parsed — eg. `zzz.3c.reverse` where `zzz` is expected to be 40 hexadecimal characters. * `name` does not exist — eg. `__dne.base.eth` where `__dne` is not a registered [Basename](https://www.base.org/names). @@ -57,7 +57,7 @@ When existence is unknown, a `null` response is preferable to a false-positive r ### Revert Priority -ENSIP-10 states *the function MUST either return valid return data for that function, or revert if it is not supported.* When both situations apply, `UnknownResolverProfile` MUST be raised before `Unreachable`. +ENSIP-10 [states](./10.md#specification) *the function MUST either return valid return data for that function, or revert if it is not supported.* When both situations apply, `UnknownResolverProfile` MUST be raised before `Unreachable`. ## Rationale From 579c8252b42cbb2eb087106fbb02607c582c54b8 Mon Sep 17 00:00:00 2001 From: Andrew Raffensperger Date: Mon, 3 Mar 2025 00:47:30 -0800 Subject: [PATCH 3/6] minor again --- ensips/x.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ensips/x.md b/ensips/x.md index 793681c..6a7f435 100755 --- a/ensips/x.md +++ b/ensips/x.md @@ -19,7 +19,7 @@ This standard establishes [custom errors](https://docs.soliditylang.org/en/lates ## Motivation -ENS and the broader Ethereum ecosystem are becoming increasingly multichain. [ERC-3668](https://eips.ethereum.org/EIPS/eip-3668) enabled crosschain state access and ENSIP-10 allows a complete namespace to be bridged from another chain. +ENS and the broader Ethereum ecosystem are becoming increasingly multichain. [ERC-3668](https://eips.ethereum.org/EIPS/eip-3668) enables offchain access and ENSIP-10 allows a complete namespace to be bridged from another chain. Currently, it is difficult to programmatically disambiguate between resolution responses that have different end-user consequences. Clients are forced interpret `null` and resolution reverts as *this record does not exist*. There is no reliable technique to check if a name exists. @@ -49,15 +49,15 @@ Selector: [`0x9e2fd406`](https://adraffy.github.io/keccak.js/test/demo.html#algo This error should be raised when the supplied `name` does not exist, which could happen for a variety of reasons: -* `name` is incorrectly encoded -* `name` cannot be parsed — eg. `zzz.3c.reverse` where `zzz` is expected to be 40 hexadecimal characters. -* `name` does not exist — eg. `__dne.base.eth` where `__dne` is not a registered [Basename](https://www.base.org/names). +* incorrectly encoded +* cannot be parsed — eg. `zzz.3c.reverse` where `zzz` is expected to be 40 hexadecimal characters. +* does not exist — eg. `__dne.base.eth` where `__dne` is not a registered [Basename](https://www.base.org/names). When existence is unknown, a `null` response is preferable to a false-positive revert. ### Revert Priority -ENSIP-10 [states](./10.md#specification) *the function MUST either return valid return data for that function, or revert if it is not supported.* When both situations apply, `UnknownResolverProfile` MUST be raised before `Unreachable`. +ENSIP-10 [states](./10.md#specification) *"the function MUST either return valid return data for that function, or revert if it is not supported."* When both errors apply, `UnknownResolverProfile` MUST be raised before `Unreachable`. ## Rationale From e3c4157ab6557e756469a1ad1a7fc22eac207aec Mon Sep 17 00:00:00 2001 From: Andrew Raffensperger Date: Mon, 3 Mar 2025 13:24:39 -0800 Subject: [PATCH 4/6] change to gregs suggested names --- ensips/x.md | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/ensips/x.md b/ensips/x.md index 6a7f435..4a601a4 100755 --- a/ensips/x.md +++ b/ensips/x.md @@ -13,7 +13,7 @@ ensip: This standard establishes [custom errors](https://docs.soliditylang.org/en/latest/contracts.html#custom-errors) for [ENSIP-10](./10.md) `resolve()` to improve the resolution experience and disambiguate the following situations: -* the resolver profile (eg. `contenthash()`) is not supported +* the [resolver profile](https://github.com/ensdomains/ens-contracts/tree/staging/contracts/resolvers/profiles) (eg. `contenthash()`) is not supported * the name (eg. `nick.eth`) does not exist * all other resolution errors @@ -27,43 +27,45 @@ Currently, it is difficult to programmatically disambiguate between resolution r An ENSIP-10 enabled contract SHOULD utilize the following errors: -### UnknownResolverProfile +### UnsupportedResolverProfile ```solidity /// @param selector Function selector of the resolver profile that cannot be answered. -error UnknownResolverProfile(bytes4 selector); +error UnsupportedResolverProfile(bytes4 selector); ``` -Selector: [`0xa427eaf9`](https://adraffy.github.io/keccak.js/test/demo.html#algo=evm&s=UnknownResolverProfile%28bytes4%29&escape=1&encoding=utf8) +Selector: [`0x7b1c461b`](https://adraffy.github.io/keccak.js/test/demo.html#algo=evm&s=UnsupportedResolverProfile%28bytes4%29&escape=1&encoding=utf8) -This error should be raised when the selector of supplied `calldata` corresponds to an unknown resolver profile. +This error should be raised when the selector of supplied `calldata` corresponds to an unsupported resolver profile. -### Unreachable +### UnreachableName ```solidity /// @param name DNS-encoded ENS name that does not exist. -error Unreachable(bytes name); +error UnreachableName(bytes name); ``` -Selector: [`0x9e2fd406`](https://adraffy.github.io/keccak.js/test/demo.html#algo=evm&s=Unreachable%28bytes%29&escape=1&encoding=utf8) +Selector: [`0x5fe9a5df`](https://adraffy.github.io/keccak.js/test/demo.html#algo=evm&s=UnreachableName%28bytes%29&escape=1&encoding=utf8) This error should be raised when the supplied `name` does not exist, which could happen for a variety of reasons: * incorrectly encoded * cannot be parsed — eg. `zzz.3c.reverse` where `zzz` is expected to be 40 hexadecimal characters. -* does not exist — eg. `__dne.base.eth` where `__dne` is not a registered [Basename](https://www.base.org/names). +* does not exist — eg. `__dne.base.eth` where `__dne` is not a registered [Basename](https://www.base.org/names). When existence is unknown, a `null` response is preferable to a false-positive revert. +When this error is raised, all responses for `name` are effectively `null`. + ### Revert Priority -ENSIP-10 [states](./10.md#specification) *"the function MUST either return valid return data for that function, or revert if it is not supported."* When both errors apply, `UnknownResolverProfile` MUST be raised before `Unreachable`. +ENSIP-10 [states](./10.md#specification) *"the function MUST either return valid return data for that function, or revert if it is not supported."* When both errors apply, `UnsupportedResolverProfile` MUST be raised before `UnreachableName`. ## Rationale The proposed implementation makes it possible to check for extended resolver profile support, similar to [ERC-165](https://eips.ethereum.org/EIPS/eip-165). -When queried with a supported resolver profile, the existence of a name can be determined by the presence of `Unreachable`. +When queried with a supported resolver profile, the existence of a name can be determined by the presence of `UnreachableName`. Clients can utilize this information to improve the resolution experience. All other errors likely correspond to unexpected resolution failures. @@ -71,7 +73,8 @@ Clients can utilize this information to improve the resolution experience. All This proposal does not alter the resolution process, it only supplies additional error information when a name cannot be resolved. -Resolvers that answer the equivalent of `null` when an unsupported resolver profile is queried should be redeployed. +* Resolvers that return `null` when queried with an unsupported resolver profile should be redeployed. +* Resolvers that follow this specification but raise a different error do not require redeployment. ## Security Considerations From 722bea4a2cce3e10da48c0355e22a4d450aefd4e Mon Sep 17 00:00:00 2001 From: Andrew Raffensperger Date: Sat, 15 Mar 2025 21:56:49 -0700 Subject: [PATCH 5/6] remove space --- ensips/x.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ensips/x.md b/ensips/x.md index 4a601a4..a1b8848 100755 --- a/ensips/x.md +++ b/ensips/x.md @@ -73,7 +73,7 @@ Clients can utilize this information to improve the resolution experience. All This proposal does not alter the resolution process, it only supplies additional error information when a name cannot be resolved. -* Resolvers that return `null` when queried with an unsupported resolver profile should be redeployed. +* Resolvers that return `null` when queried with an unsupported resolver profile should be redeployed. * Resolvers that follow this specification but raise a different error do not require redeployment. ## Security Considerations From f919c63aef4a0572524179a93d5f4531bcdf5122 Mon Sep 17 00:00:00 2001 From: Andrew Raffensperger Date: Tue, 29 Apr 2025 15:30:51 -0700 Subject: [PATCH 6/6] fix: grammar Co-authored-by: katzman --- ensips/x.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ensips/x.md b/ensips/x.md index a1b8848..e73566a 100755 --- a/ensips/x.md +++ b/ensips/x.md @@ -21,7 +21,7 @@ This standard establishes [custom errors](https://docs.soliditylang.org/en/lates ENS and the broader Ethereum ecosystem are becoming increasingly multichain. [ERC-3668](https://eips.ethereum.org/EIPS/eip-3668) enables offchain access and ENSIP-10 allows a complete namespace to be bridged from another chain. -Currently, it is difficult to programmatically disambiguate between resolution responses that have different end-user consequences. Clients are forced interpret `null` and resolution reverts as *this record does not exist*. There is no reliable technique to check if a name exists. +Currently, it is difficult to programmatically disambiguate between resolution responses that have different end-user consequences. Clients are forced to interpret `null` and resolution reverts as *this record does not exist*. There is no reliable technique to check if a name exists. ## Specification