LSTRewardsSplitter contract allows to split the staking rewards between multiple accounts based on a list of customisable fees. The LSTRewardsSplitter::_splitRewards function invoked by an external LSTRewardsSplitter::splitRewards or LSTRewardsSplitter::performUpkeep function loops through the list of fees and their receivers splitting and sending the rewards accordingly. These loops can cause a Denial of Service.
One of the loops in LSTRewardsSplitter:
Due to this loop, every fee added increases the gas/time cost of any function that loops through the fees array at some point effectively preventing normal usage due to a huge price of the transaction.
Due to the a constraint of maximum 10000 BIPs per splitter, this array can have that many elements in the worst case scenario.
If the LSTRewardsSplitter owner adds a significant amount of fees (with either bad intentions or not - depending on the aggreement with other account holders), each additional fee increases the processing time and gas cost of splitting rewards transaction which results in diminishing returns from the staking itself, subsequently causing loses for the stakers and in the end preventing normal usage of the splitter.
The affected external functions are:
LSTRewardsSplitter::performUpkeep
LSTRewardsSplitter::splitRewards
LSTRewardsSplitter::addFee
LSTRewardsSplitter::updateFee
Add the following code to lst-rewards-splitter.test.ts
The above test outputs:
which shows the significantly increased cost and processing time of splitting rewards transaction.
Manual investigation
Hardhat tests
Consider adding a constraint on maximum number of fees or minimum number of BIPs per fee or a combination of both of these per splitter so the time/gas cost remains at reasonable levels even in worst case scenario.
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.