Closed code423n4 closed 1 year ago
The issue is well demonstrated, properly formatted, contains a coded POC. Marking as HQ.
0xSorryNotSorry marked the issue as high quality report
0xSorryNotSorry marked the issue as primary issue
ElliotFriedman marked the issue as sponsor confirmed
great finding!
alcueca marked issue #314 as primary and marked this issue as a duplicate of 314
alcueca marked the issue as satisfactory
Lines of code
https://github.com/code-423n4/2023-07-moonwell/blob/main/src/core/Governance/TemporalGovernor.sol#L288-L289 https://github.com/code-423n4/2023-07-moonwell/blob/main/src/core/Governance/TemporalGovernor.sol#L256
Vulnerability details
Impact
Upon calling the pause function, the guardian's right to pause the protocol is revoked until the governance or the guardian themselves reinstate the right.
If the right to paused is restored when the contract is still paused, the contract becomes permanently unpausable. The only way to unpause the contract is to remove the guardian from the protocol.
Proof of Concept
As soon as the guardian pauses the contract, the boolean
guardianPauseAllowed
is reset to false. The governance or the guardian themselves can reinstate the guardian's right to pause by invokinggrantGuardiansPause
via_executeProposal
, flippingguardianPauseAllowed
back to true. However, this action stops the the unpausing process, as unpausing requires thatguardianPauseAllowed
is false.The only viable resolution would be for the guardian to call
revokeGuardian
, which also unpauses the contract. This action removes the guardian from the protocol by transferring ownership to the null address and can lead to a loss of funds when no guard can stop the protocol during a hack.A proof of concept that illustrates the issue is shown below:
Tools Used
Manual review.
Recommended Mitigation Steps
As long as is desired behavior that the guardian should not receive the right to pause the contract (before the contract is unpaused), we should encorce that bevaior in the function
grantGuardiansPause
by enforcing that it can not be called when the contract is not paused.As an alternative solution,
permissionlessUnpause
andtogglePause
could be adjusted to allow to invoke them, even whenguardianPauseAllowed
is true.Assessed type
Governance