Skip to content

Conversation

@arr00
Copy link
Contributor

@arr00 arr00 commented Aug 20, 2025

Closes #184

Summary by Sourcery

Add ERC7984Restricted extension for managing user transfer restrictions in ERC7984 tokens, accompanied by a mock implementation, comprehensive tests, and a changeset entry.

New Features:

  • Introduce ERC7984Restricted extension with DEFAULT, BLOCKED, and ALLOWED user states to enforce restrictions on transfers, minting, and burning.

Enhancements:

  • Provide ERC7984RestrictedMock contract to support testing of the restriction logic.

Tests:

  • Add end-to-end tests covering restriction management and restricted behavior of transfer, confidentialTransferFrom, mint, and burn operations under different user statuses.

Chores:

  • Add changeset for ERC7984Restricted extension release.

Summary by CodeRabbit

  • New Features
    • Introduced ERC7984Restricted: per-account transfer restrictions (DEFAULT, BLOCKED, ALLOWED) with events and error reporting to govern transfers, minting, and burning.
  • Documentation
    • Updated token extensions guide to include ERC7984Restricted and clarified wording for existing extensions.
  • Tests
    • Added comprehensive tests covering restriction states, event emissions, and enforcement across transfers, transferFrom, mint, and burn.
  • Chores
    • Added release entry and testing mock to support the new extension.

@netlify
Copy link

netlify bot commented Aug 20, 2025

Deploy Preview for confidential-tokens ready!

Name Link
🔨 Latest commit f29aeb7
🔍 Latest deploy log https://app.netlify.com/projects/confidential-tokens/deploys/68b08c5f7d8e4d0008261fd6
😎 Deploy Preview https://deploy-preview-182--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.

@arr00 arr00 marked this pull request as ready for review August 21, 2025 18:33
@arr00 arr00 requested a review from a team as a code owner August 21, 2025 18:33
@arr00 arr00 requested a review from james-toussaint August 25, 2025 17:51
@@ -0,0 +1,94 @@
// SPDX-License-Identifier: MIT
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not something like:

abstract contract Restricted {
    enum Restriction {
        DEFAULT, // User has no explicit restriction
        BLOCKED, // User is explicitly blocked
        ALLOWED // User is explicitly allowed
    }

    // [...]
}
abstract contract ERC20Restricted is ERC20, Restricted {
    function _update(address from, address to, uint256 value) internal virtual override {
        if (from != address(0)) _checkRestriction(from); // Not minting
        if (to != address(0)) _checkRestriction(to); // Not burning
        super._update(from, to, value);
    }
}
abstract contract ERC7984Restricted is ERC7984, Restricted {
    function _update(address from, address to, euint64 value) internal virtual override returns (euint64) {
        if (from != address(0)) _checkRestriction(from); // Not minting
        if (to != address(0)) _checkRestriction(to); // Not burning
        return super._update(from, to, value);
    }
}

considering core restriction behavior is no related here to confidentiality
?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I suggested this to @ernestognw, and he preferred to keep them separate for now. But agree that would be a good reuse of code.

@arr00
Copy link
Contributor Author

arr00 commented Aug 26, 2025

@sourcery-ai review

@SourceryAI
Copy link

Reviewer's Guide

This PR introduces the ERC7984Restricted extension to add per-account transfer restrictions (DEFAULT, BLOCKED, ALLOWED) into ERC7984 tokens, integrates restriction checks into core operations, provides a mock for testing, includes comprehensive E2E tests for various restriction scenarios, and updates documentation and release notes.

Sequence diagram for restricted transfer operation

sequenceDiagram
    participant Sender
    participant ERC7984Restricted
    participant Receiver
    Sender->>ERC7984Restricted: transfer(to, amount)
    ERC7984Restricted->>ERC7984Restricted: _checkRestriction(Sender)
    ERC7984Restricted->>ERC7984Restricted: _checkRestriction(Receiver)
    ERC7984Restricted->>ERC7984Restricted: _update(Sender, Receiver, amount)
    ERC7984Restricted-->>Sender: Transfer success or revert (UserRestricted)
Loading

Entity relationship diagram for user restriction states

