Sablier

Sablier
DeFiFoundry
53,440 USDC
View results
Submission Details
Severity: low
Invalid

Lack of Pagination Support in getTranches Function

Summary

The getTranches function in the SablierV2LockupTranched contract retrieves all tranches associated with a given stream ID. Prior to the implementation of pagination, this function attempted to return all tranches in a single call. This design could lead to excessive gas consumption when dealing with streams that have a large number of tranches, potentially causing the function call to fail due to block gas limit constraints. This issue impacts the usability and scalability of the contract, particularly for streams with a significant number of tranches.

function getTranches(uint256 streamId)
external
view
override
notNull(streamId)
returns (LockupTranched.Tranche[] memory tranches)
{
tranches = _tranches[streamId];
}

Proof of Concept

To illustrate the impact, consider a scenario where a stream has 1000 tranches. A user calling the getTranches function to retrieve all tranches would incur high gas costs due to the large amount of data being processed and returned. In contrast, if pagination were supported, the user could retrieve tranches in smaller, more manageable chunks, significantly reducing gas costs and improving efficiency.

Impact

Without pagination, users may be unable to retrieve tranche information for streams with many tranches. This could prevent users from interacting with the contract as intended, leading to a suboptimal user experience and limiting the contract's functionality.

Tools Used

Manual Review

Recommendations

Implement pagination in the getTranches function by introducing parameters for the starting index and the number of tranches to retrieve. Here is the modified function:

function getTranches(uint256 streamId, uint256 startIndex, uint256 count)
external
view
override
notNull(streamId)
returns (LockupTranched.Tranche[] memory tranches)
{
LockupTranched.Tranche[] storage allTranches = _tranches[streamId];
uint256 totalTranches = allTranches.length;
// Ensure the requested range is within bounds
require(startIndex < totalTranches, "Invalid startIndex");
require(startIndex + count <= totalTranches, "Invalid count");
// Initialize the array to return the requested subset
tranches = new LockupTranched.Tranche[](count);
// Populate the array with the requested tranche subset
for (uint256 i = 0; i < count; i++) {
tranches[i] = allTranches[startIndex + i];
}
}

Explanation:

  1. Parameters: Introduces startIndex and count to specify the range of tranches to retrieve.

  2. Bounds Checking: Ensures the requested range is within the bounds of the array.

  3. Return Subset: Returns a subset of tranches based on the specified range.

Benefits of the Proposed Solution:

  1. By retrieving smaller subsets of tranches, users can significantly reduce gas costs.

  2. The contract can handle large datasets more efficiently, enhancing its scalability and performance.

  3. Users can interact with the contract more cost-effectively and efficiently, even when dealing with large numbers of tranches.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Info/Gas/Invalid as per Docs

https://docs.codehawks.com/hawks-auditors/how-to-determine-a-finding-validity

Support

FAQs

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