@> 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);
}
This test proves players can bypass fee increases by claiming after parameter updates, and cause revenue loss.
function testVulnerability_EconomicImpact() public {
uint256 expectedRevenue = 0;
uint256 actualRevenue = 0;
console2.log("=== ECONOMIC IMPACT ANALYSIS ===");
uint256 initialFee = game.claimFee();
expectedRevenue += initialFee;
actualRevenue += initialFee;
vm.prank(player1);
game.claimThrone{value: initialFee}();
console2.log("Claim 1 - Expected:", initialFee, "Actual:", initialFee);
uint256 newInitialFee = 5 ether;
vm.prank(owner);
game.updateClaimFeeParameters(newInitialFee, 20);
uint256 currentFee = game.claimFee();
expectedRevenue += newInitialFee;
actualRevenue += currentFee;
vm.prank(player2);
game.claimThrone{value: currentFee}();
console2.log("Claim 2 - Expected:", newInitialFee, "Actual:", currentFee);
console2.log("Revenue loss:", newInitialFee - currentFee);
uint256 thirdFee = game.claimFee();
expectedRevenue += thirdFee;
actualRevenue += thirdFee;
vm.prank(player3);
game.claimThrone{value: thirdFee}();
console2.log("Claim 3 - Expected:", thirdFee, "Actual:", thirdFee);
uint256 totalExpectedRevenue = expectedRevenue;
uint256 totalActualRevenue = actualRevenue;
uint256 revenueLoss = totalExpectedRevenue - totalActualRevenue;
uint256 lossPercentage = (revenueLoss * 100) / totalExpectedRevenue;
console2.log("\n=== ECONOMIC IMPACT SUMMARY ===");
console2.log("Total expected revenue:", totalExpectedRevenue);
console2.log("Total actual revenue:", totalActualRevenue);
console2.log("Revenue loss:", revenueLoss);
console2.log("Loss percentage:", lossPercentage, "%");
assertGt(lossPercentage, 50, "Revenue loss should be significant (>50%)");
}
Simple addition of the gameEndedOnly modifier prevents game manipulation and revenue loss.
function updateClaimFeeParameters(uint256 _newInitialClaimFee, uint256 _newFeeIncreasePercentage)
external
onlyOwner
+ gameEndedOnly
isValidPercentage(_newFeeIncreasePercentage)
{
require(_newInitialClaimFee > 0, "Game: New initial claim fee must be greater than zero.");
initialClaimFee = _newInitialClaimFee;
feeIncreasePercentage = _newFeeIncreasePercentage;
emit ClaimFeeParametersUpdated(_newInitialClaimFee, _newFeeIncreasePercentage);
}