Description
The contract allows the owner to set the claimFee arbitrarily via a public setter function (setClaimFee(uint256 _claimFee)) without any bounds or constraints. This introduces a centralization risk, where a malicious or compromised owner could:
Set the fee too high, preventing further participation.
Set the fee too low, allowing front-running, manipulation, or fee griefing.
Set the fee strategically, just before interacting with the game (e.g., claiming the throne) to front-run other players or drain users unfairly.
Withdraw all accumulated fees with no accountability, further centralizing profit.
-> Vulnerable Code:
```javascript
function setClaimFee(uint256 _claimFee) external onlyOwner {
claimFee = _claimFee;
}
```
There are no validations, such as:
- No maximum cap (maxFee)
- No minimum cap (minFee)
- No time delay (e.g., timelock)
- No governance control
- No off-chain notice
Risk
Impact:
-
Denial of Game Participation:
Owner sets claimFee
to an extremely high value (e.g., 1,000 ETH), making it impossible for players to become king.
-
Front-Running Manipulation
Owner monitors mempool and right before another player sends a claimThrone()
tx:
-
Lowers claimFee
to undercut them.
-
Sends their own tx with a lower fee.
-
Raises the fee back afterward.
This allows the owner to front-run and dominate the game unfairly.
-
Player Griefing or Lock-in
Owner sets the claimFee
to a low value while also being king, making it easy for bots or scripts to repeatedly claim throne, forcing gas wars or griefing legitimate players.
-
Centralized Fund Drain
Owner withdraws all platformFeesBalance
via withdrawPlatformFees()
without restrictions or caps, with no requirement to redistribute or prove fairness.
Proof of Concept
- Owner deploys the contract and becomes initial currentKing.
- Monitors the mempool for a user sending claimThrone() with fee X.
- Calls setClaimFee(X - 1 wei) and sends own claimThrone() with that value.
- Reverts the fee or increases it to lock out others.
- Later, calls withdrawPlatformFees() and drains funds.
Recommended Mitigation
=> Add Fee Bounds:
```javascript
require(_claimFee >= minFee && _claimFee <= maxFee, "Fee out of range");
```
=> Add Delay for Fee Changes:
Schedule changes with a delay (e.g., 1 hour) to allow fair notice.
=> Emit Events for Fee Updates:
Improve transparency.
=> Limit Owner Withdrawals:
Allow withdrawals only under certain conditions (e.g., after grace period or only a percentage at a time).
Consider multi-sig governance or DAO control.
=> Document Risks:
If design is intended to be centralized, clearly document this for users.