Skip to content

docs: clarify ContractUpdateValidator scope and threat model#4465

Merged
j1010001 merged 1 commit into
masterfrom
jan/security-clarify-contract-update-validator-scope
Apr 14, 2026
Merged

docs: clarify ContractUpdateValidator scope and threat model#4465
j1010001 merged 1 commit into
masterfrom
jan/security-clarify-contract-update-validator-scope

Conversation

@j1010001

Copy link
Copy Markdown
Member

Summary

  • Adds a package-level comment to stdlib/contract_update_validation.go explaining the validator's narrow purpose: storage compatibility, not a general-purpose interface freeze.
  • Explicitly documents what is and isn't enforced, and why — in particular that access modifiers and let/var mutability are intentionally out of scope.
  • Adds a short doc comment on checkField() pointing to the package-level explanation.
  • Includes a link to the contract updatability docs.

Motivation

The validator's design intent was not documented, making it easy to misread the absence of access-modifier and mutability checks as oversights rather than deliberate decisions. This change makes the threat model explicit in the source so that readers — including security researchers — have the context needed to correctly assess the validator's behaviour.

Test plan

  • No logic changes — comment-only diff, no tests required.

🤖 Generated with Claude Code

Add a package-level comment and a checkField doc comment to make
explicit that the validator's purpose is storage compatibility only —
not a general-purpose interface freeze. Access modifiers and let/var
mutability are intentionally out of scope because they do not affect
storage serialization. Includes a link to the contract updatability docs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA d0de20f.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

Scanned Files

None

@github-actions

Copy link
Copy Markdown

Benchstat comparison

  • Base branch: onflow:master
  • Base commit: e09b4b7
Results

old.txtnew.txt
time/opdelta
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ByteArrayTransfer-41.22µs ± 0%1.34µs ± 0%~(p=1.000 n=1+1)
ByteArrayValueToByteSlice-479.4ns ± 0%87.5ns ± 0%~(p=1.000 n=1+1)
ByteSliceToByteArrayValue-41.06µs ± 0%0.96µs ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
ContractFunctionInvocation-4377µs ± 0%386µs ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
EMVAddressTransfer-43.55µs ± 0%3.39µs ± 0%~(p=1.000 n=1+1)
Emit-44.68ms ± 0%4.79ms ± 0%~(p=1.000 n=1+1)
EnumTransfer-41.37µs ± 0%1.49µs ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
ExportType/composite_type-4277ns ± 0%275ns ± 0%~(p=1.000 n=1+1)
ExportType/simple_type-478.3ns ± 0%78.3ns ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ImperativeFib-423.1µs ± 0%24.1µs ± 0%~(p=1.000 n=1+1)
InterpretRecursionFib-42.35ms ± 0%2.60ms ± 0%~(p=1.000 n=1+1)
NewInterpreter/new_interpreter-4864ns ± 0%853ns ± 0%~(p=1.000 n=1+1)
NewInterpreter/new_sub-interpreter-4336ns ± 0%333ns ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
RuntimeFungibleTokenTransferInterpreter-4638µs ± 0%613µs ± 0%~(p=1.000 n=1+1)
RuntimeFungibleTokenTransferVM-4715µs ± 0%721µs ± 0%~(p=1.000 n=1+1)
RuntimeResourceDictionaryValues-42.65ms ± 0%2.65ms ± 0%~(p=1.000 n=1+1)
RuntimeResourceTracking-49.56ms ± 0%9.69ms ± 0%~(p=1.000 n=1+1)
RuntimeScriptNoop-414.9µs ± 0%15.2µs ± 0%~(p=1.000 n=1+1)
RuntimeVMInvokeContractImperativeFib-441.1µs ± 0%41.5µs ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ValueIsSubtypeOfSemaType-461.0ns ± 0%61.0ns ± 0%~(p=1.000 n=1+1)
 
