Last Man Standing

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

Platform Fee Calculated on Overpayment Instead of Required Fee

Description

  • Platform fees should be calculated based on the required service cost (claim fee) to provide predictable and fair fee structure for users.

  • The claimThrone function accepts overpayments but calculates platform fees on the entire payment amount rather than just the required claim fee, resulting in unexpected additional fees.

function claimThrone() external payable gameNotEnded nonReentrant {
require(msg.value >= claimFee, "Game: Insufficient ETH sent to claim the throne.");
uint256 sentAmount = msg.value; // @> Could be MORE than claimFee
// @> Platform fee calculated on ENTIRE payment, not just required fee
currentPlatformFee = (sentAmount * platformFeePercentage) / 100;
// @> No refund for overpayment
amountToPot = sentAmount - currentPlatformFee;
}

Risk

Likelihood:

  • Users frequently overpay in DeFi interfaces due to frontend bugs or manual errors

  • Common user behavior when unsure about exact amounts needed

Impact:

  • Users pay unexpected additional platform fees on accidental overpayments

  • Platform owner receives unearned fees beyond documented service cost

  • Financial loss for users with no refund mechanism for excess payments

  • Common DeFi user error becomes financially penalized

Financial Impact:

  • User intended to pay: 1 ETH + 0.1 ETH fee = 1.1 ETH total

  • User actually pays: 2 ETH + 0.2 ETH fee = 2.2 ETH total

  • Extra loss: 1.1 ETH with no recourse

Proof of Concept

  1. claimFee = 1 ETH, platformFeePercentage = 10%

  2. Expected: User pays 1 ETH, platform gets 0.1 ETH fee (10%)

  3. User accidentally sends 2 ETH (common mistake in DeFi interfaces)

  4. Result: Platform gets 0.2 ETH fee instead of 0.1 ETH (100% extra profit!)

  5. User loses: Additional 0.1 ETH in unexpected platform fees

  6. No refund mechanism - overpayment is permanently captured

Recommended Mitigation

Option 1: Require exact payment:

require(msg.value == claimFee, "Game: Must send exact claim fee amount");

Option 2: Calculate fees on required amount only:

require(msg.value >= claimFee, "Game: Insufficient ETH sent to claim the throne.");
uint256 requiredFee = claimFee;
uint256 platformFee = (requiredFee * platformFeePercentage) / 100;
uint256 excessPayment = msg.value - requiredFee;
// Refund excess payment
if (excessPayment > 0) {
(bool success, ) = payable(msg.sender).call{value: excessPayment}("");
require(success, "Game: Failed to refund excess payment");
}
uint256 amountToPot = requiredFee - platformFee;
pot = pot + amountToPot;
Updates

Appeal created

inallhonesty Lead Judge about 2 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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