Summary
The custom "addressEqual" Chai matcher accepts "SkipCompare" in its TypeScript declaration, but the runtime implementation rejects the sentinel as an invalid address or account.
This creates a deterministic mismatch between the declared matcher contract and its runtime behavior.
Tested against upstream "main" commit:
"2a3e8ab10c0ac97bf1a2628a325eb98d4a468b1a"
Reproduction
The following assertion is accepted by TypeScript:
expect('0x4e59b44847b379578588920cA78FbF26c0B4956C').to.be.addressEqual(skipCompare)
On the current "main" branch, the assertion fails at runtime because the "SkipCompare" sentinel is treated as an address value.
Observed result:
0 passing
1 failing
AssertionError: expected [Function] not to throw, but the matcher rejected
"[object Object]" as an invalid address or account
Expected behavior
"addressEqual(skipCompare)" should skip expected-value validation and comparison, consistent with:
- the "addressEqual" TypeScript declaration;
- the existing "expectAddressEq" helper;
- the intended "SkipCompare" behavior.
Actual behavior
"supportAddressEqual()" passes the "SkipCompare" sentinel to "isAddressable()".
Because the sentinel is not an address or account object, the matcher fails before performing the intended skip operation.
Root cause
"tests/helpers/matchers/types.d.ts" declares that "addressEqual" accepts "SkipCompare":
addressEqual(
other:
| 0x${string}
| { address: 0x${string} }
| { account: { address: 0x${string} } }
| SkipCompare,
message?: string,
): void
However, the runtime "addressEqual" method in "tests/helpers/matchers/Address.ts" does not check "isSkipCompare(other)" before validating both operands.
Suggested fix
Return early when "isSkipCompare(other)" is true:
if (isSkipCompare(other)) {
return
}
Add focused regression coverage for:
expect('0x4e59b44847b379578588920cA78FbF26c0B4956C').to.be.addressEqual(skipCompare)
Verification
With the focused fix applied:
- matcher suite: 16 passing;
- focused reproducer: passing;
- ESLint: passed;
- Prettier: passed;
- "git diff --check": passed.
Scope
This is a test-helper correctness defect, not a production or security vulnerability.
It is separate from #399 and #400, which concern the "hexEqual" matcher.
Duplicate and WIP check
I searched open and closed issues, pull requests, commits, and branches using:
- "addressEqual";
- "SkipCompare";
- "supportAddressEqual";
- the affected file paths;
- the runtime error text.
No separate report or implementation covering "addressEqual(skipCompare)" was found.
A focused implementation is prepared in #406. That PR remains closed pending assignment, in accordance with the contribution policy.
Please assign this issue to me so I can proceed with the existing implementation.
Summary
The custom "addressEqual" Chai matcher accepts "SkipCompare" in its TypeScript declaration, but the runtime implementation rejects the sentinel as an invalid address or account.
This creates a deterministic mismatch between the declared matcher contract and its runtime behavior.
Tested against upstream "main" commit:
"2a3e8ab10c0ac97bf1a2628a325eb98d4a468b1a"
Reproduction
The following assertion is accepted by TypeScript:
expect('0x4e59b44847b379578588920cA78FbF26c0B4956C').to.be.addressEqual(skipCompare)
On the current "main" branch, the assertion fails at runtime because the "SkipCompare" sentinel is treated as an address value.
Observed result:
0 passing
1 failing
AssertionError: expected [Function] not to throw, but the matcher rejected
"[object Object]" as an invalid address or account
Expected behavior
"addressEqual(skipCompare)" should skip expected-value validation and comparison, consistent with:
Actual behavior
"supportAddressEqual()" passes the "SkipCompare" sentinel to "isAddressable()".
Because the sentinel is not an address or account object, the matcher fails before performing the intended skip operation.
Root cause
"tests/helpers/matchers/types.d.ts" declares that "addressEqual" accepts "SkipCompare":
addressEqual(
other:
|
0x${string}| { address:
0x${string}}| { account: { address:
0x${string}} }| SkipCompare,
message?: string,
): void
However, the runtime "addressEqual" method in "tests/helpers/matchers/Address.ts" does not check "isSkipCompare(other)" before validating both operands.
Suggested fix
Return early when "isSkipCompare(other)" is true:
if (isSkipCompare(other)) {
return
}
Add focused regression coverage for:
expect('0x4e59b44847b379578588920cA78FbF26c0B4956C').to.be.addressEqual(skipCompare)
Verification
With the focused fix applied:
Scope
This is a test-helper correctness defect, not a production or security vulnerability.
It is separate from #399 and #400, which concern the "hexEqual" matcher.
Duplicate and WIP check
I searched open and closed issues, pull requests, commits, and branches using:
No separate report or implementation covering "addressEqual(skipCompare)" was found.
A focused implementation is prepared in #406. That PR remains closed pending assignment, in accordance with the contribution policy.
Please assign this issue to me so I can proceed with the existing implementation.