Core Contracts

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

A part of the RAACToken is permanently loss whenever there is a balance change regardless of the operation

Summary

If burnTaxRate != 0, the corresponding RAACToken are burned during the balance change regardless of the operation.

Vunerability Details

The RAACToken::_update function is defined as below :

File: https://github.com/Cyfrin/2025-02-raac/blob/dd5516a9b318b797f82015ee63170d9064514b16/contracts/core/tokens/RAACToken.sol#L185-L204
function _update(
address from,
address to,
uint256 amount
) internal virtual override {
uint256 baseTax = swapTaxRate + burnTaxRate;
// Skip tax for whitelisted addresses or when fee collector disabled
if (baseTax == 0 || from == address(0) || to == address(0) || whitelistAddress[from] || whitelistAddress[to] || feeCollector == address(0)) {
super._update(from, to, amount);
return;
}
// All other cases where tax is applied
uint256 totalTax = amount.percentMul(baseTax);
uint256 burnAmount = totalTax * burnTaxRate / baseTax;
super._update(from, feeCollector, totalTax - burnAmount);
super._update(from, address(0), burnAmount); // @audit part of the amount in burned
super._update(from, to, amount - totalTax);
}

As one can see, part of the amount being moved is transferred to address(0) meaning it is burned instead of being transferred to the protocol or even to the receiver.

Impact

As a result, the address from which the funds are transferred loses part of it tokens since there not sent to address(0);

Tools Used

Manual review.

Recommendations

Also send burnAmount to feeCollector.

function _update(
address from,
address to,
uint256 amount
) internal virtual override {
uint256 baseTax = swapTaxRate + burnTaxRate;
// Skip tax for whitelisted addresses or when fee collector disabled
if (baseTax == 0 || from == address(0) || to == address(0) || whitelistAddress[from] || whitelistAddress[to] || feeCollector == address(0)) {
super._update(from, to, amount);
return;
}
// All other cases where tax is applied
uint256 totalTax = amount.percentMul(baseTax);
- uint256 burnAmount = totalTax * burnTaxRate / baseTax;
- super._update(from, feeCollector, totalTax - burnAmount);
+ super._update(from, feeCollector, totalTax);
- super._update(from, address(0), burnAmount);
super._update(from, to, amount - totalTax);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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