Last Man Standing

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

Centralization Risk for trusted owners in `Game.sol`

Centralization Risk for trusted owners in Game.sol

Description

  • The Game contract inherits from Ownable and implements multiple admin-only functions that control critical game parameters and funds. This is standard practice for upgradeable or configurable contracts.

  • The contract maintains significant centralization risk by granting the owner unilateral control over: game reset timing, fee parameters, grace periods, and fund withdrawals. A malicious or compromised owner could exploit these privileges to manipulate game outcomes or extract value.

contract Game is Ownable { // @> Centralization risk introduced via Ownable inheritance
// @> Privileged owner functions below:
function resetGame() external onlyOwner gameEndedOnly {
function updateGracePeriod(uint256 _newGracePeriod) external onlyOwner {
function updateClaimFeeParameters() external onlyOwner {
function updatePlatformFeePercentage() external onlyOwner {
function withdrawPlatformFees() external onlyOwner nonReentrant {

Risk

Likelihood:

  • Owner privileges are permanently enabled by design

  • Admin keys could be compromised through social engineering or technical vulnerabilities

Impact:

  • Owner could arbitrarily drain platform fees or manipulate game timing

  • Parameter changes could disrupt fair gameplay and user trust

Proof of Concept

The PoC is as follows:

// Scenario 1: Owner drains all platform fees
function testMaliciousOwnerDrain() public {
vm.prank(player1);
game.claimThrone{value: 1 ether}();
uint256 balanceBefore = owner.balance;
vm.prank(owner);
game.withdrawPlatformFees();
assert(owner.balance > balanceBefore);
}
// Scenario 2: Owner manipulates grace period
function testGracePeriodManipulation() public {
vm.prank(owner);
game.updateGracePeriod(1); // Set to 1 second
// Could declare winner immediately after own claim
}

Recommended Mitigation

Add the following:

- contract Game is Ownable {
+ contract Game is Ownable2Step { // Use 2-step ownership transfer
+ // Add timelock for critical operations
+ function updateGracePeriod(uint256 _newGracePeriod) external onlyOwner {
+ require(_newGracePeriod >= MIN_GRACE_PERIOD, "Too short");
+ require(_newGracePeriod <= MAX_GRACE_PERIOD, "Too long");
+ _updateGracePeriod(_newGracePeriod);
+ }
+ // Implement multi-sig requirement for withdrawals
+ function withdrawPlatformFees() external onlyOwnerOrMultiSig {
+ uint256 limit = totalFees * MAX_WITHDRAW_PERCENT / 100;
+ _withdrawPlatformFees(limit);
+ }
Updates

Appeal created

inallhonesty Lead Judge 17 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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