Core Contracts

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

Unauthorized Governance Execution via Executor Role

Summary

The Executor role in TimelockController.sol allows any contract or externally owned account (EOA) designated as an executor to execute scheduled governance proposals. However, this mechanism is vulnerable to abuse, as a malicious or compromised executor can front-run or manipulate governance execution, leading to unauthorized protocol control and asset theft.

If an attacker gains access to the executor role, they can:

  • Execute malicious governance proposals to drain protocol funds.

  • Front-run legitimate proposals, altering execution order for personal gain.

  • Cancel time-sensitive governance actions, disrupting protocol operations.

This severe governance vulnerability could jeopardize the protocol's entire governance mechanism, resulting in loss of user funds, malicious contract upgrades, and even complete project takeover.

Vulnerability Details

1. Weak Access Control in Timelock Execution

In TimelockController.sol, governance proposals are executed via the execute() function:

function execute(
address target,
uint256 value,
bytes calldata data,
bytes32 predecessor,
bytes32 salt
) public virtual override onlyRole(EXECUTOR_ROLE) {
require(_timestamps[id] > 0, "TimelockController: operation is not scheduled");
require(_timestamps[id] <= block.timestamp, "TimelockController: operation is not ready");
_timestamps[id] = 0;
(bool success, ) = target.call{value: value}(data);
require(success, "TimelockController: underlying transaction reverted");
emit CallExecuted(id, 0, target, value, data);
}

Flaw:

  • Any account with the EXECUTOR_ROLE can call execute() to finalize governance actions.

  • If a malicious contract or compromised EOA is assigned EXECUTOR_ROLE, it can arbitrarily execute governance transactions, bypassing protocol safeguards.

2. Attack Scenario: Malicious Executor Drains Funds

Step 1: Attacker Gains EXECUTOR_ROLE

  • An attacker social engineers, phishes, or compromises an address with EXECUTOR_ROLE.

  • If the governance system allows delegate permissions, an attacker can also convince a governance participant to delegate their executor rights.

Step 2: Front-Running Legitimate Proposals

  • Suppose a legitimate governance proposal schedules a fund allocation transaction in the lending pool.

  • The malicious executor can front-run the proposal and modify the target address, redirecting funds to an attacker-controlled wallet.

Step 3: Malicious Proposal Execution

  • The attacker submits a malicious proposal that, once executed, calls a contract function to withdraw liquidity from the lending pool to their own address.

  • Since they control the execution order, they prioritize their own malicious transactions before legitimate ones.

Step 4: Protocol Funds Drained

  • Funds are moved out before governance can react.

  • The attacker washes assets through multiple DeFi protocols or bridges them cross-chain to evade detection.

  • The project is left crippled with drained liquidity pools, affecting all users.

3. Real-World Example: The Beanstalk DAO Hack ($182M Stolen)

A similar attack occurred in Beanstalk DAO (April 2022), where an attacker gained governance execution rights, passed a malicious proposal, and drained $182M from the protocol before users could intervene.

PoC Exploit Script

Impact: Full protocol takeover & fund theft


This Proof of Concept (PoC) simulates an attacker gaining EXECUTOR_ROLE in the TimelockController.solcontract and using it to execute a malicious transaction. The attack allows the malicious executor to drain protocol funds by calling execute() on a governance transaction that sends all treasury funds to the attacker's wallet.


Attack Flow

  1. Attacker gains EXECUTOR_ROLE (via governance misconfiguration, social engineering, or compromised admin account).

  2. Attacker front-runs a legitimate proposal, replacing it with a malicious one.

  3. Attacker calls execute() to drain the protocol’s treasury.

  4. Funds are stolen & laundered via DeFi protocols or bridges.

PoC Exploit

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../contracts/governance/TimelockController.sol"; // Adjust path based on contract structure
import "@openzeppelin/contracts/access/AccessControl.sol";
contract GovernanceExploit {
TimelockController public timelock;
address public attacker;
constructor(address _timelock) {
timelock = TimelockController(_timelock);
attacker = msg.sender;
}
function attack(address target, uint256 value, bytes calldata data) external {
require(msg.sender == attacker, "Only attacker can execute");
// Creating a malicious governance proposal to transfer protocol funds
bytes32 maliciousId = keccak256(abi.encode(target, value, data));
// Force execution of a malicious transaction
timelock.execute(
target, // Target contract (e.g., protocol treasury)
value, // Value (ETH to be stolen)
data, // Data payload (function call to drain funds)
bytes32(0), // No predecessor
keccak256("MaliciousProposal") // Salt
);
}
}

Explanation of the Exploit

  1. Attacker Deploys the Exploit Contract

    • The attacker deploys GovernanceExploit.sol, pointing it to the TimelockController contract.

  2. Attacker Executes a Malicious Governance Proposal

    • Calls attack() with parameters to execute a fund transfer from the protocol treasury.

  3. Timelock Executes the Malicious Proposal

    • Since the attacker has EXECUTOR_ROLE, the transaction bypasses all verification and sends funds to the attacker's wallet.

** Expected Outcome**

  • Complete protocol compromise

  • Funds drained from protocol treasury

  • Users lose trust in governance process

Impact

Complete Governance Takeover:

  • A malicious executor can bypass checks and execute governance transactions arbitrarily.

  • This allows them to override governance decisions, steal funds, or disable governance altogether.

Loss of Protocol Funds:

  • If governance execution is compromised, liquidity pools, treasuries, and user deposits can be stolen.

  • Attackers can execute withdrawal transactions or change protocol parameters to favor themselves.

Trust Erosion & Token Collapse:

  • Users will panic and dump project tokens, leading to rapid devaluation.

  • Governance participants will lose confidence in the protocol, leading to abandonment or forks.

Tools Used

  • ** Manual Review** – Identified weak access controls in execute() function.

  • Slither – Used to analyze role-based access control vulnerabilities.

  • Foundry Fuzzing – Simulated execution of malicious governance proposals.

Recommendations

1. Restrict EXECUTOR_ROLE to Multi-Sig Governance

  • Require a multi-sig wallet (e.g., Gnosis Safe) to hold EXECUTOR_ROLE, preventing unauthorized transactions.

  • Ensure timelocked execution with veto power for emergency rollbacks.

2. Implement Proposal Verification Before Execution

  • Before executing a governance proposal, require on-chain verification to ensure it was properly voted on and approved.

  • Use Chainlink's decentralized oracle network (DON) to cross-check governance approvals.

3. Require Quorum-Based Execution

  • Instead of allowing a single executor, require multiple approvals (quorum) from different signers before execution.

  • This reduces risk if a single executor is compromised.

4. Implement Immediate Role Revocation for Suspicious Executors

  • Introduce an emergency governance function to immediately revoke EXECUTOR_ROLE from any malicious or compromised account.

5. Event Monitoring for Abnormal Governance Transactions

  • Set up real-time transaction monitoring using Forta or OpenZeppelin Defender to detect suspicious governance executions.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!