Strategy vault swaps can be frontrun
Some strategy vaults utilize borrowing one currency, swapping it for another, and then using the new currency somewhere to generate yield. For example, the CrossCurrencyfCash strategy vault could borrow USDC, swap it for DAI, and then deposit that DAI back into Notional if the DAI lending interest rates are greater than USDC borrowing interest rates. However, during vault settlement the assets would need to be swapped back into the original borrow currency.\\nSince these vaults control the borrowed assets that go only into white-listed strategies, the Notional system allows users to borrow multiples of their posted collateral and claim the yield from a much larger position. As a result, these strategy vaults would likely have significant funds being borrowed and managed into these strategies.\\nHowever, as mentioned above, these strategies usually utilize a trading mechanism to swap borrowed currencies into whatever is required by the strategy, and these trades may be quite large. In fact, the `BaseStrategyVault` implementation contains functions that interact with Notional's trading module to assist with those swaps:\\n```\\n/// @notice Can be used to delegate call to the TradingModule's implementation in order to execute\\n/// a trade.\\nfunction \\_executeTrade(\\n    uint16 dexId,\\n    Trade memory trade\\n) internal returns (uint256 amountSold, uint256 amountBought) {\\n    (bool success, bytes memory result) = nProxy(payable(address(TRADING\\_MODULE))).getImplementation()\\n        .delegatecall(abi.encodeWithSelector(ITradingModule.executeTrade.selector, dexId, trade));\\n    require(success);\\n    (amountSold, amountBought) = abi.decode(result, (uint256, uint256));\\n}\\n\\n/// @notice Can be used to delegate call to the TradingModule's implementation in order to execute\\n/// a trade.\\nfunction \\_executeTradeWithDynamicSlippage(\\n    uint16 dexId,\\n    Trade memory trade,\\n    uint32 dynamicSlippageLimit\\n) internal returns (uint256 amountSold, uint256 amountBought) {\\n    (bool success, bytes memory result) = nProxy(payable(address(TRADING\\_MODULE))).getImplementation()\\n        .delegatecall(abi.encodeWithSelector(\\n            ITradingModule.executeTradeWithDynamicSlippage.selector,\\n            dexId, trade, dynamicSlippageLimit\\n        )\\n    );\\n    require(success);\\n    (amountSold, amountBought) = abi.decode(result, (uint256, uint256));\\n}\\n```\\n\\nAlthough some strategies may manage stablecoin <-> stablecoin swaps that typically would incur low slippage, large size trades could still suffer from low on-chain liquidity and end up getting frontrun and “sandwiched” by MEV bots or other actors, thereby extracting maximum amount from the strategy vault swaps as slippage permits. This could be especially significant during vaults' settlements, that can be initiated by anyone, as lending currencies may be swapped in large batches and not do it on a per-account basis. For example with the CrossCurrencyfCash vault, it can only enter settlement if all strategy tokens (lending currency in this case) are gone and swapped back into the borrow currency:\\n```\\nif (vaultState.totalStrategyTokens == 0) {\\n    NOTIONAL.settleVault(address(this), maturity);\\n}\\n```\\n\\nAs a result, in addition to the risk of stablecoins' getting off-peg, unfavorable market liquidity conditions and arbitrage-seeking actors could eat into the profits generated by this strategy as per the maximum allowed slippage. However, during settlement the strategy vaults don't have the luxury of waiting for the right conditions to perform the trade as the borrows need to repaid at their maturities.\\nSo, the profitability of the vaults, and therefore users, could suffer due to potential low market liquidity allowing high slippage and risks of being frontrun with the chosen strategy vaults' currencies.
Ensure that the currencies chosen to generate yield in the strategy vaults have sufficient market liquidity on exchanges allowing for low slippage swaps.
```\\n/// @notice Can be used to delegate call to the TradingModule's implementation in order to execute\\n/// a trade.\\nfunction \\_executeTrade(\\n    uint16 dexId,\\n    Trade memory trade\\n) internal returns (uint256 amountSold, uint256 amountBought) {\\n    (bool success, bytes memory result) = nProxy(payable(address(TRADING\\_MODULE))).getImplementation()\\n        .delegatecall(abi.encodeWithSelector(ITradingModule.executeTrade.selector, dexId, trade));\\n    require(success);\\n    (amountSold, amountBought) = abi.decode(result, (uint256, uint256));\\n}\\n\\n/// @notice Can be used to delegate call to the TradingModule's implementation in order to execute\\n/// a trade.\\nfunction \\_executeTradeWithDynamicSlippage(\\n    uint16 dexId,\\n    Trade memory trade,\\n    uint32 dynamicSlippageLimit\\n) internal returns (uint256 amountSold, uint256 amountBought) {\\n    (bool success, bytes memory result) = nProxy(payable(address(TRADING\\_MODULE))).getImplementation()\\n        .delegatecall(abi.encodeWithSelector(\\n            ITradingModule.executeTradeWithDynamicSlippage.selector,\\n            dexId, trade, dynamicSlippageLimit\\n        )\\n    );\\n    require(success);\\n    (amountSold, amountBought) = abi.decode(result, (uint256, uint256));\\n}\\n```\\n