Last Man Standing

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

Precision Loss in Percentage Calculations

Summary

Integer division in percentage calculations causes precision loss, particularly with small ETH amounts, leading to minor fund discrepancies.

Description

The contract uses integer division for percentage calculations without considering remainders, causing small amounts of ETH to be lost due to precision truncation.

Root Cause

Solidity integer division truncates decimals:

currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
claimFee = claimFee + (claimFee * feeIncreasePercentage) / 100;

Impact

  • Minor Fund Loss: Small amounts of wei lost in each transaction

  • Cumulative Effect: Precision loss accumulates over many transactions

  • Accounting Inaccuracy: Total fees may not match expected percentages exactly

Proof of Concept

function testPrecisionLoss() public {
// Deploy with small amounts that will cause precision loss
vm.prank(deployer);
Game precisionTestGame = new Game(
0.001 ether, // Very small initial fee
GRACE_PERIOD,
3, // 3% increase - will cause precision loss
7 // 7% platform fee
);
uint256 smallClaimFee = 0.001 ether; // 1000000000000000 wei
vm.prank(player1);
precisionTestGame.claimThrone{value: smallClaimFee}();
// Expected platform fee: 1000000000000000 * 7 / 100 = 70000000000000 wei
// But integer division might lose precision
uint256 expectedPlatformFee = (smallClaimFee * 7) / 100;
uint256 actualPlatformFeeBalance = precisionTestGame.platformFeesBalance();
// Precision loss demonstrated
console2.log("Expected platform fee:", expectedPlatformFee);
console2.log("Actual platform fee balance:", actualPlatformFeeBalance);
}

Recommended Mitigation
Consider using basis points (10000) instead of percentages (100) for better precision:

// Use basis points (1 bp = 0.01%)
uint256 public platformFeeBasisPoints; // e.g., 500 for 5%
uint256 public feeIncreaseBasisPoints; // e.g., 1000 for 10%
// In calculations:
currentPlatformFee = (sentAmount * platformFeeBasisPoints) / 10000;
claimFee = claimFee + (claimFee * feeIncreaseBasisPoints) / 10000;
Updates

Appeal created

inallhonesty Lead Judge 4 months 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.

Give us feedback!