Core Contracts

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

The burn function in RAACToken still calculates and subtracts a tax amount, despite the protocol intention to allow tax-free transfers when fee collector is set to zero address

Summary

In the RAACToken.sol contract, when the fee collector is set to the zero address (address(0)), it’s supposed to turn off taxes, making burns "tax-free." However, the function still calculates and subtracts a tax amount, causing users to lose tokens without those tokens being burned or sent anywhere.

Vulnerability Details

The contract has a rule: if the feeCollector is set to address(0), no taxes should be taken, it’s supposed to be a free action. This works fine for transfers (handled by the _update function), but the burn function doesn’t follow this rule properly.
Here’s the burn function’s code

function burn(uint256 amount) external {
uint256 taxAmount = amount.percentMul(burnTaxRate);
_burn(msg.sender, amount - taxAmount);
if (taxAmount > 0 && feeCollector != address(0)) {
_transfer(msg.sender, feeCollector, taxAmount);
}
}

The function calculates a tax (e.g., 0.5% of the amount you want to burn) no matter what. It doesn’t check if feeCollector is address(0) first. Then it burns only the amount minus the tax. For example, if you burn 100 tokens and the tax is 0.5, it burns 99.5 tokens.

After that, it checks if the feeCollector isn’t address(0) after the tax is subtracted and the burn happens. If it is address(0), the tax (like 0.5 tokens) isn’t sent anywhere. The problem is that the tax is taken away before checking if taxes should even apply. When feeCollector is address(0), that tax amount just disappears, it’s not burned and not sent to anyone.
The contract’s instructions say setting feeCollector to address(0) disables fees. Look at the setFeeCollector function:

function setFeeCollector(address _feeCollector) external onlyOwner {
if (_feeCollector == address(0)) {
emit FeeCollectionDisabled();
}
feeCollector = _feeCollector;
emit FeeCollectorSet(_feeCollector);
}

The comment in setFeeCollector ("disable fee collection") and the event FeeCollectionDisabled() imply a general intent to turn off fees. If burns are part of "fee collection," they should also be tax-free when feeCollector is address(0). But the burn function’s code contradicts this. Losing the taxAmount when feeCollector == address(0) (without burning or transferring it) seems like an error, no one benefits, and it breaks the "tax-free" expectation.

Impact

  1. People burning tokens when feeCollector is address(0) lose extra tokens without them being burned or collected, which feels unfair.

  2. Users expect the full amount to burn when fees are disabled, but they’ll see their balance drop more than the burned amount, causing distrust

Tools Used

Manual Review

Recommendations

Fix the burn function to check feeCollector first and only apply tax when it’s not address(0).

function burn(uint256 amount) external {
if (feeCollector == address(0)) {
_burn(msg.sender, amount); // Burn the full amount, no tax
} else {
uint256 taxAmount = amount.percentMul(burnTaxRate);
_burn(msg.sender, amount - taxAmount); // Burn after tax
if (taxAmount > 0) {
_transfer(msg.sender, feeCollector, taxAmount); // Send tax
}
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

RAACToken::burn incorrectly deducts tax amount but doesn't burn or transfer it when feeCollector is address(0), preventing complete token burns

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

RAACToken::burn incorrectly deducts tax amount but doesn't burn or transfer it when feeCollector is address(0), preventing complete token burns

Support

FAQs

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