Rock Paper Scissors

First Flight #38
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: low
Valid

Fee Rounding Vulnerability in Rock Paper Scissors Contract

Summary

The Rock Paper Scissors contract calculates protocol fees using integer division that rounds down, potentially allowing players to bypass fee payment entirely for small bet amounts. This can lead to reduced revenue collection for the protocol and could be intentionally exploited through strategic betting amounts.

Vulnerability Details

The vulnerability exists in the fee calculation mechanism within the _finishGame and _handleTie functions:

// From _finishGame function
uint256 totalPot = game.bet * 2;
uint256 fee = (totalPot * PROTOCOL_FEE_PERCENT) / 100;
// Similarly in _handleTie function
uint256 totalPot = game.bet * 2;
uint256 fee = (totalPot * PROTOCOL_FEE_PERCENT) / 100;

Due to Solidity's integer division behavior, when (totalPot * PROTOCOL_FEE_PERCENT) is less than 100, the result will round down to zero. With PROTOCOL_FEE_PERCENT set to 10, this means that any total pot less than 10 wei will result in zero fees being collected.

For example:

  • With a bet of 4 wei, the total pot is 8 wei

  • Fee calculation: (8 * 10) / 100 = 0 (rounded down from 0.8)

  • No fees are collected despite the game being played

Impact

This vulnerability has several negative impacts:

  1. Loss of Protocol Revenue: Small-bet games will generate no fees at all, reducing overall protocol revenue.

  2. Exploitation Potential: Players could intentionally choose small bet amounts to avoid paying fees while still using the protocol functionality.

  3. Economic Inefficiency: The fee structure becomes regressive, charging proportionally less for smaller games than larger ones.

While the minimum bet is set at 0.01 ether (which is large enough that fees will be collected), the contract lacks proper validation that could prevent players from bypassing this minimum in certain scenarios.

Tools Used

Manual code review and analysis of the integer division behavior in Solidity.

Recommendations

To address this vulnerability, I recommend the following solutions:

  1. Use Fixed-Point Arithmetic: Implement a more precise calculation method:

// Calculate with higher precision
uint256 fee = (totalPot * PROTOCOL_FEE_PERCENT * 10**18) / (100 * 10**18);

By implementing these changes, the protocol will ensure consistent fee collection regardless of bet size, maintaining a fair economic model for all participants.

Updates

Appeal created

m3dython Lead Judge about 2 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Rounding Error

The tie-handling logic loses one wei due to integer division

Support

FAQs

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