Calls by the owner to the LSTRewardsSplitterController::removeSplitter
function always revert when the splitter has accrued rewards, due to the incorrect use of an outdated balance when calling the splitter's withdraw function.
The LSTRewardsSplitterController::removeSplitter
function is intended to be called by the contract owner to remove an account's splitter. During this action, the splitter balance is checked, and if it is non-zero and not equal to the principal deposits, the splitter::splitRewards
function is called to distribute the rewards among the fee receivers.
The problem arises because, after this action, the splitter::withdraw
function is called with the previously checked splitter token balance instead of an updated balance, which results in the call always reverting under these conditions.
To better illustrate:
Let's assume the splitter balance is 200 and the principal deposits are 100. During the split, assuming total fees are 50%, 50% of 100 equals 50, making the new principal deposits equal to 100 + 50, which results in 150. Thus, the new balance becomes 150.
However, the function then tries to withdraw using prior balance, causing a revert since 150 - 200 will result in an underflow revert:
I have added a runnable POC demonstrating the issue below. Please add the following test to test/core/lst-rewards-splitter.test.ts
, and then run:
Here are the logs:
A malicious user can force a revert by sending some lst
tokens to the splitter, hence blocking the removal of the splitter.
Even without malicious intervention, the function will always revert whenever the splitter to be removed has accrued rewards.
Manual Review
Update LSTRewardsSplitterController::removeSplitter to:
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.