sherlock-audit / 2024-05-pooltogether-judging

9 stars 5 forks source link

AnasTur - Prize Pool Tier Manipulation via Claim Counts #61

Closed sherlock-admin4 closed 3 months ago

sherlock-admin4 commented 3 months ago

AnasTur

high

Prize Pool Tier Manipulation via Claim Counts

Summary

The computeNextNumberOfTiers function in the PrizePool contract is susceptible to manipulation, potentially leading to unfair prize distribution.

Vulnerability Detail

The computeNextNumberOfTiers function estimates the number of prize tiers for the next draw based on the current claimCount. This count can be manipulated by malicious actors who strategically claim prizes to influence the number of tiers, potentially skewing the prize distribution in their favor. The function also allows for the number of tiers to increase or decrease by a maximum of one tier per draw. This limitation could be exploited by attackers to gradually manipulate the tier distribution over multiple draws.

Impact

This vulnerability could lead to an unfair advantage for certain participants, as they could manipulate the number of tiers to increase their chances of winning or to concentrate prizes in specific tiers. This could undermine the trust and fairness of the prize pool system. Additionally, the one-tier change limit could be exploited to gradually manipulate the tier distribution over time, making it harder to detect the manipulation.

Code Snippet

https://github.com/sherlock-audit/2024-05-pooltogether/blob/main/pt-v5-prize-pool/src/PrizePool.sol#L852

function computeNextNumberOfTiers(uint32 _claimCount) public view returns (uint8) {
    if (_lastAwardedDrawId != 0) {
      // claimCount is expected to be the estimated number of claims for the current prize tier.
      uint8 nextNumberOfTiers = _estimateNumberOfTiersUsingPrizeCountPerDraw(_claimCount);
      // limit change to 1 tier
      uint8 _numTiers = numberOfTiers;
      if (nextNumberOfTiers > _numTiers) {
        nextNumberOfTiers = _numTiers + 1;
      } else if (nextNumberOfTiers < _numTiers) {
        nextNumberOfTiers = _numTiers - 1;
      }
      return nextNumberOfTiers;
    } else {
      return numberOfTiers;
    }
}

Tool used

Manual Review

Recommendation

Consider using a time-based or block-based approach for determining the number of tiers, rather than relying solely on the claimCount. This would make the system more resistant to manipulation. For example, the number of tiers could be adjusted based on the time elapsed since the last draw or the block number at which the draw is awarded. Additionally, consider removing or adjusting the one-tier change limit to prevent gradual manipulation over multiple draws. A more dynamic adjustment mechanism could be implemented to ensure a fair and unpredictable tier distribution.