Last Man Standing

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

L02. Precision Loss in Fee Calculations

Root + Impact

Description

Normal behavior:
The contract calculates platformFee and previousKingPayout during each claimThrone() call by applying a percentage to the sentAmount. These values are expected to reflect exact proportions (e.g., 5%) of the input ETH.

Issue:
Solidity does not support floating-point arithmetic. All percentage calculations using integers truncate fractional results (i.e., round down). For small sentAmount values or low platformFeePercentage, this rounding can consistently lead to zero or reduced fees, especially for the platform, which may rely on these micro-fees over time.

This creates:

  • Loss of revenue for the platform.

  • Unpredictable fee outcomes for small claimThrone() values.

// Root cause in the codebase with @> marks to highlight the relevant section
uint256 currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
uint256 previousKingPayout = (sentAmount * feeIncreasePercentage) / 100;
@> // Integer division truncates fractional parts, e.g. 1.99 becomes 1

Risk

Likelihood: HIGH

  • Occurs every time a player claims the throne with low claimFee or small platformFeePercentage.

  • Becomes more frequent during early game rounds or when claimFee is reset to a small value.

Impact: Low

  • The platform may collect zero or suboptimal fees, especially during early rounds.

  • Rounding issues can add up across many claims, reducing sustainability or incentivization.

Proof of Concept

// Assume claimFee is 0.001 ether and platformFeePercentage is 3%
uint256 sentAmount = 0.001 ether;
uint256 platformFee = (sentAmount * 3) / 100; // = 0.00003 ether → truncated to 0
// Platform receives 0 wei instead of ~30,000 wei
assert(platformFee == 0); // true due to integer division

Recommended Mitigation

Use higher precision for percentage calculations by multiplying first, then dividing, and using basis points (1/10,000 instead of 1/100):

- uint256 currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
+ uint256 currentPlatformFee = (sentAmount * platformFeePercentage) / 10_000;

Also update the variable and setter functions accordingly:

uint256 public platformFeeBps; // e.g., 300 = 3.00%

This allows much finer granularity and reduces rounding errors.

Updates

Appeal created

inallhonesty Lead Judge 10 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Precision loss in fee calc

Support

FAQs

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