Summary
The removeSplitter function in the provided Solidity code attempts to withdraw the full token balance from a splitter contract, even after parts of the balance have been split and sent as rewards. This results in an incorrect balance being attempted for withdrawal.
Vulnerability Details
https://github.com/Cyfrin/2024-09-stakelink/blob/main/contracts/core/lstRewardsSplitter/LSTRewardsSplitterController.sol#L130-L153
-
Issue: The function does not account for the balance reduction after rewards are split and sent to receivers. It attempts to withdraw the previously cached balance, which may no longer be accurate, thereby leading to a failed token transfer
function removeSplitter(address _account) external onlyOwner {
ILSTRewardsSplitter splitter = splitters[_account];
if (address(splitter) == address(0)) revert SplitterNotFound();
uint256 balance = IERC20(lst).balanceOf(address(splitter));
uint256 principalDeposits = splitter.principalDeposits();
if (balance != 0) {
if (balance != principalDeposits) splitter.splitRewards();
splitter.withdraw(balance, _account);
}
}
}
Impact
High as splitter account can be deleted with remaining token balance
Tools Used
manual review
Recommendations
Adjust the function to accurately calculate the balance after rewards have been split and sent to receivers.
function removeSplitter(address _account) external onlyOwner {
ILSTRewardsSplitter splitter = splitters[_account];
if (address(splitter) == address(0)) revert SplitterNotFound();
uint256 balance = IERC20(lst).balanceOf(address(splitter));
uint256 principalDeposits = splitter.principalDeposits();
if (balance != 0) {
if (balance != principalDeposits) splitter.splitRewards();
uint256 balanceAfterSplit = IERC20(lst).balanceOf(address(splitter));
splitter.withdraw(balanceAfterSplit, _account);
}
}
}