Rock Paper Scissors

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

Redundant Tie Handling Function Due to Odd Turn Requirement

Summary

The Rock Paper Scissors game smart contract contains a _handleTie function that is theoretically unreachable due to the contract's requirement that all games must have an odd number of turns. This results in unused code that increases contract size, gas costs, and may indicate confusion about the game's mechanics or edge cases.

Vulnerability Details

The contract enforces that all created games must have an odd number of turns through a requirement in both game creation functions (createGameWithEth and createGameWithToken):

// From line 147 in createGameWithEth
require(_totalTurns % 2 == 1, "Total turns must be odd");
// From line 170 in createGameWithToken
require(_totalTurns % 2 == 1, "Total turns must be odd");

This requirement is specifically designed to prevent ties, as games with an odd number of turns will always result in one player having more wins than the other (assuming all turns are completed).

However, the contract still includes a _handleTie function (lines 588-622) that distributes rewards in the case of a tie. This function is referenced in _determineWinner:

// From lines 543-546 in _determineWinner
} else {
// This should never happen with odd turns, but just in case
// of timeouts or other unusual scenarios, handle as a tie
_handleTie(_gameId);
return;
}

The comment acknowledges that ties should be impossible with odd turns but suggests the function might be needed for "timeouts or other unusual scenarios." However, the contract's design doesn't create any scenarios where a properly initialized game with an odd number of turns would result in a tie, even with timeouts.

Impact

While this isn't a security vulnerability in the traditional sense, it has several negative impacts:

  1. Increased Contract Size: Unnecessary code increases the deployment cost and size of the contract.

  2. Maintenance Burden: Future developers maintaining the code might spend time understanding and maintaining a function that should never be used.

Tools Used

  • Manual code review

  • Logic flow analysis

Recommendations

  1. Remove the Redundant Function:
    The simplest solution is to remove the _handleTie function entirely and modify the _determineWinner function to not consider the tie case and use <= instead of < in the game turn check:

    function _determineWinner(uint256 _gameId) internal {
    Game storage game = games[_gameId];
    // ... existing code to determine turn winner ...
    // Reset for next turn or end game
    // change < to <=
    if (game.currentTurn <= game.totalTurns) {
    // ... existing reset code ...
    } else {
    // End game
    address winner;
    if (game.scoreA > game.scoreB) {
    winner = game.playerA;
    } else {
    // Since we require odd turns, scoreB must be greater than scoreA
    winner = game.playerB;
    }
    _finishGame(_gameId, winner);
    }
    }
Updates

Appeal created

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

Informational

Code suggestions or observations that do not pose a direct security risk.

Gas Optimization

Support

FAQs

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