HIGH severity: `TokenLocker::withdrawWithPenalty` doesn't reset account bitfield when dust handling results in no remaining locked tokens. **Description:** When users withdraw their locked tokens using `TokenLocker::withdrawWithPenalty`, if after the [dust handling](https://github.com/Bima-Labs/bima-v1-core/blob/09461f0d22556e810295b12a6d7bc5c0efec4627/contracts/dao/TokenLocker.sol#L841-L852) the user has no remaining locked tokens...

Vulnerable code:
function test_withdrawWithPenalty_activeLockWithZeroLocked() external {
    uint256 amountToLock = 100;
    uint256 weeksToLockFor = 20;

    // first enable penalty withdrawals
    test_setPenaltyWithdrawalsEnabled(0, true);

    // save user initial balance
    uint256 userPreTokenBalance = babelToken.balanceOf(users.user1);

    // perform the lock
    (uint256 lockedAmount, uint256 weeksLockedFor) = test_lock(amountToLock, weeksToLockFor);
    // verify the lock result
    assertEq(lockedAmount, 100);
    assertEq(weeksLockedFor, 20);

    // verify user has received weight in the current week
    uint256 week = tokenLocker.getWeek();
    assertTrue(tokenLocker.getAccountWeightAt(users.user1, week) != 0);

    // perform the withdraw with penalty
    vm.prank(users.user1);
    uint256 amountToWithdraw = 61;
    tokenLocker.withdrawWithPenalty(amountToWithdraw);

    // calculate expected penaltyOnAmount = 61 * 1e18 * (52 - 32) / 32 = 38.125e18
    // so amountToWithdraw + penaltyOnAmount = 99.125e18 and will be 100 after handling dust
    // https://github.com/Bima-Labs/bima-v1-core/blob/main/contracts/dao/TokenLocker.sol#L1080

    // verify account's weight was reset
    assertEq(tokenLocker.getAccountWeightAt(users.user1, week), 0);

    // verify total weight was reset
    assertEq(tokenLocker.getTotalWeight(), 0);

    // getAccountActiveLocks incorrectly shows user still has an active lock
    (ITokenLocker.LockData[] memory activeLockData, uint256 frozenAmount)
        = tokenLocker.getAccountActiveLocks(users.user1, weeksToLockFor);

    assertEq(activeLockData.length, 1); // 1 active lock
    assertEq(frozenAmount, 0);
    assertEq(activeLockData[0].amount, 0); // 0 locked amount
    assertEq(activeLockData[0].weeksToUnlock, weeksToLockFor);

    // user can register with IncentiveVoting even though they have no
    // tokens locked
    vm.prank(users.user1);
    incentiveVoting.registerAccountWeight(users.user1, weeksToLockFor);

    (uint256 frozenWeight, ITokenLocker.LockData[] memory lockData)
        = incentiveVoting.getAccountRegisteredLocks(users.user1);
    assertEq(frozenWeight, 0);
    assertEq(lockData.length, 1);
    assertEq(lockData[0].amount, 0); // 0 locked amount
    assertEq(lockData[0].weeksToUnlock, weeksToLockFor);

    // this results in an inconsistent state but there doesn't appear
    // to be any way to further exploit this state since the locked
    // amount is zero
}

if (lockAmount - penaltyOnAmount > remaining) {
          // then recalculate the penalty using only the portion of the lock
          // amount that will be withdrawn
          penaltyOnAmount = (remaining * MAX_LOCK_WEEKS) / (MAX_LOCK_WEEKS - weeksToUnlock) - remaining;

          // add any dust to the penalty amount
          uint256 dust = ((penaltyOnAmount + remaining) % lockToTokenRatio);
          if (dust > 0) penaltyOnAmount += lockToTokenRatio - dust;

          // update memory total penalty
          penaltyTotal += penaltyOnAmount;

          // calculate amount to reduce lock as penalty + withdrawn amount,
          // scaled down by lockToTokenRatio as those values were prev scaled up by this
          uint256 lockReduceAmount = (penaltyOnAmount + remaining) / lockToTokenRatio;

          // update memory total voting weight reduction
          decreasedWeight += lockReduceAmount * weeksToUnlock;

          // update storage to decrease week's future unlocks
          accountWeeklyUnlocks[msg.sender][systemWeek] -= SafeCast.toUint32(lockReduceAmount);
          totalWeeklyUnlocks[systemWeek] -= SafeCast.toUint32(lockReduceAmount);

+        if (accountWeeklyUnlocks[msg.sender][systemWeek] == 0) {
+            bitfield = bitfield & ~(uint256(1) << (systemWeek % 256));
+         }

          // nothing remaining to be withdrawn
          remaining = 0;
      }