The commitMove
function within the RockPaperScissors.sol
contract includes a require
statement intended to ensure the state related to the previous game turn (specifically, the revealed moves) is cleared before allowing a commit for the subsequent turn. However, the associated revert message, "Moves already committed for this turn"
, is inaccurate and misleading. This message incorrectly suggests that the check is preventing a double-commit within the current turn, a condition which is actually handled by separate checks later in the function. This discrepancy does not represent a security vulnerability but reduces code clarity and can significantly hinder debugging and user understanding of transaction failures.
Affected Function: RockPaperScissors.commitMove
Code Snippet:
Intended Purpose of Check: This specific require
statement (game.moveA == Move.None && game.moveB == Move.None
) is designed to act as a safeguard. It ensures that before a player can commit a move for turn N+1
, the revealed moves (moveA
, moveB
) from the completed turn N
have been reset to their default Move.None
state by the _determineWinner
function.
Actual Check for Double Commits: The prevention of committing twice within the same turn is correctly handled later in the function by these checks:
Message Discrepancy: The revert message "Moves already committed for this turn"
associated with the check on moveA
/moveB
is therefore incorrect. It describes the condition checked by the later commitA
/commitB
requirements, not the condition it is actually checking (which relates to the cleared state from the previous turn).
While the current logic in _determineWinner
correctly resets moveA
and moveB
, making this specific require
statement unlikely to trigger in normal operation, the misleading nature of the message can be understood conceptually:
Hypothetical State: Assume a multi-turn game where Turn N
has just concluded. Due to a hypothetical bug or modification in _determineWinner
, game.moveA
was not reset to Move.None
, but game.state
was set to Committed
and game.currentTurn
incremented to N+1
.
Action: Player A attempts to call commitMove
for Turn N+1
.
Expected Revert Reason: The transaction should revert because the precondition game.moveA == Move.None
is false, indicating the previous turn's state wasn't properly cleared.
Actual Revert Message: The transaction reverts with the message "Moves already committed for this turn"
.
Confusion: A developer or user seeing this message would likely assume Player A had already submitted commitA
for Turn N+1
, which is not the actual reason for the revert in this hypothetical scenario. The true reason (uncleared state from Turn N
) is obscured.
Reduced Code Clarity: The inaccurate message makes the code harder to understand and reason about.
Increased Debugging Time: Developers encountering this revert (especially if the condition could be met due to future code changes or unforeseen interactions) would be misled, potentially spending significant time investigating the wrong cause (double commits) instead of the actual state issue (uncleared previous moves).
User Confusion: Off-chain applications or users interpreting revert reasons would be confused about why their commit failed, potentially leading to incorrect assumptions or support requests.
Maintainability Issues: Misleading messages make future maintenance and refactoring more error-prone.
The severity is considered Low / Informational as it does not directly impact fund security or core game fairness logic but affects developer experience and code quality.
Manual Code Review
The revert string associated with the check should be updated to accurately reflect the condition being verified.
Modify Revert Message: Change the message in the commitMove
function:
Suggested Messages: Use a clearer message such as:
"Previous turn not resolved"
"Moves not cleared from previous turn"
"Waiting for previous turn state reset"
Implementing this change will improve code clarity and make debugging potential issues related to game state transitions more straightforward.
Code suggestions or observations that do not pose a direct security risk.
Code suggestions or observations that do not pose a direct security risk.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.