erDiagram
    USER {
        address id
        enum restriction
    }
    RESTRICTION {
        string state
    }
    USER ||--|{ RESTRICTION : has
    RESTRICTION {
        string DEFAULT
        string BLOCKED
        string ALLOWED
    }
Loading

File-Level Changes

Change Details Files
Implement ERC7984Restricted extension
  • Define Restriction enum, mapping, and getter
  • Implement isUserAllowed and override _update to enforce restrictions
  • Add internal methods (_blockUser/_allowUser/_resetUser) with event emission
  • Introduce UserRestricted error and UserRestrictionsUpdated event
contracts/token/ERC7984/extensions/ERC7984Restricted.sol
Provide mock contract for restricted tokens
  • Create ERC7984RestrictedMock inheriting the extension
  • Expose mint, burn, and transfer wrappers using FHE conversions
contracts/mocks/token/ERC7984RestrictedMock.sol
Add end-to-end tests for restriction logic
  • Cover default, allowed, blocked, and reset states
  • Test transfer, confidentialTransferFrom, mint, and burn under restrictions
  • Verify event emissions and no-op behavior on unchanged restrictions
test/token/ERC7984/extensions/ERC7984Restricted.test.ts
Update documentation and release notes
  • Document the extension in README.adoc
  • Add changeset entry for ERC7984Restricted release
contracts/token/README.adoc
.changeset/fruity-bananas-smile.md

Assessment against linked issues

Issue Objective Addressed Explanation
#184 Implement an extension for ERC7984 that provides account-level restrictions for transferring and receiving tokens.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@SourceryAI SourceryAI left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments

### Comment 1
<location> `contracts/token/ERC7984/extensions/ERC7984Restricted.sol:91` </location>
<code_context>
+    }
+
+    /// @dev Checks if a user account is restricted. Reverts with {ERC20Restricted} if so.
+    function _checkRestriction(address account) internal view virtual {
+        require(isUserAllowed(account), UserRestricted(account));
+    }
+}
</code_context>

<issue_to_address>
Custom error is used in a require statement, which may not provide optimal revert data.

Use 'revert UserRestricted(account);' instead to ensure the error selector and arguments are returned, improving error handling and reducing gas costs.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
    function _checkRestriction(address account) internal view virtual {
        require(isUserAllowed(account), UserRestricted(account));
    }
=======
    function _checkRestriction(address account) internal view virtual {
        if (!isUserAllowed(account)) {
            revert UserRestricted(account);
        }
    }
>>>>>>> REPLACE

</suggested_fix>

