The lack of fractional number support can lead to precision loss or rounding to zero in token distribution. This occurs when the token amount each winner should receive, based on their percentage share, is calculated. If the total tokens are small and a winner's share is less than 1%, the token amount could round down to zero. Similarly, if the total tokens are large and the winner's share results in a fractional token amount, the token amount could be rounded down, leading to a loss.
The _distribute
function in the Distributor.sol
may potentially lead to precision loss or rounding to zero. This is because the calculation totalAmount * percentages[i] / BASIS_POINTS
might not always result in a whole number. Solidity does not support floating point numbers, so any fractional part is truncated, which can lead to precision loss.
Moreover, if totalAmount * percentages[i]
is less than BASIS_POINTS (10_000)
, the result will be zero due to the way integer division works in Solidity. This could potentially lead to a situation where a winner is supposed to receive a small amount of tokens but receives none due to rounding to zero.
Let's consider a few examples:
Rounding down to zero:
Suppose totalAmount
is 1000 tokens, BASIS_POINTS
is 10000 (representing 100%), and a winner's percentage (percentages[i])
is 0.01% (which would be 1 in terms of basis points). The calculation would be: 1000 * 1 / 10000 = 0.1
.
Since Solidity doesn't support fractional numbers, this would be rounded down to 0. So, even though the winner should receive 0.1 tokens, they would receive none due to rounding down to zero.
Precision loss:
Suppose totalAmount
is 1000 tokens, BASIS_POINTS
is 10000, and a winner's percentage is 33.33% (which would be 3333 in terms of basis points). The calculation would be: 1000 * 3333 / 10000 = 333.3
.
Again, since Solidity doesn't support fractional numbers, this would be rounded down to 333. So, the winner would receive 333 tokens instead of 333.3, leading to a precision loss of 0.3 tokens.
Add the following test to the FuzzTestProxyFactory.t.sol
file.
Run the test using the command: forge test --match-test testDistributePrecisionLoss -vvv
.
The impact of this issue can be significant, especially in a scenario where a large number of tokens are being distributed among a large number of winners.
Loss of Funds: Winners could potentially lose funds due to the rounding down of their token amounts. In extreme cases, winners could end up receiving no tokens at all if their calculated token amount rounds down to zero.
Inequitable Distribution: The distribution of tokens may not accurately reflect the intended percentages due to rounding errors. This could lead to some winners receiving less than their fair share of tokens.
Manual Review
To mitigate this, it's important to ensure that the totalAmount
of tokens and the percentages are set in a way that prevents such precision loss or rounding to zero.
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.