Core Contracts

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

Tax Rate Manipulation Through Rapid Changes in RAACToken

Summary

The RAACToken's tax rate change mechanism has a maxChange limit but no cooldown period, allowing owners to chain multiple small changes to bypass the intended rate limit.

Vulnerability Details

There is a protection for users to avoid big spike in tax rates, but this protection is useless. An owner can simply call multiple times setSwapTaxRate() or setBurnTaxRate() as there is no timestamp check on the last call.

//RAACToken.sol
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 tax rate protection for users can be bypassed and is not as effective as it should. Owner can make drastic tax changes instantly, that will undermines user trust.

Tools Used

Manual

Recommendations

Add a timestamp for the swap and burn tax rate when last called and a threshold.

uint256 public constant RATE_CHANGE_COOLDOWN = 7 days;
mapping(bool => uint256) private lastRateChange; // isSwapTax => timestamp
function _setTaxRate(uint256 newRate, bool isSwapTax) private {
uint256 lastChange = lastRateChange[isSwapTax];
require(
block.timestamp >= lastChange + RATE_CHANGE_COOLDOWN,
"Must wait for cooldown"
);
// Existing checks...
lastRateChange[isSwapTax] = block.timestamp;
}
Updates

Lead Judging Commences

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

Appeal created

foufrix Submitter
3 months ago
inallhonesty Lead Judge
3 months ago
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.