If a hat is owned by address(0), phony signatures will be accepted by the safe
If a hat is sent to `address(0)`, the multisig will be fooled into accepting phony signatures on its behalf. This will throw off the proper accounting of signatures, allowing non-majority transactions to pass and potentially allowing users to steal funds.\\nIn order to validate that all signers of a transaction are valid signers, `HatsSignerGateBase.sol` implements the `countValidSignatures()` function, which recovers the signer for each signature and checks `isValidSigner()` on them.\\nThe function uses `ecrecover` to get the signer. However, `ecrecover` is well known to return `address(0)` in the event that a phony signature is passed with a `v` value other than 27 or 28. See this example for how this can be done.\\nIn the event that this is a base with only a single hat approved for signing, the `isValidSigner()` function will simply check if the owner is the wearer of a hat:\\n```\\nfunction isValidSigner(address _account) public view override returns (bool valid) {\\n    valid = HATS.isWearerOfHat(_account, signersHatId);\\n}\\n```\\n\\nOn the `Hats.sol` contract, this simply checks their balance:\\n```\\nfunction isWearerOfHat(address _user, uint256 _hatId) public view returns (bool isWearer) {\\n    isWearer = (balanceOf(_user, _hatId) > 0);\\n}\\n```\\n\\n... which only checks if it is active or eligible...\\n```\\nfunction balanceOf(address _wearer, uint256 _hatId)\\n    public\\n    view\\n    override(ERC1155, IHats)\\n    returns (uint256 balance)\\n{\\n    Hat storage hat = _hats[_hatId];\\n\\n    balance = 0;\\n\\n    if (_isActive(hat, _hatId) && _isEligible(_wearer, hat, _hatId)) {\\n        balance = super.balanceOf(_wearer, _hatId);\\n    }\\n}\\n```\\n\\n... which calls out to ERC1155, which just returns the value in storage (without any address(0) check)...\\n```\\nfunction balanceOf(address owner, uint256 id) public view virtual returns (uint256 balance) {\\n    balance = _balanceOf[owner][id];\\n}\\n```\\n\\nThe result is that, if a hat ends up owned by `address(0)` for any reason, this will give blanket permission for anyone to create a phony signature that will be accepted by the safe.\\nYou could imagine a variety of situations where this may apply:\\nAn admin minting a mutable hat to address(0) to adjust the supply while waiting for a delegatee to send over their address to transfer the hat to\\nAn admin sending a hat to address(0) because there is some reason why they need the supply slightly inflated\\nAn admin accidentally sending a hat to address(0) to burn it\\nNone of these examples are extremely likely, but there would be no reason for the admin to think they were putting their multisig at risk for doing so. However, the result would be a free signer on the multisig, which would have dramatic consequences.
The easiest option is to add a check in `countValidSignatures()` that confirms that `currentOwner != address(0)` after each iteration.
If a hat is sent to `address(0)`, any phony signature can be accepted by the safe, leading to transactions without sufficient support being executed.\\nThis is particularly dangerous in a 2/3 situation, where this issue would be sufficient for a single party to perform arbitrary transactions.
```\\nfunction isValidSigner(address _account) public view override returns (bool valid) {\\n    valid = HATS.isWearerOfHat(_account, signersHatId);\\n}\\n```\\n