Core Contracts

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

RAACToken's tax mechanism may affect collectFee function in the FeeCollector contract

Summary

The collectFee function in the FeeCollector contract calls raacToken.safeTransferFrom(msg.sender, address(this), amount) to transfer tokens from the sender to the contract. However, due to the tax mechanism implemented in the RAACToken contract, the actual amount of tokens received by the FeeCollector may be less than the specified amount. This discrepancy arises because the RAACToken contract applies swap and burn taxes on transfers, reducing the amount received by the FeeCollector.

Vulnerability Details

The collectFee function in the FeeCollector contract calls raacToken.safeTransferFrom(msg.sender, address(this), amount) to transfer tokens from the sender to the contract.

function collectFee(uint256 amount, uint8 feeType) external override nonReentrant whenNotPaused returns (bool) {
if (amount == 0 || amount > MAX_FEE_AMOUNT) revert InvalidFeeAmount();
if (feeType > 7) revert InvalidFeeType();
// Transfer tokens from sender
raacToken.safeTransferFrom(msg.sender, address(this), amount);
// Update collected fees
_updateCollectedFees(amount, feeType);
emit FeeCollected(feeType, amount);
return true;
}

The RAACToken contract applies swap and burn taxes on token transfers via the _update function:

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);
super._update(from, to, amount - totalTax);
}
  • When collectFee calls raacToken.safeTransferFrom(msg.sender, address(this), amount), the RAACToken contract deducts swap and burn taxes from the amount.

  • The actual amount received by the FeeCollector is:

    actualAmount = amount - (amount * (swapTaxRate + burnTaxRate) / 10000)
  • However, the FeeCollector updates its internal state (collectedFees) using the original amount, leading to an inconsistency between the recorded and actual fees.

Impact

  • The FeeCollector contract overstates the amount of fees collected, which can lead to incorrect calculations in reward distribution and other fee-related operations.

  • This discrepancy undermines the accuracy and reliability of the protocol's fee tracking mechanism.

The impact is Medium, the likelihood is Low, so the severity is Low.

Tools Used

Manual Review

Recommendations

Consider following fix:

function collectFee(uint256 amount, uint8 feeType) external override nonReentrant whenNotPaused returns (bool) {
if (amount == 0 || amount > MAX_FEE_AMOUNT) revert InvalidFeeAmount();
if (feeType > 7) revert InvalidFeeType();
// Get the contract's balance before the transfer
uint256 balanceBefore = raacToken.balanceOf(address(this));
// Transfer tokens from sender
raacToken.safeTransferFrom(msg.sender, address(this), amount);
// Get the contract's balance after the transfer
uint256 balanceAfter = raacToken.balanceOf(address(this));
// Calculate the actual amount received
uint256 actualAmount = balanceAfter - balanceBefore;
// Update collected fees with the actual amount received
_updateCollectedFees(actualAmount, feeType);
emit FeeCollected(feeType, actualAmount);
return true;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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