Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: medium
Valid

Timelock Execution After Cancel

Summary

The current implementation of the governance contract allows for queued proposals to be executed even after they have been canceled by governance. This oversight can lead to significant issues, as it undermines the intent of the cancellation process and can result in unwanted actions being executed.

Current Code Issue

Issue Explanation

  1. Canceling Proposal Doesn't Cancel Timelock Operations: When a proposal is canceled, the corresponding timelock operation remains pending and can still be executed after the specified delay.

  2. Queued Proposals Execute After Governance Cancellation: If a proposal is queued in the timelock and then canceled by governance, the timelock will still execute the proposal after the delay, leading to actions that were intended to be aborted.

Attack Flow

  1. A proposal is queued in the timelock.

  2. Governance cancels the proposal.

  3. The timelock still executes the proposal after the delay, despite the cancellation.

Recommended Mitigation

To address this vulnerability, the cancellation function should include logic to cancel any pending operations in the timelock when a proposal is canceled. This ensures that no actions are executed after a proposal has been canceled.

Proposed Code Update

Here’s how the cancel function could be modified to include this logic:

function cancel(uint256 proposalId) external {
ProposalCore storage proposal = _proposals[proposalId];
// Check if the proposal is already canceled
if (proposal.canceled) {
revert ProposalAlreadyCanceled(proposalId);
}
// Mark the proposal as canceled
proposal.canceled = true;
// Cancel the corresponding timelock operation if it is pending
bytes32 id = _timelock.hashOperationBatch(
proposal.targets,
proposal.values,
proposal.calldatas,
bytes32(0),
proposal.descriptionHash
);
if (_timelock.isOperationPending(id)) {
_timelock.cancel(id);
}
emit ProposalCanceled(proposalId, msg.sender, block.timestamp);
}

Conclusion

Implementing this change will ensure that queued proposals cannot be executed after they have been canceled by governance, thereby preserving the integrity of the governance process.

Updates

Lead Judging Commences

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Governance::cancel and state lack synchronization with TimelockController

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Governance::cancel and state lack synchronization with TimelockController

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.