Formal Peach Starling
High
HSG v2 allows users to migrate their Safe to a potential new version of the HSG, using the migrateToNewHSG
function
function migrateToNewHSG(address _newHSG, uint256[] calldata _signerHatIds, address[] calldata _signersToMigrate)
public
{
_checkUnlocked();
_checkOwner();
ISafe s = safe; // save SLOADS
// remove existing HSG as guard
s.execRemoveHSGAsGuard();
// enable new HSG as module and guard
s.execAttachNewHSG(_newHSG);
// remove existing HSG as module
s.execDisableHSGAsModule(_newHSG); // @audit -> problem
// if _signersToMigrate is provided, migrate them to the new HSG by calling claimSignersFor()
uint256 toMigrateCount = _signersToMigrate.length;
if (toMigrateCount > 0) {
// check that the arrays are the same length
if (_signerHatIds.length != toMigrateCount) revert InvalidArrayLength();
IHatsSignerGate(_newHSG).claimSignersFor(_signerHatIds, _signersToMigrate);
}
emit Migrated(_newHSG);
}
However, as we can see it accidentally calls execDisableHSGAsModule
is called with _newHSG
which just disables the new HSG, instead of the old one. This leaves the old HSG as the connected module and breaks operability as the new HSG is set to being a guard. As the new HSG is not a module, migrating back to the old HSG will not be possible.
Executing transactions would still be possible, but changing crucial parameters such as threshold will not be possible. For the same reason, removing signers will not be possible.
Calling function with wrong argument.
- DAO wishes to migrate to HSG v3
- DAO calls
migrateToNewHSG
- Due to faulty logic, old HSG remains the protocol's module
- New HSG implementation can no longer change its threshold.
- If for some reason DAO cannot reach threshold, all funds are permanently lost (e.g. due to requiring X/X signatures and one of signers going rogue)
Broken functionality. Unable to change threshold and overall execute any Safe transaction from Module. Possibly full loss of funds.
Call the function with the correct argument.