Skip to content
This repository has been archived by the owner on Jun 11, 2023. It is now read-only.

obront - Changing hat toggle address can lead to unexpected changes in status #34

Open
sherlock-admin opened this issue Mar 9, 2023 · 8 comments
Labels
Escalation Resolved This issue's escalations have been approved/rejected Fix Approved Hats.sol Medium A valid Medium severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed

Comments

@sherlock-admin
Copy link
Contributor

obront

medium

Changing hat toggle address can lead to unexpected changes in status

Summary

Changing the toggle address should not change the current status unless intended to. However, in the event that a contract's toggle status hasn't been synced to local state, this change can accidentally toggle the hat back on when it isn't intended.

Vulnerability Detail

When an admin for a hat calls changeHatToggle(), the toggle address is updated to a new address they entered:

function changeHatToggle(uint256 _hatId, address _newToggle) external {
    if (_newToggle == address(0)) revert ZeroAddress();

    _checkAdmin(_hatId);
    Hat storage hat = _hats[_hatId];

    if (!_isMutable(hat)) {
        revert Immutable();
    }

    hat.toggle = _newToggle;

    emit HatToggleChanged(_hatId, _newToggle);
}

Toggle addresses can be either EOAs (who must call setHatStatus() to change the local config) or contracts (who must implement the getHatStatus() function and return the value).

The challenge comes if a hat has a toggle address that is a contract. The contract changes its toggle value to false but is never checked (which would push the update to the local state). The admin thus expects that the hat is turned off.

Then, the toggle is changed to an EOA. One would expect that, until a change is made, the hat would remain in the same state, but in this case, the hat defaults back to its local storage state, which has not yet been updated and is therefore set to true.

Even in the event that the admin knows this and tries to immediately toggle the status back to false, it is possible for a malicious user to sandwich their transaction between the change to the EOA and the transaction to toggle the hat off, making use of a hat that should be off. This could have dramatic consequences when hats are used for purposes such as multisig signing.

Impact

Hats may unexpectedly be toggled from off to on during toggle address transfer, reactivating hats that are intended to be turned off.

Code Snippet

https://github.com/Hats-Protocol/hats-protocol/blob/fafcfdf046c0369c1f9e077eacd94a328f9d7af0/src/Hats.sol#L623-L636

Tool used

Manual Review

Recommendation

The changeHatToggle() function needs to call checkHatToggle() before changing over to the new toggle address, to ensure that the latest status is synced up.

@github-actions github-actions bot added Medium A valid Medium severity issue Has Duplicates A valid issue with 1+ other issues describing the same vulnerability labels Mar 12, 2023
@spengrah spengrah added the Will Fix The sponsor confirmed this issue will be fixed label Mar 13, 2023
@spengrah
Copy link

The risk here is limited since toggle modules are treated as the source of truth for hat status and so admins should be aware that changing the toggle also changes the source of truth. But the recommended fix is simple and cheap enough that it makes sense to apply.

@zobront, does this same concept apply to eligibility?

@spengrah spengrah added Hats.sol Sponsor Confirmed The sponsor acknowledged this issue is valid labels Mar 13, 2023
@zobront
Copy link
Collaborator

zobront commented Mar 14, 2023

@spengrah Agreed. The only situation I think would break a user's assumption is a change from contract => EOA, because in most cases the toggle will be saved in hat.config (so they won't need to take any action), but in this edge case it will be reset to an old version. That inconsistent behavior is the root of the problem.

The same is true with eligibility, but not sure if there's anything you can do about it, because it's on an individual hat by hat basis. If the eligibility contract is changed, you can't go through all the hats and update them. So my advice is just to be sure to document it very clearly in this case.

@spengrah
Copy link

spengrah commented Mar 15, 2023

@cducrest
Copy link

Escalate for 10 USDC

Disagree with being sever enough for being a medium. The Sherlock doc state "The vulnerability must be something that is not considered an acceptable risk by a reasonable protocol team." However, as was explained, this problem is present both for status and eligibility, and a fix is possible and implemented in Hats-Protocol/hats-protocol#116 only for status, proving that the risk is acceptable for the eligibility part thus acceptable for the status part.

As noted in the comment by spengrah, the fix was implemented mostly because it is not expensive to do so, even though the risk is limited.

@sherlock-admin
Copy link
Contributor Author

Escalate for 10 USDC

Disagree with being sever enough for being a medium. The Sherlock doc state "The vulnerability must be something that is not considered an acceptable risk by a reasonable protocol team." However, as was explained, this problem is present both for status and eligibility, and a fix is possible and implemented in Hats-Protocol/hats-protocol#116 only for status, proving that the risk is acceptable for the eligibility part thus acceptable for the status part.

As noted in the comment by spengrah, the fix was implemented mostly because it is not expensive to do so, even though the risk is limited.

You've created a valid escalation for 10 USDC!

To remove the escalation from consideration: Delete your comment.

You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.

@sherlock-admin sherlock-admin added the Escalated This issue contains a pending escalation label Mar 31, 2023
@hrishibhat
Copy link
Contributor

Escalation rejected

The issue is a valid medium
Given the edge case that the attack is still possible and can cause a hat to be activated which should not be and vice versa.

@sherlock-admin
Copy link
Contributor Author

Escalation rejected

The issue is a valid medium
Given the edge case that the attack is still possible and can cause a hat to be activated which should not be and vice versa.

This issue's escalations have been rejected!

Watsons who escalated this issue will have their escalation amount deducted from their next payout.

@sherlock-admin sherlock-admin added Escalation Resolved This issue's escalations have been approved/rejected and removed Escalated This issue contains a pending escalation Has Duplicates A valid issue with 1+ other issues describing the same vulnerability labels Apr 3, 2023
@MLON33
Copy link

MLON33 commented Apr 13, 2023

zobront added "Fix Approved" label

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Escalation Resolved This issue's escalations have been approved/rejected Fix Approved Hats.sol Medium A valid Medium severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed
Projects
None yet
Development

No branches or pull requests

6 participants