Open code423n4 opened 12 months ago
0xSorryNotSorry marked the issue as primary issue
this is a valid finding
ElliotFriedman marked the issue as sponsor confirmed
however, in order for this to be exploitable, the proper governor would have to emit the proper calldata on another chain, with the exactly needed calldata formatting, and call publishMessage for this to be exploitable which is a 0% chance of happening
alcueca marked the issue as selected for report
Lines of code
https://github.com/code-423n4/2023-07-moonwell/blob/main/src/core/Governance/TemporalGovernor.sol#L261-L268
Vulnerability details
Description
Wormhole cross chain communication is multicasted to all their supported chains:
The
TermporalGovernor
contract handles this by checkingqueueProposal
that theintendedRecipient
is itself:https://github.com/code-423n4/2023-07-moonwell/blob/main/src/core/Governance/TemporalGovernor.sol#L320-L322
There is also a
fastTrackProposalExecution
that the guardian can perform (owner
is referred ot asguardian
):https://github.com/code-423n4/2023-07-moonwell/blob/main/src/core/Governance/TemporalGovernor.sol#L261-L268
This will bypass the
queueProposal
flow and execute commands immediately.The issue here is that there is no check in
_executeProposal
that theintendedRecipient
is thisTemporalGovernor
.Impact
governor
can execute any commands communicated acrossWormhole
as long as they are from a trusted source.This requires that the
targets
line up between chains for agovernor
to abuse this. However only onetarget
must line up as the.call
made does not check for contract existence. Since "unaligned" addresses between chains will most likely not exist on other chains these calls will succeeed.Proof of Concept
Test in
TemporalGovernorExec.t.sol
, all of the test is copied fromtestProposeFailsIncorrectDestination
with just the change at the end where instead of callingqueueProposal
,fastTrackProposalExecution
is called instead, which doesn't revert, thus highligting the issue.Tools Used
Manual audit
Recommended Mitigation Steps
Consider adding a check in
_executeProposal
forintendedRecipient
same as is done in_queueProposal
.Assessed type
Invalid Validation