The cancel function allows users to cancel proposals.
To do so it will make an internal call to the _cancel function.
Both cancel and _cancel are overriding functions inherited from a parent contract. In this process of overriding, critical access control logic has been inadvertently removed. Specifically, the following check from the original implementation has been omitted:
function cancel
. . .
require(_msgSender() == _proposals[proposalId].proposer, "Governor: only proposer can cancel");
As a result, the current implementation allows any user to cancel any proposal, regardless of whether they are the original proposer.
Tools Used
Manual review
Recommended Mitigation Steps
Consider adding proper access control. This has to suit the model you want to use of course, this should be allowed by either governance or proposer
Lines of code
https://github.com/code-423n4/2024-07-reserve/blob/3f133997e186465f4904553b0f8e86ecb7bbacbf/contracts/plugins/governance/Governance.sol#L124-L134
Vulnerability details
Impact
Any proposals can be cancelled by anyone
Proof of Concept
The cancel function allows users to cancel proposals. To do so it will make an internal call to the _cancel function. Both cancel and _cancel are overriding functions inherited from a parent contract. In this process of overriding, critical access control logic has been inadvertently removed. Specifically, the following check from the original implementation has been omitted:
As a result, the current implementation allows any user to cancel any proposal, regardless of whether they are the original proposer.
Tools Used
Manual review
Recommended Mitigation Steps
Consider adding proper access control. This has to suit the model you want to use of course, this should be allowed by either governance or proposer
Assessed type
Access Control