Core Contracts

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

Inconsistent Governance State Due to External Timelock Execution

Summary

The Governance contract fails to synchronize its internal state with the TimelockController when proposals are executed directly via the Timelock. This results in incorrect proposal statuses, allowing the Governance contract to report outdated or invalid states even after execution.
https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/governance/proposals/Governance.sol

Vulnerability Details

The Governance contract tracks proposal execution solely via an executed flag, which is only updated when proposals are executed through its own execute function. If a proposal is directly executed via the TimelockController (e.g., by an address with the EXECUTOR_ROLE), the Governance contract’s state becomes inconsistent:

  1. The executed flag remains false.

  2. The state() function does not verify the Timelock’s execution status, leading to incorrect state reporting.

problematic implementation

function state(uint256 proposalId) public view returns (ProposalState) {
if (proposal.executed) return ProposalState.Executed; // <-- Only checks local flag
// ...
}

Impact

Governance reports incorrect statuses (e.g., "Succeeded" instead of "Executed").
Off-chain systems relying on the state() function receive unreliable data.

Tools Used

Manual review

Recommendations

Sync Governance State with Timelock by modifying the state() function to check the Timelock’s execution status:

function state(uint256 proposalId) public view returns (ProposalState) {
ProposalCore storage proposal = _proposals[proposalId];
// ... existing checks ...
bytes32 id = _timelock.hashOperationBatch(
proposal.targets,
proposal.values,
proposal.calldatas,
bytes32(0),
proposal.descriptionHash
);
if (_timelock.isOperationDone(id)) { // NEW CHECK
return ProposalState.Executed;
}
// ... remaining logic ...
}
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.