The LSTRewardsSplitter contract has a flaw in its reward distribution mechanism, specifically within the splitRewards function. The contract does not verify whether the total of all fee receivers' basis points adds up to 10,000 (i.e., 100%). This omission can lead to a scenario where the total basis points are less than 10,000, meaning that not all rewards are distributed as intended. The remaining, undistributed rewards are incorrectly added to the contract’s principalDeposits, which can distort future reward calculations and result in inefficiencies or unintended reward distributions.
In the current implementation of the splitRewards
and performUpkeep
functions, new rewards are calculated as the difference between the contract’s LST token balance and the stored principalDeposits
:
int256 newRewards = int256(lst.balanceOf(address(this))) - int256(principalDeposits);
The total rewards are then distributed among the fee receivers based on their assigned basis points. The issue arises when the total basis points of all fee receivers do not add up to 10,000 (100%). This creates a scenario where not all rewards are allocated, leaving a portion of the rewards unclaimed. This unallocated amount is then added back to the principal deposits.
There is no check to make sure that the Fee Receivers receive the total rewards sent to the LSTRewardsSplitter; the performUpkeep can be triggered even when there are no Fee Receivers, and the splitRewards function can be called by anyone because it lacks access control.
If the sum of the fee receivers' basis points is less than 10,000, a portion of the rewards will not be distributed. These remaining rewards will be retained in the contract and added to the principalDeposits
.
This scenario creates inefficiencies in the reward distribution system, where not all rewards are effectively distributed to the designated recipients. Over time, this can result in an accumulation of unallocated rewards, reducing the intended efficiency of the rewards mechanism.
Manual Review
Add a validation check in the checkUpkeep and SplitReward function to ensure that the sum of all basis points equals exactly 10,000. before running the _splitReward.
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.