Tautological
id: LS03I
title: Tautological
baseSeverity: I
category: logic
language: solidity
blockchain: [ethereum]
impact: Ineffective checks, audit confusion, gas waste
status: draft
complexity: low
attack_vector: internal
mitigation_difficulty: easy
versions: [">=0.6.0"]
cwe: CWE-570
swc: SWC-131
๐ Description
- A tautological compare occurs when a condition always evaluates to true or false due to the way values are constrained or types are defined.
- In Solidity, this typically happens when:
- Unsigned integers (uint) are compared to < 0 (always false)
- Boolean values are checked redundantly (e.g., if (flag == true))
- Enum values are checked against impossible conditions
- Comparisons rely on constant return values or static inputs
- These conditions lead to unreachable code, unnecessary gas usage, or logic branches that mislead reviewers, potentially obscuring genuine security-relevant logic.
๐จ Vulnerable Code
pragma solidity ^0.8.0;
contract TautologyExample {
function isValid(uint256 amount) public pure returns (bool) {
if (amount >= 0) { // โ Always true for uint256
return true;
} else {
return false;
}
}
}
๐งช Exploit Scenario
- A developer writes a check like if (amount >= 0) intending to guard input.
- They add different behaviors to the if and else branches.
- However, the else branch can never execute.
- This may lead to incorrect assumptions about coverage, testing, or validation logic.
Assumptions:
- The code uses unsigned types or constants.
- Developer unintentionally introduces an unreachable path.
โ Fixed Code
pragma solidity ^0.8.0;
contract FixedCompare {
function isValid(uint256 amount) public pure returns (bool) {
// Just return true, since uint >= 0 is always true
return true;
}
}
๐งญ Contextual Severity
- context: "Default"
severity: I
reasoning: "No direct impact, but adds noise to logic and gas usage."
- context: "High-frequency DeFi function"
severity: M
reasoning: "Can lead to measurable gas inefficiency at scale."
- context: "Testnet or internal utility contract"
severity: I
reasoning: "Negligible impact when not used in production flows."
๐ก๏ธ Prevention
Primary Defenses
- Avoid comparing unsigned integers against 0 with >= or < (redundant).
- Use direct boolean expressions (if (flag) instead of if (flag == true)).
Additional Safeguards
- Run static analysis to catch unreachable code.
- Add unit tests that explicitly check for all logic branches.
Detection Methods
- Search for tautologies like uint >= 0, x == true, false == false, etc.
- Tools: Slither (tautology, dead-code), Surya, manual review
๐ฐ๏ธ Historical Exploits
- Name: Solidity Tautological Comparison Issue
- Date: 2022
- Loss: Potential for unintended behavior due to always-true conditions
- Post-mortem: Link to post-mortem
๐ Further Reading
- SWC-135: Incorrect Logic
- Slither Tautology Detector
- Solidity Docs โ Comparison Operators
- Trail of Bits โ Secure Smart Contract Patterns
โ Vulnerability Report
id: LS03I
title: Tautological
severity: I
score:
impact: 2
exploitability: 1
reachability: 3
complexity: 1
detectability: 5
finalScore: 2.1
๐ Justifications & Analysis
- Impact: Logic is misleading or ineffective, but not directly exploitable in most cases.
- Exploitability: Cannot be abused unless misused in access control or conditional logic.
- Reachability: Commonly encountered in code with type misunderstandings.
- Complexity: A trivial but easy-to-make mistake.
- Detectability: Very easy to detect with static analysis or basic code review.