The original code for AutoExit and AutoRange will call _validateSwap even when users
input swapAmount is zero (meaning they don't want to swap), and _validateSwap will revert
if the difference between current tick and twap tick is too large:
function _validateSwap(
bool swap0For1,
uint256 amountIn,
IUniswapV3Pool pool,
uint32 twapPeriod,
uint16 maxTickDifference,
uint64 maxPriceDifferenceX64
) internal view returns (uint256 amountOutMin, int24 currentTick, uint160 sqrtPriceX96, uint256 priceX96) {
// get current price and tick
(sqrtPriceX96, currentTick,,,,,) = pool.slot0();
// check if current tick not too far from TWAP
if (!_hasMaxTWAPTickDifference(pool, twapPeriod, currentTick, maxTickDifference)) {
revert TWAPCheckFailed();
}
}
function _hasMaxTWAPTickDifference(IUniswapV3Pool pool, uint32 twapPeriod, int24 currentTick, uint16 maxDifference)
internal
view
returns (bool)
{
(int24 twapTick, bool twapOk) = _getTWAPTick(pool, twapPeriod);
if (twapOk) {
return twapTick - currentTick >= -int16(maxDifference) && twapTick - currentTick <= int16(maxDifference);
} else {
return false;
}
}
This will make the users transaction revert even if they choose not to swap
Mitigation
PR #12
The mitigation code now only call _validateSwap if swap amount !=0, for example in AutoRange contract:
Lines of code
Vulnerability details
C4 issue
M-18: Users cannot stop loss in AutoRange and AutoExit
Comment
The original code for AutoExit and AutoRange will call
_validateSwap
even when users input swapAmount is zero (meaning they don't want to swap), and_validateSwap
will revert if the difference between current tick and twap tick is too large:This will make the users transaction revert even if they choose not to swap
Mitigation
PR #12 The mitigation code now only call
_validateSwap
if swap amount !=0, for example inAutoRange
contract:The mitigation solved the orignal issue.
Conclusion
LGTM