The execute(uint256 proposalId) function does not enforce any caller restrictions, allowing any external address to execute a proposal once it has been successfully voted on and queued in the timelock. While _executeProposal(proposalId) correctly verifies that a proposal was properly queued by computing its id with:
this only ensures that the proposal is valid for execution, but it does not control who is allowed to execute it. As a result, anyone—including malicious actors—can call execute(proposalId), front-run governance decisions, and execute proposals at strategically favorable times. This creates an opportunity for execution timing exploits, where attackers may delay or accelerate execution to maximize personal gain or disrupt governance processes (e.g., triggering a proposal at a time that benefits certain traders, exploits a market inefficiency, or front-runs critical protocol updates). Since the function does not include an authorization check like onlyProposer or onlyGovernanceExecutor, governance decisions are vulnerable to manipulation by external actors who control execution timing.
Malicious actors can front-run or delay proposal execution to manipulate governance outcomes, disrupt protocol operations, or gain an unfair financial advantage.
Restrict execution to the original proposer, governance contract, or a designated executor role by enforcing access control through an onlyProposer or onlyGovernanceExecutor modifier.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.