Description
The defensive check below does not work as intended:
if (currentPlatformFee > (sentAmount - previousKingPayout)) {
currentPlatformFee = sentAmount - previousKingPayout;
}
This is because previousKingPayout
is set to 0
on every call. As a result, the deployer can make currentPlatformFee
a very large amount by setting platformFeePercentage
to a high value.
This check will always pass:
If platformFeePercentage
is 50%, then:
0.55 > (1.1 - 1)
→ currentPlatformFee = 0.1
, which correctly limits the platform fee.
But if previousKingPayout
is 0
, then:
0.55 < (1.1 - 0)
→ currentPlatformFee = 0.55
,
which makes the platform fee exceed the available post-payout balance.
At some point, the platform fee exceeds the pot, leaving no incentive for new players to claim the throne due to the low or zero reward.
Proof of Concept
Before that, edit this value in Game.t.sol just to show the damage:
+ import "@openzeppelin/contracts/utils/Strings.sol";
- uint256 public constant FEE_INCREASE_PERCENTAGE = 10;
- uint256 public constant PLATFORM_FEE_PERCENTAGE = 5;
+ uint256 public constant FEE_INCREASE_PERCENTAGE = 20;
+ uint256 public constant PLATFORM_FEE_PERCENTAGE = 80;
+ address public randomPlayer;
then Add this to Game.t.sol
:
function testclaimThrone() public {
console2.log("total pot amount:", game.pot() / 1e15);
console2.log("platform fees balance:", game.platformFeesBalance() / 1e15);
console2.log("claim fee:", game.claimFee() / 1e15);
console2.log("__________________________________________________________");
for (uint i = 0; i < 21; i++) {
randomPlayer = makeAddr(Strings.toString(i));
vm.deal(randomPlayer, 10 ether);
uint256 claimfee = game.claimFee();
vm.startPrank(randomPlayer);
game.claimThrone{value: claimfee}();
vm.stopPrank();
}
console2.log("total pot amount:", game.pot() / 1e15);
console2.log("platform fees balance:", game.platformFeesBalance() / 1e15);
console2.log("claim fee:", game.claimFee() / 1e15);
}
Then run:
forge test --match-test testclaimThrone -vv
🧾 Output
Logs:
total pot amount: 0
platform fees balance: 0
claim fee: 100
__________________________________________________________
total pot amount: 4500
platform fees balance: 18002
claim fee: 4600
As shown, the claimFee
eventually becomes greater than the total pot,
which leads to no profit for claiming the throne — discouraging participation.
Recommended Mitigation
you need to make previousKingPayout state variable and update it at the end of claimThrone() , not setting it to 0 in every call of claimThrone()
You should declare `previousKingPayout` a state variable, and update it at the end of each `claimThrone()` call, instead of resetting it to `0` every time.
```diff
+ uint256 public previousKingPayout;
...
- uint256 previousKingPayout = 0;
...
+ previousKingPayout = sentAmount;
```
This ensures `currentPlatformFee` is always constrained by a realistic, up-to-date value.