Core Contracts

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

Tax Rate Increment Limit Bypass When Setting From Zero Rate

Summary

The _setTaxRate() function in RAACToken.sol fails to properly enforce the incremental tax rate change limit when setting rates from zero, allowing an owner to bypass the intended gradual increase mechanism and instantly set high tax rates.
https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/tokens/RAACToken.sol#L118

Vulnerability Details

The contract implements a tax rate increment limit mechanism to prevent sudden large changes in tax rates. However, this protection is bypassed when the current tax rate is 0, due to logic in _setTaxRate():

if (currentRate != 0) {
uint256 maxChange = currentRate.percentMul(taxRateIncrementLimit);
bool isTooHighOrTooLow = newRate > currentRate + maxChange ||
newRate < currentRate && currentRate - newRate > maxChange;
if (isTooHighOrTooLow) {
revert TaxRateChangeExceedsAllowedIncrement();
}
}

The increment check is only performed when currentRate != 0. This allows:

Scenario 1: Normal Case (Working as intended)

  • Current rate: 500 (5%)

  • Increment limit: 1000 (10%)

  • Max allowed change: 500 + (500 × 10%) = 550

  • Cannot set rate above 550 in one transaction

Scenario 2: Zero Rate Case (Vulnerable)

  • Current rate: 0

  • Increment limit: 1000 (10%)

  • Can set directly to any value up to MAX_TAX_RATE (1000)

  • Bypasses intended incremental steps (0→100→200→...→1000)

Impact

  • Owner can instantly set high tax rates without following the gradual increase requirement

Tools Used

Recommendations

Modify the _setTaxRate function to enforce incremental limits even when starting from zero:

function _setTaxRate(uint256 newRate, bool isSwapTax) private {
if (newRate > MAX_TAX_RATE) revert TaxRateExceedsLimit();
uint256 currentRate = isSwapTax ? swapTaxRate : burnTaxRate;
uint256 baseIncrement = 100; // 1% base increment
// Always enforce increment limit, even from zero
if (newRate > currentRate) {
require(newRate <= currentRate + baseIncrement,
"Rate change exceeds base increment");
} else if (newRate < currentRate) {
require(currentRate - newRate <= baseIncrement,
"Rate change exceeds base increment");
}
if (isSwapTax) {
swapTaxRate = newRate;
emit SwapTaxRateUpdated(newRate);
} else {
burnTaxRate = newRate;
emit BurnTaxRateUpdated(newRate);
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 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.