Skip to content
This repository was archived by the owner on Aug 5, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ca34b63
Add 'refresh' to the relative time in <AcceptanceTestResultFooter>
Y3drk Jun 10, 2026
b008d7b
Add Exchange app type
Y3drk Jun 10, 2026
b2cb56a
Add Binance
Y3drk Jun 11, 2026
7e4b1ae
Add OKX Wallet
Y3drk Jun 11, 2026
d5ec675
Add Kraken (no official icons yet)
Y3drk Jun 11, 2026
7888ef9
Add OKX exchange + new benchmark for Binance exchange
Y3drk Jun 11, 2026
1988cd2
Add Crypto.com
Y3drk Jun 11, 2026
7c8349c
Add Robinhood Wallet
Y3drk Jun 11, 2026
d30f6d7
Add Gemini Wallet & Kraken icons
Y3drk Jun 12, 2026
39a6870
Add Coinbase exchange
Y3drk Jun 12, 2026
f3749db
Apply AI agents' suggestions, pt.1
Y3drk Jun 12, 2026
de7239e
Merge branch 'main' of https://github.com/namehash/ensawards into y3d…
Y3drk Jun 12, 2026
2585fee
Add Frame & rebenchmark Rabby
Y3drk Jun 15, 2026
7708d03
Add Robinhood Exchange
Y3drk Jun 15, 2026
fdb1eb8
Add OG images for the majority of new apps
Y3drk Jun 15, 2026
cc281bb
Add OG images for the majority of new apps, pt.2
Y3drk Jun 15, 2026
48c48da
Apply AI agents' suggestions, pt.2
Y3drk Jun 15, 2026
3450299
Fix audited dependency vulnerabilities
Y3drk Jun 15, 2026
63f2cd0
Apply AI agents' suggestions, pt.3
Y3drk Jun 15, 2026
a9c0744
Add OG images for the remaining apps (only Frame remining)
Y3drk Jun 15, 2026
1a1ec23
Add new benchmark result type --> not-applicable
Y3drk Jun 15, 2026
15fe9dc
Fix build error
Y3drk Jun 15, 2026
051b956
Apply AI agents' suggestions, pt.1 + build error fixes
Y3drk Jun 15, 2026
25b0ee7
Apply AI agents' suggestions, pt.2 + build error fixes 3
Y3drk Jun 15, 2026
61d82c7
Apply AI agents' suggestions, pt.3
Y3drk Jun 15, 2026
be94938
Resolve conflicts with main
Y3drk Jun 16, 2026
f601ca6
Apply 06/15/26 GitHub narrative suggestion
Y3drk Jun 16, 2026
bd71c1e
Fix surfaced vulnerabilities, pt.1
Y3drk Jun 16, 2026
07a1609
Apply AI agents' suggestions, pt.4
Y3drk Jun 16, 2026
ce5532a
Add new required mock functions to the unit tests
Y3drk Jun 16, 2026
3c12d79
Delete unused import
Y3drk Jun 16, 2026
1598ed3
Remove informative comments before the review
Y3drk Jun 18, 2026
b9e008b
Resolving conflicts with main, pt.2
Y3drk Jun 18, 2026
38f21b3
Fix audited dependency vulnerabilities
Y3drk Jun 18, 2026
d3895d2
Apply AI agents' suggestions, pt.5
Y3drk Jun 18, 2026
eccb9d2
Add exampleNotApplicable field to AcceptanceTest
Y3drk Jun 18, 2026
b91b41f
Apply the terminology improvements from the 06/18/26 GitHub review fe…
Y3drk Jun 18, 2026
be62cf9
Apply the requested overall app score display from the 06/18/26 GitHu…
Y3drk Jun 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,22 +289,26 @@ For reference, see [ensawards.org/data/ens-best-practices/contract-naming/name-y
* user interactions to be evaluated,
* and any relevant technical details or considerations.
*
* @note The description should not include examples of passed or failed benchmarks,
* @note The description should not include examples of
* passed, partially passed, failed, or not applicable benchmarks,
* there are dedicated fields for that
* (see {@link AcceptanceTest.examplePass},
* {@link AcceptanceTest.examplePartialPass},
* or {@link AcceptanceTest.exampleFail}).
* {@link AcceptanceTest.exampleFail},
* or {@link AcceptanceTest.exampleNotApplicable}).
*/
description: JSX.Element;

