Skip to content

Merge release-v0.3 branch#287

Merged
arr00 merged 25 commits intomasterfrom
merge/release-v0.3
Jan 8, 2026
Merged

Merge release-v0.3 branch#287
arr00 merged 25 commits intomasterfrom
merge/release-v0.3

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot commented Jan 7, 2026

Summary by CodeRabbit

  • New Features

    • Added ERC165 interface support to ERC7984 for enhanced interoperability.
    • Introduced new disclosure request mechanism for encrypted amounts.
  • Bug Fixes

    • Fixed overflow protection in ERC20Wrapper to prevent total supply exceeded errors.
  • Documentation

    • Updated changelog with detailed release notes for versions 0.2.0 and 0.3.1.
  • Chores

    • Updated library version to 0.3.1.
    • Updated dependencies to latest compatible versions.

✏️ Tip: You can customize this high-level summary in your review settings.

github-actions bot and others added 24 commits October 9, 2025 12:49
* Release v0.3.0 (rc)

* Update changelog

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>
* generate versioned docs

* publish docs even on pre-release
* N-05: Named mapping var in `ERC7984ObserverAccess`

* Update contracts/token/ERC7984/extensions/ERC7984ObserverAccess.sol

Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>

---------

Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>
* N-08: constant names are screaming camel case

* fix lint
* Support ERC-165 interface detection on ERC-7984

* update link format

* Add ERC7984 impl changeset

* Update changeset

---------

Co-authored-by: Arr00 <13561405+arr00@users.noreply.github.com>
* M-03: grant allowances to agent in `ERC7984Rwa`

* up
* chore: fhevm-v9

* chore: port all tests for fhevm v9

* Merge pull request #1 from OpenZeppelin/chore/update-disclose-flow

update disclose flow

* Update wrapper contract (#2)

* Update wrapper contract

* fix tests

* fix mock

* update docs

* add changeset

* request id unnecessary

* Update contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol

Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>

* remove unused params

* Update test/token/ERC7984/ERC7984.test.ts

Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>

* `cts` -> `handles`

* `cleartext` -> `cleartextAmount`

* Update test/token/ERC7984/extensions/ERC7984Wrapper.test.ts

Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>

* nit

---------

Co-authored-by: 0xalexbel <alexandre.belhoste@zama.ai>
Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>
* M-11: fix `ERC7984Rwa` docs

* add docs

* Update contracts/token/ERC7984/extensions/ERC7984Rwa.sol
* L-05: Grant allowances in `confidentialAvailable`

* fix doc
…241)

* L-01: `tryDecrease` return initialized value if delta is initialized

* add comment

* Add changeset
* Upgrade to use fhevm contracts v0.9.1

* bump sub package as well
* Release v0.3.0

