Core Contracts

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

Improper Fee Collection and Distribution Logic in RAACToken and FeeCollector Contracts

Summary

There is a critical issue with the logic used to collect and distribute fees in the RAACToken and FeeCollector contracts. Specifically, the FeeCollector contract does not properly track and accumulate the fees sent from the RAACToken, which leads to incorrect fee distribution behavior. This vulnerability may cause the distributeCollectedFees function to fail and the fees to be improperly allocated or lost.

Vulnerability Details

  1. RAACToken Contract:

    • The RAACToken contract implements a tax system (swap tax and burn tax) on token transfers.

    • Part of the collected tax (swap tax) is transferred to the FeeCollector contract using the _transfer function in the _update method.

  2. FeeCollector Contract:

    • The FeeCollector contract is supposed to collect taxes sent to it and accumulate them.

    • However, when tokens are transferred to the FeeCollector contract, the collectFee function is not being called or properly triggered, leading to the collected fees not being tracked.

    • As a result, the fees that are supposed to be distributed via the distributeCollectedFees function are not properly accumulated and are essentially lost or incorrectly tracked.

Impact

  • Incorrect Fee Collection: The FeeCollector does not update its internal state (collectedFees) when tokens are transferred from the RAACToken. As a result, the total fees collected are not properly accounted for.

  • Disrupted Fee Distribution: Since the distributeCollectedFees function relies on the collectedFees variable, its execution may fail or result in incorrect distribution of fees.

  • Loss of Fees: Collected fees could be "lost" or inaccessible for future distribution, leading to potential losses for users relying on the fee distribution system (e.g., liquidity providers, stakers, etc.).

Tools Used

Manual Code Review

Recommendations

Code Fix for RAACToken:

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);
+ FeeCollector(feeCollector).collectFee(taxAmount);
}
}
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)) {
+ if (to == feeCollector || 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);
+ FeeCollector(feeCollector).collectFee(totalTax - burnAmount);
super._update(from, address(0), burnAmount);
super._update(from, to, amount - totalTax);
}
Updates

Lead Judging Commences

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

RAACToken::burn sends tax directly to FeeCollector without using collectFee(), causing tokens to bypass accounting and remain undistributed. `collectFee` is not used anywhere.

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

RAACToken::burn sends tax directly to FeeCollector without using collectFee(), causing tokens to bypass accounting and remain undistributed. `collectFee` is not used anywhere.

Support

FAQs

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