/**
* Examples of benchmark results that illustrate
* what a passing, partially passing, or failing result
* what a passing, partially passing, failing,
* or not applicable result
* looks like for this acceptance test.
*/
examplePass: AcceptanceTestBenchmarkPass;
examplePartialPass?: AcceptanceTestBenchmarkPartialPass;
exampleFail?: AcceptanceTestBenchmarkFail;
exampleNotApplicable?: NotApplicableAcceptanceTestBenchmark;
}
```
4. In your PR describe your reasoning for adding it.
Expand Down Expand Up @@ -371,6 +375,7 @@ export const BenchmarkResults = {
Pass: "passed",
PartialPass: "partially-passed",
Fail: "failed",
NotApplicable: "not-applicable",
} as const;

export type BenchmarkResult = (typeof BenchmarkResults)[keyof typeof BenchmarkResults];
Expand Down Expand Up @@ -444,10 +449,23 @@ export interface AcceptanceTestBenchmarkPartialPass
export interface AcceptanceTestBenchmarkFail
extends AcceptanceTestBenchmarkAbstract<typeof BenchmarkResults.Fail> {}

export type AcceptanceTestBenchmark =
/**
* Represents a benchmark of an {@link AcceptanceTest} on an {@link App} against a {@link BestPractice},
* that is not applicable to the acceptance test scenario.
* Most often, this is because the app doesn't use ENS at all,
* in places where it should.
Comment thread
Y3drk marked this conversation as resolved.
*/
export interface NotApplicableAcceptanceTestBenchmark
extends AcceptanceTestBenchmarkAbstract<typeof BenchmarkResults.NotApplicable> {}

export type ApplicableAcceptanceTestBenchmark =
| AcceptanceTestBenchmarkPass
| AcceptanceTestBenchmarkPartialPass
| AcceptanceTestBenchmarkFail;

export type AcceptanceTestBenchmark =
| ApplicableAcceptanceTestBenchmark
| NotApplicableAcceptanceTestBenchmark;
```

3. Add notes made during the benchmarking process in the form of a simple JSX element that is a part of the new item in the `benchmarks` record. For reference, see
Expand Down
25 changes: 21 additions & 4 deletions ensawards.org/data/acceptance-tests/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,26 @@ export interface AcceptanceTest {
* user interactions to be evaluated,
* and any relevant technical details or considerations.
*
* @note The description should not include examples of passed or failed benchmarks,
* @note The description should not include examples of
* passed, partially passed, failed, or not applicable benchmarks,
* there are dedicated fields for that
* (see {@link AcceptanceTest.examplePass},
* {@link AcceptanceTest.examplePartialPass},
* or {@link AcceptanceTest.exampleFail}).
* {@link AcceptanceTest.exampleFail},
* or {@link AcceptanceTest.exampleNotApplicable}).
*/
description: JSX.Element;

/**
* Examples of benchmark results that illustrate
* what a passing, partially passing, or failing result
* what a passing, partially passing, failing,
* or not applicable result
* looks like for this acceptance test.
*/
examplePass: AcceptanceTestBenchmarkPass;
examplePartialPass?: AcceptanceTestBenchmarkPartialPass;
exampleFail?: AcceptanceTestBenchmarkFail;
exampleNotApplicable?: AcceptanceTestBenchmarkNotApplicable;
}

/**
Expand Down Expand Up @@ -92,7 +96,20 @@ export interface AcceptanceTestBenchmarkPartialPass
export interface AcceptanceTestBenchmarkFail
extends AcceptanceTestBenchmarkAbstract<typeof BenchmarkResults.Fail> {}

export type AcceptanceTestBenchmark =
/**
* Represents a benchmark of an {@link AcceptanceTest} on an {@link App} against a {@link BestPractice},
* that is not applicable to the acceptance test scenario.
* Most often, this is because the app doesn't use ENS at all,
* in places where it should.
*/
export interface AcceptanceTestBenchmarkNotApplicable
extends AcceptanceTestBenchmarkAbstract<typeof BenchmarkResults.NotApplicable> {}

export type AcceptanceTestBenchmarkApplicable =
| AcceptanceTestBenchmarkPass
| AcceptanceTestBenchmarkPartialPass
| AcceptanceTestBenchmarkFail;

export type AcceptanceTestBenchmark =
| AcceptanceTestBenchmarkApplicable
| AcceptanceTestBenchmarkNotApplicable;
67 changes: 50 additions & 17 deletions ensawards.org/data/acceptance-tests/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,32 @@ describe("Acceptance test utils", () => {
},
);

