Core Contracts

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

Non-Payable execute() Function in Governance.sol

Summary

The Governance.sol contract contains a critical bug in the execute() function, which is not marked as payable. This oversight prevents the contract from forwarding any Ether (ETH) that may be required for executing proposals through the _timelock contract. As a result, if a proposal requires sending ETH ie the value is greater than zero, the execution will always revert, rendering the proposal unexecutable.

Vulnerability Details

The execute() function in the Governance contract is responsible for executing successful proposals through the timelock mechanism. However, it lacks the payable modifier, which is necessary for functions that need to accept Ether. Additionally, the contract does not implement a receive() function, meaning it cannot accept incoming ETH transfers. Consequently, if a proposal attempts to send ETH (i.e., if the values array in the proposal contains any non-zero amounts), the execution will fail with a revert error, as the contract cannot forward the required ETH to the _timelock contract.

Code Snippet

function execute(uint256 proposalId) external override nonReentrant {
ProposalCore storage proposal = _proposals[proposalId];
if (proposal.executed) revert ProposalAlreadyExecuted(proposalId, block.timestamp);
ProposalState currentState = state(proposalId);
// Check if the proposal is in the correct state for execution
if (currentState == ProposalState.Succeeded) {
// Queue the proposal
_queueProposal(proposalId);
} else if (currentState == ProposalState.Queued) {
// Execute the queued proposal
_executeProposal(proposalId);
} else {
// If not in Succeeded or Queued state, revert
revert InvalidProposalState(
proposalId,
currentState,
currentState == ProposalState.Active ? ProposalState.Succeeded : ProposalState.Queued,
"Invalid state for execution"
);
}
}

Impact

The inability to execute proposals that require ETH can severely impact the functionality of the governance mechanism. Proposals that involve transferring funds or executing actions that necessitate ETH will fail, leading to:

  • Loss of Functionality: Proposals that are intended to fund projects or pay for services will not be executed, undermining the governance process.

Tools Used

  • Manual Review

Recommendations

  1. Make the execute() Function Payable: Modify the execute() function to include the payable modifier, allowing it to accept ETH.

    function execute(uint256 proposalId) external override nonReentrant payable {
    // Function implementation
    }
  2. Implement a receive() Function: Add a receive() function to the contract to allow it to accept incoming ETH transfers.

Updates

Lead Judging Commences

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

Governance.execute lacks payable modifier and ETH forwarding mechanism, preventing proposals with ETH transfers from being executed through TimelockController

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

Governance.execute lacks payable modifier and ETH forwarding mechanism, preventing proposals with ETH transfers from being executed through TimelockController

Support

FAQs

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

Give us feedback!