Adding too many splitters can cause a denial of service
Description
The addSplitter
function is an onlyOwner
function that adds a splitter to the contract's list:
function addSplitter(
address _account,
LSTRewardsSplitter.Fee[] memory _fees
) external onlyOwner {
if (address(splitters[_account]) != address(0)) revert SplitterAlreadyExists();
address splitter = address(new LSTRewardsSplitter(lst, _fees, owner()));
splitters[_account] = ILSTRewardsSplitter(splitter);
accounts.push(_account);
IERC677(lst).safeApprove(splitter, type(uint256).max);
}
This function runs in constant time, so it can be called an unlimited number of times by the owner, no matter how many items are in the accounts
array.
But if it is called too many times, then it may be impossible to perform upkeep or use this contract because the gas fees required to iterate through the accounts
array is too high.
Impact
Unexpected out-of-gas reverts can occur if too many splitters are added.
Note that although removeSplitter
does have a loop that loops through accounts
, this loop exits early if the target account is found:
uint256 numAccounts = accounts.length;
for (uint256 i = 0; i < numAccounts; ++i) {
if (accounts[i] == _account) {
accounts[i] = accounts[numAccounts - 1];
accounts.pop();
break;
}
}
Thus, removing the first account will always take a constant amount of gas. So, if this brick occurs, then it can be resolved by removing and re-adding splitters that are earlier in the array.
Recommendations
We recommend hardcoding a reasonable upper limit on the number of splitters, in order to fail noisily and early if it is reached. This is better because it is safer to fail on the addition of a new splitter than it is at any other part of the business logic.
If the above recommendation is taken, then we additionally recommend adding tests that reach that limit so that the gas costs at the limit can be monitored through any future development.
Remediation
In addition Stake.link has provided the following response:
We will ensure that the number of splitters will always be small.