Core Contracts

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

The `burn()` function in `RAACToken` contract does not BURN all the Tokens when the `feeCollector` is `address(0)`

Description:

In order to burn shares in RAACToken contract, a series of steps are performed.

The burn() function in RAACToken contract takes a portion of amount to be burnt as taxAmount and sends this portion to the feeCollector.

In case the feeCollector has not been assigned yet, we skip the transfer. However, this introduces an issue.
Source

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);
}
}

Notice, that the transfer only happens after burning the tokens. Therefore, if the feeCollector is not assigned, the portion of amount i.e. taxAmount will NOT be burned and will be kept by the caller.

It may seem harmless at first. However, when this function burn() is called by the contract FeeCollector _processDistributions() .

This function processes the distribution of collected fees to different stakeholders. While doing so, it also burns some portion of collected fee(this is where burn() on raacToken gets called) i.e. Source

if (shares[1] > 0) raacToken.burn(shares[1]); // issue here
if (shares[2] > 0) raacToken.safeTransfer(repairFund, shares[2]);
if (shares[3] > 0) raacToken.safeTransfer(treasury, shares[3]);

All these different portions of shares to be burnt, transferred etc comes from state variable collectedFees which is updated whenever a certain FeeType is deposited into the FeeCollector contract.

We reset this state variable by deleting it, at the end of function call i.e. distributeCollectedFees()

This should not be the intended behaviour, as the shares intended to be burnt are not getting burned.

Multiple distribution will cause these shares to accumulate in the contract when the feeCollector is not present in raacToken.

Tools Used

Manual

Recommendations

Consider adding this in burn() function

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

Lead Judging Commences

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

Give us feedback!