Closed sherlock-admin closed 1 year ago
This is expected behavior. Mechanistic toggle and eligibility modules (ie those conforming to the IHatsToggle or IHatsEligibility interfaces, respectively) should be treated as the source of truth for hat status and hat wearer status.
roguereddwarf
medium
Hats._isEligible and Hats._isActive functions might access old data
Summary
That Hats contract makes use of the
Hats._isEligible
andHats._isActive
function to retrieve the eligibility or active status of a hat.The issue is that both functions do not save the data they query to storage. So the data that can be retrieved from storage at any time might not be the most recently queried data.
This means that when the
eligibility
ortoggle
module are turned off (i.e. they provide no longer any eligibility or active status data) the eligibility or active status data that the contract has access to might not be the most recent one.Vulnerability Detail
Think of the following scenario:
Hats.balanceOf
is called which calls_isEligible
. It is determined that User A is not eligible to wear a certain hat. However this information is not stored to storageHats.balanceOf
is called again now, it will fall back to reading the eligibility from storage. The storage is not yet aware that User A is not eligible. So it returns that User A is eligible to wear the hat.The first call to
Hats.balanceOf
should have saved the result to storage such that even when the module returns invalid data later on, the most recently queried data can be returned.Impact
If the eligibility or toggle module do not provide valid data anymore, the fallback data from storage might not be up-to-date. This means hats might be active that should be inactive or addresses eligible to wear hats that should not be eligible (and vice versa).
Code Snippet
https://github.com/Hats-Protocol/hats-protocol/blob/fafcfdf046c0369c1f9e077eacd94a328f9d7af0/src/Hats.sol#L890-L917
https://github.com/Hats-Protocol/hats-protocol/blob/fafcfdf046c0369c1f9e077eacd94a328f9d7af0/src/Hats.sol#L971-L998
Tool used
Manual Review
Recommendation
When
_isEligible
or_isActive
is called, they should save the data they receive to storage.Fix: