Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: low
Invalid

Incremental tax rate updates can be bypassed

Summary

In RAACToken.sol:L118, the function _setTaxRate implements custom logic to prevent sudden rate changes outside a specific range. The external functions can only be called by the owner. However, there are two ways to bypass these limits:

  • By first setting the tax rate to zero, the owner can than call the function again and set the new rate to any value below the max rate

  • By repeatedly calling the same function, the owner can continuously raise the tax rates as there is no limitation on the number of calls per time interval

Vulnerability Details

In RAACToken, an incremental rate change mechanism has been implemented so that tax rates can only change in a predictable manner. The documentation of the contract says:

"Implements a tax rate increment limit to prevent sudden large changes in tax rates"

However, there are at least 2 methods to bypass these limitations.

First, the logic is not executed if the current rate is 0. Therefore, by first setting the rate to zero, the owner can go to any arbitrary value below the max rate.

Second, there is no limits on the number of functions calls within a specific timeframe. As a result, the owner can just simply call the function repeatedly, each time changing the rates in the allowed increment range.

/**
* @dev Sets the swap tax rate
* @param rate The new swap tax rate (in basis points)
*/
function setSwapTaxRate(uint256 rate) external onlyOwner { _setTaxRate(rate, true); }
/**
* @dev Sets the burn tax rate
* @param rate The new burn tax rate (in basis points)
*/
function setBurnTaxRate(uint256 rate) external onlyOwner { _setTaxRate(rate, false); }
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;
if (isTooHighOrTooLow) {
revert TaxRateChangeExceedsAllowedIncrement();
}
}
if (isSwapTax) {
swapTaxRate = newRate;
emit SwapTaxRateUpdated(newRate);
} else {
burnTaxRate = newRate;
emit BurnTaxRateUpdated(newRate);
}
}

Impact

The existing incremental tax rate change can be bypassed, leading to sudden tax rate changes that users did not expect.

Tools Used

  • Manual review

Recommendations

Consider adding a time limit to the tax rate setting so that a change can be applied only once in a time interval (e.g. once per every 24 hours).

Consider adding a condition to prevent setting tax rates to zero, or implement custom logic so that existing 0 tax rates can only be changed under an upper bound (e.g. from 0 tax rate we can go to 1% maximum).

Updates

Lead Judging Commences

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.