Core Contracts

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

Governance proposals with non-empty values cannot be executed

Summary

The Governance system allows proposals to be created with ETH values (transfers), but the current implementation makes it impossible to execute such proposals due to limitations in the ETH transfer flow between contracts.

Vulnerability Details

The issue arises from the interaction between the Governance and TimelockController contracts.

Proposals can be created with non-zero ETH values:

function propose(
address[] memory targets,
> uint256[] memory values,
bytes[] memory calldatas,
string memory description,
ProposalType proposalType
) external override returns (uint256)

However, the execution flow is restricted:

// in Governance
function execute(uint256 proposalId) external override nonReentrant { // not payable
_timelock.executeBatch(proposal.targets, proposal.values, ...);
}
// in TimelockController
function executeBatch(...) external payable nonReentrant onlyRole(EXECUTOR_ROLE) {
for (uint256 i = 0; i < targets.length; i++) {
(bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]);
}
}

The execution fails because:

  • Only Governance can call TimelockController.executeBatch (EXECUTOR_ROLE)

  • Governance.execute is not payable, so it cannot receive or forward ETH

  • TimelockController cannot send ETH via call{value} without having ETH balance

  • No mechanism exists for TimelockController to receive ETH from other source

Impact

High: TimelockController.executeBatch attempts to send ETH using call{value: values[i]}, but since TimelockController does not hold ETH, this transfer fails. Proposals can never be executed.

Recommendations

Redesign the system's ETH transfer mechanism since the current design cannot support ETH transfers regardless of TimelockController's balance. The core issue is the flow that prevents ETH from reaching TimelockController. Consider adding a way for TimelockController to receive and manage ETH.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 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 4 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.