-
Notifications
You must be signed in to change notification settings - Fork 52
Enhance Solidity Code Formatting for code consistency and beautification #306
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
pankajjagtapp
wants to merge
3
commits into
master
Choose a base branch
from
pankaj/feat/enhance-code-formatting
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
8a95e6f
chore: Update foundry.toml with linting and formatting configurations…
pankajjagtapp 9f32ead
Merge remote-tracking branch 'origin/master' into pankaj/feat/enhance…
pankajjagtapp af170ce
fix: clean and recreate cache directory in bytecode verification script
pankajjagtapp File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,211 @@ | ||
| #!/bin/bash | ||
|
|
||
| # Command to Run: | ||
| # 1. chmod +x script/verify-forge-fmt-bytecode.sh | ||
| # 2. ./script/verify-forge-fmt-bytecode.sh | ||
|
|
||
| set -e | ||
|
|
||
| echo "🔍 Verifying that forge fmt doesn't change bytecode..." | ||
|
|
||
| # Define cache directory | ||
| CACHE_DIR="cache/bytecodeComparison" | ||
|
|
||
| # Clean and create cache directory (removes stale data from previous runs) | ||
| rm -rf "$CACHE_DIR" | ||
| mkdir -p "$CACHE_DIR" | ||
|
|
||
| # Step 1: Compile and save bytecode before formatting | ||
| echo "📝 Compiling contracts before formatting..." | ||
| forge build --force | ||
|
|
||
| echo "💾 Extracting bytecode for each contract (pre-format)..." | ||
|
|
||
| # Create a temporary directory to store pre-format data | ||
| TEMP_BEFORE=$(mktemp -d) | ||
|
|
||
| # Extract bytecode from each contract's JSON artifact (excluding build-info) | ||
| find out -name "*.json" -type f ! -path "*/build-info/*" | while read -r file; do | ||
| # Get relative path from out directory | ||
| rel_path="${file#out/}" | ||
|
|
||
| # Get everything except the filename itself to preserve directory structure | ||
| dir_structure=$(dirname "$rel_path") | ||
| filename=$(basename "$rel_path" .json) | ||
|
|
||
| # Full path preserves the directory structure | ||
| full_path="${dir_structure}/${filename}" | ||
|
|
||
| # Extract contract name and bytecode | ||
| contract_name=$(basename "${file%.json}") | ||
| bytecode=$(jq -r '.deployedBytecode.object // .bytecode.object // ""' "$file" 2>/dev/null || echo "") | ||
|
|
||
| # Save to temp file with proper directory structure | ||
| mkdir -p "$TEMP_BEFORE/$dir_structure" | ||
| echo "$bytecode" > "$TEMP_BEFORE/${full_path}.bytecode" | ||
| echo "$contract_name|$rel_path" > "$TEMP_BEFORE/${full_path}.meta" | ||
| done | ||
|
|
||
| echo "✅ Pre-format bytecode extracted" | ||
|
|
||
| # Step 2: Run forge fmt | ||
| echo "🎨 Running forge fmt..." | ||
| forge fmt | ||
|
|
||
| # Step 3: Compile again after formatting | ||
| echo "📝 Recompiling contracts after formatting..." | ||
| forge build --force | ||
|
|
||
| echo "💾 Extracting bytecode for each contract (post-format)..." | ||
|
|
||
| # Extract post-format bytecode and create combined JSON files | ||
| find out -name "*.json" -type f ! -path "*/build-info/*" | while read -r file; do | ||
| rel_path="${file#out/}" | ||
|
|
||
| # Preserve the directory structure | ||
| dir_structure=$(dirname "$rel_path") | ||
| filename=$(basename "$rel_path" .json) | ||
| full_path="${dir_structure}/${filename}" | ||
|
|
||
| contract_name=$(basename "${file%.json}") | ||
| bytecode_after=$(jq -r '.deployedBytecode.object // .bytecode.object // ""' "$file" 2>/dev/null || echo "") | ||
|
|
||
| # Read pre-format bytecode if exists | ||
| if [ -f "$TEMP_BEFORE/${full_path}.bytecode" ]; then | ||
| bytecode_before=$(cat "$TEMP_BEFORE/${full_path}.bytecode") | ||
| else | ||
| bytecode_before="" | ||
| fi | ||
|
|
||
| # Create combined JSON file with proper directory structure | ||
| mkdir -p "$CACHE_DIR/$dir_structure" | ||
| output_file="$CACHE_DIR/${full_path}.json" | ||
|
|
||
| # Normalize empty bytecode (treat "", "0x", and missing as equivalent) | ||
| normalized_before="$bytecode_before" | ||
| normalized_after="$bytecode_after" | ||
|
|
||
| if [ -z "$normalized_before" ] || [ "$normalized_before" = "0x" ]; then | ||
| normalized_before="" | ||
| fi | ||
|
|
||
| if [ -z "$normalized_after" ] || [ "$normalized_after" = "0x" ]; then | ||
| normalized_after="" | ||
| fi | ||
|
|
||
| jq -n \ | ||
| --arg name "$contract_name" \ | ||
| --arg path "$rel_path" \ | ||
| --arg before "$bytecode_before" \ | ||
| --arg after "$bytecode_after" \ | ||
| --argjson changed "$([ "$normalized_before" != "$normalized_after" ] && echo true || echo false)" \ | ||
| '{ | ||
| contractName: $name, | ||
| artifactPath: $path, | ||
| preFormatBytecode: $before, | ||
| postFormatBytecode: $after, | ||
| bytecodeChanged: $changed | ||
| }' > "$output_file" | ||
| done | ||
|
|
||
| echo "✅ Post-format bytecode extracted and comparison saved" | ||
|
|
||
| # Cleanup temp directory | ||
| rm -rf "$TEMP_BEFORE" | ||
|
|
||
| # Step 4: Compare bytecode for each contract | ||
| echo "" | ||
| echo "🔍 Analyzing bytecode changes..." | ||
| echo "" | ||
|
|
||
| # Create temporary files to store results | ||
| TEMP_CHANGED=$(mktemp) | ||
| TEMP_STATS=$(mktemp) | ||
|
|
||
| # Analyze all contracts recursively | ||
| while IFS= read -r json_file; do | ||
| # Extract contract info | ||
| artifact_path=$(jq -r '.artifactPath' "$json_file") | ||
| pre_bytecode=$(jq -r '.preFormatBytecode' "$json_file") | ||
| post_bytecode=$(jq -r '.postFormatBytecode' "$json_file") | ||
|
|
||
| # Skip contracts with no bytecode (abstract contracts, interfaces, libraries without code) | ||
| # Normalize empty values: treat "", "0x", and missing as equivalent | ||
| normalized_pre="$pre_bytecode" | ||
| normalized_post="$post_bytecode" | ||
|
|
||
| if [ -z "$normalized_pre" ] || [ "$normalized_pre" = "0x" ]; then | ||
| normalized_pre="" | ||
| fi | ||
|
|
||
| if [ -z "$normalized_post" ] || [ "$normalized_post" = "0x" ]; then | ||
| normalized_post="" | ||
| fi | ||
|
|
||
| if [ -z "$normalized_pre" ] && [ -z "$normalized_post" ]; then | ||
| echo "⊘ $artifact_path - SKIPPED (no bytecode)" | ||
| echo "skipped" >> "$TEMP_STATS" | ||
| continue | ||
| fi | ||
|
|
||
| bytecode_changed=$(jq -r '.bytecodeChanged' "$json_file") | ||
|
|
||
| if [ "$bytecode_changed" = "true" ]; then | ||
| echo "❌ $artifact_path - BYTECODE CHANGED" | ||
| echo "$artifact_path" >> "$TEMP_CHANGED" | ||
| echo "changed" >> "$TEMP_STATS" | ||
| else | ||
| echo "identical" >> "$TEMP_STATS" | ||
| fi | ||
| done < <(find "$CACHE_DIR" -name "*.json" -type f) | ||
|
|
||
| # Count results | ||
| if [ -f "$TEMP_CHANGED" ]; then | ||
| CHANGED_COUNT=$(wc -l < "$TEMP_CHANGED") | ||
| # Read into array without mapfile | ||
| CHANGED_CONTRACTS=() | ||
| while IFS= read -r line; do | ||
| CHANGED_CONTRACTS+=("$line") | ||
| done < "$TEMP_CHANGED" | ||
| else | ||
| CHANGED_COUNT=0 | ||
| fi | ||
|
|
||
| TOTAL_COUNT=$(wc -l < "$TEMP_STATS" 2>/dev/null || echo "0") | ||
| IDENTICAL_COUNT=$(grep -c "identical" "$TEMP_STATS" 2>/dev/null || echo "0") | ||
| SKIPPED_COUNT=$(grep -c "skipped" "$TEMP_STATS" 2>/dev/null || echo "0") | ||
pankajjagtapp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| echo "" | ||
| echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" | ||
|
|
||
| # Check if any contracts changed | ||
| if [ $CHANGED_COUNT -gt 0 ]; then | ||
| echo "❌ FAILURE: $CHANGED_COUNT contract(s) have bytecode changes!" | ||
| echo " ($IDENTICAL_COUNT verified, $SKIPPED_COUNT skipped, $TOTAL_COUNT total)" | ||
| echo "" | ||
| echo "Affected contracts:" | ||
| for contract in "${CHANGED_CONTRACTS[@]}"; do | ||
| echo " - $contract" | ||
| done | ||
| echo "" | ||
| echo "📁 Detailed comparison saved in: $CACHE_DIR/" | ||
| echo "" | ||
| echo "💡 To inspect a specific contract:" | ||
| echo " jq '.' $CACHE_DIR/src/AccessControl.sol/AccessControl.json" | ||
| echo "" | ||
| echo "💡 To see which contracts changed:" | ||
| echo " find $CACHE_DIR -name '*.json' -exec jq -r 'select(.bytecodeChanged == true) | .artifactPath' {} \\;" | ||
|
|
||
| # Cleanup | ||
| rm -f "$TEMP_CHANGED" "$TEMP_STATS" | ||
| exit 1 | ||
| else | ||
| echo "✅ SUCCESS: All contracts have identical bytecode!" | ||
| echo " ($IDENTICAL_COUNT verified, $SKIPPED_COUNT skipped, $TOTAL_COUNT total)" | ||
| echo "" | ||
| echo "📁 Comparison data saved in: $CACHE_DIR/" | ||
|
|
||
| # Cleanup | ||
| rm -f "$TEMP_CHANGED" "$TEMP_STATS" | ||
| exit 0 | ||
| fi | ||
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.