Last Man Standing

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

Zero feeIncreasePercentage Allowed in updateFeeIncreasePercentage Causes Static claimFee

Description

The Game contract’s updateClaimFeeParameters function allows the owner to set feeIncreasePercentage to any value from 0 to 100 via the isValidPercentage modifier. Setting feeIncreasePercentage to 0 causes the claimFee to remain static in claimThrone (using claimFee = claimFee + (claimFee * feeIncreasePercentage) / 100), breaking the intended mechanic of an escalating claimFee.

function updateClaimFeeParameters(
uint256 _newInitialClaimFee,
uint256 _newFeeIncreasePercentage
) external onlyOwner isValidPercentage(_newFeeIncreasePercentage) {
require(_newInitialClaimFee > 0, "Game: New initial claim fee must be greater than zero.");
initialClaimFee = _newInitialClaimFee;
@> feeIncreasePercentage = _newFeeIncreasePercentage;
emit ClaimFeeParametersUpdated(_newInitialClaimFee, _newFeeIncreasePercentage);
}
// Modifier
modifier isValidPercentage(uint256 _percentage) {
@> require(_percentage <= 100, "Game: Percentage must be 0-100.");
_;
}
function claimThrone() external payable gameNotEnded nonReentrant {
require(msg.value >= claimFee, "Game: Insufficient ETH sent to claim the throne.");
require(msg.sender == currentKing, "Game: You are already the king. No need to re-claim.");
// ...
@> claimFee = claimFee + (claimFee * feeIncreasePercentage) / 100;
// ...
}

Risk

Likelihood:

Owner can set feeIncreasePercentage = 0 intentionally or by mistake, as the modifier allows it.
Persists after resetGame, affecting all rounds.

Impact:

Static claimFee removes the escalating cost, reducing game competitiveness and allowing spamming claims at low cost.
Lower pot growth.

Proof of Concept

function test_ZeroFeeIncreasePercentage() public {
// Set feeIncreasePercentage to 0
vm.prank(deployer);
game.updateClaimFeeParameters(INITIAL_CLAIM_FEE, 0);
// Player1 claims throne
vm.prank(player1);
game.claimThrone{value: INITIAL_CLAIM_FEE}();
// Player2 claims throne
vm.prank(player2);
game.claimThrone{value: INITIAL_CLAIM_FEE}();
//there is no increase n the ClaimFee even after player 1 and 2 played
assertEq(game.claimFee(), 0.1 ether, "Claim fee remains static");
}

Recommended Mitigation

enforce a minimum percentage in the isValidPercentage modifier, ensuring the claimFee always increases.
This aligns with the game’s design and prevents static fees across all rounds.

modifier isValidPercentage(uint256 _percentage) {
- require(_percentage <= 100, "Game: Percentage must be 0-100.");
+ require(_percentage > 0 && _percentage <= 100, "Game: Percentage must be 1-100.");
_;
}
Updates

Appeal created

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!