* Update changelog (#259)

* Update changelog

* Update CHANGELOG.md

Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>

---------

Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>

* remove duplicate entry

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Arr00 <13561405+arr00@users.noreply.github.com>
Co-authored-by: James Toussaint <33313130+james-toussaint@users.noreply.github.com>
* Revert when wrapper full

* up

* simplify and add tests

* update docs

* cei

* add doc

* up

* add custom error and fix tests

* comment clarification

* Rename `_checkTotalSupply` to `_checkConfidentialTotalSupply`

* add changeset

* Update contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol



* docs

---------

Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
#284)

Rename `totalSupply()` to `inferredTotalSuppy()`
* Release v0.3.1

* update changelog

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Arr00 <13561405+arr00@users.noreply.github.com>
@github-actions github-actions bot requested a review from a team as a code owner January 7, 2026 14:03
@netlify
Copy link
Copy Markdown

netlify bot commented Jan 7, 2026

Deploy Preview for confidential-tokens ready!

Name Link
🔨 Latest commit 17920ba
🔍 Latest deploy log https://app.netlify.com/projects/confidential-tokens/deploys/695ed8cac243d000086323f8
😎 Deploy Preview https://deploy-preview-287--confidential-tokens.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 7, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This pull request releases version 0.3.1 of OpenZeppelin Confidential Contracts, featuring a refactored ERC7984 disclosure mechanism, unwrap flow changes in the ERC20 wrapper, ERC165 interface support, dependency updates to @fhevm/solidity v0.9.1, configuration migration from SepoliaConfig to ZamaEthereumConfig across mocks, and storage constant naming standardizations.

Changes

Cohort / File(s) Summary
Changeset Cleanup
.changeset/beige-fans-call.md, .changeset/fast-ravens-lose.md, .changeset/floppy-otters-dance.md, .changeset/floppy-wasps-clap.md, .changeset/fruity-bananas-smile.md, .changeset/new-crews-boil.md, .changeset/public-dolls-lose.md, .changeset/seven-books-dig.md, .changeset/six-maps-follow.md, .changeset/sour-ties-warn.md, .changeset/stupid-fans-bow.md
Deleted changeset files documenting minor version updates and feature descriptions for ERC7984 extensions, FHESafeMath, and related components.
Version & Dependency Updates
package.json, contracts/package.json, docs/antora.yml
Bumped package version from 0.2.0 to 0.3.1; updated @fhevm/solidity from 0.8.0 to 0.9.1, @fhevm/hardhat-plugin to 0.3.0-1, and @zama-fhe/relayer-sdk to 0.3.0-5.
Storage Constant Renames (Naming Convention)
contracts/finance/ERC7821WithExecutor.sol, contracts/finance/VestingWalletCliffConfidential.sol, contracts/finance/VestingWalletConfidential.sol
Renamed private storage location constants from CamelCase to UPPER_SNAKE_CASE (e.g., VestingWalletStorageLocation → VESTING_WALLET_STORAGE_LOCATION) and updated all assembly references.
Config Migration: Sepolia→ZamaEthereum
contracts/mocks/finance/VestingWalletCliffConfidentialMock.sol, contracts/mocks/finance/VestingWalletConfidentialMock.sol, contracts/mocks/finance/VestingWalletConfidentialFactoryMock.sol, contracts/mocks/token/ERC7984ERC20WrapperMock.sol, contracts/mocks/token/ERC7984FreezableMock.sol, contracts/mocks/token/ERC7984Mock.sol, contracts/mocks/token/ERC7984ReceiverMock.sol, contracts/mocks/token/ERC7984RestrictedMock.sol, contracts/mocks/utils/FHESafeMathMock.sol, contracts/mocks/utils/HandleAccessManagerMock.sol, contracts/mocks/utils/HandleAccessManagerUserMock.sol
Replaced SepoliaConfig import/inheritance with ZamaEthereumConfig across all mocks; removed unused import in ERC7984ObserverAccessMock.sol.
ERC7984 Interface & Core Logic
contracts/interfaces/IERC7984.sol, contracts/token/ERC7984/ERC7984.sol
Added IERC165 inheritance to IERC7984 interface; ERC7984 now implements ERC165; added supportsInterface() override; refactored disclosure flow from two-part gateway pattern to requestDiscloseEncryptedAmount() + discloseEncryptedAmount() with new AmountDiscloseRequested event.
ERC7984ERC20Wrapper Unwrap Refactor
contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol
Replaced gateway-based unwrap with unwrapRequests mapping (euint64 → recipient); added UnwrapRequested/UnwrapFinalized events and supply-overflow checks; introduced inferredTotalSupply/maxTotalSupply accessors and _checkConfidentialTotalSupply() guard; refactored finalizeUnwrap signature and flow.
ERC7984Rwa Interface Expansion & Mocks
contracts/interfaces/IERC7984Rwa.sol, contracts/token/ERC7984/extensions/ERC7984Rwa.sol, contracts/mocks/token/ERC7984RwaMock.sol
Removed IERC165 inheritance from IERC7984Rwa; added 16+ new public functions (pause, unpause, blockUser, unblockUser, confidential operations with dual overloads); added AGENT_ROLE constant; refactored force-transfer and mint/burn flows to return amounts and grant FHE allowances; ERC7984RwaMock adds supportsInterface override.
ERC7984 Extensions: Freezable & ObserverAccess
contracts/token/ERC7984/extensions/ERC7984Freezable.sol, contracts/token/ERC7984/extensions/ERC7984ObserverAccess.sol
Added internal _confidentialAvailable() helper to compute available balance without ACL grants; updated confidentialAvailable() and _update() to use internal helper for gating while public API grants ACLs; renamed mapping key in ERC7984ObserverAccess to named parameter style.
Swap Mock & Omnibus Refactor
contracts/mocks/docs/SwapERC7984ToERC20.sol, contracts/token/ERC7984/extensions/ERC7984Omnibus.sol
Renamed SwapConfidentialToERC20 → SwapERC7984ToERC20; refactored swap finalization to use euint64-keyed _receivers mapping and FHE.makePubliclyDecryptable; reordered ACL setup in omnibus transfer.
FHESafeMath & Utilities
contracts/utils/FHESafeMath.sol, contracts/token/ERC7984/utils/ERC7984Utils.sol, contracts/utils/structs/temporary-Checkpoints.sol
Updated FHESafeMath.tryDecrease to return (FHE.eq(delta, 0), 0) for uninitialized oldValue instead of comparison-based logic; updated documentation for ERC7984Utils.checkOnTransferReceived and header comments; no signature changes.
Version Headers & Comments
contracts/finance/VestingWalletConfidentialFactory.sol, contracts/interfaces/IERC7984Receiver.sol, contracts/token/ERC7984/extensions/ERC7984Restricted.sol, contracts/token/ERC7984/extensions/ERC7984Votes.sol
Updated OpenZeppelin Confidential Contracts version references from v0.2.0 to v0.3.0; minor documentation/example removals in ERC7984Restricted.
Test Helpers & ABIs
test/helpers/accounts.ts
Updated ACL ABI source path from @fhevm/core-contracts to @fhevm/host-contracts.
Workflow & Build Config
.github/workflows/docs.yml, scripts/update-docs-branch.js
Changed docs workflow trigger from master to release-v\* branches; refactored update-docs-branch script to detect release branches via regex and dynamically name docs branches as docs-v0.minor.x or docs-vX.x.
Documentation
CHANGELOG.md
Added 0.3.1 entry (2026-01-06) with bug-fix reference to ERC7984ERC20Wrapper overflow protection; expanded 0.2.0 section with detailed subsections for Token, Utils, Governance, Finance, and Misc entries.
Tests: Core ERC7984 & RWA
test/token/ERC7984/ERC7984.test.ts, test/token/ERC7984/extensions/ERC7984Rwa.test.ts, test/token/ERC7984/extensions/ERC7984Wrapper.test.ts
Updated ERC7984 tests to verify ERC165 support, track requester in disclose flow, and replace direct discloseEncryptedAmount with requestDiscloseEncryptedAmount + AmountDiscloseRequested event validation; refactored ERC7984Rwa interface test collection via flatMap; added ERC7984Wrapper tests for max underlying-to-confidential balance checks and introduced publicDecryptAndFinalizeUnwrap helper.
Tests: FHESafeMath
test/utils/FHESafeMath.test.ts
Updated test cases for tryIncrease and tryDecrease to expect explicit result value of 0 instead of undefined for uninitialized input scenarios, triggering decryption validation against concrete expected results.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant ERC7984 as ERC7984<br/>(Smart Contract)
    participant FHE as FHE Library
    participant Decryptor as Public Decryptor
    
    User->>ERC7984: requestDiscloseEncryptedAmount(encryptedAmount)
    ERC7984->>FHE: makePubliclyDecryptable(encryptedAmount)
    ERC7984->>ERC7984: emit AmountDiscloseRequested(encryptedAmount, requester)
    
    Note over Decryptor: Off-chain: Decrypts encryptedAmount<br/>and generates decryptionProof
    
    User->>ERC7984: discloseEncryptedAmount(encryptedAmount, cleartextAmount, decryptionProof)
    ERC7984->>FHE: checkSignatures(handles, abi.encode(cleartextAmount), decryptionProof)
    alt Verification Successful
        ERC7984->>ERC7984: emit AmountDisclosed(encryptedAmount, cleartextAmount)
    else Verification Failed
        ERC7984-->>User: revert
    end
Loading
sequenceDiagram
    actor User
    participant ERC7984ERC20Wrapper as ERC7984ERC20Wrapper<br/>(Smart Contract)
    participant FHE as FHE Library
    participant Decryptor as Public Decryptor
    
    User->>ERC7984ERC20Wrapper: _unwrap(from, to, encryptedAmount)
    ERC7984ERC20Wrapper->>ERC7984ERC20Wrapper: _burn(from, encryptedAmount)
    ERC7984ERC20Wrapper->>ERC7984ERC20Wrapper: _checkConfidentialTotalSupply()
    alt Supply Overflow
        ERC7984ERC20Wrapper-->>User: revert ERC7984TotalSupplyOverflow()
    end
    ERC7984ERC20Wrapper->>FHE: makePubliclyDecryptable(encryptedAmount)
    ERC7984ERC20Wrapper->>ERC7984ERC20Wrapper: _receivers[encryptedAmount] = to
    ERC7984ERC20Wrapper->>ERC7984ERC20Wrapper: emit UnwrapRequested(to, encryptedAmount)
    
    Note over Decryptor: Off-chain: Decrypts encryptedAmount<br/>and generates decryptionProof
    
    User->>ERC7984ERC20Wrapper: finalizeUnwrap(encryptedAmount, cleartextAmount, decryptionProof)
    ERC7984ERC20Wrapper->>ERC7984ERC20Wrapper: lookup recipient from _receivers[encryptedAmount]
    ERC7984ERC20Wrapper->>FHE: checkSignatures(handles, abi.encode(cleartextAmount), decryptionProof)
    alt Verification Successful
        ERC7984ERC20Wrapper->>ERC7984ERC20Wrapper: transfer cleartextAmount \\* rate() underlying tokens to recipient
        ERC7984ERC20Wrapper->>ERC7984ERC20Wrapper: emit UnwrapFinalized(recipient, encryptedAmount, cleartextAmount)
    else Verification Failed
        ERC7984ERC20Wrapper-->>User: revert InvalidUnwrapRequest()
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

ignore-changeset

Suggested reviewers

  • arr00
  • james-toussaint

Poem

🐰 A disclosure blooms, requests now gleam,
Unwraps refined with a decryptor's dream,
ZamaEthereum paths replace the old,
ERC165 truths and storage names bold,
Version three point one—the future takes hold! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Merge release-v0.3 branch' accurately describes the primary action of the pull request, which is a merge operation of the release-v0.3 branch into master.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch merge/release-v0.3

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

Copy link
Copy Markdown
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: 2

🤖 Fix all issues with AI agents
In @contracts/utils/FHESafeMath.sol:
- Around line 11-12: Fix the grammar in the FHESafeMath library comment: replace
the phrase "will may return an uninitialized value" with a correct wording such
as "may return an uninitialized value" (or "will return an uninitialized value"
if you mean certainty) in the top-of-file doc comment so the sentence reads
correctly and conveys intended meaning.

In @test/token/ERC7984/ERC7984.test.ts:
- Around line 540-545: The requester variable is typed as HardhatEthersSigner |
undefined but is assigned this.holder.address (a string) and later used as an
address; change requester to a string type (e.g., string | undefined) or
consistently use a signer object instead—update the declaration for requester
and any places that set or pass it (references: requester, this.holder.address,
and any tests that use requester as an address) so the types match and no
undefined/signer-to-string mismatch remains.
🧹 Nitpick comments (4)
CHANGELOG.md (1)

22-22: Optional: Minor style improvements.

Static analysis suggests two minor style improvements:

  • Line 22: Consider using a synonym for "given" (e.g., "granted" or "provided")
  • Line 25: Consider hyphenating "Real-World Assets" as a compound adjective

These are stylistic nitpicks and can be safely deferred.

Also applies to: 25-25

test/token/ERC7984/extensions/ERC7984Wrapper.test.ts (1)

364-370: Helper function assumes single UnwrapRequested event.

The helper always takes the first event from queryFilter. If multiple unwrap requests exist in the same test context (e.g., from beforeEach setup or prior test steps), this could retrieve the wrong event. Consider filtering by block number or clearing events between tests.

♻️ Suggested improvement
-async function publicDecryptAndFinalizeUnwrap(wrapper: ERC7984ERC20WrapperMock, caller: HardhatEthersSigner) {
-  const [to, amount] = (await wrapper.queryFilter(wrapper.filters.UnwrapRequested()))[0].args;
+async function publicDecryptAndFinalizeUnwrap(wrapper: ERC7984ERC20WrapperMock, caller: HardhatEthersSigner) {
+  const events = await wrapper.queryFilter(wrapper.filters.UnwrapRequested());
+  const [to, amount] = events[events.length - 1].args; // Get the most recent event
contracts/token/ERC7984/extensions/ERC7984Rwa.sol (1)

243-247: Hardcoded function selectors are fragile and error-prone.

The selectors 0x6c9c3c85 and 0x44fd6e40 are computed from function signatures and must be manually updated if function signatures change. Consider using computed selectors for maintainability.

♻️ Suggested improvement
     function _isForceTransfer() private pure returns (bool) {
         return
-            msg.sig == 0x6c9c3c85 || // bytes4(keccak256("forceConfidentialTransferFrom(address,address,bytes32)"))
-            msg.sig == 0x44fd6e40; // bytes4(keccak256("forceConfidentialTransferFrom(address,address,bytes32,bytes)"))
+            msg.sig == this.forceConfidentialTransferFrom.selector ||
+            msg.sig == bytes4(keccak256("forceConfidentialTransferFrom(address,address,bytes32,bytes)"));
     }

Note: The first overload's selector can be obtained via .selector. For the second, you may need to compute it or use a constant.

contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol (1)

200-201: assert for request uniqueness could panic in edge cases.

If two burns somehow produce the same burntAmount handle (extremely unlikely given FHE guarantees), this assert would panic. Consider using require with a custom error for better error handling, though this is likely over-cautious given FHE handle uniqueness.

♻️ Optional: Use require for clearer error handling
-        assert(_unwrapRequests[burntAmount] == address(0));
+        require(_unwrapRequests[burntAmount] == address(0), "Duplicate unwrap handle");
         _unwrapRequests[burntAmount] = to;
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 35a5132 and 14f20de.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (54)
  • .changeset/beige-fans-call.md
  • .changeset/fast-ravens-lose.md
  • .changeset/floppy-otters-dance.md
  • .changeset/floppy-wasps-clap.md
  • .changeset/fruity-bananas-smile.md
  • .changeset/new-crews-boil.md
  • .changeset/public-dolls-lose.md
  • .changeset/seven-books-dig.md
  • .changeset/six-maps-follow.md
  • .changeset/sour-ties-warn.md
  • .changeset/stupid-fans-bow.md
  • .github/workflows/docs.yml
  • CHANGELOG.md
  • contracts/finance/ERC7821WithExecutor.sol
  • contracts/finance/VestingWalletCliffConfidential.sol
  • contracts/finance/VestingWalletConfidential.sol
  • contracts/finance/VestingWalletConfidentialFactory.sol
  • contracts/interfaces/IERC7984.sol
  • contracts/interfaces/IERC7984Receiver.sol
  • contracts/interfaces/IERC7984Rwa.sol
  • contracts/mocks/docs/SwapERC7984ToERC20.sol
  • contracts/mocks/finance/VestingWalletCliffConfidentialMock.sol
  • contracts/mocks/finance/VestingWalletConfidentialFactoryMock.sol
  • contracts/mocks/finance/VestingWalletConfidentialMock.sol
  • contracts/mocks/token/ERC7984ERC20WrapperMock.sol
  • contracts/mocks/token/ERC7984FreezableMock.sol
  • contracts/mocks/token/ERC7984Mock.sol
  • contracts/mocks/token/ERC7984ObserverAccessMock.sol
  • contracts/mocks/token/ERC7984ReceiverMock.sol
  • contracts/mocks/token/ERC7984RestrictedMock.sol
  • contracts/mocks/token/ERC7984RwaMock.sol
  • contracts/mocks/utils/FHESafeMathMock.sol
  • contracts/mocks/utils/HandleAccessManagerMock.sol
  • contracts/mocks/utils/HandleAccessManagerUserMock.sol
  • contracts/package.json
  • contracts/token/ERC7984/ERC7984.sol
  • contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol
  • contracts/token/ERC7984/extensions/ERC7984Freezable.sol
  • contracts/token/ERC7984/extensions/ERC7984ObserverAccess.sol
  • contracts/token/ERC7984/extensions/ERC7984Omnibus.sol
  • contracts/token/ERC7984/extensions/ERC7984Restricted.sol
  • contracts/token/ERC7984/extensions/ERC7984Rwa.sol
  • contracts/token/ERC7984/extensions/ERC7984Votes.sol
  • contracts/token/ERC7984/utils/ERC7984Utils.sol
  • contracts/utils/FHESafeMath.sol
  • contracts/utils/structs/temporary-Checkpoints.sol
  • docs/antora.yml
  • package.json
  • scripts/update-docs-branch.js
  • test/helpers/accounts.ts
  • test/token/ERC7984/ERC7984.test.ts
  • test/token/ERC7984/extensions/ERC7984Rwa.test.ts
  • test/token/ERC7984/extensions/ERC7984Wrapper.test.ts
  • test/utils/FHESafeMath.test.ts
💤 Files with no reviewable changes (12)
  • .changeset/fast-ravens-lose.md
  • .changeset/sour-ties-warn.md
  • .changeset/fruity-bananas-smile.md
  • .changeset/floppy-wasps-clap.md
  • .changeset/floppy-otters-dance.md
  • .changeset/six-maps-follow.md
  • .changeset/new-crews-boil.md
  • .changeset/seven-books-dig.md
  • .changeset/beige-fans-call.md
  • .changeset/stupid-fans-bow.md
  • .changeset/public-dolls-lose.md
  • contracts/mocks/token/ERC7984ObserverAccessMock.sol
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-09-15T14:43:25.644Z
Learnt from: arr00
Repo: OpenZeppelin/openzeppelin-confidential-contracts PR: 186
File: contracts/token/ERC7984/extensions/ERC7984Omnibus.sol:140-167
Timestamp: 2025-09-15T14:43:25.644Z
Learning: In ERC7984Omnibus callback functions like confidentialTransferFromAndCallOmnibus, the encrypted sender and recipient addresses are not passed to the callback recipient - only the standard transfer parameters (omnibusFrom, omnibusTo, amount, data) are passed. The ACL grants for the encrypted addresses are for omnibus event emission and future access, not for callback usage.

Applied to files:

  • contracts/token/ERC7984/extensions/ERC7984Omnibus.sol
  • contracts/mocks/token/ERC7984ReceiverMock.sol
  • contracts/token/ERC7984/utils/ERC7984Utils.sol
  • contracts/token/ERC7984/extensions/ERC7984Freezable.sol
  • contracts/token/ERC7984/ERC7984.sol
  • contracts/token/ERC7984/extensions/ERC7984Rwa.sol
📚 Learning: 2025-09-22T09:21:34.470Z
Learnt from: james-toussaint
Repo: OpenZeppelin/openzeppelin-confidential-contracts PR: 160
File: test/token/ERC7984/extensions/ERC7984Rwa.test.ts:474-479
Timestamp: 2025-09-22T09:21:34.470Z
Learning: In ERC7984Freezable force transfers, the frozen balance is reset to the new balance only when the transferred amount exceeds the available balance (balance - frozen). If the transferred amount is within the available balance, the frozen amount remains unchanged. This is implemented via FHE.select(FHE.gt(encryptedAmount, confidentialAvailable(account)), confidentialBalanceOf(account), frozen).

Applied to files:

  • contracts/token/ERC7984/extensions/ERC7984Omnibus.sol
  • test/token/ERC7984/ERC7984.test.ts
  • contracts/token/ERC7984/extensions/ERC7984Freezable.sol
  • contracts/token/ERC7984/ERC7984.sol
  • contracts/interfaces/IERC7984Rwa.sol
  • contracts/mocks/docs/SwapERC7984ToERC20.sol
  • contracts/mocks/token/ERC7984FreezableMock.sol
  • contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol
  • contracts/token/ERC7984/extensions/ERC7984Rwa.sol
📚 Learning: 2025-09-22T09:21:34.470Z
Learnt from: james-toussaint
Repo: OpenZeppelin/openzeppelin-confidential-contracts PR: 160
File: test/token/ERC7984/extensions/ERC7984Rwa.test.ts:474-479
Timestamp: 2025-09-22T09:21:34.470Z
Learning: For force transfers in ERC7984Freezable, the frozen balance should be reset to the new balance if the transfer amount exceeded the available balance. If the transfer amount was within the available balance, the frozen amount behavior needs clarification from the user.

Applied to files:

  • contracts/token/ERC7984/extensions/ERC7984Freezable.sol
  • contracts/token/ERC7984/ERC7984.sol
  • contracts/mocks/token/ERC7984FreezableMock.sol
  • contracts/token/ERC7984/extensions/ERC7984Rwa.sol
🧬 Code graph analysis (3)
test/helpers/accounts.ts (1)
hardhat/remappings.js (1)
  • fs (1-1)
test/token/ERC7984/extensions/ERC7984Rwa.test.ts (1)
test/helpers/interface.ts (1)
  • getFunctions (4-8)
test/token/ERC7984/ERC7984.test.ts (1)
test/helpers/interface.ts (2)
  • getFunctions (4-8)
  • getInterfaceId (10-15)
🪛 LanguageTool
CHANGELOG.md

[style] ~22-~22: Try using a synonym here to strengthen your writing.
Context: ... each account to add an observer who is given access to their transfer and balance am...

(GIVE_PROVIDE)


[uncategorized] ~25-~25: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...f ERC7984, that supports confidential Real World Assets (RWAs). ([#160](https://github.c...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: boostsecurity - boostsecurityio/semgrep-pro
🔇 Additional comments (68)
contracts/token/ERC7984/utils/ERC7984Utils.sol (2)

2-2: Header comment updated correctly.

The version metadata is now aligned with the v0.3.0 release. The full file path is also included for clarity.


19-20: Documentation clarification is helpful.

The updated comment now explicitly documents the refund behavior when the callback returns false. This aligns the documentation with standard callback patterns and makes the expected behavior clear to callers.

Please verify that all ERC7984 transfer implementations that use checkOnTransferReceived properly handle the false return value by attempting to refund the from address as documented.

contracts/token/ERC7984/extensions/ERC7984ObserverAccess.sol (2)

2-2: LGTM! Version header updated correctly.

The header comment now reflects the v0.3.0 version, aligning with this release.


14-14: LGTM! Named mapping key improves readability.

Adding the account identifier to the mapping key is a best practice that enhances code documentation without any functional changes.

contracts/token/ERC7984/extensions/ERC7984Restricted.sol (3)

2-2: LGTM: Header comment addition.

The addition of the OpenZeppelin Confidential Contracts header with version tracking is good practice for maintaining library version information.


54-54: LGTM: English spelling standardization.

The standardization to American English spelling ("behavior" instead of "behaviour") improves consistency in the documentation.


86-86: LGTM: Corrected error reference in documentation.

The doc comment now correctly references {UserRestricted} (defined at line 30) instead of the incorrect {ERC20Restricted}. This improves documentation accuracy and helps developers understand the actual revert error.

contracts/mocks/utils/FHESafeMathMock.sol (1)

4-4: LGTM! Configuration migration looks correct.

The migration from SepoliaConfig to ZamaEthereumConfig aligns with the broader configuration update across the codebase and introduces no behavioral changes to the mock contract.

Also applies to: 8-8

contracts/utils/FHESafeMath.sol (1)

34-43: Improved edge-case handling for uninitialized values.

The updated logic in tryDecrease now correctly handles the case where oldValue is uninitialized but delta is initialized. When attempting to subtract an initialized value from an uninitialized value (0), the function now:

  • Returns success only if delta is 0 (since 0 - 0 = 0 is valid)
  • Returns an explicit 0 instead of an uninitialized value

This is more semantically consistent with the operation's intent.

test/utils/FHESafeMath.test.ts (1)

64-67: LGTM! Test expectations updated to match new behavior.

The test cases have been correctly updated to expect an explicit 0 result instead of an undefined value when oldValue is uninitialized in tryDecrease. This aligns with the implementation changes in FHESafeMath.sol where the function now returns FHE.asEuint64(0) instead of leaving the result uninitialized.

docs/antora.yml (1)

3-3: LGTM!

Version bump to 0.3 aligns with the broader release and is consistent with the contract header updates to v0.3.0.

.github/workflows/docs.yml (1)

5-5: Verify the workflow trigger change is intentional.

The docs workflow will no longer trigger on pushes to master. It will only build docs when pushing to release-v* branches. Ensure this aligns with the intended documentation release workflow and that docs are still properly published when releases are merged to master.

contracts/utils/structs/temporary-Checkpoints.sol (1)

2-2: LGTM!

Header version update to v0.3.0 is consistent with the release. No functional changes to the Checkpoints library implementation.

contracts/interfaces/IERC7984Receiver.sol (1)

2-2: LGTM!

Header version and filename reference updated appropriately for v0.3.0. The interface signature remains correct for the ERC7984 receiver callback pattern.

contracts/mocks/token/ERC7984FreezableMock.sol (2)

5-5: LGTM!

Config import migration from SepoliaConfig to ZamaEthereumConfig is consistent with the broader mock updates across the repository.


34-38: The use of _confidentialAvailable is correct.

The internal method _confidentialAvailable is properly defined in ERC7984Freezable with the signature function _confidentialAvailable(address account) internal virtual returns (euint64), and ERC7984FreezableMock inherits from this contract. The change from confidentialAvailable(account) to _confidentialAvailable(account) is valid and aligns with the internal balance calculation pattern.

contracts/finance/VestingWalletConfidentialFactory.sol (1)

2-2: LGTM!

Header version update to v0.3.0 is consistent with the release. The factory implementation for confidential vesting wallets remains unchanged and correct.

contracts/token/ERC7984/extensions/ERC7984Votes.sol (1)

2-2: LGTM!

Header version and path reference updated appropriately for v0.3.0. The ERC7984Votes extension implementation for confidential voting remains correct.

contracts/finance/ERC7821WithExecutor.sol (1)

17-19: LGTM! Storage constant naming aligned with Solidity conventions.

The rename to ERC7821_WITH_EXECUTOR_STORAGE_LOCATION follows the idiomatic SCREAMING_SNAKE_CASE convention for constants, eliminating the need for the previous solhint-disable directive. The storage slot value and assembly usage remain correct.

Also applies to: 40-44

contracts/package.json (1)

34-37: Version bump and peer dependency update look correct.

The @fhevm/solidity peer dependency is pinned to exactly 0.9.1 while other peer dependencies use caret ranges (^5.4.0). This is likely intentional given FHE compatibility requirements, but consumers will need to use exactly this version.

scripts/update-docs-branch.js (2)

30-35: Docs branch naming logic looks correct.

The conditional logic correctly handles the 0.x series (docs-v0.{minor}.x) separately from major versions (docs-v{major}.x), which aligns with semantic versioning conventions where 0.x versions may have breaking changes between minor versions.


44-46: No changes needed. The Set destructuring at line 45 works correctly in JavaScript—when destructuring a Set via its iterator with [first, ...rest], the rest operator correctly produces an array with the remaining elements. The code properly detects multiple unique matching branches by checking if others.length > 0 after deduplication. This approach is sound and idiomatic.

contracts/token/ERC7984/extensions/ERC7984Freezable.sol (2)

34-49: Good refactoring separating ACL grants from internal balance calculation.

The split between confidentialAvailable (public, grants ACLs) and _confidentialAvailable (internal, no ACLs) is a clean separation of concerns. This avoids unnecessary gas costs from ACL grants during internal gating operations in _update.


68-74: Internal gating correctly uses _confidentialAvailable.

The _update function now uses the internal _confidentialAvailable to avoid granting ACL allowances during balance checks. The gating logic remains correct: if encryptedAmount > unfrozen, the transfer amount is set to 0.

contracts/interfaces/IERC7984.sol (2)

6-9: LGTM! ERC165 inheritance enables standard interface discovery.

Extending IERC165 allows callers to use supportsInterface to detect ERC7984 support, following established Ethereum interface discovery patterns. This is a backwards-compatible addition.


36-37: Documentation updated with ERC-7572 reference.

The contractURI() documentation now includes a direct link to the ERC-7572 specification, improving discoverability.

test/helpers/accounts.ts (1)

20-22: ACL ABI path requires actual dependency installation to verify.

The code references node_modules/@fhevm/host-contracts/artifacts/contracts/ACL.json, but this path cannot be verified in the sandbox environment where node_modules is not available. While the package.json lists the expected dependencies (@fhevm/hardhat-plugin 0.3.0-1, @fhevm/solidity 0.9.1), actual verification that the ACL.json file exists at this path and exports the correct ABI structure requires running npm install in a non-sandbox environment.

package.json (1)

48-49: @zama-fhe/relayer-sdk 0.3.0-5 is the officially required minimum version.

According to Zama's documentation, @zama-fhe/relayer-sdk >= 0.3.0-5 is required, so using 0.3.0-5 is not a stability concern but the expected version for this release. However, @fhevm/hardhat-plugin 0.3.0-1 remains a prerelease version without a stable 0.3.0 release on npm—confirm this is intentional for the 0.3.1 release.

Likely an incorrect or invalid review comment.

contracts/finance/VestingWalletConfidential.sol (2)

2-2: LGTM: Version header updated to v0.3.0.

The OpenZeppelin Confidential Contracts version header has been correctly updated to reflect the new release.


37-38: LGTM: Storage constant standardized to UPPER_SNAKE_CASE.

The storage location constant has been renamed from VestingWalletStorageLocation to VESTING_WALLET_STORAGE_LOCATION, following Solidity naming conventions for constants. The assembly reference has been correctly updated, and the storage slot hash remains unchanged, ensuring no impact on existing storage layout.

Also applies to: 138-138

contracts/mocks/token/ERC7984RwaMock.sol (2)

6-6: LGTM: Import added to support interface override.

The ERC7984 import is necessary for the supportsInterface override declaration.


20-22: LGTM: Standard diamond inheritance resolution.

The supportsInterface override correctly resolves the diamond problem by explicitly specifying both parent contracts and delegating to super. This ensures proper interface detection for both ERC7984 and ERC7984Rwa interfaces.

contracts/token/ERC7984/extensions/ERC7984Omnibus.sol (2)

2-2: LGTM: Version header updated to v0.3.0.


192-207: LGTM: ACL ordering correctly handles transfer flow.

The ACL setup is properly sequenced:

  1. Sender/recipient ACLs established before transfer (lines 192-198)
  2. Transfer executed to get actual transferred amount (line 200)
  3. Transferred amount ACLs set up post-transfer (lines 202-204)
  4. Event emitted with all encrypted values properly accessible (line 206)

This ordering ensures ACLs are available when needed while accounting for the fact that the actual transferred amount may differ from the requested amount.

contracts/finance/VestingWalletCliffConfidential.sol (2)

2-2: LGTM: Version header updated to v0.3.0.


19-20: LGTM: Storage constant standardized to UPPER_SNAKE_CASE.

The storage location constant follows the same naming convention update as other vesting contracts. The assembly reference is correctly updated, and the storage slot hash remains unchanged, preserving the existing storage layout.

Also applies to: 69-69

contracts/mocks/token/ERC7984ERC20WrapperMock.sol (1)

4-4: Configuration import is correct and compatible with @fhevm/solidity v0.9.1.

ZamaEthereumConfig is the unified configuration export introduced in @fhevm/solidity v0.9.1 to replace SepoliaConfig. The import path and contract inheritance are correctly implemented.

contracts/mocks/finance/VestingWalletConfidentialMock.sol (1)

4-4: LGTM! Consistent config migration.

The migration to ZamaEthereumConfig is consistent with the broader configuration changes in this PR.

Also applies to: 7-7

contracts/mocks/token/ERC7984ReceiverMock.sol (1)

4-4: LGTM! Config migration applied correctly.

The switch to ZamaEthereumConfig follows the same pattern as other mock contracts in this PR.

Also applies to: 8-8

contracts/mocks/utils/HandleAccessManagerMock.sol (1)

4-4: LGTM! Config migration consistent.

The configuration change aligns with the broader migration to ZamaEthereumConfig across all mock contracts.

Also applies to: 8-8

contracts/mocks/token/ERC7984Mock.sol (1)

5-5: Migration to ZamaEthereumConfig is consistent and complete.

The change from SepoliaConfig to ZamaEthereumConfig aligns with the @fhevm/solidity v0.9.1 dependency and is applied uniformly across all mock contracts in the repository (11 contracts total). All claims in the review are verified as correct.

Recommend running the test suite to ensure ERC7984Mock and its dependent tests pass with the new configuration.

test/token/ERC7984/extensions/ERC7984Rwa.test.ts (1)

25-30: No change needed—interface composition is correct and consistent with contract implementation.

The pattern using [IERC7984__factory, IERC165__factory] is already established in the base ERC7984.test.ts (line 56) and correctly reflects how the contract hierarchy works. Both ERC7984 and ERC7984Rwa inherit from ERC165 and their supportsInterface implementations delegate through the inheritance chain, which means they support the combined interface ID of IERC7984 + IERC165 functions. The test expectations align with the contract's actual behavior where supportsInterface returns true for IERC7984, IERC165, and (for ERC7984Rwa) IERC7984Rwa interface IDs.

contracts/mocks/token/ERC7984RestrictedMock.sol (1)

5-5: LGTM: Config migration is consistent.

The migration to ZamaEthereumConfig follows the same pattern as other mocks in this PR. The implementation logic remains unchanged.

Also applies to: 9-9

CHANGELOG.md (2)

4-9: LGTM: Clear bug fix documentation.

The v0.3.1 changelog entry appropriately documents the overflow protection fix in ERC7984ERC20Wrapper.


10-31: Documentation expanded appropriately.

The v0.3.0 changelog provides comprehensive coverage of the token and utility changes, including ERC165 support, new extensions, and FHESafeMath enhancements.

contracts/mocks/finance/VestingWalletCliffConfidentialMock.sol (1)

4-4: LGTM: Consistent config migration.

The config update is consistent with the project-wide migration pattern.

Also applies to: 7-7

contracts/mocks/finance/VestingWalletConfidentialFactoryMock.sol (2)

4-4: LGTM: Config migration follows established pattern.

The import and inheritance updates align with the project-wide migration to ZamaEthereumConfig.

Also applies to: 10-10, 49-53


68-68: No changes needed. The code at line 68 correctly uses ZamaConfig.getEthereumCoprocessorConfig(), which aligns with the contract's inheritance of ZamaEthereumConfig. No evidence exists of prior Sepolia configuration usage or any recent change between config types. The implementation is consistent with test usage and operates as intended.

Likely an incorrect or invalid review comment.

contracts/mocks/utils/HandleAccessManagerUserMock.sol (1)

4-4: Config migration to ZamaEthereumConfig is complete and consistent across all mock contracts.

The migration is clean and fully applied. All 11 mock contracts now use ZamaEthereumConfig imported from "@fhevm/solidity/config/ZamaConfig.sol" with no remaining SepoliaConfig references. Verify that this config change aligns with your deployment targets and doesn't break existing tests.

test/token/ERC7984/extensions/ERC7984Wrapper.test.ts (4)

85-106: Good coverage for max amount wrapping scenario.

The test correctly validates that the maximum underlying balance (derived from maxTotalSupply * rate) wraps successfully and results in the expected confidential balance.


108-124: Overflow protection test looks correct.

The test properly verifies that depositing beyond maxTotalSupply reverts with ERC7984TotalSupplyOverflow. The two-step approach (deposit max, then try to deposit more) is a good way to test boundary conditions.


283-312: Good coverage for invalid signature scenario.

The test correctly simulates a corrupted decryption proof by truncating it. Using .to.be.reverted without a specific error is acceptable here since the revert comes from the FHE library.


314-318: LGTM!

The test correctly verifies that finalizing a non-existent unwrap request reverts with InvalidUnwrapRequest.

test/token/ERC7984/ERC7984.test.ts (2)

54-67: ERC165 interface support tests look good.

The tests correctly verify that the token supports both IERC7984 and IERC165 interfaces, and returns false for an unsupported interface ID. The use of helper functions getFunctions and getInterfaceId keeps the test clean.


596-619: afterEach pattern for disclosure verification is well-structured.

The afterEach correctly:

  1. Skips if no expected values are set
  2. Validates the AmountDiscloseRequested event args
  3. Performs public decryption and verifies the AmountDisclosed event

This pattern ensures consistent verification across all disclosure tests.

contracts/token/ERC7984/ERC7984.sol (3)

69-72: ERC165 implementation is correct.

The supportsInterface correctly returns true for IERC7984 interface ID and delegates to super.supportsInterface for IERC165 support.


201-216: requestDiscloseEncryptedAmount implementation looks correct.

The function properly:

  1. Validates caller has access to the encrypted amount
  2. Makes the value publicly decryptable
  3. Emits the AmountDiscloseRequested event

218-235: discloseEncryptedAmount is permissionless - consider access control.

The function can be called by anyone with valid decryption proof, even without prior requestDiscloseEncryptedAmount. While the NatSpec notes this, consider whether this is intentional. An attacker could potentially disclose amounts they obtained proofs for through other means.

If this is intentional (e.g., allowing off-chain signature collection), the design is acceptable. If disclosure should be tied to a prior request, consider tracking requests and validating them here.

contracts/token/ERC7984/extensions/ERC7984Rwa.sol (3)

22-33: Comprehensive documentation for AGENT_ROLE.

The NatSpec clearly documents the capabilities granted by the agent role, which is helpful for auditors and developers.


51-56: supportsInterface override is correctly simplified.

The function now only checks for IERC7984Rwa interface and delegates to the parent chain, which already includes IERC7984 and IERC165 support.


94-96: Implementation is correct—no action required.

The semantics of _resetUser properly unblock the user as expected. _resetUser sets the restriction to DEFAULT (the unblocked state in the blocklist model), which is the correct inverse of _blockUser (which sets BLOCKED). Using _allowUser instead would be semantically incorrect, as it sets the restriction to ALLOWED, which is an explicit allowlist state rather than an unblocked state.

contracts/mocks/docs/SwapERC7984ToERC20.sol (2)

12-12: Using euint64 as mapping key relies on handle uniqueness.

The mapping euint64 amount => address assumes each amountTransferred handle is unique. This should be true since _fromToken.confidentialTransferFrom returns a new encrypted handle per call, but this is an implicit dependency on FHE implementation behavior.

Confirm that confidentialTransferFrom always returns a unique handle for the transferred amount, even if the cleartext values are identical across different calls.


30-42: finalizeSwap allows anyone to finalize - verify this is intentional.

The function is public and can be called by anyone with a valid proof. This is acceptable if finalization is meant to be permissionless (e.g., relayer-friendly), but the original sender has no control over when finalization occurs.

contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol (3)

177-181: Overflow check timing may allow brief over-supply.

_checkConfidentialTotalSupply() is called in _update before super._update, but inferredTotalSupply() reads the underlying balance which is already updated by wrap() before _mint() is called. This ordering is correct.


113-133: finalizeUnwrap implementation is correct and secure.

The function properly:

  1. Validates the unwrap request exists
  2. Deletes the request before external calls (CEI pattern)
  3. Verifies the decryption proof
  4. Transfers underlying tokens and emits event

161-163: Documentation clearly warns about inferredTotalSupply limitations.

The NatSpec correctly notes that the value can be inflated by direct transfers and lags compared to confidentialTotalSupply. This is important context for consumers.

contracts/interfaces/IERC7984Rwa.sol (2)

9-9: Interface inheritance correctly simplified.

Removing IERC165 from IERC7984Rwa is correct since IERC7984 now extends IERC165. This avoids diamond inheritance issues and keeps the hierarchy clean.


10-62: Interface definition is comprehensive and well-documented.

All public functions are properly declared with NatSpec comments. The interface correctly includes both overloads for functions that accept either euint64 or externalEuint64 with proof.

Comment on lines +11 to +12
* NOTE: An uninitialized `euint64` value (equivalent to euint64.wrap(bytes32(0))) is evaluated as 0.
* This library will may return an uninitialized value if all inputs are uninitialized.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix grammatical error in documentation.

The phrase "will may return" is grammatically incorrect.

📝 Proposed fix
- * This library will may return an uninitialized value if all inputs are uninitialized.
+ * This library may return an uninitialized value if all inputs are uninitialized.
📝 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: An uninitialized `euint64` value (equivalent to euint64.wrap(bytes32(0))) is evaluated as 0.
* This library will may return an uninitialized value if all inputs are uninitialized.
* NOTE: An uninitialized `euint64` value (equivalent to euint64.wrap(bytes32(0))) is evaluated as 0.
* This library may return an uninitialized value if all inputs are uninitialized.
🤖 Prompt for AI Agents
In @contracts/utils/FHESafeMath.sol around lines 11 - 12, Fix the grammar in the
FHESafeMath library comment: replace the phrase "will may return an
uninitialized value" with a correct wording such as "may return an uninitialized
value" (or "will return an uninitialized value" if you mean certainty) in the
top-of-file doc comment so the sentence reads correctly and conveys intended
meaning.

Comment on lines +540 to +545
let requester: HardhatEthersSigner | undefined;

beforeEach(async function () {
expectedAmount = undefined;
expectedHandle = undefined;
requester = undefined;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

requester variable type allows undefined assignment but is later used as address.

The variable requester is typed as HardhatEthersSigner | undefined but is assigned this.holder.address (a string) on line 553. This type mismatch could cause issues.

🔧 Suggested fix
-    let requester: HardhatEthersSigner | undefined;
+    let requester: string | undefined;
📝 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
let requester: HardhatEthersSigner | undefined;
beforeEach(async function () {
expectedAmount = undefined;
expectedHandle = undefined;
requester = undefined;
let requester: string | undefined;
beforeEach(async function () {
expectedAmount = undefined;
expectedHandle = undefined;
requester = undefined;
🤖 Prompt for AI Agents
In @test/token/ERC7984/ERC7984.test.ts around lines 540 - 545, The requester
variable is typed as HardhatEthersSigner | undefined but is assigned
this.holder.address (a string) and later used as an address; change requester to
a string type (e.g., string | undefined) or consistently use a signer object
instead—update the declaration for requester and any places that set or pass it
(references: requester, this.holder.address, and any tests that use requester as
an address) so the types match and no undefined/signer-to-string mismatch
remains.

@arr00 arr00 merged commit 7defe3e into master Jan 8, 2026
15 of 16 checks passed
@arr00 arr00 deleted the merge/release-v0.3 branch January 8, 2026 18:05
@coderabbitai coderabbitai bot mentioned this pull request Feb 4, 2026
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.

2 participants