The LSTRewardsSplitter contract distributes LST rewards to multiple recipients based on their fee percentages (basis points). The _splitRewards function uses integer division to calculate the reward amount for each recipient.
Integer division inherently truncates any remainder, leading to potential precision loss. In the context of reward distribution, this means small amounts of LST might remain undistributed after each split. While the loss might be negligible for individual transactions, it can accumulate over time, especially with a large number of splits or with fee percentages that result in repeating decimals.
Accumulated Loss: Precision loss can accumulate over time, leading to a significant amount of undistributed rewards trapped in the contract.
Unfair Distribution: While the loss might seem minor for individual recipients, it can lead to an unfair distribution over the long term.
Consider a scenario with three recipients and 100 tokens to distribute:
Recipient A: 33.33% (3333 basis points)
Recipient B: 33.33% (3333 basis points)
Recipient C: 33.34% (3334 basis points)
Due to integer division:
A receives 33 tokens.
B receives 33 tokens.
C receives 33 tokens.
This leaves 1 token undistributed.
There are a couple of approaches to mitigate this issue:
Distribute Remainder: Track the total distributed amount and distribute any remaining tokens to a designated address (as explained in the previous bug report).
Higher Precision Math: Use a higher precision for calculations. This can be achieved by multiplying the _rewardsAmount and fee.basisPoints by a large number (e.g., 10^18) before dividing. Dividing the result by the same large number to get the final amount.
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.