keep-tecdsa - keep cannot be closed if a members bond was seized or fully reassigned
A keep cannot be closed if the bonds have been completely reassigned or seized before, leaving at least one member with zero `lockedBonds`. In this case `closeKeep()` will throw in `freeMembersBonds()` because the requirement in `keepBonding.freeBond` is not satisfied anymore (lockedBonds[bondID] > 0). As a result of this, none of the potentially remaining bonds (reassign) are freed, the keep stays active even though it should be closed.\\n```\\n/// @notice Closes keep when owner decides that they no longer need it.\\n/// Releases bonds to the keep members. Keep can be closed only when\\n/// there is no signing in progress or requested signing process has timed out.\\n/// @dev The function can be called by the owner of the keep and only is the\\n/// keep has not been closed already.\\nfunction closeKeep() external onlyOwner onlyWhenActive {\\n    require(\\n        !isSigningInProgress() || hasSigningTimedOut(),\\n        "Requested signing has not timed out yet"\\n    );\\n\\n    isActive = false;\\n\\n    freeMembersBonds();\\n\\n    emit KeepClosed();\\n}\\n\\n/// @notice Returns bonds to the keep members.\\nfunction freeMembersBonds() internal {\\n    for (uint256 i = 0; i < members.length; i++) {\\n        keepBonding.freeBond(members[i], uint256(address(this)));\\n    }\\n}\\n```\\n\\n```\\n/// @notice Releases the bond and moves the bond value to the operator's\\n/// unbounded value pool.\\n/// @dev Function requires that caller is the holder of the bond which is\\n/// being released.\\n/// @param operator Address of the bonded operator.\\n/// @param referenceID Reference ID of the bond.\\nfunction freeBond(address operator, uint256 referenceID) public {\\n    address holder = msg.sender;\\n    bytes32 bondID = keccak256(\\n        abi.encodePacked(operator, holder, referenceID)\\n    );\\n\\n    require(lockedBonds[bondID] > 0, "Bond not found");\\n\\n    uint256 amount = lockedBonds[bondID];\\n    lockedBonds[bondID] = 0;\\n    unbondedValue[operator] = amount;\\n}\\n```\\n
Make sure the keep can be set to an end-state (closed/inactive) indicating its end-of-life even if the bond has been seized before. Avoid throwing an exception when freeing member bonds to avoid blocking the unlocking of bonds.
```\\n/// @notice Closes keep when owner decides that they no longer need it.\\n/// Releases bonds to the keep members. Keep can be closed only when\\n/// there is no signing in progress or requested signing process has timed out.\\n/// @dev The function can be called by the owner of the keep and only is the\\n/// keep has not been closed already.\\nfunction closeKeep() external onlyOwner onlyWhenActive {\\n    require(\\n        !isSigningInProgress() || hasSigningTimedOut(),\\n        "Requested signing has not timed out yet"\\n    );\\n\\n    isActive = false;\\n\\n    freeMembersBonds();\\n\\n    emit KeepClosed();\\n}\\n\\n/// @notice Returns bonds to the keep members.\\nfunction freeMembersBonds() internal {\\n    for (uint256 i = 0; i < members.length; i++) {\\n        keepBonding.freeBond(members[i], uint256(address(this)));\\n    }\\n}\\n```\\n