11// SPDX-License-Identifier: MIT
2- pragma solidity 0.8.24 ;
2+ pragma solidity 0.8.26 ;
33
44import "@openzeppelin/contracts/security/ReentrancyGuard.sol " ;
55import "@openzeppelin/contracts/access/Ownable.sol " ;
66
77contract AgentTrumpGame is ReentrancyGuard , Ownable {
8- // State variables remain the same
98 uint256 public gameEndTime;
109 uint256 public constant INITIAL_GAME_DURATION = 30 minutes ;
1110 uint256 public constant ESCALATION_PERIOD = 5 minutes ;
@@ -28,7 +27,6 @@ contract AgentTrumpGame is ReentrancyGuard, Ownable {
2827
2928 mapping (address => PlayerResponse[]) public playerResponses;
3029
31- // Events remain the same
3230 event GuessSubmitted (
3331 address indexed player ,
3432 uint256 amount ,
@@ -42,45 +40,44 @@ contract AgentTrumpGame is ReentrancyGuard, Ownable {
4240 event EscalationStarted (uint256 startTime );
4341 event GameExtended (uint256 newEndTime , uint256 newMultiplier );
4442
45- // Constructor and other functions remain the same until endGame
4643 constructor () Ownable (msg .sender ) {
4744 gameEndTime = block .timestamp + INITIAL_GAME_DURATION;
4845 currentMultiplier = 100 ;
4946 lastGuessTime = block .timestamp ;
5047 currentRequiredAmount = GAME_FEE;
5148 }
5249
53- // Modified endGame function
5450 function endGame () external onlyOwner nonReentrant {
5551 require (totalCollected > 0 , "No funds to distribute " );
5652 require (lastPlayer != address (0 ), "No players participated " );
5753
58- uint256 lastPlayerReward = (totalCollected * 10 ) / 100 ;
59- uint256 ownerReward = totalCollected - lastPlayerReward;
54+ uint256 ownerReward;
55+ uint256 lastPlayerReward;
56+
57+ if (block .timestamp >= gameEndTime) {
58+ lastPlayerReward = (totalCollected * 10 ) / 100 ;
59+ ownerReward = totalCollected - lastPlayerReward;
60+
61+ (bool success1 , ) = payable (lastPlayer).call {value: lastPlayerReward}("" );
62+ require (success1, "Last player reward transfer failed " );
63+ } else {
64+ ownerReward = totalCollected;
65+ }
6066
6167 totalCollected = 0 ;
6268
63- (bool success1 , ) = payable (lastPlayer).call {value: lastPlayerReward}("" );
64- require (success1, "Last player reward transfer failed " );
65-
6669 (bool success2 , ) = payable (owner ()).call {value: ownerReward}("" );
6770 require (success2, "Owner reward transfer failed " );
6871
69- // Update game state
7072 gameEndTime = block .timestamp ;
7173 gameWon = false ;
7274
7375 emit GameEnded (lastPlayer, lastPlayerReward, ownerReward);
7476 }
7577
76- // Rest of the contract functions remain unchanged
77- function deposit () external payable onlyOwner {
78- require (msg .value > 0 , "Must deposit some ETH " );
79- }
80-
8178 function withdraw () external onlyOwner {
82- require (block .timestamp > gameEndTime || gameWon, "Game still in progress " );
8379 require (address (this ).balance > 0 , "No balance to withdraw " );
80+ require (totalCollected == 0 , "Must call endGame first to distribute rewards " );
8481
8582 (bool success , ) = payable (owner ()).call {value: address (this ).balance}("" );
8683 require (success, "Withdraw failed " );
@@ -107,30 +104,46 @@ contract AgentTrumpGame is ReentrancyGuard, Ownable {
107104 require (bytes (response).length > 0 , "Response cannot be empty " );
108105 require (bytes (response).length <= 1000 , "Response too long " );
109106
107+ bytes memory responseBytes = bytes (response);
108+ for (uint i = 0 ; i < responseBytes.length ; i++ ) {
109+ require (
110+ // Basic printable ASCII (includes letters, numbers, basic punctuation)
111+ (responseBytes[i] >= 0x20 && responseBytes[i] <= 0x7E ) ||
112+ // Additional special characters
113+ responseBytes[i] == 0x2C || // comma
114+ responseBytes[i] == 0x3B || // semicolon
115+ responseBytes[i] == 0x22 || // double quote "
116+ responseBytes[i] == 0x27 || // single quote/apostrophe '
117+ // You can add more special characters here if needed
118+ false ,
119+ "Invalid character in response "
120+ );
121+ }
122+
123+ // Rest of the function remains unchanged
124+ uint256 requiredAmount = getCurrentRequiredAmount ();
125+ require (msg .value >= requiredAmount, "Insufficient payment " );
126+
110127 if (shouldStartEscalation ()) {
111128 escalationActive = true ;
112129 escalationStartTime = block .timestamp ;
113130 currentRequiredAmount = GAME_FEE * BASE_MULTIPLIER / 100 ;
114131 emit EscalationStarted (escalationStartTime);
115132 }
116-
117- require (msg .value >= currentRequiredAmount, "Insufficient payment " );
118133
119134 if (shouldExtendGame ()) {
120135 gameEndTime = block .timestamp + ESCALATION_PERIOD;
121136 currentRequiredAmount = currentRequiredAmount * BASE_MULTIPLIER / 100 ;
122137 emit GameExtended (gameEndTime, currentRequiredAmount);
123138 }
124139
125- require (block .timestamp <= gameEndTime, "Game has ended " );
126-
127- if (msg .value > currentRequiredAmount) {
128- uint256 excess = msg .value - currentRequiredAmount;
140+ if (msg .value > requiredAmount) {
141+ uint256 excess = msg .value - requiredAmount;
129142 (bool success , ) = payable (msg .sender ).call {value: excess}("" );
130143 require (success, "Refund failed " );
131144 }
132145
133- uint256 ownerShare = (currentRequiredAmount * 30 ) / 100 ;
146+ uint256 ownerShare = (requiredAmount * 30 ) / 100 ;
134147 (bool success2 , ) = payable (owner ()).call {value: ownerShare}("" );
135148 require (success2, "Owner payment failed " );
136149
@@ -142,25 +155,25 @@ contract AgentTrumpGame is ReentrancyGuard, Ownable {
142155
143156 uint256 responseIndex = playerResponses[msg .sender ].length - 1 ;
144157
145- totalCollected += (currentRequiredAmount - ownerShare);
158+ totalCollected += (requiredAmount - ownerShare);
146159 lastPlayer = msg .sender ;
147160 lastGuessTime = block .timestamp ;
148161
149162 emit GuessSubmitted (
150163 msg .sender ,
151- currentRequiredAmount ,
164+ requiredAmount ,
152165 currentMultiplier,
153166 response,
154167 block .timestamp ,
155168 responseIndex
156169 );
157170 }
158171
159- function getPlayerResponseCount (address player ) external view returns (uint256 ) {
172+ function getPlayerResponseCount (address player ) public view returns (uint256 ) {
160173 return playerResponses[player].length ;
161174 }
162175
163- function getPlayerResponseByIndex (address player , uint256 index ) external view returns (
176+ function getPlayerResponseByIndex (address player , uint256 index ) public view returns (
164177 string memory response ,
165178 uint256 timestamp ,
166179 bool exists
@@ -170,7 +183,7 @@ contract AgentTrumpGame is ReentrancyGuard, Ownable {
170183 return (playerResponse.response, playerResponse.timestamp, playerResponse.exists);
171184 }
172185
173- function getAllPlayerResponses (address player ) external view returns (
186+ function getAllPlayerResponses (address player ) public view returns (
174187 string [] memory responses ,
175188 uint256 [] memory timestamps ,
176189 bool [] memory exists
@@ -192,7 +205,6 @@ contract AgentTrumpGame is ReentrancyGuard, Ownable {
192205 }
193206
194207 function buttonPushed (address winner ) external onlyOwner nonReentrant {
195- require (block .timestamp <= gameEndTime, "Game has ended " );
196208 require (! gameWon, "Game already won " );
197209 require (winner != address (0 ), "Invalid winner address " );
198210 require (playerResponses[winner].length > 0 , "Winner must have submitted at least one response " );
@@ -207,20 +219,24 @@ contract AgentTrumpGame is ReentrancyGuard, Ownable {
207219 emit GameWon (winner, reward);
208220 }
209221
210- function getTimeRemaining () external view returns (uint256 ) {
222+ function getTimeRemaining () public view returns (uint256 ) {
211223 if (block .timestamp >= gameEndTime) return 0 ;
212224 return gameEndTime - block .timestamp ;
213225 }
214226
215- function getContractBalance () external view returns (uint256 ) {
227+ function getContractBalance () public view returns (uint256 ) {
216228 return address (this ).balance;
217229 }
218230
219- function getCurrentEscalationPeriod () external view returns (uint256 ) {
231+ function getCurrentEscalationPeriod () public view returns (uint256 ) {
220232 if (! escalationActive) return 0 ;
221233 return (block .timestamp - escalationStartTime) / ESCALATION_PERIOD;
222234 }
223235
236+ function deposit () external payable onlyOwner {
237+ require (msg .value > 0 , "Must deposit some ETH " );
238+ }
239+
224240 receive () external payable {}
225241 fallback () external payable {}
226242}
0 commit comments