DatingDapp

AI First Flight #6
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: low
Likelihood: medium
Invalid

Unbounded Matches Array Can Cause DoS in getMatches

Root + Impact

Description

  • The `getMatches()` function returns the entire `matches[msg.sender]` array without any pagination or limits. If a user has many matches, this array could grow very large, causing the function to consume excessive gas and potentially exceed block gas limits, making it impossible to retrieve matches.

    ```solidity

    function getMatches() external view returns (address[] memory) {

    return matches[msg.sender]; // @> Unbounded array return

    }

    ```

    ### Root Cause

    The matches array grows indefinitely as users get matched, and there's no mechanism to limit or paginate the results.


Risk

Likelihood:

  • * Popular users could accumulate many matches over time

    * The array grows with each match, so this becomes more likely as the protocol gains users

    * This will occur whenever a user with many matches calls `getMatches()`

Impact:

  • * Function becomes unusable for users with many matches

    * Gas costs become prohibitive

    * Potential DoS if gas limit is exceeded

    * Frontend applications may fail to load user matches

Proof of Concept

```solidity
// User gets matched with 1000+ users
// Calling getMatches() tries to return all 1000+ addresses
// Gas cost exceeds block limit or becomes prohibitively expensive
// Function becomes unusable
```

Recommended Mitigation

```diff
+ uint256 public constant MAX_MATCHES_PER_QUERY = 50;
- function getMatches() external view returns (address[] memory) {
- return matches[msg.sender];
+ function getMatches() external view returns (address[] memory) {
+ return getMatchesPaginated(0, MAX_MATCHES_PER_QUERY);
+ }
+
+ function getMatchesPaginated(uint256 offset, uint256 limit) external view returns (address[] memory) {
+ address[] storage userMatches = matches[msg.sender];
+ uint256 length = userMatches.length;
+ if (offset >= length) {
+ return new address[](0);
+ }
+
+ uint256 end = offset + limit;
+ if (end > length) {
+ end = length;
+ }
+
+ address[] memory result = new address[](end - offset);
+ for (uint256 i = offset; i < end; i++) {
+ result[i - offset] = userMatches[i];
+ }
+ return result;
+ }
+
+ function getMatchesCount() external view returns (uint256) {
+ return matches[msg.sender].length;
+ }
```
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 16 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!