Description: In the TwentyOne:startGame function, the game accepts deposits exceeding 1 ether.
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);
}
However, the game only pays out a maximum of 2 ether. This means that players might not win the full amount they bet and could even incur a loss despite winning.
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:
This can breaks the game logic, players did not won the value they bet and players can lose money despite winning.
Proof of Concept:
PLAYER deposits 3 ether.
PLAYER wins the game.
Add the following code into TwentyOne.t.sol:
Proof of Code
```solidity
modifier fundTwentyOne() {
vm.deal(address(twentyOne), 100 ether); // Fund the contract with 10 ether
_;
}
...
function test_player_send_more_than_required_eth() public fundTwentyOne {
vm.startPrank(player1);
uint256 initialPlayerBalance = player1.balance;
twentyOne.startGame{value: 3 ether}();
vm.recordLogs();
twentyOne.call();
Vm.Log[] memory logs = vm.getRecordedLogs();
assertEq(logs[0].topics[0], keccak256("PlayerWonTheGame(string,uint256)"));
uint256 finalPlayerBalance = player1.balance;
assertEq(finalPlayerBalance, initialPlayerBalance - 1 ether);
vm.stopPrank();
}
```
run forge test --mt test_player_send_more_than_required_eth and you will see the test pass (final player balance < initial player balance).
Recommended Mitigation:
Ensure that the game only accepts deposits of 1 ether in TwentyOne:startGame function.
function startGame() public payable returns (uint256) {
address player = msg.sender;
- require(msg.value >= 1 ether, "not enough ether sent");
+ require(msg.value == 1 ether, "only 1 ether allowed");
initializeDeck(player);
uint256 card1 = drawCard(player);
uint256 card2 = drawCard(player);
addCardForPlayer(player, card1);
addCardForPlayer(player, card2);
return playersHand(player);
}