Liquid Staking

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

Array length mismatch in performUpkeep function

Summary

The performUpkeep function assumes that the length of the decoded splittersToCall array matches the length of the accounts array (which is used in the loop). If these lengths don't match, it could lead to out-of-bounds access or missed elements.

Vulnerability Details

In the given function:

function performUpkeep(bytes calldata _performData) external {
bool[] memory splittersToCall = abi.decode(_performData, (bool[]));
bool splitterCalled;
for (uint256 i = 0; i < splittersToCall.length; ++i) {
if (splittersToCall[i] == true) {
splitters[accounts[i]].performUpkeep("");
splitterCalled = true;
}
}
if (splitterCalled == false) {
revert InvalidPerformData();
}
}

https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/lstRewardsSplitter/LSTRewardsSplitterController.sol#L93C3-L107C6

The issue arises from the relationship between splittersToCall and accounts:

  1. splittersToCall is created by decoding _performData.

  2. The loop iterates over the length of splittersToCall.

  3. Inside the loop, accounts[i] is accessed.


The function assumes that splittersToCall.length and accounts.length are the same. However, there's no explicit check to ensure this.

If splittersToCall.length is greater than accounts.length:

  • When i becomes equal to accounts.length, but is still less than splittersToCall.length, the loop will continue.

  • This will cause accounts[i] to access an out-of-bounds index, potentially causing a runtime error.

Impact

When splittersToCall.length is less than accounts.length:

  • The loop will terminate before all accounts have been considered.

  • This means some accounts that should be processed will be missed.

Tools Used

Manual review

Recommendations

Add a check that ensures that the lengths match before proceeding with the loop:

function performUpkeep(bytes calldata _performData) external {
bool[] memory splittersToCall = abi.decode(_performData, (bool[]));
require(splittersToCall.length == accounts.length, "Length mismatch");
// ... rest of the function
}
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

Appeal created

sabit Submitter
about 1 year ago
sabit Submitter
about 1 year ago
inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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