When a user calls the burn() function while the fee collector is disabled (set to zero address), only a portion of tokens are actually burned while the remaining tax amount stays in the user's balance, violating the user's intention to burn their entire specified amount.
The burn() function in RAACToken implements a tax mechanism where a portion of the burned amount (determined by burnTaxRate) is meant to be sent to the fee collector. Here's how it works:
The issue arises because:
The function first calculates the tax amount using burnTaxRate
It then burns only (amount - taxAmount) tokens
The remaining taxAmount is only transferred to the fee collector if:
taxAmount > 0 AND
feeCollector != address(0)
When feeCollector is set to address(0) (which is explicitly allowed by the setFeeCollector function):
This creates a situation where:
The user intends to burn amount tokens
Only (amount - taxAmount) tokens are burned
The taxAmount portion remains in the user's balance because the condition for transfer fails
This effectively results in a partial burn, contrary to the user's intention to burn their entire specified amount
Contract deploys with burnTaxRate = 50 (0.5%)
Owner calls setFeeCollector(address(0)) to disable fee collection
Alice has 1000 tokens and calls burn(1000)
Expected: All 1000 tokens should be burned
Actual result:
taxAmount = 1000 * 0.5% = 5 tokens
Only 995 tokens are burned
5 tokens remain in Alice's balance
Users trying to burn tokens while fee collection is disabled will always end up with residual tokens, as the tax portion remains unburned in their balance. This violates the principle of burning operations and could interfere with token economics and user expectations.
Manual code review
Modify the burn function to burn the entire amount when fee collector is disabled:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.