duc - When all signers of the gate lose their hats, `reconcileSignerCount` will not update threshold, then `targetThreshold` can be updated to be lower than the current threshold during here, leads to freeze safe's actions. #66
When all signers of the gate lose their hats, reconcileSignerCount will not update threshold, then targetThreshold can be updated to be lower than the current threshold during here, leads to freeze safe's actions.
Summary
In contract HatsSignerGateBase.sol, function reconcileSignerCount only updates the threshold if newThreshold > 0. When all signers of the gate lose their hats, reconcileSignerCount updates validSignerCount = 0, but safe's threshold doesn't change. During this time, targetThreshold can be updated without _setSafeThreshold, then targetThreshold can be
Vulnerability Detail
In function reconcileSignerCount, if validSignerCount == 0, newThreshold will be 0 and safe's threshold will not be updated:
All of signers lose their hats, reconcileSignerCount updates validSignerCount = 0, safe's threshold doesn't change (still = 3)
Owner updates targetThreshold to be 2
All of signers regain their hats, reconcileSignerCount updates validSignerCount = 3, safe's threshold doesn't change (still = 3) because current threshold == validSignerCount
After that, safe's actions can not be executed because function checkAfterExecution always revert (cause safe's threshold > targetThreshold)
Impact
If owner updates targetThreshold (decrease) during the time validSignerCount == 0, safe's actions can be freezed when the signers regain their hats.
duc
medium
When all signers of the gate lose their hats,
reconcileSignerCount
will not update threshold, thentargetThreshold
can be updated to be lower than the current threshold during here, leads to freeze safe's actions.Summary
In contract
HatsSignerGateBase.sol
, functionreconcileSignerCount
only updates the threshold ifnewThreshold
> 0. When all signers of the gate lose their hats,reconcileSignerCount
updatesvalidSignerCount
= 0, but safe's threshold doesn't change. During this time,targetThreshold
can be updated without_setSafeThreshold
, thentargetThreshold
can beVulnerability Detail
In function
reconcileSignerCount
, ifvalidSignerCount
== 0,newThreshold
will be 0 and safe's threshold will not be updated:Function
setTargetThreshold
doesn't update threshold whensignerCount
<= 1 :If the new
targetThreshold
is lower than current threshold, safe's actions will be freezed because functioncheckAfterExecution
always revert.An example scenerio is as follows:
reconcileSignerCount
updates validSignerCount = 0, safe's threshold doesn't change (still = 3)reconcileSignerCount
updates validSignerCount = 3, safe's threshold doesn't change (still = 3) because current threshold == validSignerCountcheckAfterExecution
always revert (cause safe's threshold > targetThreshold)Impact
If owner updates
targetThreshold
(decrease) during the timevalidSignerCount
== 0, safe's actions can be freezed when the signers regain their hats.Code Snippet
https://github.com/Hats-Protocol/hats-zodiac/blob/9455cc0957762f5dbbd8e62063d970199109b977/src/HatsSignerGateBase.sol#L203 https://github.com/Hats-Protocol/hats-zodiac/blob/9455cc0957762f5dbbd8e62063d970199109b977/src/HatsSignerGateBase.sol#L99
Tool used
Manual review
Recommendation
Should still call
_setSafeThreshold
whensignerCount
<= 1 in functionsetTargetThreshold
:Duplicate of #44