it("Returns `BenchmarkResults.Fail` if all defined benchmarks are `BenchmarkResults.Fail`", () => {
const expectedResult = BenchmarkResults.Fail;
it(
"Returns `BenchmarkResults.Fail` if in all defined benchmarks there is at least one `BenchmarkResults.Fail`" +
" and all others are `BenchmarkResults.Fail` or `BenchmarkResults.NotApplicable`",
() => {
const expectedResult = BenchmarkResults.Fail;

const inputBenchmarks = {
"mock-acceptance-test-1": createMockAcceptanceTestBenchmark(BenchmarkResults.Fail),
"mock-acceptance-test-2": createMockAcceptanceTestBenchmark(BenchmarkResults.Fail),
"mock-acceptance-test-3": undefined,
// pending benchmarks should be ignored in this case of the generalization
} as const satisfies AcceptanceTestBenchmarks;
const inputBenchmarks = {
"mock-acceptance-test-1": createMockAcceptanceTestBenchmark(BenchmarkResults.Fail),
"mock-acceptance-test-2": createMockAcceptanceTestBenchmark(BenchmarkResults.Fail),
"mock-acceptance-test-3": createMockAcceptanceTestBenchmark(
BenchmarkResults.NotApplicable,
),
"mock-acceptance-test-4": undefined,
// pending benchmarks should be ignored in this case of the generalization
} as const satisfies AcceptanceTestBenchmarks;

expect(
generalizeAcceptanceTestBenchmarks(inputBenchmarks),
"generalizeAcceptanceTestBenchmarks should return `BenchmarkResults.Fail`",
).toEqual(expectedResult);
});
expect(
generalizeAcceptanceTestBenchmarks(inputBenchmarks),
"generalizeAcceptanceTestBenchmarks should return `BenchmarkResults.Fail`",
).toEqual(expectedResult);
},
);