### Comment 2
<location> `test/token/ERC7984/extensions/ERC7984Restricted.test.ts:70` </location>
<code_context>
+  });
+
+  describe('restricted token operations', function () {
+    describe('transfer', function () {
+      it('allows transfer when sender and recipient have DEFAULT restriction', async function () {
+        await this.token.connect(this.holder).transfer(this.recipient, initialSupply);
+      });
</code_context>

<issue_to_address>
Consider adding a test for transferring to self.

Please add a test where the sender and recipient are the same address, covering various restriction states, to verify correct contract behavior.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
  describe('restricted token operations', function () {
=======
  describe('restricted token operations', function () {
    describe('transfer to self', function () {
      it('allows transfer to self when restriction is DEFAULT', async function () {
        // Ensure holder has DEFAULT restriction
        await this.token.$_setUserRestriction(this.holder.address, 0); // 0 = DEFAULT
        await expect(
          this.token.connect(this.holder).transfer(this.holder.address, initialSupply)
        ).to.not.be.reverted;
      });

      it('reverts transfer to self when restriction is BLOCKED', async function () {
        // Set holder to BLOCKED restriction
        await this.token.$_blockUser(this.holder.address); // BLOCKED
        await expect(
          this.token.connect(this.holder).transfer(this.holder.address, initialSupply)
        ).to.be.revertedWith('ERC7984: sender is blocked');
      });
    });
>>>>>>> REPLACE

</suggested_fix>

Hi @arr00! 👋

Thanks for trying out Sourcery by commenting with @sourcery-ai review! 🚀

Install the sourcery-ai bot to get automatic code reviews on every pull request ✨

Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

import {FHE, euint64, externalEuint64} from "@fhevm/solidity/lib/FHE.sol";
import {ERC7984Restricted} from "../../token/ERC7984/extensions/ERC7984Restricted.sol";

abstract contract ERC7984RestrictedMock is ERC7984Restricted, SepoliaConfig {
Copy link
Contributor

Choose a reason for hiding this comment

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

How about adding another mock/tests for testing allowlist.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As in override isUserAllowed and test with a different config? I don't think that's necessary.

Copy link
Contributor

Choose a reason for hiding this comment

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

Some ways to test what suggests our doc yes:

     * function isUserAllowed(address account) public view virtual override returns (bool) {
     *     return getRestriction(account) == Restriction.ALLOWED;
     * }

but ok

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

coderabbitai bot commented Aug 28, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Introduces ERC7984Restricted extension adding per-account transfer restrictions to ERC7984; adds an abstract mock for testing, updates token README to list the extension, includes a changeset entry, and adds tests covering restriction states, events, transfers, transferFrom, mint, and burn.

Changes

Cohort / File(s) Summary
New restriction extension
contracts/token/ERC7984/extensions/ERC7984Restricted.sol
Adds ERC7984Restricted with Restriction enum (DEFAULT, BLOCKED, ALLOWED), UserRestrictionUpdated event, UserRestricted error; overrides _update to enforce restrictions; exposes getRestriction and isUserAllowed; internal APIs _setRestriction, _blockUser, _allowUser, _resetUser, and _checkRestriction.
Mock for testing
contracts/mocks/token/ERC7984RestrictedMock.sol
Adds abstract mock extending ERC7984Restricted and SepoliaConfig; internal wrappers _mint/_burn using FHE.asEuint64; public transfer(address to, uint64 amount) calling _transfer.
Tests
test/token/ERC7984/extensions/ERC7984Restricted.test.ts
Adds tests for restriction management and events; verifies transfer, transferFrom (encrypted input), mint, and burn under DEFAULT/ALLOWED/BLOCKED states and appropriate reverts (UserRestricted).
Docs
contracts/token/README.adoc
Adds ERC7984Restricted to extensions list and updates phrasing for existing extensions.
Release metadata
.changeset/fruity-bananas-smile.md
Adds changeset entry noting new ERC7984Restricted contract and minor release for the package.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User as Caller
  participant T as ERC7984Restricted
  participant S as ERC7984 (super)

  rect rgba(220,240,255,0.5)
  note over User,T: Transfer flow
  User->>T: transfer(from, to, amount)
  T->>T: _update(from, to, euint64)
  T->>T: _checkRestriction(from) if not mint
  T->>T: _checkRestriction(to) if not burn
  alt Allowed (DEFAULT/ALLOWED)
    T->>S: super._update(from, to, euint64)
    S-->>T: balances updated
    T-->>User: success
  else Blocked
    T-->>User: revert UserRestricted(account)
  end
  end

  rect rgba(235,255,235,0.5)
  note over User,T: Mint flow
  User->>T: _mint(to, euint64)
  T->>T: _checkRestriction(to)
  alt Allowed
    T->>S: super._update(0x0, to, euint64)
    S-->>T: minted
  else Blocked
    T-->>User: revert UserRestricted(to)
  end
  end

  rect rgba(255,235,235,0.5)
  note over User,T: Burn flow
  User->>T: _burn(from, euint64)
  T->>T: _checkRestriction(from)
  alt Allowed
    T->>S: super._update(from, 0x0, euint64)
    S-->>T: burned
  else Blocked
    T-->>User: revert UserRestricted(from)
  end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Assessment against linked issues

Objective Addressed Explanation
Create an ERC7984 extension implementing account-level restrictions for sending/receiving tokens (#184)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Documentation wording change in contracts/token/README.adoc (lines where phrasing changed to "An extension of {ERC7984}") This is a copy-edit unrelated to implementing account-level restrictions; not required by #184.

Poem

In hush of bytes, I twitch an ear—
New gates to guard where carrots steer.
DEFAULT hops, ALLOWED skies,
BLOCKED burrows where transfer dies.
I guard the field with gentle hop—secure, precise, and full of hope. 🥕


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ca981bd and f29aeb7.

📒 Files selected for processing (1)
  • contracts/mocks/token/ERC7984RestrictedMock.sol (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • contracts/mocks/token/ERC7984RestrictedMock.sol
⏰ 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). (7)
  • GitHub Check: Redirect rules - confidential-tokens
  • GitHub Check: Header rules - confidential-tokens
  • GitHub Check: Pages changed - confidential-tokens
  • GitHub Check: boostsecurity - boostsecurityio/semgrep-pro
  • GitHub Check: slither
  • GitHub Check: tests
  • GitHub Check: coverage
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/erc7984-restricted

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbit in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbit in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbit gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbit read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbit help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbit ignore or @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbit summary or @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbit or @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 1

♻️ Duplicate comments (3)
test/token/ERC7984/extensions/ERC7984Restricted.test.ts (2)

110-111: Minor: prefer destructuring for readability.

Matches prior suggestion; keeps code concise.

-        const timestamp = (await ethers.provider.getBlock('latest')).timestamp;
+        const { timestamp } = await ethers.provider.getBlock('latest');

71-81: Optionally assert post-conditions (event or state).

Currently success is inferred by lack of revert. Consider asserting an expected event or observable state to tighten tests.

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

91-93: Compile error: require cannot use a custom error. Use revert UserRestricted(account).

This currently won’t compile; require only accepts a string for the second arg.

-    /// @dev Checks if a user account is restricted. Reverts with {ERC20Restricted} if so.
+    /// @dev Checks if a user account is restricted. Reverts with {UserRestricted} if so.
     function _checkRestriction(address account) internal view virtual {
-        require(isUserAllowed(account), UserRestricted(account));
+        if (!isUserAllowed(account)) {
+            revert UserRestricted(account);
+        }
     }
🧹 Nitpick comments (6)
.changeset/fruity-bananas-smile.md (1)

5-5: Clarify release note with event and error names.

Add concrete identifiers to aid consumers scanning changelogs.

-`ERC7984Restricted`: An extension of `ERC7984` that implements user account transfer restrictions.
+`ERC7984Restricted`: An extension of `ERC7984` that implements user account transfer restrictions (emits `UserRestrictionUpdated`, reverts with `UserRestricted`).
contracts/token/README.adoc (1)

9-12: Standardize phrasing: “An extension of {ERC7984} …”.

Line 9 still uses “Extension of” while the rest use “An extension of”. Align for consistency.

-- {ERC7984ERC20Wrapper}: Extension of {ERC7984} which wraps an `ERC20` into a confidential token. The wrapper allows for free conversion in both directions at a fixed rate.
+- {ERC7984ERC20Wrapper}: An extension of {ERC7984} which wraps an `ERC20` into a confidential token. The wrapper allows for free conversion in both directions at a fixed rate.
contracts/mocks/token/ERC7984RestrictedMock.sol (1)

6-7: Remove unused imports.

euint64 and externalEuint64 are not referenced in this mock.

-import {FHE, euint64, externalEuint64} from "@fhevm/solidity/lib/FHE.sol";
+import {FHE} from "@fhevm/solidity/lib/FHE.sol";
test/token/ERC7984/extensions/ERC7984Restricted.test.ts (2)

10-14: Be explicit passing addresses to contract methods.

Passing Signer can work in ethers v6, but using .address avoids ambiguity with different toolchains.

-  const token = await ethers.deployContract('$ERC7984RestrictedMock', ['token', 'tk', 'uri']);
-  await token['$_mint(address,uint64)'](holder, initialSupply);
+  const token = await ethers.deployContract('$ERC7984RestrictedMock', ['token', 'tk', 'uri']);
+  await token['$_mint(address,uint64)'](holder.address, initialSupply);

Apply similarly where this.holder / this.recipient are passed to address params.


69-104: Add a self-transfer test case.

Covers an edge path and ensures restrictions apply consistently when from == to.

I can draft a test under “transfer” asserting:

  • DEFAULT: self-transfer allowed
  • BLOCKED: self-transfer reverts with UserRestricted(holder)
    Want me to add a patch?
contracts/token/ERC7984/extensions/ERC7984Restricted.sol (1)

53-60: Docstring contradicts implementation (mint/burn are checked).

The function enforces restrictions for both mint (checks to) and burn (checks from). Fix the comment.

-     * @dev See {ERC7984-_update}. Enforces transfer restrictions (excluding minting and burning).
+     * @dev See {ERC7984-_update}. Enforces restrictions on transfers, minting (checks `to`) and burning (checks `from`).
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cbbf27f and ca981bd.

📒 Files selected for processing (5)
  • .changeset/fruity-bananas-smile.md (1 hunks)
  • contracts/mocks/token/ERC7984RestrictedMock.sol (1 hunks)
  • contracts/token/ERC7984/extensions/ERC7984Restricted.sol (1 hunks)
  • contracts/token/README.adoc (2 hunks)
  • test/token/ERC7984/extensions/ERC7984Restricted.test.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
test/token/ERC7984/extensions/ERC7984Restricted.test.ts (1)
test/utils/structs/Checkpoints.test.js (1)
  • fixture (10-35)
🔇 Additional comments (5)
contracts/token/README.adoc (1)

12-12: Docs entry looks good.

Accurate, succinct description of the new extension.

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

18-20: Public transfer wrapper is fine.

Simple helper for tests; no reentrancy or value transfers here. LGTM.

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

61-65: Update hook logic looks correct.

Checks both ends except the zero-address side, then delegates to parent. Matches tests.


25-27: Good event design (indexed account, enum payload).

Efficient to filter and audit.


49-51: Reasonable default policy.

Blocklist semantics by default; clearly overridable to allowlist.

@arr00 arr00 requested a review from james-toussaint August 28, 2025 13:46
import {FHE, euint64, externalEuint64} from "@fhevm/solidity/lib/FHE.sol";
import {ERC7984Restricted} from "../../token/ERC7984/extensions/ERC7984Restricted.sol";

abstract contract ERC7984RestrictedMock is ERC7984Restricted, SepoliaConfig {
Copy link
Contributor

Choose a reason for hiding this comment

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

Some ways to test what suggests our doc yes:

     * function isUserAllowed(address account) public view virtual override returns (bool) {
     *     return getRestriction(account) == Restriction.ALLOWED;
     * }

but ok

@arr00 arr00 merged commit c628672 into master Aug 28, 2025
15 checks passed
@arr00 arr00 deleted the feat/erc7984-restricted branch August 28, 2025 17:09
@coderabbitai coderabbitai bot mentioned this pull request Aug 29, 2025
@github-actions github-actions bot mentioned this pull request Oct 9, 2025
@github-actions github-actions bot mentioned this pull request Nov 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Confidential Token Restrictions

4 participants