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);
}
}
contract TwentyOneTest is Test {
event PlayerWonTheGame(string message, uint256 cardsTotal);
.
.
.
function testTransferFailsIfMoreThan2300GasIsRequired() public {
SmartContractPlayerWithFallbackLogic scpFallbackLogic = new SmartContractPlayerWithFallbackLogic();
SmartContractPlayerWithoutFallbackLogic scpNoFallbackLogic = new SmartContractPlayerWithoutFallbackLogic();
vm.deal(address(scpFallbackLogic), 1 ether);
vm.deal(address(scpNoFallbackLogic), 1 ether);
vm.deal(address(twentyOne), 2 ether);
vm.startPrank(address(scpFallbackLogic));
uint256 playerHand1 = twentyOne.startGame{value: 1 ether}();
uint256 initialscpFallbackLogicBalance = address(scpFallbackLogic).balance;
vm.expectRevert();
vm.expectEmit(true, true, false, true);
emit PlayerWonTheGame("Dealer went bust, players winning hand: ", playerHand1);
twentyOne.call();
uint256 finalscpFallbackLogicBalance = address(scpFallbackLogic).balance;
assertEq(finalscpFallbackLogicBalance, initialscpFallbackLogicBalance);
vm.stopPrank();
vm.startPrank(address(scpNoFallbackLogic));
uint256 playerHand2 = twentyOne.startGame{value: 1 ether}();
uint256 initialscpNoFallbackLogicBalance = address(scpNoFallbackLogic).balance;
vm.warp(4);
vm.expectEmit(true, true, false, true);
emit PlayerWonTheGame("Dealer went bust, players winning hand: ", playerHand2);
twentyOne.call();
uint256 finalscpNoFallbackLogicBalance = address(scpNoFallbackLogic).balance;
assertGt(finalscpNoFallbackLogicBalance, initialscpNoFallbackLogicBalance);
vm.stopPrank();
}
}
contract SmartContractPlayerWithFallbackLogic {
uint256 total;
fallback() external payable {
total = msg.value;
}
}
contract SmartContractPlayerWithoutFallbackLogic {
fallback() external payable {}
}
Using the transfer function could make it impossible to send value in certain cases. This means that a winner would not receive their payout and would lose their win.
function endGame(address player, bool playerWon) internal {
delete playersDeck[player].playersCards; // Clear the player's cards
delete dealersDeck[player].dealersCards; // Clear the dealer's cards
delete availableCards[player]; // Reset the deck
if (playerWon) {
- payable(player).transfer(2 ether); // Transfer the prize to the player
- emit FeeWithdrawn(player, 2 ether); // Emit the prize withdrawal event
+ emit FeeWithdrawn(player, 2 ether); // Emit the prize withdrawal event
+ (bool success, ) = payable(player).call{value: 2 ether}(""); // Transfer the prize to the player
+ require(success, "Transfer failed");
}
}