Skip to content

Merge release-v5.6 branch#6369

Merged
Amxx merged 36 commits intomasterfrom
merge/release-v5.6
Feb 26, 2026
Merged

Merge release-v5.6 branch#6369
Amxx merged 36 commits intomasterfrom
merge/release-v5.6

Conversation

@github-actions
Copy link
Contributor

No description provided.

github-actions bot and others added 30 commits December 19, 2025 14:29
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: ernestognw <ernestognw@gmail.com>
Co-authored-by: Arr00 <13561405+arr00@users.noreply.github.com>
Co-authored-by: ernestognw <ernestognw@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
…6247)

Co-authored-by: ernestognw <ernestognw@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Co-authored-by: ernestognw <ernestognw@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
…6303)

Co-authored-by: Ernesto <ernestognw@Ernestos-MacBook-Pro.local>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Co-authored-by: ernestognw <ernestognw@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
…ing the FMP to a low value (#6348)

Co-authored-by: ernestognw <ernestognw@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
…ift (#6302)

Co-authored-by: ernestognw <ernestognw@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
…es empty (#6331)

Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Co-authored-by: ernestognw <ernestognw@gmail.com>
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Amxx and others added 3 commits February 25, 2026 14:26
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
@github-actions github-actions bot requested a review from a team as a code owner February 25, 2026 17:06
@changeset-bot
Copy link

changeset-bot bot commented Feb 25, 2026

⚠️ No Changeset found

Latest commit: 7de0f45

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

Walkthrough

This PR prepares OpenZeppelin Contracts for v5.6.0 release by removing 16 changeset files, updating version headers across contracts from v5.5.0 to v5.6.0, and bumping package versions. It renames BridgeERC20Core to BridgeFungible, refactors ERC7786Recipient to stateless design, updates Memory API (setFreeMemoryPointer to unsafeSetFreeMemoryPointer), adds ERC165 support to ERC6909 extensions, modifies TrieProof traversal logic, updates compiler versions to 0.8.31, and consolidates GitHub Actions setup. Test files are updated to reflect renamed events and new interface contracts.

Possibly related PRs

Suggested labels

ignore-changeset, release-cycle, breaking change

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive No description was provided by the author, making it impossible to assess relevance to the changeset. Add a description explaining the purpose of the merge, such as releasing v5.6.0 and listing major changes or breaking changes included.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main action of merging the release-v5.6 branch, which is the primary objective evident from the extensive changeset covering v5.6.0 release updates.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch merge/release-v5.6

Warning

Tools execution failed with the following error:

Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
contracts/utils/cryptography/signers/SignerWebAuthn.sol (1)

13-16: ⚠️ Potential issue | 🟡 Minor

Stale class-level NatSpec: "raw P256 signature validation" path is removed.

The class documentation (lines 13-16) still states the contract "allows for both WebAuthn and raw P256 signature validation, providing compatibility with both signature types," but the new implementation returns false for any non-WebAuthn input — the raw P256 fallback via super._rawSignatureValidation has been removed. The NatSpec should be updated to reflect the contract now only accepts WebAuthn authentication assertions.

- * This contract enables signature validation using WebAuthn authentication assertions,
- * leveraging the P256 public key stored in the contract. It allows for both WebAuthn
- * and raw P256 signature validation, providing compatibility with both signature types.
+ * This contract enables signature validation using WebAuthn authentication assertions,
+ * leveraging the P256 public key stored in the contract. The signature must be a valid
+ * WebAuthn authentication assertion; raw P256 signatures are not accepted.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contracts/utils/cryptography/signers/SignerWebAuthn.sol` around lines 13 -
16, Update the class NatSpec for SignerWebAuthn.sol to remove the stale claim
about raw P256 signature validation and state that this contract only accepts
WebAuthn authentication assertions; specifically mention that the signature
input is expected to be an abi-encoded WebAuthn-WebAuthnAuth struct and that
non-WebAuthn inputs are rejected (the previous fallback to
super._rawSignatureValidation has been removed).
CHANGELOG.md (1)

71-73: ⚠️ Potential issue | 🟡 Minor

Pre-existing duplicate bug-fix entry in the 5.5.0 section.

Lines 71 and 73 contain the identical AccountERC7579 isModuleInstalled fix entry (PR #5961). One should be removed. This is a pre-existing issue but is now visible in the context of this release PR.

📝 Proposed fix
 - `AccountERC7579`: Prevent revert in `isModuleInstalled` for fallback modules when `additionalContext` has fewer than 4 bytes. The function now returns `false` instead of reverting, ensuring ERC-7579 compliance. ([`#5961`](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5961))
 - `ERC165Checker`: Ensure the `supportsERC165` function returns false if the target reverts during the `supportsInterface(0xffffffff)` call. ([`#5880`](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5880))
-- `AccountERC7579`: Prevent revert in `isModuleInstalled` for fallback modules when `additionalContext` has fewer than 4 bytes. The function now returns `false` instead of reverting, ensuring ERC-7579 compliance. ([`#5961`](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5961))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CHANGELOG.md` around lines 71 - 73, There is a duplicate changelog entry for
the AccountERC7579 isModuleInstalled bugfix (PR `#5961`) in the 5.5.0 section;
remove the redundant line so only one entry referencing `AccountERC7579` and
`isModuleInstalled` (PR `#5961`) remains, keeping the other unrelated entry
(`ERC165Checker` supportsERC165) untouched.
contracts/crosschain/bridges/abstract/BridgeFungible.sol (1)

18-21: ⚠️ Potential issue | 🟡 Minor

Minor NatSpec grammar nit: "which interface with" → "which interfaces with".

Line 19: {BridgeERC7802}, which interface with ERC-7802 should read which interfaces with.

📝 Proposed fix
- * which interface with ERC-7802 to provide an approve-free user experience. It is also used by the {ERC20Crosschain}
+ * which interfaces with ERC-7802 to provide an approve-free user experience. It is also used by the {ERC20Crosschain}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contracts/crosschain/bridges/abstract/BridgeFungible.sol` around lines 18 -
21, Update the NatSpec comment in the BridgeFungible contract documentation:
change the phrase "{BridgeERC7802}, which interface with ERC-7802" to
"{BridgeERC7802}, which interfaces with ERC-7802" so the grammar matches the
singular "which interfaces with" used for BridgeERC20/BridgeERC7802 and the
ERC20Crosschain reference; modify the comment block that documents BridgeERC20,
BridgeERC7802, and ERC20Crosschain accordingly.
🧹 Nitpick comments (2)
test/utils/cryptography/RSA.test.js (1)

34-34: Consider normalizing static test case exponents for consistency.

The NIST loop normalizes the exponent via ethers.stripZerosLeft for gas savings, but the static others tests cases (e.g., exp: '0x010001' on line 53) retain leading-zero-padded exponents. For consistency, '0x010001' could be stripped to '0x10001'.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/utils/cryptography/RSA.test.js` at line 34, Normalize the static
exponent literals in the RSA tests so they match the NIST loop's normalized
form: update the hard-coded exponent values in the "others tests" cases (e.g.,
change the literal '0x010001' used as test.e to '0x10001') so they no longer
contain leading-zero padding, ensuring consistency with the runtime
normalization done via ethers.stripZerosLeft('0x' + test.e).
test/utils/cryptography/TrieProof.test.js (1)

191-247: Consider extracting the duplicated inline-node proof assertions into a helper.

Lines 196-215 and Lines 225-246 repeat the same setup/verification pattern with different slot fixtures. A local helper would reduce duplication and future drift.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/utils/cryptography/TrieProof.test.js` around lines 191 - 247, Extract
the duplicated setup and verification into a small helper (e.g.,
runInlineNodeProofTest) that accepts the slots map and performs: create a
MerklePatriciaTrie({ useKeyHashing: false }), put each slot/value via
tree.put(ethers.getBytes(slot), ethers.getBytes(value)), compute const root =
ethers.hexlify(tree.root()), loop over entries to build const proof = await
createMerkleProof(tree, ethers.getBytes(slot)) and assert both
this.mock.$verify(encodeStorageLeaf(value), root, slot, proof) and
this.mock.$verify(encodeStorageLeaf(value), root, slot, proof.slice(0, -1));
then call that helper from both it blocks (support inlining in extension node
and support inlining in branch node) passing their respective slots objects to
remove the duplicated lines.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/actions/setup/action.yml:
- Around line 106-108: The current steps download and install
"solc-static-linux" without verifying integrity or using the official source;
replace the simple wget/chmod/mv sequence with a verification flow: fetch the
official solc-bin metadata (binaries.soliditylang.org/linux-amd64/list.json) for
the version from steps.versions.outputs.solc (or, if intentionally using
argotorg/solidity, fetch that fork's signed checksum), extract the expected
SHA256 for that binary, download the binary to a temp file (the current wget
target "solc-static-linux"), compute its SHA256 and compare to the expected
value, and abort the job with a clear error if the checksums do not match; only
after a successful match run the existing chmod +x and sudo mv commands to
install /usr/local/bin/solc.

In `@contracts/interfaces/draft-IERC4337.sol`:
- Line 2: The file header string "OpenZeppelin Contracts (last updated v5.6.0)
(interfaces/draft-IERC4337.sol)" was bumped despite no substantive changes;
restore the accurate last-updated annotation (e.g., change "v5.6.0" back to
"v5.4.0") or add a brief commit-note indicating this is a deliberate
project-wide release-header normalization so downstream consumers know it's
intentional; update the header text in the top-of-file comment accordingly.

In `@contracts/utils/introspection/ERC165Checker.sol`:
- Around line 124-125: Update the NatSpec in ERC165Checker for the function that
returns (bool success, bool supported) to state explicitly that the `supported`
flag is only meaningful when `success` is true; mention that a failing call can
still produce a non-zero first word in a >=32-byte revert payload yielding
(false, true), so callers should interpret `supported` only when `success` is
true (i.e., use `success && supported`). Reference the ERC165Checker contract
and the function that returns (success, supported) so future callers understand
the correct gating.

In `@contracts/utils/RelayedCall.sol`:
- Around line 19-21: Fix the grammar in the header comment of the
RelayedCall.sol library: change the phrase "their target chain has supports for
EIP-3855" to "their target chain has support for EIP-3855" (update the comment
inside the RelayedCall.sol file near the NOTE about PUSH0/EIP-3855).

In `@test/helpers/trie.js`:
- Around line 18-22: Replace the use of tx.wait() when building the receipt trie
with fetching the receipt by hash via the transaction's provider so reverted
transactions don't throw; specifically, in the block where you call tx.wait()
and then this.receiptTrie.put(BlockTries.indexToKeyBytes(tx.index),
BlockTries.serializeReceipt(receipt)), change to
tx.provider.getTransactionReceipt(tx.hash) and then put the returned receipt
using BlockTries.serializeReceipt so all receipts (including status 0) are
included in receiptTrie.

---

Outside diff comments:
In `@CHANGELOG.md`:
- Around line 71-73: There is a duplicate changelog entry for the AccountERC7579
isModuleInstalled bugfix (PR `#5961`) in the 5.5.0 section; remove the redundant
line so only one entry referencing `AccountERC7579` and `isModuleInstalled` (PR
`#5961`) remains, keeping the other unrelated entry (`ERC165Checker`
supportsERC165) untouched.

In `@contracts/crosschain/bridges/abstract/BridgeFungible.sol`:
- Around line 18-21: Update the NatSpec comment in the BridgeFungible contract
documentation: change the phrase "{BridgeERC7802}, which interface with
ERC-7802" to "{BridgeERC7802}, which interfaces with ERC-7802" so the grammar
matches the singular "which interfaces with" used for BridgeERC20/BridgeERC7802
and the ERC20Crosschain reference; modify the comment block that documents
BridgeERC20, BridgeERC7802, and ERC20Crosschain accordingly.

In `@contracts/utils/cryptography/signers/SignerWebAuthn.sol`:
- Around line 13-16: Update the class NatSpec for SignerWebAuthn.sol to remove
the stale claim about raw P256 signature validation and state that this contract
only accepts WebAuthn authentication assertions; specifically mention that the
signature input is expected to be an abi-encoded WebAuthn-WebAuthnAuth struct
and that non-WebAuthn inputs are rejected (the previous fallback to
super._rawSignatureValidation has been removed).

---

Nitpick comments:
In `@test/utils/cryptography/RSA.test.js`:
- Line 34: Normalize the static exponent literals in the RSA tests so they match
the NIST loop's normalized form: update the hard-coded exponent values in the
"others tests" cases (e.g., change the literal '0x010001' used as test.e to
'0x10001') so they no longer contain leading-zero padding, ensuring consistency
with the runtime normalization done via ethers.stripZerosLeft('0x' + test.e).

In `@test/utils/cryptography/TrieProof.test.js`:
- Around line 191-247: Extract the duplicated setup and verification into a
small helper (e.g., runInlineNodeProofTest) that accepts the slots map and
performs: create a MerklePatriciaTrie({ useKeyHashing: false }), put each
slot/value via tree.put(ethers.getBytes(slot), ethers.getBytes(value)), compute
const root = ethers.hexlify(tree.root()), loop over entries to build const proof
= await createMerkleProof(tree, ethers.getBytes(slot)) and assert both
this.mock.$verify(encodeStorageLeaf(value), root, slot, proof) and
this.mock.$verify(encodeStorageLeaf(value), root, slot, proof.slice(0, -1));
then call that helper from both it blocks (support inlining in extension node
and support inlining in branch node) passing their respective slots objects to
remove the duplicated lines.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b659750 and 56a3de2.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (123)
  • .changeset/blue-mirrors-agree.md
  • .changeset/bright-webs-create.md
  • .changeset/clean-worlds-end.md
  • .changeset/flat-ideas-count.md
  • .changeset/fluffy-facts-brake.md
  • .changeset/forty-ads-design.md
  • .changeset/full-emus-hear.md
  • .changeset/fuzzy-lizards-do.md
  • .changeset/grumpy-cats-brake.md
  • .changeset/khaki-crews-join.md
  • .changeset/new-socks-deny.md
  • .changeset/shaky-phones-mix.md
  • .changeset/social-tools-sniff.md
  • .changeset/spotty-plums-brush.md
  • .changeset/stale-lizards-cheat.md
  • .changeset/swift-planets-juggle.md
  • .changeset/tame-monkeys-make.md
  • .changeset/tender-pans-yawn.md
  • .changeset/thick-banks-relate.md
  • .changeset/vast-worlds-pull.md
  • .changeset/whole-turkeys-swim.md
  • .changeset/yellow-clowns-mate.md
  • .changeset/young-corners-help.md
  • .github/actions/setup/action.yml
  • .github/workflows/formal-verification.yml
  • .github/workflows/release-upgradeable.yml
  • CHANGELOG.md
  • LICENSE
  • contracts/access/AccessControl.sol
  • contracts/access/extensions/AccessControlDefaultAdminRules.sol
  • contracts/access/extensions/IAccessControlDefaultAdminRules.sol
  • contracts/access/manager/IAccessManager.sol
  • contracts/account/Account.sol
  • contracts/account/extensions/draft-AccountERC7579.sol
  • contracts/account/extensions/draft-AccountERC7579Hooked.sol
  • contracts/account/utils/EIP7702Utils.sol
  • contracts/account/utils/draft-ERC4337Utils.sol
  • contracts/account/utils/draft-ERC7579Utils.sol
  • contracts/crosschain/CrosschainLinked.sol
  • contracts/crosschain/ERC7786Recipient.sol
  • contracts/crosschain/README.adoc
  • contracts/crosschain/bridges/BridgeERC20.sol
  • contracts/crosschain/bridges/BridgeERC7802.sol
  • contracts/crosschain/bridges/abstract/BridgeFungible.sol
  • contracts/finance/VestingWallet.sol
  • contracts/governance/Governor.sol
  • contracts/governance/TimelockController.sol
  • contracts/governance/extensions/GovernorStorage.sol
  • contracts/governance/utils/Votes.sol
  • contracts/governance/utils/VotesExtended.sol
  • contracts/interfaces/draft-IERC4337.sol
  • contracts/interfaces/draft-IERC7579.sol
  • contracts/metatx/ERC2771Context.sol
  • contracts/metatx/ERC2771Forwarder.sol
  • contracts/package.json
  • contracts/proxy/ERC1967/ERC1967Proxy.sol
  • contracts/proxy/ERC1967/ERC1967Utils.sol
  • contracts/token/ERC1155/ERC1155.sol
  • contracts/token/ERC1155/extensions/ERC1155Supply.sol
  • contracts/token/ERC1155/extensions/ERC1155URIStorage.sol
  • contracts/token/ERC20/README.adoc
  • contracts/token/ERC20/extensions/ERC20Crosschain.sol
  • contracts/token/ERC20/extensions/ERC20FlashMint.sol
  • contracts/token/ERC20/extensions/ERC20Wrapper.sol
  • contracts/token/ERC20/extensions/ERC4626.sol
  • contracts/token/ERC6909/extensions/ERC6909ContentURI.sol
  • contracts/token/ERC6909/extensions/ERC6909Metadata.sol
  • contracts/token/ERC6909/extensions/ERC6909TokenSupply.sol
  • contracts/token/ERC721/ERC721.sol
  • contracts/token/ERC721/extensions/ERC721Enumerable.sol
  • contracts/token/ERC721/extensions/ERC721URIStorage.sol
  • contracts/utils/Arrays.sol
  • contracts/utils/Base64.sol
  • contracts/utils/Bytes.sol
  • contracts/utils/LowLevelCall.sol
  • contracts/utils/Memory.sol
  • contracts/utils/RLP.sol
  • contracts/utils/RelayedCall.sol
  • contracts/utils/Strings.sol
  • contracts/utils/cryptography/ECDSA.sol
  • contracts/utils/cryptography/MerkleProof.sol
  • contracts/utils/cryptography/MessageHashUtils.sol
  • contracts/utils/cryptography/SignatureChecker.sol
  • contracts/utils/cryptography/TrieProof.sol
  • contracts/utils/cryptography/WebAuthn.sol
  • contracts/utils/cryptography/draft-ERC7739Utils.sol
  • contracts/utils/cryptography/signers/MultiSignerERC7913.sol
  • contracts/utils/cryptography/signers/SignerECDSA.sol
  • contracts/utils/cryptography/signers/SignerEIP7702.sol
  • contracts/utils/cryptography/signers/SignerWebAuthn.sol
  • contracts/utils/cryptography/verifiers/ERC7913WebAuthnVerifier.sol
  • contracts/utils/draft-InteroperableAddress.sol
  • contracts/utils/introspection/ERC165Checker.sol
  • contracts/utils/math/Math.sol
  • contracts/utils/math/SafeCast.sol
  • contracts/utils/structs/Accumulators.sol
  • contracts/utils/structs/CircularBuffer.sol
  • contracts/utils/structs/DoubleEndedQueue.sol
  • contracts/utils/structs/EnumerableMap.sol
  • contracts/utils/structs/EnumerableSet.sol
  • contracts/utils/structs/Heap.sol
  • docs/modules/ROOT/pages/utilities.adoc
  • foundry.toml
  • hardhat.config.js
  • package.json
  • scripts/generate/templates/Arrays.js
  • test/account/AccountWebAuthn.test.js
  • test/crosschain/BridgeERC20.behavior.js
  • test/crosschain/ERC7786Recipient.test.js
  • test/helpers/trie.js
  • test/token/ERC20/extensions/ERC20Crosschain.test.js
  • test/token/ERC6909/extensions/ERC6909ContentURI.test.js
  • test/token/ERC6909/extensions/ERC6909Metadata.test.js
  • test/token/ERC6909/extensions/ERC6909TokenSupply.test.js
  • test/utils/Memory.t.sol
  • test/utils/Memory.test.js
  • test/utils/Strings.test.js
  • test/utils/cryptography/P256.t.sol
  • test/utils/cryptography/RSA.test.js
  • test/utils/cryptography/TrieProof.test.js
  • test/utils/cryptography/WebAuthn.t.sol
  • test/utils/draft-InteroperableAddress.test.js
  • test/utils/introspection/SupportsInterface.behavior.js
💤 Files with no reviewable changes (24)
  • .changeset/khaki-crews-join.md
  • test/account/AccountWebAuthn.test.js
  • .changeset/forty-ads-design.md
  • .changeset/grumpy-cats-brake.md
  • .changeset/fuzzy-lizards-do.md
  • .changeset/bright-webs-create.md
  • .changeset/young-corners-help.md
  • .changeset/full-emus-hear.md
  • .changeset/spotty-plums-brush.md
  • .changeset/social-tools-sniff.md
  • .changeset/vast-worlds-pull.md
  • .changeset/clean-worlds-end.md
  • .changeset/new-socks-deny.md
  • .changeset/shaky-phones-mix.md
  • .changeset/thick-banks-relate.md
  • .changeset/tender-pans-yawn.md
  • .changeset/yellow-clowns-mate.md
  • .changeset/flat-ideas-count.md
  • .changeset/blue-mirrors-agree.md
  • .changeset/stale-lizards-cheat.md
  • .changeset/fluffy-facts-brake.md
  • .changeset/swift-planets-juggle.md
  • .changeset/whole-turkeys-swim.md
  • .changeset/tame-monkeys-make.md

Comment on lines +124 to 125
* * `supported`: true if the returned data indicating the interface is supported
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Doc clarification: supported can be true even when success is false.

The updated comment ("true if the returned data indicating the interface is supported") removes the success coupling, which is technically accurate since the assembly derives supported independently of success. However, a revert with a ≥32-byte payload that happens to be non-zero at offset 0 would yield (false, true), which could surprise callers. All current call sites correctly gate on success && supported, but a future caller relying only on supported could be misled.

Consider clarifying that supported should only be interpreted when success is true:

- * * `supported`: true if the returned data indicating the interface is supported
+ * * `supported`: true if the returned data indicates the interface is supported (only meaningful when `success` is true)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* * `supported`: true if the returned data indicating the interface is supported
*/
* * `supported`: true if the returned data indicates the interface is supported (only meaningful when `success` is true)
*/
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contracts/utils/introspection/ERC165Checker.sol` around lines 124 - 125,
Update the NatSpec in ERC165Checker for the function that returns (bool success,
bool supported) to state explicitly that the `supported` flag is only meaningful
when `success` is true; mention that a failing call can still produce a non-zero
first word in a >=32-byte revert payload yielding (false, true), so callers
should interpret `supported` only when `success` is true (i.e., use `success &&
supported`). Reference the ERC165Checker contract and the function that returns
(success, supported) so future callers understand the correct gating.

Comment on lines +19 to +21
* NOTE: This library uses the PUSH0 opcode that was introduced in the Shanghai hardfork. While this instruction is
* now widely supported, developers using the library on exotic chains should verify that their target chain has
* supports for EIP-3855.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Grammar nit: "has supports for" → "has support for"

Line 21 reads "their target chain has supports for EIP-3855" — "supports" should be the noun "support".

✏️ Proposed fix
- * now widely supported, developers using the library on exotic chains should verify that their target chain has
- * supports for EIP-3855.
+ * now widely supported, developers using the library on exotic chains should verify that their target chain has
+ * support for EIP-3855.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* NOTE: This library uses the PUSH0 opcode that was introduced in the Shanghai hardfork. While this instruction is
* now widely supported, developers using the library on exotic chains should verify that their target chain has
* supports for EIP-3855.
* NOTE: This library uses the PUSH0 opcode that was introduced in the Shanghai hardfork. While this instruction is
* now widely supported, developers using the library on exotic chains should verify that their target chain has
* support for EIP-3855.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contracts/utils/RelayedCall.sol` around lines 19 - 21, Fix the grammar in the
header comment of the RelayedCall.sol library: change the phrase "their target
chain has supports for EIP-3855" to "their target chain has support for
EIP-3855" (update the comment inside the RelayedCall.sol file near the NOTE
about PUSH0/EIP-3855).

Comment on lines +18 to +22
tx
.wait()
.then(receipt =>
this.receiptTrie.put(BlockTries.indexToKeyBytes(tx.index), BlockTries.serializeReceipt(receipt)),
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

ethers.js v6 TransactionResponse.wait() status 0 reverted transaction behavior

💡 Result:

In ethers.js v6, a mined transaction that reverted will have a receipt with status === 0, and the typical behavior when you do:

await tx.wait();

is that it rejects/throws a CALL_EXCEPTION (a CallExceptionError) rather than resolving normally. The thrown error includes the mined receipt (with status 0) on error.receipt. (docs.ethers.org)

So handle it like:

try {
  const receipt = await tx.wait();
  // success; receipt.status should be 1
} catch (e: any) {
  if (e.code === "CALL_EXCEPTION" && e.receipt) {
    const receipt = e.receipt;        // mined receipt
    // receipt.status === 0 (reverted)
  }
  throw e;
}

Notes:

  • status: 0 means the EVM reverted (state changes rolled back, but gas is still paid). (alchemy.com)
  • This “throw on status === 0” is explicitly documented in ethers v5 for TransactionResponse.wait() and matches the v6 CallExceptionError.receipt contract (receipt present when mined + status 0). (docs.ethers.org)

Citations:


🏁 Script executed:

cat -n test/helpers/trie.js | head -40

Repository: OpenZeppelin/openzeppelin-contracts

Length of output: 1769


Use tx.provider.getTransactionReceipt() instead of tx.wait() for receipt-trie construction.

On Line 19, tx.wait() rejects with CALL_EXCEPTION for reverted transactions (status 0). This breaks trie building for valid blocks containing failed transactions, even though their receipts exist and must be included in the receipt trie. Fetch receipts directly by hash to bypass this error and include all receipts regardless of execution status.

🔧 Suggested fix
-            tx
-              .wait()
-              .then(receipt =>
-                this.receiptTrie.put(BlockTries.indexToKeyBytes(tx.index), BlockTries.serializeReceipt(receipt)),
-              ),
+            tx.provider.getTransactionReceipt(tx.hash).then(receipt => {
+              if (receipt == null) {
+                throw new Error(`Missing receipt for tx ${tx.hash}`);
+              }
+              return this.receiptTrie.put(
+                BlockTries.indexToKeyBytes(tx.index),
+                BlockTries.serializeReceipt(receipt),
+              );
+            }),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
tx
.wait()
.then(receipt =>
this.receiptTrie.put(BlockTries.indexToKeyBytes(tx.index), BlockTries.serializeReceipt(receipt)),
),
tx.provider.getTransactionReceipt(tx.hash).then(receipt => {
if (receipt == null) {
throw new Error(`Missing receipt for tx ${tx.hash}`);
}
return this.receiptTrie.put(
BlockTries.indexToKeyBytes(tx.index),
BlockTries.serializeReceipt(receipt),
);
}),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/helpers/trie.js` around lines 18 - 22, Replace the use of tx.wait() when
building the receipt trie with fetching the receipt by hash via the
transaction's provider so reverted transactions don't throw; specifically, in
the block where you call tx.wait() and then
this.receiptTrie.put(BlockTries.indexToKeyBytes(tx.index),
BlockTries.serializeReceipt(receipt)), change to
tx.provider.getTransactionReceipt(tx.hash) and then put the returned receipt
using BlockTries.serializeReceipt so all receipts (including status 0) are
included in receiptTrie.

@Amxx Amxx requested a review from ernestognw February 25, 2026 21:19
@Amxx Amxx merged commit 9fa6e3b into master Feb 26, 2026
24 checks passed
@Amxx Amxx deleted the merge/release-v5.6 branch February 26, 2026 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants