Rock Paper Scissors

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

Reentrancy in `joinGameWithToken`

Summary

The joinGameWithToken function in RockPaperScissors.sol is prone to reentrancy attacks due to the lack of a reentrancy guard when interacting with an external contract.

Vulnerability Details

This vulnerability is as a result of unsafe external call. The function calls winningToken.transferFrom to transfer tokens to the contract. This could be
exploited by a malicious token contract to re-enter the joinGameWithToken function before the internal state changes are committed and disrupt the game state, which may lead to unexpected behavior and other risks.

function joinGameWithToken(uint256 _gameId) external {
Game storage game = games[_gameId];

function joinGameWithToken(uint256 _gameId) external {
Game storage game = games[_gameId];
require(game.state == GameState.Created, "Game not open to join");
require(game.playerA != msg.sender, "Cannot join your own game");
require(block.timestamp <= game.joinDeadline, "Join deadline passed");
require(game.bet == 0, "This game requires ETH bet");
require(winningToken.balanceOf(msg.sender) >= 1, "Must have winning token");
// Transfer token to contract
winningToken.transferFrom(msg.sender, address(this), 1);
game.playerB = msg.sender;
emit PlayerJoined(_gameId, msg.sender);
}

Attack Scenario

An attacker can call back the joinGameWithToken function with their malicious token before playerB is set/updated.

Since playerB has not been assigned, the attacker can bypass the checks in place to join multiple times or drain all the tokens.

Impact

  • An attacker can join the game multiple times, thus breaking the game logic.

  • The attacker could disrupt the flow of the game by calling the function multiple times, which may cause the contract to show unexpected behaviors, or potentially leading to a DoS attack.

Tools Used

  • Manual Code Review

  • Slither

Recommendations

Make use of OpenZeppelin's ReentrancyGuard to prevent reentrant calls to the function.

Updates

Appeal created

m3dython Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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