LOW severity: [TOKE-12] Potential DoS attack of AutoPool's rebalance and debt reporting functions due to division by zero in profit locking calculation from AutoPoolFees. **Severity:** High

**Path:** src/vault/libs/AutoPoolFees.sol#L330-L346, src/vault/libs/AutoPoolFees.sol#L402, src/vault/libs/AutoPoolFees.sol#L42-L53

**Description:**

In `AutoPoolFees::_updateProfitUnlockTimings` function, if `fullUnlockTime > block.timestamp`, `previousLockTime` will be 0....

Vulnerable code:
uint256 newUnlockPeriod = (previousLockTime + newLockShares * unlockPeriod) / totalLockShares;
settings.profitUnlockRate = totalLockShares * MAX_BPS_PROFIT / newUnlockPeriod;

function unlockedShares(
    IAutopool.ProfitUnlockSettings storage profitUnlockSettings,
    AutopoolToken.TokenData storage tokenData
) public view returns (uint256 shares) {
    uint256 fullTime = profitUnlockSettings.fullProfitUnlockTime;
    if (fullTime > block.timestamp) {
        shares = profitUnlockSettings.profitUnlockRate
            * (block.timestamp - profitUnlockSettings.lastProfitUnlockTime) / MAX_BPS_PROFIT;
    } else if (fullTime != 0) {
        shares = tokenData.balances[address(this)];
    }
}

function calculateProfitLocking(
  IAutopool.ProfitUnlockSettings storage settings,
  AutopoolToken.TokenData storage tokenData,
  uint256 feeShares,
  uint256 newTotalAssets,
  uint256 startTotalAssets,
  uint256 startTotalSupply,
  uint256 previousLockShares
) external returns (uint256) {
  uint256 unlockPeriod = settings.unlockPeriodInSeconds;

  // If there were existing shares and we set the unlock period to 0 they are immediately unlocked
  // so we don't have to worry about existing shares here. And if the period is 0 then we
  // won't be locking any new shares
  if (unlockPeriod == 0 || startTotalAssets == 0) {
      return startTotalSupply;
  }

  uint256 newLockShares = 0;
  uint256 previousLockToBurn = 0;
  uint256 effectiveTs = startTotalSupply;

  // The total supply we would need to not see a change in nav/share
  uint256 targetTotalSupply = newTotalAssets * (effectiveTs - feeShares) / startTotalAssets;

  if (effectiveTs > targetTotalSupply) {
      // Our actual total supply is greater than our target.
      // This means we would see a decrease in nav/share
      // See if we can burn any profit shares to offset that
      if (previousLockShares > 0) {
          uint256 diff = effectiveTs - targetTotalSupply;
          if (previousLockShares >= diff) {
              previousLockToBurn = diff;
              effectiveTs -= diff;
          } else {
              previousLockToBurn = previousLockShares;
              effectiveTs -= previousLockShares;
          }
      }
  }

  if (targetTotalSupply > effectiveTs) {
      // Our actual total supply is less than our target.
      // This means we would see an increase in nav/share (due to gains) which we can't allow
      // We need to mint shares to the vault to offset
      newLockShares = targetTotalSupply - effectiveTs;
      effectiveTs += newLockShares;
  }

  // We know how many shares should be locked at this point
  // Mint or burn what we need to match if necessary
  uint256 totalLockShares = previousLockShares - previousLockToBurn + newLockShares;
  if (totalLockShares > previousLockShares) {
      uint256 mintAmount = totalLockShares - previousLockShares;
      tokenData.mint(address(this), mintAmount);
      startTotalSupply += mintAmount;
  } else if (totalLockShares < previousLockShares) {
      uint256 burnAmount = previousLockShares - totalLockShares;
      tokenData.burn(address(this), burnAmount);
      startTotalSupply -= burnAmount;
  }

  // If we're going to end up with no profit shares, zero the rate
  // We don't need to 0 the other timing vars if we just zero the rate
  if (totalLockShares == 0) {
      settings.profitUnlockRate = 0;
  }

  // We have shares and they are going to unlocked later
  if (totalLockShares > 0 && unlockPeriod > 0) {
      _updateProfitUnlockTimings(
          settings, unlockPeriod, previousLockToBurn, previousLockShares, newLockShares, totalLockShares
      );
  }

  return startTotalSupply;
}