Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: medium
Invalid

Potential operator removal bypass in OperatorStakingPool

Summary

removeOperators function in the OperatorStakingPool has an issue in the way operators are removed. This can affect the removal process.

Vulnerability Details

Take a look at the removeOperators function of the OperatorStakingPool contract. Especially in the loop that removes operators from the operators array:
https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/linkStaking/OperatorStakingPool.sol#L163-L184

function removeOperators(address[] calldata _operators) external onlyOwner {
uint256 numOperators = operators.length;
for (uint256 i = 0; i < _operators.length; ++i) {
address operator = _operators[i];
if (!isOperator(operator)) revert OperatorNotFound();
uint256 staked = getOperatorStaked(operator);
if (staked != 0) {
_withdraw(operator, staked);
}
operatorMap[operator] = false;
for (uint256 j = 0; j < numOperators; ++j) {
if (operators[j] == operator) {
operators[j] = operators[numOperators - 1];
operators.pop();
--numOperators;
}
}
}
}

The issue lies in the inner loop. When an operator is found and removed, it's replaced by the last element of the array. But, the loop continues to the next index without rechecking the newly swapped element. This could cause operators to be skipped if they were moved to a position that has already been checked.

Impact

This issue could cause incomplete removal of operators. If multiple operators are to be removed, and one of the later operators in the removal list is swapped into a position that has already been checked, it will not be removed. This could result in unauthorized operators retaining their status.

Tools Used

Manual review

Recommendations

The inner loop in the removeOperators function should be modified to recheck the same index after a swap occurs.

for (uint256 j = 0; j < numOperators; ) {
if (operators[j] == operator) {
operators[j] = operators[numOperators - 1];
operators.pop();
--numOperators;
} else {
++j;
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.