SmartVaultV3.swap function utilizes exactInputSingle swap-function from Uniswap, but doesn't provide slippage tolerance option for users.
Protocol users(borrowers) able to deposit ERC20 tokens to their vaults and later perform swaps on these tokens (inside the vault). Under the hood, the SmartVaultV3.swap function uses UniswapV3 pools.
In the following chunk of code we can see how swap parameters for Uniswap generated:
And calculateMinimumAmountOut function, which calculates the amountOutMinimum value:
At line 210 we can see that amountOutMinimum calculated only if user trying to swap tokens worth of more value than required collateral (requiredCollateralValue). This logic prevents the vault becoming undercollateralized after the swap. So, this logic protects the Protocol.
But if user performs a swap within the collateral bounds (standard case), then amountOutMinimum is set "0", which doesn't provide any slippage protection for user.
Missing slippage protection poses risks for users being "sandwiched" and receive much less funds than expected.
Front-running might be not be a big issue on Arbitrum One (where the Protocol currently operates), but Sponsor stated in the Contest details that the Protocol expected to be compatible with "Any EVM chains with live Chainlink data feeds and live Uniswap pools".
Consider adding a new param to the swap function, to allow users specify slippage tolerance (or at least set sensible defaults) .
Additionally, I'd suggest to simplify the logic which protects a position being undercollaterlized after swap:
instead of calculating amountOutMinimum in dangerously looking calculateMinimumAmountOut function, we can just perform swap (with amountOutMinimum provided by user), and then confirm that the position is healthy using existing undercollateralised function:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.