Core Contracts

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

Invalid fee distribution in `FeeCollector::_calculateDistribution()`

Summary

The FeeCollector is used to distribute fees, which are distributed as rewards to different entities, including veRAACToken holders. However, the way the current _calculateDistribution works, is that it first calculates each fee type's weight, and then it uses this weight to calculate the fee share based on the total fees. This introduces double percentage calculation which compounds precision loss.

Vulnerability Details

If we look at the fee distribution calculations:

function _calculateDistribution(uint256 totalFees) internal view returns (uint256[4] memory shares) {
uint256 totalCollected;
for (uint8 i = 0; i < 8; i++) {
uint256 feeAmount = _getFeeAmountByType(i);
if (feeAmount == 0) continue;
FeeType memory feeType = feeTypes[i];
totalCollected += feeAmount;
@> uint256 weight = (feeAmount * BASIS_POINTS) / totalFees; // @audit - initial source of precision loss, due to integer division
@> shares[0] += (weight * feeType.veRAACShare) / BASIS_POINTS;
shares[1] += (weight * feeType.burnShare) / BASIS_POINTS;
shares[2] += (weight * feeType.repairShare) / BASIS_POINTS;
shares[3] += (weight * feeType.treasuryShare) / BASIS_POINTS;
}
if (totalCollected != totalFees) revert InvalidFeeAmount();
@> shares[0] = (totalFees * shares[0]) / BASIS_POINTS; // @audit - if any precision loss is present then this will further compound it
shares[1] = (totalFees * shares[1]) / BASIS_POINTS;
shares[2] = (totalFees * shares[2]) / BASIS_POINTS;
shares[3] = (totalFees * shares[3]) / BASIS_POINTS;
@> uint256 remainder = totalFees - (shares[0] + shares[1] + shares[2] + shares[3]); // @audit - treasury get unfair amount of tokens
if (remainder > 0) shares[3] += remainder;
}

From the above, we can see that the precision loss is compounded, leading to an unfair distribution to the treasury, where the funds could have gone to the veRAACToken holders, or burned, or to the repairFund.

Impact

Fees are unevenly distributed, where tokens that should go to veRAAC holders go to the treasury.

Tools Used

Manual review

Recommendations

Remove the first weight percentage calculation, and directly apply the fee type share on the fee amount.

Updates

Lead Judging Commences

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

FeeCollector distributes too much to treasury when fee amounts are small relative to total due to precision loss in (feeAmount * BASIS_POINTS) / totalFees

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

FeeCollector distributes too much to treasury when fee amounts are small relative to total due to precision loss in (feeAmount * BASIS_POINTS) / totalFees

Support

FAQs

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

Give us feedback!