Platform: Code4rena
Start Date: 17/07/2023
Pot Size: $85,500 USDC
Total HM: 11
Participants: 26
Period: 14 days
Judge: Picodes
Total Solo HM: 1
Id: 263
League: ETH
Rank: 14/26
Findings: 1
Award: $31.38
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: MiloTruck
Also found by: 0xAnah, AlexCzm, Bughunter101, BugzyVonBuggernaut, DavidGiladi, Emmanuel, Iurii3, Kaysoft, MohammedRizwan, Prestige, Rolezn, Sathish9098, Stormreckson, adeolu, descharre, evmboi32, fatherOfBlocks, ginlee, ihtishamsudo, juancito, mrudenko, tnquanghuy0512
31.3772 USDC - $31.38
setState function in GovernanceLib.sol allow Governance to set any state and EmergencyAdmin to pause further. Internal checks of the function made in a way that firstly msg.sender checked to be EmergencyAdmin and if no checked further to be Governance. It is possible that msg.sender has both these roles. It might be doe on purpose, accidentally or due to governance transition. In this rare circumstances address with Governance role won't be able to unpausa state.
Change the order of internal checks. For example,
function setState(Types.ProtocolState newState) external { // NOTE: This does not follow the CEI-pattern, but there is no interaction and this allows to abstract `_setState` logic. Types.ProtocolState prevState = _setState(newState); // If the sender is the emergency admin, prevent them from reducing restrictions. if (msg.sender != StorageLib.getGovernance()) { if (msg.sender == StorageLib.getEmergencyAdmin()) { if (newState <= prevState) { revert Errors.EmergencyAdminCanOnlyPauseFurther(); } } else { revert Errors.NotGovernanceOrEmergencyAdmin(); } } emit Events.StateSet(msg.sender, prevState, newState, block.timestamp); }
To change protocol state function setState of the LensGovernance contract should be called. This function calls setState of the GovernanceLib that further calls _setState of the GovernanceLib. Both setState and _setState function of the GovernanceLib contain the same SetState event
emit Events.StateSet(msg.sender, prevState, newState, block.timestamp);
During the state change two event will be emitted that might mislead users of the protocol.
Delete event emitting in the setState function of the GovernanceLib.sol
validateAddressIsProfileOwnerOrDelegatedExecutor function checks if an address is Profile Owner or Delegated Executor. The function may revert only with Errors.ExecutorInvalid() inside validateAddressIsDelegatedExecutor function. But it rather should revert with Errors.NotProfileOwnerNorExecutor().
Add appropriate Error handle
#0 - c4-judge
2023-08-28T20:53:20Z
Picodes marked the issue as grade-b