alloc/opdelta
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ByteArrayTransfer-41.08kB ± 0%1.08kB ± 0%~(all equal)
ByteArrayValueToByteSlice-432.0B ± 0%32.0B ± 0%~(all equal)
ByteSliceToByteArrayValue-4871B ± 0%861B ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
ContractFunctionInvocation-4144kB ± 0%144kB ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
EMVAddressTransfer-42.44kB ± 0%2.45kB ± 0%~(p=1.000 n=1+1)
Emit-41.50MB ± 0%1.50MB ± 0%~(p=1.000 n=1+1)
EnumTransfer-4833B ± 0%888B ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
ExportType/composite_type-4120B ± 0%120B ± 0%~(all equal)
ExportType/simple_type-40.00B 0.00B ~(all equal)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ImperativeFib-48.30kB ± 0%8.30kB ± 0%~(all equal)
InterpretRecursionFib-41.19MB ± 0%1.19MB ± 0%~(all equal)
NewInterpreter/new_interpreter-4976B ± 0%976B ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-4232B ± 0%232B ± 0%~(all equal)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
RuntimeFungibleTokenTransferInterpreter-4165kB ± 0%165kB ± 0%~(p=1.000 n=1+1)
RuntimeFungibleTokenTransferVM-4188kB ± 0%188kB ± 0%~(p=1.000 n=1+1)
RuntimeResourceDictionaryValues-41.76MB ± 0%1.77MB ± 0%~(p=1.000 n=1+1)
RuntimeResourceTracking-46.98MB ± 0%6.98MB ± 0%~(p=1.000 n=1+1)
RuntimeScriptNoop-48.08kB ± 0%8.09kB ± 0%~(p=1.000 n=1+1)
RuntimeVMInvokeContractImperativeFib-413.4kB ± 0%13.4kB ± 0%~(all equal)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ValueIsSubtypeOfSemaType-432.0B ± 0%32.0B ± 0%~(all equal)
 
allocs/opdelta
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ByteArrayTransfer-47.00 ± 0%7.00 ± 0%~(all equal)
ByteArrayValueToByteSlice-41.00 ± 0%1.00 ± 0%~(all equal)
ByteSliceToByteArrayValue-45.00 ± 0%5.00 ± 0%~(all equal)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
ContractFunctionInvocation-42.25k ± 0%2.25k ± 0%~(all equal)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
EMVAddressTransfer-429.0 ± 0%29.0 ± 0%~(all equal)
Emit-440.0k ± 0%40.0k ± 0%~(all equal)
EnumTransfer-413.0 ± 0%13.0 ± 0%~(all equal)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
ExportType/composite_type-43.00 ± 0%3.00 ± 0%~(all equal)
ExportType/simple_type-40.00 0.00 ~(all equal)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ImperativeFib-4176 ± 0%176 ± 0%~(all equal)
InterpretRecursionFib-417.7k ± 0%17.7k ± 0%~(all equal)
NewInterpreter/new_interpreter-415.0 ± 0%15.0 ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-44.00 ± 0%4.00 ± 0%~(all equal)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
RuntimeFungibleTokenTransferInterpreter-43.08k ± 0%3.08k ± 0%~(all equal)
RuntimeFungibleTokenTransferVM-43.61k ± 0%3.61k ± 0%~(all equal)
RuntimeResourceDictionaryValues-436.7k ± 0%36.7k ± 0%~(all equal)
RuntimeResourceTracking-4129k ± 0%129k ± 0%~(all equal)
RuntimeScriptNoop-4114 ± 0%114 ± 0%~(all equal)
RuntimeVMInvokeContractImperativeFib-4426 ± 0%426 ± 0%~(all equal)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ValueIsSubtypeOfSemaType-41.00 ± 0%1.00 ± 0%~(all equal)
 

@turbolent turbolent left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Could we please also add this to the top of https://cadence-lang.org/docs/language/contract-updatability ?

@turbolent turbolent added the Documentation Improvements or additions to documentation label Apr 13, 2026
@j1010001 j1010001 merged commit affdce3 into master Apr 14, 2026
13 of 17 checks passed
j1010001 added a commit to onflow/cadence-lang.org that referenced this pull request Apr 14, 2026
Add a 'Threat model and scope' section at the top of the contract
updatability page to make explicit that the validator's purpose is
storage compatibility only — not a general-purpose interface freeze.
Access modifiers and let/var mutability are intentionally out of scope
because they do not affect storage serialization.

Mirrors the clarification added to stdlib/contract_update_validation.go
in onflow/cadence#4465.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@turbolent turbolent deleted the jan/security-clarify-contract-update-validator-scope branch April 21, 2026 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants