The fee distribution mechanism in the FeeCollector introduces an unintended accumulation of fee shares into the treasury due to rounding errors due to the division calculations. When the collected fees are split among different stakeholders, the rounding effect disproportionately favors the treasury, leading to a gradual increase in its share over time.
When there are accumulated fees inside the FeeCollector contract, the distributor role calls the function distributeCollectedFees(). This function calls the _calculateDistribution() to calculate the shareholders' accurate values. Let's look at the _calculateDistribution() with details:
First of all, the global weight is calculated by multiplying the feeAmount (the amount of fee that is accumulated from one of the eight fee categories) then dividing by the totalFees. This weight is then used for calculating the individual shareholders' fee shares. Finally, the calculated shares are multiplied by the totalFees and divided by the BASIS_POINTS. Here due to the multiple priority of division over multiplication, a huge precision loss occurs.
This rounding error depends on the share factor of each 4 shareholders and also the accumulated fees and its amount may become great which makes an unfair treasury share mintings as the remainder, which calculates the remainder of the shares, escalates. As the remainder becomes high, the protocol sends mints them for the treasury shares.
As a consequence, the shares[3]which is the treasury shares, increase unintendedly.
Other stakeholders (veRAACShare, burnShare, and repairShare) receive slightly less than their intended share, reducing their expected rewards.
While each transaction might introduce a small rounding error, continuous operations over thousands of transactions significantly magnify the impact, potentially distorting the protocol’s economic model.
If we run this function, we can see the differences:
For testing purposes, we suppose the feeAmount to be 2.4e15, totalFees to be 7e18, and veRAACShare to be 5000 (a scenario where the insurance fee weight for distribution is being calculated inside the for loop). The result for this function would be:
This shows a 71% precision loss which is significant and can lead to wrong share calculation and a large remainder which will then be added to the treasury shares. Furthermore, an unfair treasury share distribution occurs here.
Manual
Consider modifying the share calculation mechanism with improving the precision to prevent such unfair fee distribution. A fixed-point math or WadMath libraries can be used here if it is not intended to change the calculations.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.