Core Contracts

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

Proposal Execution Atomicity Violation in Governance System

Summary

The Governance contract's proposal execution system contains an atomicity violation where proposals can be marked as executed even when their underlying actions partially fail. This creates a critical mismatch between the proposal's recorded state and its actual execution status.

Governance.sol#_executeProposal

function _executeProposal(uint256 proposalId) internal {
ProposalCore storage proposal = _proposals[proposalId];
bytes32 salt = proposal.descriptionHash;
bytes32 id = _timelock.hashOperationBatch(
proposal.targets,
proposal.values,
proposal.calldatas,
bytes32(0),
salt
);
// Check if ready for execution
if (!_timelock.isOperationReady(id)) {
revert ProposalNotQueued(proposalId, id);
}
// Critical: executeBatch return value is not checked
_timelock.executeBatch(
proposal.targets,
proposal.values,
proposal.calldatas,
bytes32(0),
salt
);
// Proposal marked as executed without verifying all actions succeeded
proposal.executed = true; // Marked executed regardless of individual action success
emit ProposalExecuted(proposalId, msg.sender, block.timestamp);
}
  1. The executeBatch return value indicating success/failure is not captured or checked

  2. The proposal is marked as executed regardless of whether all actions completed successfully

Vulnerability Details

When a governance proposal is executed, it's like a chain of dominos, each action should either all fall perfectly or none at all. However, in the current implementation, some dominos can fall while others remain standing, creating a dangerous half-executed state.

Imagine a critical protocol upgrade proposal that needs to update both interest rates and collateral requirements. The proposal begins execution through the timelock controller, successfully updates interest rates, but fails to adjust collateral parameters. Despite this partial failure, the system marks the entire proposal as executed, leading to mismatched protocol parameters.

Impact The governance system's state tracking shows:

proposalId = 1
success = true // Claims success
proposalExecutedAfter = false // But reality disagrees

This isn't just a boolean mismatch, it means critical protocol parameters could be left in inconsistent states. For example, a proposal to adjust both lending rates and collateral ratios could leave the protocol with updated rates but old collateral requirements, creating immediate arbitrage opportunities.

Impact

  • Governance proposals can enter an inconsistent state

  • System state could become inconsistent if multi-action proposals partially complete

  • System security assumptions about atomic updates are broken

  • Governance decisions could be partially implemented leading to unexpected behavior

Recommendations

capturing the return value and requiring full execution success before marking the proposal as executed. Think of this like a bank transaction, you wouldn't want a transfer to debit one account but fail to credit another.

function _executeProposal(uint256 proposalId) internal {
ProposalCore storage proposal = _proposals[proposalId];
// First get the operation hash for timelock verification
bytes32 salt = proposal.descriptionHash;
bytes32 id = _timelock.hashOperationBatch(
proposal.targets,
proposal.values,
proposal.calldatas,
bytes32(0),
salt
);
// Verify timelock readiness
if (!_timelock.isOperationReady(id)) {
revert ProposalNotQueued(proposalId, id);
}
// Execute and capture success status
bool success = _timelock.executeBatch(
proposal.targets,
proposal.values,
proposal.calldatas,
bytes32(0),
salt
);
// Enforce atomic execution
require(success, "All or nothing execution required");
// Only mark as executed if all operations succeeded
proposal.executed = true;
emit ProposalExecuted(proposalId, msg.sender, block.timestamp);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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