Skip to content

Conversation

@RenanSouza2
Copy link
Contributor

This PR implemetns ERC6909Pausable in the OZ style

  • Tests
  • Documentation
  • Changeset entry (run npx changeset add)

@RenanSouza2 RenanSouza2 requested a review from a team as a code owner December 4, 2025 13:07
@changeset-bot
Copy link

changeset-bot bot commented Dec 4, 2025

🦋 Changeset detected

Latest commit: 2700b3b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
openzeppelin-solidity Patch

Not sure what this means? Click here to learn what changesets are.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 4, 2025

Walkthrough

This pull request introduces ERC6909Pausable, a new abstract contract that integrates the ERC6909 token standard with pausable functionality. The contract overrides the _update function with a whenNotPaused modifier to guard token operations. A changeset entry marks this as a patch release. Supporting test coverage verifies that transfer, transferFrom, mint, and burn operations revert with EnforcedPause when paused, while operator management and balance queries continue to function during pause states.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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
Title check ✅ Passed The title 'ERC6909Pausable' is a single word that refers directly to the main component added in this changeset - a new abstract contract combining ERC6909 with pausable functionality.
Description check ✅ Passed The description clearly relates to the changeset, explaining that the PR implements ERC6909Pausable in the OpenZeppelin style and includes completed checklist items for tests, documentation, and changeset entry.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9d96210 and 2700b3b.

📒 Files selected for processing (3)
  • .changeset/full-chicken-beg.md (1 hunks)
  • contracts/token/ERC6909/extensions/ERC6909Pausable.sol (1 hunks)
  • test/token/ERC6909/extensions/ERC6909Pausable.test.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
test/token/ERC6909/extensions/ERC6909Pausable.test.js (2)
test/token/ERC1155/ERC1155.test.js (1)
  • operator (11-11)
test/utils/Address.test.js (1)
  • recipient (12-12)
🔇 Additional comments (3)
.changeset/full-chicken-beg.md (1)

1-5: Changeset scope and message are appropriate

Patch-level bump for openzeppelin-solidity with description "Implements ERC6909Pausable" correctly reflects the addition of a new extension plus tests.

test/token/ERC6909/extensions/ERC6909Pausable.test.js (1)

1-55: Good fixture and pause-behavior coverage

The fixture wiring (holder, operator, recipient, other) plus shouldBehaveLikeERC6909() gives you baseline ERC6909 behavior, and the when token is paused block correctly focuses on ensuring that transfer/mint/burn revert with EnforcedPause while operator management and read-only queries continue to work. This matches the expected semantics of a Pausable extension that guards _update only.

contracts/token/ERC6909/extensions/ERC6909Pausable.sol (1)

9-32: Pausable integration via _update override looks correct and consistent

The abstract ERC6909Pausable that inherits ERC6909 and Pausable, combined with the whenNotPaused guard on _update delegating to super._update, cleanly ensures that transfers, mints, and burns go through the pause check while leaving approvals and view functions untouched. The documentation also correctly pushes implementing contracts to wire public pause/unpause with appropriate access control rather than baking in a policy here.

Comment on lines +57 to +67
describe('setOperator', function () {
it('approves an operator', async function () {
await this.token.connect(this.holder).setOperator(this.other, true);
expect(await this.token.isOperator(this.holder, this.other)).to.be.true;
});

it('disapproves an operator', async function () {
await this.token.connect(this.holder).setOperator(this.other, false);
expect(await this.token.isOperator(this.holder, this.other)).to.be.false;
});
});
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

disapproves an operator test never makes other an operator

In this block, this.other is never approved before calling setOperator(this.other, false), so the test will pass even if disapproval is a no-op. To actually exercise revocation while paused, first approve other, then disapprove:

     describe('setOperator', function () {
       it('approves an operator', async function () {
         await this.token.connect(this.holder).setOperator(this.other, true);
         expect(await this.token.isOperator(this.holder, this.other)).to.be.true;
       });

       it('disapproves an operator', async function () {
-        await this.token.connect(this.holder).setOperator(this.other, false);
-        expect(await this.token.isOperator(this.holder, this.other)).to.be.false;
+        await this.token.connect(this.holder).setOperator(this.other, true);
+        await this.token.connect(this.holder).setOperator(this.other, false);
+        expect(await this.token.isOperator(this.holder, this.other)).to.be.false;
       });
     });

This way the test guarantees that operator revocation still works while the token is paused.

📝 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
describe('setOperator', function () {
it('approves an operator', async function () {
await this.token.connect(this.holder).setOperator(this.other, true);
expect(await this.token.isOperator(this.holder, this.other)).to.be.true;
});
it('disapproves an operator', async function () {
await this.token.connect(this.holder).setOperator(this.other, false);
expect(await this.token.isOperator(this.holder, this.other)).to.be.false;
});
});
describe('setOperator', function () {
it('approves an operator', async function () {
await this.token.connect(this.holder).setOperator(this.other, true);
expect(await this.token.isOperator(this.holder, this.other)).to.be.true;
});
it('disapproves an operator', async function () {
await this.token.connect(this.holder).setOperator(this.other, true);
await this.token.connect(this.holder).setOperator(this.other, false);
expect(await this.token.isOperator(this.holder, this.other)).to.be.false;
});
});
🤖 Prompt for AI Agents
In test/token/ERC6909/extensions/ERC6909Pausable.test.js around lines 57 to 67,
the "disapproves an operator" test never approves this.other before attempting
to disapprove it, so it can pass even if revocation is a no-op; update the test
to first call setOperator(this.other, true) (or otherwise ensure this.other is
an operator), then call setOperator(this.other, false) and assert isOperator
returns false to verify revocation works while paused.

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.

1 participant