Skip to content

v0.7.0: a third reading of the access risk

Choose a tag to compare

@Yonkoo11 Yonkoo11 released this 19 Sep 22:16
· 106 commits to main since this release
cc5da71

Quorum had two readings of unguarded-state-write, and both judge a function by how it is written: whether it carries a modifier, and whether the variable it writes carries a privileged-looking name. Recent Solidity writes last_gauge and _validatorsMap, not feeRate, so on bench/MODERN.md that pair corroborated nothing and recall there was 0%. The last release ended by saying a genuinely different second reading was needed and was not designed yet. This is it.

consistency-lens asks the contract instead of the spelling. If every other externally callable function that writes a variable agrees on a modifier, and this one carries no guard at all, that disagreement is the evidence.

Three rules narrow it, and each came from opening a false confirmation and finding a reason for it:

  • a one-shot initializer is guarded by being one-shot, because after deployment nobody can call it;
  • a function that tests its own caller is not missing a guard, it is guarding differently;
  • the caller has to be able to reach the write, by choosing either the value or the slot it goes to.

Carrying a different guard is not enough to be sighted. An admin setter beside a sibling that checks the caller in its own body is guarded, only differently, and reading that as a finding was noise on every corpus here.

Measured on all three, before and after, with the before files kept in bench/history:

  • SmartBugs-curated: precision 49% to 48%, recall 63% to 64%, and one more labelled target confirmed, the owner change in multiowned_vulnerable.sol.
  • DeFiVulnLabs, held out: unchanged at 62% precision and 50% recall, the same eight confirmations.
  • Recent audit contests: recall 0% to 29%. Two real High severity findings confirmed, ServiceNft.updateImpact and AgentNftV2.addValidator in the Virtuals Protocol contest.

All 40 confirmations on that corpus were read by hand. Thirty-eight are false, and bench/MODERN.md names the four shapes they fall into: a write-once create on a fresh id, an in-body check the modifier reading cannot see, a caller writing their own row, and a value no caller can influence. The first and the last are the two worth a rule next, and they will be built against a labelled corpus before they are measured there.

The cost is written in the same file. This lens was developed against bench/MODERN.md, so that corpus is no longer held out for the access risk, and its 29% is not a measurement on unseen code. DeFiVulnLabs is now the only corpus no lens has ever been tuned against.

The package also reports its own version again. pyproject, quorum/init and the SARIF exporter all still said 0.1.0, six releases after that stopped being true.

81 tests.