Summary
If a player transfer more than 1 ether during startGame()
, the excess ether can get stuck in the contract because when the player wins, they only receive back 2 ether.
Vulnerability Details
In startGame()
, this allows the user to transfer more than 1 ether even when the bet is 1 ether. And in endGame()
, the player receives 2 ether when he wins.
function startGame() public payable returns (uint256) {
address player = msg.sender;
require(msg.value >= 1 ether, "not enough ether sent");
initializeDeck(player);
uint256 card1 = drawCard(player);
uint256 card2 = drawCard(player);
addCardForPlayer(player, card1);
addCardForPlayer(player, card2);
return playersHand(player);
}
function endGame(address player, bool playerWon) internal {
delete playersDeck[player].playersCards;
delete dealersDeck[player].dealersCards;
delete availableCards[player];
if (playerWon) {
payable(player).transfer(2 ether);
emit FeeWithdrawn(player, 2 ether);
}
}
Impact
In the scenario where the player transfers 3 ether to startGame()
and won the game, he would only receive 2 ether back. And have 1 ether stuck in the contract.
Tools Used
Foundry
Recommendations
Implement a system to track how much player has transferred over and return the excess ether when a player wins or loses.
Check if msg.value == 1 ether instead
function startGame() public payable returns (uint256) {
address player = msg.sender;
- require(msg.value >= 1 ether, "not enough ether sent");
+ require(msg.value == 1 ether, "not enough ether sent");
initializeDeck(player);
uint256 card1 = drawCard(player);
uint256 card2 = drawCard(player);
addCardForPlayer(player, card1);
addCardForPlayer(player, card2);
return playersHand(player);
}