StrategyVault can perform a full exit without repaying all secondary debt
StrategyVault can perform a full exit without repaying all secondary debt, leaving bad debt with the protocol.\\nNoted from the codebase's comment that:\\nVaults can borrow up to the capacity using the `borrowSecondaryCurrencyToVault` and `repaySecondaryCurrencyToVault` methods. Vaults that use a secondary currency must ALWAYS repay the secondary debt during redemption and handle accounting for the secondary currency themselves.\\nThus, when the StrategyVault-side performs a full exit for a vault account, Notional-side does not check that all secondary debts of that vault account are cleared (= zero) and will simply trust StrategyVault-side has already handled them properly.\\nLine 271 below shows that only validates the primary debt but not the secondary debt during a full exit.\\n```\\nFile: VaultAccountAction.sol\\n        if (vaultAccount.accountDebtUnderlying == 0 && vaultAccount.vaultShares == 0) {\\n            // If the account has no position in the vault at this point, set the maturity to zero as well\\n            vaultAccount.maturity = 0;\\n        }\\n        vaultAccount.setVaultAccount({vaultConfig: vaultConfig, checkMinBorrow: true});\\n\\n        // It's possible that the user redeems more vault shares than they lend (it is not always the case\\n        // that they will be increasing their collateral ratio here, so we check that this is the case). No\\n        // need to check if the account has exited in full (maturity == 0).\\n        if (vaultAccount.maturity != 0) {\\n            IVaultAccountHealth(address(this)).checkVaultAccountCollateralRatio(vault, account);\\n        }\\n```\\n
Consider checking that all secondary debts of a vault account are cleared before executing a full exit.\\n```\\n// Add the line below\\n int256 accountDebtOne;\\n// Add the line below\\n int256 accountDebtTwo;\\n\\n// Add the line below\\n if (vaultConfig.hasSecondaryBorrows()) {\\n// Add the line below\\n  (/* */, accountDebtOne, accountDebtTwo) = VaultSecondaryBorrow.getAccountSecondaryDebt(vaultConfig, account, pr);\\n// Add the line below\\n }\\n\\n// Remove the line below\\n if (vaultAccount.accountDebtUnderlying == 0 && vaultAccount.vaultShares == 0) {\\n// Add the line below\\n if (vaultAccount.accountDebtUnderlying == 0 && vaultAccount.vaultShares == 0 && accountDebtOne == 0 && accountDebtTwo == 0) {\\n // If the account has no position in the vault at this point, set the maturity to zero as well\\n vaultAccount.maturity = 0;\\n}\\nvaultAccount.setVaultAccount({vaultConfig: vaultConfig, checkMinBorrow: true});\\n```\\n
Leveraged vaults are designed to be as isolated as possible to mitigate the risk to the Notional protocol and its users. However, the above implementation seems to break this principle. As such, if there is a vulnerability in the leverage vault that allows someone to exploit this issue and bypass the repayment of the secondary debt, the protocol will be left with a bad debt which affects the insolvency of the protocol.
```\\nFile: VaultAccountAction.sol\\n        if (vaultAccount.accountDebtUnderlying == 0 && vaultAccount.vaultShares == 0) {\\n            // If the account has no position in the vault at this point, set the maturity to zero as well\\n            vaultAccount.maturity = 0;\\n        }\\n        vaultAccount.setVaultAccount({vaultConfig: vaultConfig, checkMinBorrow: true});\\n\\n        // It's possible that the user redeems more vault shares than they lend (it is not always the case\\n        // that they will be increasing their collateral ratio here, so we check that this is the case). No\\n        // need to check if the account has exited in full (maturity == 0).\\n        if (vaultAccount.maturity != 0) {\\n            IVaultAccountHealth(address(this)).checkVaultAccountCollateralRatio(vault, account);\\n        }\\n```\\n