Core Contracts

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

Double Taxation via `_transfer` in Burn Function

Link to Affected Code:

Description:

The burn function uses _transfer to send the taxAmount to feeCollector, which triggers the overridden _update function in RAACToken. This reapplies the swap and burn taxes on the taxAmount, leading to double taxation on the same tokens.

Impact:

  • Fee collector receives fewer tokens: A portion of the taxAmount is diverted to the burn address due to secondary taxation.

Proof of Concept:

  1. Initial Setup:

    • swapTaxRate = 100 (1%), burnTaxRate = 50 (0.5%).

    • User calls burn(1000), generating taxAmount = 5 (0.5% of 1000).

  2. Tax Transfer:

    • _transfer(msg.sender, feeCollector, 5) triggers _update.

    • _update applies a 1.5% tax on the 5 tokens:

      • Swap tax: 5 * 1% = 0.05 → Sent to feeCollector.

      • Burn tax: 5 * 0.5% = 0.025 → Burned.

      • Remaining: 5 - 0.075 = 4.925 → Sent to feeCollector.

  3. Result:

    • User’s Loss: 5 tokens (correct).

    • Fee Collector Receives: 0.05 + 4.925 = 4.975 (instead of 5).

    • Burned: 0.025 (not part of the original burn).

Recommended Mitigation:
Use super._update to bypass the tax logic during tax transfers:

function burn(uint256 amount) external {
uint256 taxAmount = amount.percentMul(burnTaxRate);
_burn(msg.sender, amount - taxAmount);
if (taxAmount > 0 && feeCollector != address(0)) {
// Directly update balances without triggering taxes
super._update(msg.sender, feeCollector, taxAmount);
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

RAACToken::burn applies burn tax twice when transferring to feeCollector, causing excess tokens to be burned and reduced fees to be collected

This is by design, sponsor's words: Yes, burnt amount, done by whitelisted contract or not always occur the tax. The feeCollector is intended to always be whitelisted and the address(0) is included in the _transfer as a bypass of the tax amount, so upon burn->_burn->_update it would have not applied (and would also do another burn...). For this reason, to always apply such tax, the burn function include the calculation (the 2 lines that applies) and a direct transfer to feeCollector a little bit later. This is done purposefully

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

RAACToken::burn applies burn tax twice when transferring to feeCollector, causing excess tokens to be burned and reduced fees to be collected

This is by design, sponsor's words: Yes, burnt amount, done by whitelisted contract or not always occur the tax. The feeCollector is intended to always be whitelisted and the address(0) is included in the _transfer as a bypass of the tax amount, so upon burn->_burn->_update it would have not applied (and would also do another burn...). For this reason, to always apply such tax, the burn function include the calculation (the 2 lines that applies) and a direct transfer to feeCollector a little bit later. This is done purposefully

Appeal created

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

RAACToken::burn applies burn tax twice when transferring to feeCollector, causing excess tokens to be burned and reduced fees to be collected

This is by design, sponsor's words: Yes, burnt amount, done by whitelisted contract or not always occur the tax. The feeCollector is intended to always be whitelisted and the address(0) is included in the _transfer as a bypass of the tax amount, so upon burn->_burn->_update it would have not applied (and would also do another burn...). For this reason, to always apply such tax, the burn function include the calculation (the 2 lines that applies) and a direct transfer to feeCollector a little bit later. This is done purposefully

Support

FAQs

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