DnGmxJuniorVaultManager#harvestFees can push junior vault borrowedUSDC above borrow cap and DOS vault
DnGmxJuniorVaultManager#harvestFees grants fees to the senior vault by converting the WETH to USDC and staking it directly. The result is that the senior vault gains value indirectly by increasing the debt of the junior vault. If the junior vault is already at it's borrow cap this will push it's total borrow over the borrow cap causing DnGmxSeniorVault#availableBorrow to underflow and revert. This is called each time a user deposits or withdraws from the junior vault meaning that the junior vault can no longer deposit or withdraw.\\n```\\n  if (_seniorVaultWethRewards > state.wethConversionThreshold) {\\n      // converts senior tranche share of weth into usdc and deposit into AAVE\\n      // Deposit aave vault share to AAVE in usdc\\n      uint256 minUsdcAmount = _getTokenPriceInUsdc(state, state.weth).mulDivDown(\\n          _seniorVaultWethRewards * (MAX_BPS - state.slippageThresholdSwapEthBps),\\n          MAX_BPS * PRICE_PRECISION\\n      );\\n      // swaps weth into usdc\\n      (uint256 aaveUsdcAmount, ) = state._swapToken(\\n          address(state.weth),\\n          _seniorVaultWethRewards,\\n          minUsdcAmount\\n      );\\n\\n      // supplies usdc into AAVE\\n      state._executeSupply(address(state.usdc), aaveUsdcAmount);\\n\\n      // resets senior tranche rewards\\n      state.seniorVaultWethRewards = 0;\\n```\\n\\nThe above lines converts the WETH owed to the senior vault to USDC and deposits it into Aave. Increasing the aUSDC balance of the junior vault.\\n```\\nfunction getUsdcBorrowed() public view returns (uint256 usdcAmount) {\\n    return\\n        uint256(\\n            state.aUsdc.balanceOf(address(this)).toInt256() -\\n                state.dnUsdcDeposited -\\n                state.unhedgedGlpInUsdc.toInt256()\\n        );\\n}\\n```\\n\\nThe amount of USDC borrowed is calculated based on the amount of aUSDC that the junior vault has. By depositing the fees directly above, the junior vault has effectively "borrowed" more USDC. This can be problematic if the junior vault is already at it's borrow cap.\\n```\\nfunction availableBorrow(address borrower) public view returns (uint256 availableAUsdc) {\\n    uint256 availableBasisCap = borrowCaps[borrower] - IBorrower(borrower).getUsdcBorrowed();\\n    uint256 availableBasisBalance = aUsdc.balanceOf(address(this));\\n\\n    availableAUsdc = availableBasisCap < availableBasisBalance ? availableBasisCap : availableBasisBalance;\\n}\\n```\\n\\nIf the vault is already at it's borrow cap then the line calculating `availableBasisCap` will underflow and revert.
Check if borrowed exceeds borrow cap and return zero to avoid underflow:\\n```\\nfunction availableBorrow(address borrower) public view returns (uint256 availableAUsdc) {\\n\\n+   uint256 borrowCap = borrowCaps[borrower];\\n+   uint256 borrowed = IBorrower(borrower).getUsdcBorrowed();\\n\\n+   if (borrowed > borrowCap) return 0;\\n\\n+   uint256 availableBasisCap = borrowCap - borrowed;\\n\\n-   uint256 availableBasisCap = borrowCaps[borrower] - IBorrower(borrower).getUsdcBorrowed();\\n    uint256 availableBasisBalance = aUsdc.balanceOf(address(this));\\n\\n    availableAUsdc = availableBasisCap < availableBasisBalance ? availableBasisCap : availableBasisBalance;\\n}\\n```\\n
availableBorrow will revert causing deposits/withdraws to revert
```\\n  if (_seniorVaultWethRewards > state.wethConversionThreshold) {\\n      // converts senior tranche share of weth into usdc and deposit into AAVE\\n      // Deposit aave vault share to AAVE in usdc\\n      uint256 minUsdcAmount = _getTokenPriceInUsdc(state, state.weth).mulDivDown(\\n          _seniorVaultWethRewards * (MAX_BPS - state.slippageThresholdSwapEthBps),\\n          MAX_BPS * PRICE_PRECISION\\n      );\\n      // swaps weth into usdc\\n      (uint256 aaveUsdcAmount, ) = state._swapToken(\\n          address(state.weth),\\n          _seniorVaultWethRewards,\\n          minUsdcAmount\\n      );\\n\\n      // supplies usdc into AAVE\\n      state._executeSupply(address(state.usdc), aaveUsdcAmount);\\n\\n      // resets senior tranche rewards\\n      state.seniorVaultWethRewards = 0;\\n```\\n