Skip to content

Conversation

@avorylli
Copy link
Contributor

Implements issue #6052 by adding a simple way to enforce delays on all proposals without requiring external timelock contracts.

Changes

  • Add GovernorDelay extension that enforces a configurable delay on all proposals
  • Delay is enforced by the Governor itself (unlike GovernorTimelockControl which uses external timelock)
  • Delay uses block.timestamp (seconds) regardless of governor's clock mode
  • Delay can be updated through governance proposals

Testing

  • 20 tests covering all scenarios
  • Tests pass for both blocknumber and timestamp clock modes

This contract adds a configurable delay to successful proposals, enforcing a waiting period before execution. It includes functions to set and retrieve the delay, as well as checks to ensure the delay is met before executing operations.
Added description for GovernorDelay extension in README.
@avorylli avorylli requested a review from a team as a code owner December 16, 2025 20:27
@changeset-bot
Copy link

changeset-bot bot commented Dec 16, 2025

⚠️ No Changeset found

Latest commit: 0f5d744

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 Dec 16, 2025

Walkthrough

A new GovernorDelay governance extension is introduced that adds a configurable execution delay to proposals. The extension includes state management for delay duration, governance-controlled delay modification, queuing requirement detection when delay is active, ETA calculation during queuing, and execution-time delay enforcement with error handling. Supporting files include documentation updates, a mock contract for testing, and comprehensive test coverage validating deployment, delay configuration, queuing behavior, execution timing, and error scenarios across both blocknumber and timestamp voting modes.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: Add GovernorDelay extension for simple proposal delays' accurately reflects the main change: introducing a new GovernorDelay extension for proposal delays.
Description check ✅ Passed The description is directly related to the changeset, clearly explaining the GovernorDelay extension purpose, key features, and testing approach.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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: 0

🧹 Nitpick comments (1)
test/governance/extensions/GovernorDelay.test.js (1)

302-355: Consider adding edge case: proposals with identical operations.

The multiple proposals test uses different descriptions ('descr1' vs 'descr2') to differentiate proposals. Consider adding a comment or an additional test case that explicitly verifies behavior when proposals have identical targets/values/calldatas but different descriptions, to document that uniqueness comes from the description hash.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 353f564 and 0f5d744.

📒 Files selected for processing (4)
  • contracts/governance/README.adoc (2 hunks)
  • contracts/governance/extensions/GovernorDelay.sol (1 hunks)
  • contracts/mocks/governance/GovernorDelayMock.sol (1 hunks)
  • test/governance/extensions/GovernorDelay.test.js (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-29T13:16:08.640Z
Learnt from: Amxx
Repo: OpenZeppelin/openzeppelin-contracts PR: 5904
File: contracts/mocks/crosschain/ERC7786RecipientMock.sol:12-14
Timestamp: 2025-08-29T13:16:08.640Z
Learning: In OpenZeppelin contracts, mock contracts (like ERC7786RecipientMock) don't require input validation such as zero-address checks in constructors, as they are only used for testing purposes in controlled environments.

Applied to files:

  • contracts/mocks/governance/GovernorDelayMock.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). (9)
  • GitHub Check: tests
  • GitHub Check: coverage
  • GitHub Check: tests-upgradeable
  • GitHub Check: slither
  • GitHub Check: tests-foundry
  • GitHub Check: halmos
  • GitHub Check: Redirect rules - solidity-contracts
  • GitHub Check: Header rules - solidity-contracts
  • GitHub Check: Pages changed - solidity-contracts
🔇 Additional comments (5)
contracts/governance/extensions/GovernorDelay.sol (1)

1-105: LGTM! Well-structured governance delay extension.

The implementation is clean and follows OpenZeppelin patterns:

  • Event emission before state mutation follows Checks-Effects-Interactions pattern
  • The uint32 delay type provides sufficient range (~136 years) while being gas-efficient
  • Proper use of SafeCast and Time utilities
  • Clear documentation about timestamp-based delays regardless of clock mode
contracts/governance/README.adoc (2)

39-40: LGTM! Documentation accurately describes the extension.

The documentation correctly positions GovernorDelay as a simpler alternative to external timelocks and clearly explains that the delay is enforced by the Governor itself.


91-92: API entry correctly placed.

contracts/mocks/governance/GovernorDelayMock.sol (1)

11-50: LGTM! Proper resolution of multiple inheritance conflicts.

The override declarations correctly resolve the diamond inheritance pattern by delegating to super, which follows the C3 linearization order. Based on learnings, mock contracts don't require additional validation as they're only used for testing purposes.

test/governance/extensions/GovernorDelay.test.js (1)

25-357: Comprehensive test coverage for GovernorDelay.

The test suite thoroughly covers:

  • Deployment verification
  • Governance-controlled delay modification with access control check
  • Zero vs non-zero delay queuing behavior
  • ETA calculation and enforcement
  • State transitions through the proposal lifecycle
  • Multiple concurrent proposals with independent ETAs

Testing both blocknumber and timestamp token modes ensures the extension works correctly regardless of clock mode, which aligns with the documented behavior.

@Amxx Amxx added this to the 5.7 milestone Dec 19, 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.

2 participants