it(
"Returns `BenchmarkResults.PartialPass` if at least one defined benchmark is `BenchmarkResults.Fail`" +
" and at least one defined benchmark is `BenchmarkResults.Pass`",
" and at least one defined benchmark is `BenchmarkResults.Pass` or `BenchmarkResults.PartialPass`",
() => {
const expectedResult = BenchmarkResults.PartialPass;

Expand Down Expand Up @@ -78,18 +85,44 @@ describe("Acceptance test utils", () => {
).toEqual(expectedResult);
});

it("Returns `undefined` if all benchmarks are `undefined` (pending)", () => {
const expectedResult = undefined;
it("Returns `BenchmarkResults.NotApplicable` if all benchmarks are defined and `BenchmarkResults.NotApplicable`", () => {
const expectedResult = BenchmarkResults.NotApplicable;

const inputBenchmarks = {
"mock-acceptance-test-1": createMockAcceptanceTestBenchmark(BenchmarkResults.NotApplicable),
"mock-acceptance-test-2": createMockAcceptanceTestBenchmark(BenchmarkResults.NotApplicable),
"mock-acceptance-test-3": createMockAcceptanceTestBenchmark(BenchmarkResults.NotApplicable),
} as const satisfies AcceptanceTestBenchmarks;

expect(
generalizeAcceptanceTestBenchmarks(inputBenchmarks),
"generalizeAcceptanceTestBenchmarks should return `BenchmarkResults.NotApplicable`",
).toEqual(expectedResult);
});

it("Returns `undefined` if all benchmarks are `undefined` (pending) or all defined benchmarks are `BenchmarkResults.NotApplicable`", () => {
const expectedResult = undefined;

const inputBenchmarks1 = {
"mock-acceptance-test-1": undefined,
"mock-acceptance-test-2": undefined,
} as const satisfies AcceptanceTestBenchmarks;

const inputBenchmarks2 = {
"mock-acceptance-test-1": createMockAcceptanceTestBenchmark(BenchmarkResults.NotApplicable),
"mock-acceptance-test-2": createMockAcceptanceTestBenchmark(BenchmarkResults.NotApplicable),
"mock-acceptance-test-3": undefined,
} as const satisfies AcceptanceTestBenchmarks;

expect(
generalizeAcceptanceTestBenchmarks(inputBenchmarks),
generalizeAcceptanceTestBenchmarks(inputBenchmarks1),
"generalizeAcceptanceTestBenchmarks should return `undefined` for all pending benchmarks",
).toEqual(expectedResult);

expect(
generalizeAcceptanceTestBenchmarks(inputBenchmarks2),
"generalizeAcceptanceTestBenchmarks should return `undefined` for all defined benchmarks being `NotApplicable`",
).toEqual(expectedResult);
});
});
});
30 changes: 25 additions & 5 deletions ensawards.org/data/acceptance-tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,22 @@ export const getAcceptanceTestBenchmarksByApp = (
* {@link BenchmarkResults.Pass}
* - and all others are {@link BenchmarkResults.Pass} or {@link BenchmarkResults.PartialPass}
*
* - Returns {@link BenchmarkResults.Fail} if all defined benchmarks
* are {@link BenchmarkResults.Fail},
* - Returns {@link BenchmarkResults.Fail} if:
* - in all defined benchmarks there is at least one
* {@link BenchmarkResults.Fail}
* - and all others are {@link BenchmarkResults.Fail} or {@link BenchmarkResults.NotApplicable}
*
Comment thread
Y3drk marked this conversation as resolved.
* - Returns {@link BenchmarkResults.PartialPass} if:
* - at least one defined benchmark is {@link BenchmarkResults.Fail}
* and at least one defined benchmark is
* {@link BenchmarkResults.Pass} or {@link BenchmarkResults.PartialPass},
* - or all defined benchmarks are {@link BenchmarkResults.PartialPass},
*
* - Returns `undefined` if all benchmarks are `undefined` (pending).
* - Returns {@link BenchmarkResults.NotApplicable} if:
* - all benchmarks are **defined** and {@link BenchmarkResults.NotApplicable}
*
* - Returns `undefined` if all benchmarks are `undefined` (pending)
* or all defined benchmarks are {@link BenchmarkResults.NotApplicable}.
*/
export const generalizeAcceptanceTestBenchmarks = (
acceptanceTestBenchmarks: AcceptanceTestBenchmarks,
Expand All @@ -75,7 +81,19 @@ export const generalizeAcceptanceTestBenchmarks = (

const definedBenchmarkResults = benchmarkResults.filter((result) => result !== undefined);

if (definedBenchmarkResults.length === 0) {
const allBenchmarksNotApplicable = definedBenchmarkResults.every(
(result) => result === BenchmarkResults.NotApplicable,
);

// We want to be very strict about returning NotApplicable,
// so we only return it if all benchmarks are defined and `NotApplicable`.
if (allBenchmarksNotApplicable && definedBenchmarkResults.length === benchmarkResults.length) {
return BenchmarkResults.NotApplicable;
}

// And for all possible mixes of pending and NotApplicable,
// we want to return undefined (pending).
if (definedBenchmarkResults.length === 0 || allBenchmarksNotApplicable) {
return undefined;
}

Expand All @@ -97,8 +115,10 @@ export const generalizeAcceptanceTestBenchmarks = (
return BenchmarkResults.Pass;
}

// For now, we'll explicitly treat fail and not applicable equally
// (For cases where not all benchmarks are not applicable)
const allDefinedBenchmarksFail = definedBenchmarkResults.every(
(result) => result === BenchmarkResults.Fail,
(result) => result === BenchmarkResults.Fail || result === BenchmarkResults.NotApplicable,
);

if (allDefinedBenchmarksFail) {
Expand Down
21 changes: 16 additions & 5 deletions ensawards.org/data/apps/binance-exchange/benchmarks/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,37 @@ import correctlyResolveEnsv2TestNameAddressProofImageWithdrawal from "./correctl
const benchmarks: BestPracticeBenchmarks = {
"ensv2-ready-resolution": {
"correctly-resolve-ensv2-test-name-address": {
result: BenchmarkResults.Fail,
result: BenchmarkResults.NotApplicable,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
contributions: [
{ from: contributors.y3drk, lastUpdated: parseTimestamp("2026-06-11T07:30:06Z") },
],
notes: (
<div className={cn(acceptanceTestDetailsContainerStyles, "w-full")}>
<p className="w-full">
ENSv2 ready resolution was tested using the search tool in the &quot;copy-trading&quot;
flow. The app either doesn't allow using ENS name as the trader identifier or fails to
resolve it, both of which we interpret as a failure.
flow. The app doesn't support the use of ENS names at all as the trader identifier.
<br />
<br />
While that's a key issue that this app is encouraged to improve, this best practice is
applicable specifically to apps that already have an existing ENS integration and making
sure existing integrations are ENSv2 compatible. Therefore, for this best practice we
apply a rating of not applicable.
</p>
<img
alt="Binance exchange doesn't allow ENS name as trader in the copy-trading flow"
src={correctlyResolveEnsv2TestNameAddressProofImageCopyTrading.src}
className="w-auto h-full max-h-[325px] rounded-xl"
/>
<span className="w-full h-px bg-gray-200 my-5" />
<p className="w-full">
The ENSv2 ready resolution was also tested using the &quot;withdrawal&quot; flow. The
app doesn't allow using ENS name as the recipient identifier, which we interpret as a
failure.
app doesn't support the use of ENS names at all as the recipient identifier.
<br />
<br />
While that's a key issue that this app is encouraged to improve, this best practice is
applicable specifically to apps that already have an existing ENS integration and making
sure existing integrations are ENSv2 compatible. Therefore, for this best practice we
apply a rating of not applicable.
</p>
<img
alt="Binance exchange doesn't allow ENS name as recipient in the withdrawal flow"
Expand Down
10 changes: 8 additions & 2 deletions ensawards.org/data/apps/binance-wallet/benchmarks/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,21 @@ const benchmarks: BestPracticeBenchmarks = {
},
"ensv2-ready-resolution": {
"correctly-resolve-ensv2-test-name-address": {
result: BenchmarkResults.Fail,
result: BenchmarkResults.NotApplicable,
contributions: [
{ from: contributors.y3drk, lastUpdated: parseTimestamp("2026-06-11T07:33:06Z") },
],
notes: (
<div className={cn(acceptanceTestDetailsContainerStyles, "w-full")}>
<p className="w-full">
ENSv2 ready resolution was tested using the &quot;send&quot; flow. The wallet doesn't
allow using ENS name as the recipient identifier, which we interpret as a failure.
support the use of ENS names at all as the recipient identifier.
<br />
<br />
While that's a key issue that this app is encouraged to improve, this best practice is
applicable specifically to apps that already have an existing ENS integration and making
sure existing integrations are ENSv2 compatible. Therefore, for this best practice we
apply a rating of not applicable.
</p>
<img
alt="Binance Wallet doesn't allow ENS name as recipient in the send flow"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,21 @@ import correctlyResolveEnsv2TestNameAddressProofImage from "./correctly-resolve-
const benchmarks: BestPracticeBenchmarks = {
"ensv2-ready-resolution": {
"correctly-resolve-ensv2-test-name-address": {
result: BenchmarkResults.Fail,
result: BenchmarkResults.NotApplicable,
contributions: [
{ from: contributors.y3drk, lastUpdated: parseTimestamp("2026-06-11T13:47:40Z") },
],
notes: (
<div className={cn(acceptanceTestDetailsContainerStyles, "w-full")}>
<p className="w-full">
ENSv2 ready resolution was tested using the &quot;withdrawal&quot; flow. The app doesn't
allow using ENS name as the recipient identifier, which we interpret as a failure.
support the use of ENS names at all as the recipient identifier.
<br />
<br />
While that's a key issue that this app is encouraged to improve, this best practice is
applicable specifically to apps that already have an existing ENS integration and making
sure existing integrations are ENSv2 compatible. Therefore, for this best practice we
apply a rating of not applicable.
</p>
<img
alt="Crypto.com exchange doesn't allow ENS name as recipient in the withdrawal flow"
Expand Down
10 changes: 8 additions & 2 deletions ensawards.org/data/apps/kraken-exchange/benchmarks/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,21 @@ import correctlyResolveEnsv2TestNameAddressProofImage from "./correctly-resolve-
const benchmarks: BestPracticeBenchmarks = {
"ensv2-ready-resolution": {
"correctly-resolve-ensv2-test-name-address": {
result: BenchmarkResults.Fail,
result: BenchmarkResults.NotApplicable,
contributions: [
{ from: contributors.y3drk, lastUpdated: parseTimestamp("2026-06-11T10:47:44Z") },
],
notes: (
<div className={cn(acceptanceTestDetailsContainerStyles, "w-full")}>
<p className="w-full">
ENSv2 ready resolution was tested using the &quot;withdrawal&quot; flow. The app doesn't
allow using ENS name as the recipient identifier, which we interpret as a failure.
support the use of ENS names at all as the recipient identifier.
<br />
<br />
While that's a key issue that this app is encouraged to improve, this best practice is
applicable specifically to apps that already have an existing ENS integration and making
sure existing integrations are ENSv2 compatible. Therefore, for this best practice we
apply a rating of not applicable.
</p>
<img
alt="Kraken exchange doesn't allow ENS name as recipient in the withdrawal flow"
Expand Down
Loading
Loading