Raisebox Faucet

First Flight #50
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: low
Likelihood: medium
Invalid

Floating Pragma Version in Contract Declaration

Root + Impact

Description

Solidity pragmas specify the compiler version for the contract. The ^0.8.30 notation enables compilation with 0.8.30 or any higher minor version up to but not including 0.9.0. Minor updates (e.g., 0.8.31) often include optimizations, bug fixes, or subtle semantic changes that can alter gas costs, bytecode, or even execution behavior in edge cases. For audited contracts, exact versioning ensures reproducibility; floating pragmas allow unverified updates, potentially introducing regressions.

Best practices from Solidity documentation and security audits recommend pinning to exact versions (e.g., 0.8.30) for production contracts to avoid unintended variations. This pragma risks future compatibility issues if the contract is redeployed on a node with a different minor version.

// @> Root cause in the codebase
pragma solidity ^0.8.30; // @> Floating version allows untested minor updates (>=0.8.30 <0.9.0)

Risk

Likelihood:

  • Medium: Minor updates occur frequently (Solidity releases every few months), and development environments may default to the latest compatible version.

  • Higher in multi-team or CI/CD setups where compiler versions vary.

Impact:

  • Low-Medium: No direct security hole, but potential for gas discrepancies or subtle bugs (e.g., optimizer changes affecting reentrancy guards).

  • Audit and deployment challenges: Reproducibility lost, increasing verification effort.

Proof of Concept

To demonstrate the risk, compile the contract with different minor versions and compare bytecode or gas costs. Use solc-select to switch versions and run forge build or solc --bin contract.sol.

Example commands (run in project root):

# Install solc-select and switch versions
pip install solc-select
solc-select install 0.8.30
solc-select install 0.8.24 # Older for comparison
# Compile with 0.8.30
solc-select use 0.8.30
forge build --force # Generates artifacts with version 0.8.30
# Compile with 0.8.24 (if compatible)
solc-select use 0.8.24
forge build --force # May succeed but produce different bytecode
# Compare bytecode
diff out/RaiseBoxFaucet.sol/RaiseBoxFaucet.json # Check for differences

Explanation

  • Setup: Switch Solidity versions compatible with the pragma (^0.8.30 allows 0.8.30+).

  • Issue Demonstration: Compilation succeeds across versions, but bytecode or ABI may differ (e.g., optimizer changes in 0.8.31 vs. 0.8.30), verifiable via diff or forge inspect RaiseBoxFaucet bytecode.

  • Result: Variations in output confirm the pragma's flexibility leads to non-reproducible artifacts, highlighting deployment risks.

  • The test shows successful builds but potential inconsistencies, proving the need for pinning.

Recommended Mitigation

Pin the pragma to an exact version to ensure reproducibility and eliminate minor update risks. Update to the latest stable if needed, but avoid the caret operator.

- pragma solidity ^0.8.30;
+ pragma solidity 0.8.30; // Exact version for audit reproducibility
Updates

Lead Judging Commences

inallhonesty Lead Judge about 2 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!