Core Contracts

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

`_calculateDistribution` does not allocate amounts correctly

Summary

Vulnerability Details

_calculateDistribution will not work well with 6th and 7th distribution, as they don't sum up to 100% like the rest:

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/collectors/FeeCollector.sol#L372-L394

// sums up to 100%
feeTypes[5] = FeeType({
veRAACShare: 7000, // 70%
burnShare: 0,
repairShare: 0,
treasuryShare: 3000 // 30%
});
// sums up to 20% (even comments are wrong, as 500 -> 5%)
feeTypes[6] = FeeType({
veRAACShare: 500, // 0.5%
burnShare: 500, // 0.5%
repairShare: 1000, // 1.0%
treasuryShare: 0
});
// sums up to 20%
feeTypes[7] = FeeType({
veRAACShare: 500, // 0.5%
burnShare: 0,
repairShare: 1000, // 1.0%
treasuryShare: 500 // 0.5%
});

This can be seen when we start the for loop.

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/collectors/FeeCollector.sol#L431-L457

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

The formula we use would calculate each distribution against it's weight to make it distribute the full 100% allocated to it, but for that each distribution needs to sum up to 100%. However the problem is that 6th and 7th don't, which would mean that they distribute only a tiny fraction of their amounts and leave the rest stuck inside the contract.

Example:

/**
* totalFees = 1000
*
* feeAmount1 = 100
* feeAmount2 = 500
* feeAmount3 = 250
* feeAmount6 = 150
*
* w1 = 100 * 10k / 1000 = 1000
* shares[0] += 1000 * 8000 / 10k = 800
* shares[3] += 1000 * 2000 / 10k = 200
*
* w2 = 500 * 10k / 1000 = 5000
* shares[0] += 5000 * 7000 / 10k = 3500
* shares[3] += 5000 * 3000 / 10k = 1500
*
* w3 = 250 * 10k / 1000 = 2500
* shares[0] += 2500 * 6000 / 10k = 1500
* shares[3] += 2500 * 4000 / 10k = 1000
*
* w6 = 150 * 10k / 1000 = 1500
* shares[0] += 1500 * 500 / 10k = 75
* shares[1] += 1500 * 500 / 10k = 75
* shares[2] += 1500 * 1000 / 10k = 150
*
* shares[0] = 5875
* shares[1] = 75
* shares[2] = 150
* shares[3] = 2700
*
* total = 8800
*
*/

As we can see from this drawn out example the total does not sum up to 10k, meaning that when we perform the bellow 1200 or 12% of the weight is not gonna be distributed and it's gonna end up in shares[3]

shares[0] = (totalFees * shares[0]) / BASIS_POINTS;
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]);
if (remainder > 0) shares[3] += remainder;

Impact

For is flawed, does not distribute amounts correctly
Assigns a huge percentage toward the treasury fee, where this percentage should have been distributed to the rest of the allocations

Tools Used

Manual review

Recommendations

Make sure all of the values sum up to 100%

Updates

Lead Judging Commences

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

Fee shares for fee type 6 and 7 inside FeeCollector do not total up to the expected 10000 basis points, this leads to update problems, moreover they are 10x the specifications

Support

FAQs

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

Give us feedback!