In the _splitRewards function, there's a precision loss when calculating fee amounts.
The line in question is:
This calculation is used to determine the amount of rewards to be distributed for each fee. The issue arises due to how integer division works in Solidity.
In Solidity, when you divide two integers, the result is always rounded down to the nearest integer. This can lead to precision loss, especially when dealing with small numbers or percentages.
Here's a practical example:
Imagine we have a very small reward amount, say 5 tokens, and a fee with 100 basis points (1%).
When we plug these into the formula:
Even though 1% of 5 should be 0.05, because of integer division, the result is rounded down to 0. This means no fee would be paid in this case, even though there should be a small fee.
This precision loss becomes more significant with smaller reward amounts or smaller fee percentages. For instance:
With 99 tokens and a 1% fee: (99 * 100) / 10000 = 0 (should be 0.99)
With 1000 tokens and a 0.1% fee: (1000 * 10) / 10000 = 1 (should be 1.0)
In the second case, we get the correct result, but we wouldn't for any amount less than 1000.
Fee receivers will not receive fees for small transactions, leading to lost revenue over time.
Manual review
Fees transferred should be rounded up, and not down.
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.