Summary
The RAACToken._setTaxRate() function contains check for newRate, however the implementation is flawed due to improper logical operation ordering.
Vulnerability Details
The RAACToken._setTaxRate() function validate the newRate, however the implementation is incorrect.
The order of logic operation is &&, ||. But the check doesn't bracket properly and get incorrect result.
Correct approach: bool isTooHighOrTooLow = (newRate > currentRate + maxChange) || (newRate < currentRate && currentRate - newRate > maxChange)
Current implementation: bool isTooHighOrTooLow = (newRate > currentRate + maxChange || newRate < currentRate) && (currentRate - newRate > maxChange)
Therefore, current implemenation always returns false when newRate < currentRate.
function _setTaxRate(uint256 newRate, bool isSwapTax) private {
if (newRate > MAX_TAX_RATE) revert TaxRateExceedsLimit();
uint256 currentRate = isSwapTax ? swapTaxRate : burnTaxRate;
if (currentRate != 0) {
uint256 maxChange = currentRate.percentMul(taxRateIncrementLimit);
@> bool isTooHighOrTooLow = newRate > currentRate + maxChange || newRate < currentRate && currentRate - newRate > maxChange;
if (isTooHighOrTooLow) {
revert TaxRateChangeExceedsAllowedIncrement();
}
}
if (isSwapTax) {
swapTaxRate = newRate;
emit SwapTaxRateUpdated(newRate);
} else {
burnTaxRate = newRate;
emit BurnTaxRateUpdated(newRate);
}
}
Impact
The RAACToken._setTaxRate() function doesn't work correctly.
Tools Used
Manual Review
Recommendations
Group the conditions properly to ensure that both conditions are evaluated correctly
function _setTaxRate(uint256 newRate, bool isSwapTax) private {
if (newRate > MAX_TAX_RATE) revert TaxRateExceedsLimit();
uint256 currentRate = isSwapTax ? swapTaxRate : burnTaxRate;
if (currentRate != 0) {
uint256 maxChange = currentRate.percentMul(taxRateIncrementLimit);
// Check if the new rate is too high (newRate > currentRate + maxChange) or too low (newRate < currentRate && currentRate - newRate > maxChange) by more than the allowed increment
- bool isTooHighOrTooLow = newRate > currentRate + maxChange || newRate < currentRate && currentRate - newRate > maxChange;
+ bool isTooHighOrTooLow = (newRate > currentRate + maxChange) || (newRate < currentRate && currentRate - newRate > maxChange);
if (isTooHighOrTooLow) {
revert TaxRateChangeExceedsAllowedIncrement();
}
}
if (isSwapTax) {
swapTaxRate = newRate;
emit SwapTaxRateUpdated(newRate);
} else {
burnTaxRate = newRate;
emit BurnTaxRateUpdated(newRate);
}
}