DeFiFoundry
20,000 USDC
View results
Submission Details
Severity: medium
Invalid

The `unstakeAll` function does not interact with the `_streamIDs` mapping or update `NFTData` after unstaking

Summary

Vulnerability Details

The unstakeAll function is designed to unstake all active streams associated with the caller by iterating over their stream IDs and calling the unstake function. However, this function has a significant flaw: it does not interact with the _streamIDs mapping or update NFTData after unstaking. This oversight can lead to stale or incorrect information about a user's active streams and their corresponding data.
Code Analysis:
Here’s the function in question:

function unstakeAll() external {
uint256[] memory streamIDs = _streamIDs[msg.sender];
for (uint256 i = 0; i < streamIDs.length; i++) {
uint256 streamID = streamIDs[i];
if (activeStreams[streamID].stakedAmount > 0) {
unstake(streamID, activeStreams[streamID].stakedAmount);
}
}
// Missing interaction with `_streamIDs` and decrementing `NFTData`
}

Detailed Breakdown:

  1. Retrieving Stream IDs:

uint256[] memory streamIDs = _streamIDs[msg.sender];
  • This line retrieves the list of stream IDs associated with the caller. This list represents all active streams that the user has staked in.

  1. Iterating Over Stream IDs:

for (uint256 i = 0; i < streamIDs.length; i++) {
uint256 streamID = streamIDs[i];
if (activeStreams[streamID].stakedAmount > 0) {
unstake(streamID, activeStreams[streamID].stakedAmount);
}
}
  • The function iterates over each stream ID and checks if there is an amount staked. If so, it calls the unstake function with the amount staked. The unstake function presumably handles the logic of removing the staked amount.

  1. Missing Interactions:

  • Modification of _streamIDs: The function does not clear or update the entries in _streamIDs[msg.sender] after unstaking. This means that after unstaking, the stream IDs still exist in the mapping, potentially leading to stale data about the user’s active streams.

  • Decrementing NFTData: There is no code to decrement or update the NFTData associated with each stream. If the contract maintains a record of data (e.g., amount staked) in NFTData, this record remains outdated and incorrect if the stream is unstaked but not updated in the data structure.
    Example of Possible Data Inconsistency:
    Assume a user has staked tokens in three streams with IDs [1, 2, 3]. After calling unstakeAll:

  • _streamIDs[msg.sender] should ideally be empty or updated to reflect the removed streams.

  • NFTData related to streams [1, 2, 3] should be decremented to reflect the fact that the user no longer has staked amounts in these streams.
    If these updates are not performed:

  • The user’s active stream list still includes IDs [1, 2, 3], even though they are no longer staked.

  • The NFTData still holds the old staked amounts, which can lead to incorrect calculations or states in the contract.

Impact

  • Stale Data: Since _streamIDs is not updated, the list of stream IDs associated with the user remains unchanged. This can lead to inconsistencies if the user queries their active streams or if other parts of the contract rely on this mapping.

  • Incorrect NFTData: Without decrementing NFTData, the contract maintains incorrect records about the amount or status of the streams that have been unstaked. This discrepancy can lead to further issues such as inaccurate calculations, invalid user states, or incorrect reporting.

Tools Used

Manual

Recommendations

Update the _streamIDs mapping and decrement NFTData after unstaking each stream.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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