Skip to content

getRatingDistribution overflows uint16 when an agent has > ~6.5K reviews per dimension #15

Description

@dolceo

contracts/src/AgentReviewRegistry.sol:113-117:

for (uint256 i = 0; i < 6; i++) {
    goodRatios[i] = uint16((goodCounts[i] * 10000) / count);
    neutralRatios[i] = uint16((neutralCounts[i] * 10000) / count);
}

The intermediate goodCounts[i] * 10000 is computed in uint256 (fine), then divided by count to produce a value bounded by 10000. Since 10000 < type(uint16).max (= 65535), the cast itself never truncates — that's OK.

However, the real issue is the unbounded loop in _reviews[tokenId] at line 102:

for (uint256 i = 0; i < count; i++) {
    Review memory r = _reviews[tokenId][i];
    ...
}

This is an external view and has no gas in normal calls, but it copies a full Review struct (storage → memory) per iteration. For agents with thousands of reviews it will exceed block gas if ever called from a state-changing context, and it will eat the eth_call gas cap of many public RPC providers (50M-300M), making the function silently revert for popular agents in the marketplace frontend.

Consider:

  • bounding the iteration window (e.g. getRatingDistribution(tokenId, fromIndex, toIndex)), or
  • maintaining incremental goodCounts/neutralCounts storage as reviews are added.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions