The RockPaperScissors contract implements a commit-reveal pattern where both players first commit to a hashed move, then reveal their actual moves. However, the revelation process is vulnerable to frontrunning, where the second player can see the first player's move in the transaction mempool before deciding whether to reveal their own move or allow the timeout, creating an unfair advantage.
When the first player reveals their move by calling the revealMove
function, their choice becomes visible in the public mempool before being confirmed in a block. The second player can observe this move and make a strategic decision: if they would lose based on their committed move, they can simply abstain from revealing, forcing a timeout where they'll lose anyway (but without completing the game naturally). If they would win, they proceed with revealing. This selective revelation undermines the fairness the commit-reveal pattern is designed to ensure.
The critical issue is that when a player reveals their move, the actual move value is visible in the transaction parameters before being confirmed on-chain. The emit MoveRevealed
event also broadcasts this information publicly.
When one player reveals their move, the second player can:
See the first player's move before it's confirmed
Compare it against their own committed move to determine if they would win
If they would lose, simply not reveal and let the timeout occur
If they would win, proceed with revealing their move
This gives the second player a strategic advantage, as they can guarantee they never lose a game outright (only through timeout), while still collecting wins when possible.
Fairness compromised: The second player to reveal has a significant advantage.
Game theory undermined: The incentive is to wait for an opponent to reveal first.
Selective completion: Games will likely only complete when favorable to the second revealer.
Timeout abuse: Increased number of timeouts rather than natural game conclusions.
While this doesn't result in direct fund loss, it fundamentally undermines the fairness of the game and the commit-reveal mechanism, which is the core security pattern of the protocol.
Manual code review
Implement a two-phase reveal process:
Use a commit-reveal-with-timeout pattern:
Both players must reveal within a fixed timeframe
If only one reveals within the timeframe, they win
If neither reveals, game is cancelled
This ensures no advantage from being the second revealer
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.