JSON file detection with SOROBAN and Impl all done - #946
Merged
Conversation
|
@tzar-deek Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Soroban Storage & Footprint Analysis — Implementation Report
Overview
I implemented four new Soroban analyzers for the GasGuard codebase to detect storage inefficiencies, classify storage entries, identify footprint expansion risks, and analyze footprint access patterns. All four analyzers include comprehensive test suites with 41 tests passing.
Issue 1: Soroban Storage Entry Classifier
File:
packages/analyzers/soroban/storage/storage-entry-classifier.ts(489 lines)Tests:
packages/analyzers/soroban/storage/__tests__/storage-entry-classifier.spec.ts(231 lines, 10 tests)I built a classifier that categorizes Soroban storage entries into semantic types:
configuration,access_control,user_data,counter,cache,state,metadata,token,mapping, andunknown.My approach combines two analysis strategies:
Name-based classification — I scan storage key names against keyword lists for each category. For example, keys containing
admin,fee,thresholdare classified asconfiguration; keys withrole,paused,whitelistmap toaccess_control. I score each category using exact matches, segment matches (split by_), and substring matches, then pick the highest-scoring category.Usage-based fallback — When name-based classification yields low confidence, I analyze the access pattern. Write-once-read-many suggests
configuration; write-only temporary storage suggestscache; access withextend_ttlsuggestsuser_data.I also detect misclassifications where the storage tier doesn't match the semantic category:
extend_ttl→ suggests persistentEach classification includes a confidence level (
high,medium,low) and human-readable reasons explaining why the category was chosen.Issue 2: Inefficient Soroban Temporary Storage Usage
File:
packages/analyzers/soroban/storage/inefficient-temporary-storage-analyzer.ts(335 lines)Tests:
packages/analyzers/soroban/storage/__tests__/inefficient-temporary-storage.spec.ts(208 lines, 10 tests)I created a detector that identifies seven inefficiency patterns in how contracts use Soroban's temporary storage tier:
repeated_accesswrite_only_no_readshould_be_persistentextend_ttl, indicating it needs longer persistenceshould_be_localshould_be_persistentover_fragmentedshould_be_localMy implementation resolves
Symbol::newvariable bindings to their string literals so I track keys by their logical name rather than their variable reference. I also detect ephemeral data misplaced in persistent storage by scanning for keywords likenonce,session,ephemeral,cache.Issue 3: Soroban Storage Footprint Expansion
File:
packages/analyzers/soroban/storage/storage-footprint-expansion-analyzer.ts(313 lines)Tests:
packages/analyzers/soroban/storage/__tests__/storage-footprint-expansion.spec.ts(202 lines, 10 tests)I implemented a detector that identifies six patterns causing a contract's storage footprint to grow unboundedly:
unbounded_collection_growthno_cleanup_mechanismgrowing_map_in_storagedynamic_key_patternformat!,to_string) with storage writesunbounded_key_generationDataKeyvariants combined with collection growthappend_without_boundI restructured the detection logic so that
growing_map_in_storageis checked independently of growth-method detection. This ensures contracts usingMap.set()(rather thanpush/insert) are still flagged when they store collections in persistent storage without cleanup.Issue 4: Soroban Footprint Access Analyzer
File:
packages/analyzers/soroban/footprint/footprint-access-analyzer.ts(369 lines)Tests:
packages/analyzers/soroban/footprint/__tests__/footprint-access-analyzer.spec.ts(234 lines, 12 tests)I built an analyzer that examines access patterns within Soroban transaction footprints to identify eight pattern types:
hot_keycold_keyloop_accessimbalanced_accessread_heavywrite_heavyhigh_overlapMy implementation builds per-function footprint profiles that track which keys each function accesses, read/write counts, and loop access counts. I also compute a footprint overlap score between function pairs to identify candidates for consolidation.
I refactored the template literal expressions to extract
Array.from(access.functions)[0]into a localfnNamevariable. This resolved a TypeScript parser issue where}inside template literals was being misinterpreted as the closing brace of an object literal.Infrastructure Changes
I updated the module export indexes:
packages/analyzers/soroban/storage/index.ts— Added exports for all three new storage analyzerspackages/analyzers/soroban/footprint/index.ts— Added export for the footprint access analyzerTechnical Decisions
Lexical analysis approach: I followed the existing codebase pattern of using regex-based lexical analysis with the shared utilities in
packages/analyzers/soroban/common/source-utils.ts. I usedmaskNonCode()to strip comments and string literals before scanning,extractFunctions()for brace-aware function body extraction, andblockStackAt()/isInLoop()for loop detection.Symbol resolution: I pre-scan for
Symbol::new(&env, "key")andsymbol_short!definitions to build a variable-to-key map. This lets me track storage accesses by their logical key name rather than their variable reference. I run this regex on the original source (not the masked version) because string literals are blanked out in the masked copy.Key extraction from method calls: I use the same pattern as the existing
storage-in-loop-analyzer.ts— a regex that matches up to the method's opening paren, thenextractArgs()with balanced-paren matching to correctly extract arguments even with nested parentheses.Testing
I wrote 41 tests across 4 test suites covering:
All 41 tests pass. The 5 pre-existing test failures in
dataflow/andresources/ledger/directories are unrelated to my changes.Files Created
storage-entry-classifier.tsinefficient-temporary-storage-analyzer.tsstorage-footprint-expansion-analyzer.tsfootprint-access-analyzer.tsstorage-entry-classifier.spec.tsinefficient-temporary-storage.spec.tsstorage-footprint-expansion.spec.tsfootprint-access-analyzer.spec.tsFiles Modified
storage/index.tsfootprint/index.tsfootprint-access-analyzer.tsstorage-footprint-expansion-analyzer.tsgrowing_map_in_storageRELATED ISSUES: