Every concrete .sol file in this repo floats its pragma. The convention is ^ for library and abstract files, = for concrete contracts including concrete test mocks.
I enumerated all four Solidity files at main:
| file |
declares |
pragma |
|
src/lib/LibRainDeploy.sol |
library |
^0.8.25 |
correct |
test/src/lib/LibRainDeploy.t.sol |
contract |
^0.8.25 |
should be =0.8.25 |
test/src/lib/MockDeployable.sol |
contract |
^0.8.25 |
should be =0.8.25 |
test/src/lib/MockReverter.sol |
contract |
^0.8.25 |
should be =0.8.25 |
The one file that is right is the one the convention exists to protect: LibRainDeploy.sol is a library, downstream soldeer consumers compile it, and a hard pin there would break a consumer on a different 0.8.x. Everything else is concrete and nothing downstream compiles it, so the exact pin costs nothing and buys a reproducible build.
Why now
#20 was rejected for adding a fourth violation — a new mock, MockAddressRevertingFactory.sol, with ^0.8.25. That reject is scoped to the file that PR adds, deliberately: sweeping three pre-existing files into a bug-fix PR would have made a one-line assembly fix unreviewable.
This is that sweep. It should land independently of #20, in either order — the two touch disjoint files.
Scope
Change the pragma on the three concrete files. Nothing else. No reformatting, no reordering imports, no touching LibRainDeploy.sol, which is already correct and where a change would be actively wrong.
Verification
forge build and the full forge test suite green afterwards. An exact pin either compiles under the repo's configured solc or it does not, so this is a change whose correctness the toolchain settles directly — but it must actually be run, because a pin that does not match the configured compiler breaks the build loudly and immediately.
No test can discriminate a pragma change at runtime, and inventing one would be theatre. Say so in the QA block rather than manufacturing evidence — n/a with a reason is a valid line; an absent line is not.
The general case
This is one repo, found by hand because a PR happened to add a fourth instance. The class is almost certainly org-wide, and finding it by hand one PR at a time is how it stayed at three for this long.
#141 is where that gets solved — a linter in pr-review-report for the mechanical conventions the audit skill already states in prose, so a floating pragma on a concrete contract is caught by code rather than by a model remembering the rule. This issue is the local cleanup; that one stops it recurring.
Check
Every concrete contract in this repo pins exactly. LibRainDeploy.sol still floats. The suite is green.
Every concrete
.solfile in this repo floats its pragma. The convention is^for library and abstract files,=for concrete contracts including concrete test mocks.I enumerated all four Solidity files at
main:src/lib/LibRainDeploy.sollibrary^0.8.25test/src/lib/LibRainDeploy.t.solcontract^0.8.25=0.8.25test/src/lib/MockDeployable.solcontract^0.8.25=0.8.25test/src/lib/MockReverter.solcontract^0.8.25=0.8.25The one file that is right is the one the convention exists to protect:
LibRainDeploy.solis a library, downstream soldeer consumers compile it, and a hard pin there would break a consumer on a different0.8.x. Everything else is concrete and nothing downstream compiles it, so the exact pin costs nothing and buys a reproducible build.Why now
#20was rejected for adding a fourth violation — a new mock,MockAddressRevertingFactory.sol, with^0.8.25. That reject is scoped to the file that PR adds, deliberately: sweeping three pre-existing files into a bug-fix PR would have made a one-line assembly fix unreviewable.This is that sweep. It should land independently of
#20, in either order — the two touch disjoint files.Scope
Change the pragma on the three concrete files. Nothing else. No reformatting, no reordering imports, no touching
LibRainDeploy.sol, which is already correct and where a change would be actively wrong.Verification
forge buildand the fullforge testsuite green afterwards. An exact pin either compiles under the repo's configured solc or it does not, so this is a change whose correctness the toolchain settles directly — but it must actually be run, because a pin that does not match the configured compiler breaks the build loudly and immediately.No test can discriminate a pragma change at runtime, and inventing one would be theatre. Say so in the QA block rather than manufacturing evidence —
n/awith a reason is a valid line; an absent line is not.The general case
This is one repo, found by hand because a PR happened to add a fourth instance. The class is almost certainly org-wide, and finding it by hand one PR at a time is how it stayed at three for this long.
#141is where that gets solved — a linter inpr-review-reportfor the mechanical conventions the audit skill already states in prose, so a floating pragma on a concrete contract is caught by code rather than by a model remembering the rule. This issue is the local cleanup; that one stops it recurring.Check
Every concrete contract in this repo pins exactly.
LibRainDeploy.solstill floats. The suite is green.