Last Man Standing

First Flight #45
Beginner FriendlyFoundrySolidity
100 EXP
View results
Submission Details
Impact: medium
Likelihood: low
Invalid

Owner Can Change Game Parameters Mid-Round, Potentially Manipulating the Game

Description

  • Game parameters like gracePeriod, initialClaimFee, feeIncreasePercentage, and platformFeePercentage are adjustable by the owner to configure gameplay, with the expectation that they remain consistent during a round for fairness.

  • The owner can update these parameters at any time via functions like updateGracePeriod(), and the changes take effect immediately, even mid-round, potentially altering the game’s outcome unfairly (e.g., shortening the grace period to favor the current king).

function updateGracePeriod(uint256 _newGracePeriod) external onlyOwner {
require(_newGracePeriod > 0, "Game: New grace period must be greater than zero.");
//@> gracePeriod = _newGracePeriod;
emit GracePeriodUpdated(_newGracePeriod);
}

Risk

Likelihood:

  • This occurs when the owner decides to adjust parameters during an active game round, which depends on their discretion.

  • It’s less frequent unless the owner has a motive, such as being a player or colluding with one.

Impact:

  • Players face unfair conditions if rules change unexpectedly, potentially losing their chance to claim the throne or win the pot.

  • Trust in the game diminishes, deterring participation and affecting its reputation.

Proof of Concept

// 1. Game starts with gracePeriod = 24 hours.
// 2. Player A claims the throne at block.timestamp = 1000.
// 3. At block.timestamp = 1012 (12 hours later), owner calls:
Game.updateGracePeriod(3600); // 1 hour
// 4. Grace period expires at 1000 + 3600 = 4600, and declareWinner() can be called immediately since 1012 > 1000 + 1 hour.
// 5. Game ends earlier than the original 24 hours, limiting other players’ chances.

Recommended Mitigation

Make parameter changes apply only to the next round by using separate variables:

contract Game is Ownable {
uint256 public gracePeriod; // Current round
+ uint256 public nextGracePeriod; // Next round
// Similarly for initialClaimFee, feeIncreasePercentage, platformFeePercentage
constructor(...) {
// ...
+ nextGracePeriod = _gracePeriod;
gracePeriod = initialGracePeriod;
}
function updateGracePeriod(uint256 _newGracePeriod) external onlyOwner {
require(_newGracePeriod > 0, "Game: New grace period must be greater than zero.");
- gracePeriod = _newGracePeriod;
+ nextGracePeriod = _newGracePeriod;
emit GracePeriodUpdated(_newGracePeriod);
}
function resetGame() external onlyOwner gameEndedOnly {
// ...
- gracePeriod = initialGracePeriod;
+ gracePeriod = nextGracePeriod;
// Apply other next-round parameters similarly
}
}
Updates

Appeal created

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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