# locking pragma versions prevents deployment with untested compiler versions Using an exact version pragma (`pragma solidity 0.8.20;`) instead of a range (`pragma solidity ^0.8.0;`) ensures the contract compiles only with the specific compiler version that was tested and audited. Since compiler updates can introduce subtle behavioral changes, such as [[transient storage introduces new storage semantics with novel security implications|new storage semantics]], [[solidity 0.8.31 deprecates send and transfer signaling the move away from fixed gas stipend patterns|deprecated functions]], or [[solidity 0.8.0 introduced default arithmetic overflow protection making unchecked blocks the new attack surface|fundamental arithmetic behavior changes]]: deploying with an untested compiler version may change the contract's behavior in ways the audit did not cover. This is a low-cost defensive measure that eliminates an entire class of deployment-time risk. The source's guidance distinguishes two related but separate risks. The floating pragma risk: an unlocked pragma allows deployment with any compatible compiler version, including versions with publicly disclosed vulnerabilities unknown at the time of development. The outdated compiler version risk: a locked pragma targeting an old compiler version may pin to one that has known bugs; locking must target a recent, non-vulnerable version to address both risks simultaneously. Checking the Solidity changelog between the current version and the pinned version is part of responsible version selection. Since [[EVM opcode incompatibility across chains causes failures when contracts assume uniform opcode support]], pragma locking is doubly important for multi-chain deployments where compiler default targets may introduce incompatible opcodes. Exception: libraries intended for downstream consumption may use floating pragmas (`^0.8.0`) to allow integrators flexibility in compiler choice. --- Relevant Notes: - [[transient storage introduces new storage semantics with novel security implications]]: an example of compiler changes with security implications - [[solidity 0.8.31 deprecates send and transfer signaling the move away from fixed gas stipend patterns]]: another compiler change that affects contract behavior - [[solidity 0.8.0 introduced default arithmetic overflow protection making unchecked blocks the new attack surface]]: the most significant behavioral change between compiler versions - [[EVM opcode incompatibility across chains causes failures when contracts assume uniform opcode support]]: compiler target affects opcode compatibility - [[the Curve Finance Vyper compiler exploit proved that source-level reentrancy guards can be silently broken by compiler bugs invisible to auditors]]: demonstrates the limits of version pinning: affected Curve pools were pinned to a vulnerable Vyper version, and pinning alone cannot protect against bugs within the pinned version - [[majority of solidity 0.8.x compiler bugs manifest only under specific pipeline configurations creating hidden behavioral divergence from identical source code]]: version pinning addresses compiler version risk but not compilation flag divergence, which is the broader problem - [[compiler bugs represent a distinct threat category where source-level security analysis is structurally insufficient]]: grounds: provides the higher-order framework explaining why pinning to a compiler version is necessary but cannot protect against bugs within the pinned version itself - [[Solidity functions without an explicit visibility modifier defaulted to public before version 0.5.0 allowing anyone to call intended-internal functions]]: exemplifies: a historic compiler-version behavioral change that a floating pragma would allow re-encountering if compilation regressed below 0.5.0 - [[solidity via-IR transient storage clearing helper collision emits wrong opcode when clearing both persistent and transient variables of the same type]]: exemplifies: a case where the locked version itself may be the vulnerability; locking to 0.8.28-0.8.33 with --via-ir would pin to the buggy pipeline Topics: - [[security-patterns]]