Rock Paper Scissors

First Flight #38
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: low
Invalid

Non-standard decimals Return Value May Break Integrations

Summary

The WinningToken::decimals function in WinningToken overrides the default ERC20 decimal precision by returning 0 instead of the standard 18. While this is a valid design choice for non-divisible tokens, it breaks compatibility with many wallets, front-end interfaces, and DeFi protocols that assume an 18-decimal format. This can result in incorrect balance displays, failed transactions, and degraded user experience, especially in integrations that do not explicitly handle decimals = 0.


Vulnerability Details

function decimals() public view virtual override returns (uint8) {
// @audit-issue Non‑standard decimals value breaks integrations expecting 18 decimals
@> return 0; // Non‑divisible token
}

Issue Explanation

By returning 0:

  1. No Fractional Transfers
    Users cannot transfer fractional amounts (e.g. 0.5 tokens), which may be required in some game‑reward or marketplace scenarios.

  2. Integration Breakage
    Many wallets, block explorers, analytics tools, and DeFi protocols assume decimals == 18. A 0 value can lead to:

    • Incorrect token balance display

    • Arithmetic errors in front‑end unit conversion

    • Reverted transactions when interacting with contracts expecting standard decimals

  3. Poor UX
    End users may be unaware that tokens are non‑divisible, causing confusion when they cannot send smaller amounts.


Impact

  • User Confusion: Transfers appear to “round” or fail unexpectedly.

  • Compatibility Issues: Third‑party tools may reject or misinterpret the token.

  • Indirect Risk to Funds: While funds aren’t directly at risk, failed or mis‑priced transfers may lead to lost UX trust or erroneous game logic.


Tools Used

  • Manual Code Review


Recommendations

Either revert to the standard 18 decimals or, if non‑divisible tokens are intended, clearly document this choice and ensure all integrations handle decimals = 0.

// Option 1: Use standard ERC20 precision
function decimals() public view virtual override returns (uint8) {
return 18;
}
// Option 2: Keep 0 but document clearly in your front‑end and integration guides
function decimals() public view virtual override returns (uint8) {
return 0;
}

Updates

Appeal created

m3dython Lead Judge about 2 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
m3dython 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.