Skip to content

Conversation

@maurelian
Copy link
Contributor

@maurelian maurelian commented Sep 9, 2025

Description

TimelockGuard and LivenessModule2 are inherited into a single contract. The primary purpose of which is to avoid the need to deploy and manage two different contracts.

Also makes the parent contracts abstract in order to prevent deploying
them individually.

Since their functionality is otherwise distinct, the child contract contains none of its own logic. The benefit of this approach is that it ensures the logic is available
in both contracts, while ensuring that their state and logic are kept
separate thus reducing the complexity and review effort.

Tests are kept separate for the same reason.

JosepBove and others added 6 commits September 8, 2025 16:00
- Add configureTimelockGuard function to allow Safes to set timelock delays
- Validate timelock delay between 1 second and 1 year
- Check that guard is properly enabled on calling Safe using getStorageAt()
- Store configuration per Safe with GuardConfigured event emission
- Add comprehensive test suite covering all spec requirements
- Implement IGuard interface for Safe compatibility

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Add clearTimelockGuard function to allow Safes to clear timelock configuration
- Validate that guard is disabled before allowing configuration clearing
- Check that Safe was previously configured before clearing
- Delete configuration data and emit GuardCleared event
- Add comprehensive test suite covering all spec requirements
- Add new errors: TimelockGuard_GuardNotConfigured, TimelockGuard_GuardStillEnabled

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Add internal _getGuard() helper to centralize guard address retrieval
- Update configureTimelockGuard and clearTimelockGuard to use helper
- Reduces code duplication and improves maintainability

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Add cancellationThreshold function to return current threshold for a Safe
- Return 0 if guard not enabled or not configured
- Initialize to 1 when Safe configures guard
- Clear threshold when Safe clears guard configuration
- Add comprehensive test suite covering all spec requirements
- Function never reverts as per spec requirements

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
…lity

- Add scheduleTransaction placeholder (Function 4)
- Add checkPendingTransactions placeholder (Function 6)
- Add rejectTransaction placeholder (Function 7)
- Add rejectTransactionWithSignature placeholder (Function 8)
- Add cancelTransaction placeholder (Function 9)
- Update checkTransaction placeholder (Function 5)
- All placeholders have proper signatures and documentation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link
Contributor Author

maurelian commented Sep 9, 2025

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@maurelian maurelian marked this pull request as ready for review September 9, 2025 20:03
@maurelian maurelian requested a review from a team as a code owner September 9, 2025 20:03
@maurelian maurelian requested review from mslipper and removed request for a team September 9, 2025 20:03
@codecov
Copy link

codecov bot commented Sep 9, 2025

Codecov Report

❌ Patch coverage is 92.92035% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.69%. Comparing base (891015e) to head (b62ec78).
⚠️ Report is 63 commits behind head on jm/timelock.

Files with missing lines Patch % Lines
...kages/contracts-bedrock/src/safe/TimelockGuard.sol 82.05% 7 Missing ⚠️
...ges/contracts-bedrock/src/safe/LivenessModule2.sol 98.64% 1 Missing ⚠️
Additional details and impacted files
@@               Coverage Diff                @@
##           jm/timelock   #17402       +/-   ##
================================================
+ Coverage        78.34%   89.69%   +11.34%     
================================================
  Files              163      110       -53     
  Lines             9706     5034     -4672     
================================================
- Hits              7604     4515     -3089     
+ Misses            1956      519     -1437     
+ Partials           146        0      -146     
Flag Coverage Δ
cannon-go-tests-64 ?
contracts-bedrock-tests 89.69% <92.92%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ges/contracts-bedrock/src/safe/LivenessModule2.sol 98.64% <98.64%> (ø)
...kages/contracts-bedrock/src/safe/TimelockGuard.sol 82.05% <82.05%> (ø)

... and 55 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Also makes the parent contracts abstract in order to prevent deploying
them individually.

The benefit of this approach is that it ensures the logic is available
in both contracts, while ensuring that their state and logic are kept
separate thus reducing the complexity and review effort.
/// @dev This contract can be enabled simultaneously as both a module and a guard on a Safe:
/// - As a module: provides liveness challenge functionality to prevent multisig deadlock
/// - As a guard: provides timelock functionality for transaction delays and cancellation
contract SafeExtensions is LivenessModule2, TimelockGuard {
Copy link
Contributor

Choose a reason for hiding this comment

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

I liked SaferSafes as the name for the contract :)

Copy link
Contributor

Choose a reason for hiding this comment

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

It gives a bit more information about what the contract is about, and it is memorable.

@alcueca
Copy link
Contributor

alcueca commented Sep 10, 2025

The problem here is that the LivenessModule needs to know the timelock_delay, because it should be added to its own liveness_challenge_period.

This is inconsistently explained in the specs, let's continue the conversation there.

@maurelian
Copy link
Contributor Author

Closing this for now. Will revisit the problem of composition after both modules are complete.

@maurelian maurelian closed this Sep 11, 2025
@maurelian maurelian mentioned this pull request Sep 11, 2025
@alcueca
Copy link
Contributor

alcueca commented Sep 12, 2025

My comment just above is resolved. It's better to not couple the LivenessModule and TimelockGuard features, and make sure that timelock_delay < liveness_challenge_period in the superchain-ops tasks.

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.

4 participants