Last Man Standing

First Flight #45
Beginner FriendlyFoundrySolidity
100 EXP
View results
Submission Details
Severity: medium
Valid

[L-1] Unreachable Code in Fee Distribution Logic

[L-1] Unreachable Code in Fee Distribution Logic

Description

The claimThrone function contains logic to distribute the incoming msg.value between the contract's pot and the platformFeesBalance. This logic includes a "defensive" if statement intended to prevent the platform fee from exceeding the available amount.

However, due to the surrounding logic, this if statement is unreachable. The check if (currentPlatformFee > (sentAmount - previousKingPayout)) can never evaluate to true because previousKingPayout is hardcoded to 0(because it is never calculated as previously presented in another finding) and currentPlatformFee (calculated as a percentage of sentAmount) can never be greater than sentAmount. This dead code makes the function confusing and indicates a potential misunderstanding of the intended fee distribution mechanism.

// src/Game.sol
function claimThrone() external payable gameNotEnded nonReentrant {
// ...
uint256 sentAmount = msg.value;
uint256 previousKingPayout = 0; // Always 0
//...
@> // Defensive check to ensure platformFee doesn't exceed available amount after previousKingPayout
@> // This block is unreachable because `currentPlatformFee` can never be > `sentAmount`.
@> if (currentPlatformFee > (sentAmount - previousKingPayout)) {
@> currentPlatformFee = sentAmount - previousKingPayout;
@> }
platformFeesBalance = platformFeesBalance + currentPlatformFee;
// Remaining amount goes to the pot
amountToPot = sentAmount - currentPlatformFee;
pot = pot + amountToPot;
// ...
}

Risk

Likelihood: High

  • This logical flaw is present in every single call to claimThrone.

Impact: Low

  • This issue does not lead to a direct loss or theft of funds. The fee distribution works, but not for the reasons the code suggests.

  • The presence of dead, unreachable code makes the contract harder to read, maintain, and audit, and it could mask the true intent of the fee logic.

Proof of Concept

This issue can be demonstrated by analyzing the variables and the condition itself:

  1. The Condition: For the if block to execute, the condition currentPlatformFee > (sentAmount - previousKingPayout) must be true.

  2. Simplifying the Condition: Since previousKingPayout is hardcoded to 0, the condition simplifies to currentPlatformFee > sentAmount.

  3. The Mathematical Impossibility: We can now substitute the calculation for currentPlatformFee into the simplified condition:
    (sentAmount * platformFeePercentage) / 100 > sentAmount

    This inequality can never be true. The platformFeePercentage is logically capped at 100.

    • If platformFeePercentage is 100, the expression becomes sentAmount > sentAmount, which is false.

    • If platformFeePercentage is less than 100, the expression is (a fraction of sentAmount) > sentAmount, which is also always false.

Since currentPlatformFee can at most be equal to sentAmount but never greater, the condition is impossible to satisfy, proving the if block is unreachable dead code.

Recommended Mitigation

The easiest way to fix this issue is to implement the previous king payout functionality, as shown in a previous finding.

Updates

Appeal created

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

Missing Previous King Payout Functionality

Support

FAQs

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