Skip to content

Commit

Permalink
Merge branch 'main' of github.com:lifinance/contracts into deprecate-…
Browse files Browse the repository at this point in the history
…stargateV1-and-Amarok
  • Loading branch information
0xDEnYO committed Feb 26, 2025
2 parents 51fcda2 + 60e9024 commit a448ccc
Show file tree
Hide file tree
Showing 36 changed files with 4,786 additions and 770 deletions.
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ ETH_NODE_URI_FUSE=https://rpc.fuse.io #[pre-commit-checker: not a secret]
ETH_NODE_URI_GNOSIS=https://rpc.ankr.com/gnosis #[pre-commit-checker: not a secret]
ETH_NODE_URI_GRAVITY=https://rpc.gravity.xyz #[pre-commit-checker: not a secret]
ETH_NODE_URI_IMMUTABLEZKEVM=https://rpc.immutable.com #[pre-commit-checker: not a secret]
ETH_NODE_URI_INK=https://rpc-gel.inkonchain.com #[pre-commit-checker: not a secret]
ETH_NODE_URI_KAIA=https://klaytn.drpc.org #[pre-commit-checker: not a secret]
ETH_NODE_URI_LINEA=https://rpc.linea.build #[pre-commit-checker: not a secret]
ETH_NODE_URI_LISK=https://rpc.api.lisk.com #[pre-commit-checker: not a secret]
Expand Down Expand Up @@ -73,3 +74,6 @@ GOERLI_ETHERSCAN_API_KEY=
LINEATEST_ETHERSCAN_API_KEY=
MUMBAI_ETHERSCAN_API_KEY=
SEPOLIA_ETHERSCAN_API_KEY=

# Mongo DB for SAFE transactions
MONGODB_URI=""
1 change: 1 addition & 0 deletions .github/workflows/diamondEmergencyPause.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ jobs:
ETH_NODE_URI_GNOSIS: ${{ secrets.ETH_NODE_URI_GNOSIS }}
ETH_NODE_URI_GRAVITY: ${{ secrets.ETH_NODE_URI_GRAVITY }}
ETH_NODE_URI_IMMUTABLEZKEVM: ${{ secrets.ETH_NODE_URI_IMMUTABLEZKEVM }}
ETH_NODE_URI_INK: ${{ secrets.ETH_NODE_URI_INK }}
ETH_NODE_URI_KAIA: ${{ secrets.ETH_NODE_URI_KAIA }}
ETH_NODE_URI_LINEA: ${{ secrets.ETH_NODE_URI_LINEA }}
ETH_NODE_URI_LISK: ${{ secrets.ETH_NODE_URI_LISK }}
Expand Down
55 changes: 55 additions & 0 deletions .github/workflows/olympixStaticAnalysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Olympix Static Analysis

# - runs the olympix static analyzer on newly added or modified solidity contracts inside the src/ folder in a pull request
# - detects potential security vulnerabilities and uploads the results to github code scanning
# - only scans diff (added, renamed, modified) solidity files in src/ instead of the whole repository
# - ensures security issues are identified before merging, allowing the team to review and discuss findings within the PR

on:
pull_request:
types:
- opened
- synchronize
- reopened
- ready_for_review
paths:
- 'src/**/*.sol'

jobs:
static-analysis:
name: Static Analysis Security Check
runs-on: ubuntu-latest

steps:
- name: Checkout Repository
uses: actions/checkout@v4

- name: Get added, renamed, modified Solidity Files
id: changed-files
uses: tj-actions/changed-files@v45
with:
files: |
src/**/*.sol
- name: Convert Changed Files to Args
if: steps.changed-files.outputs.any_changed == 'true'
id: format-args
env:
ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
args=$(echo "$ALL_CHANGED_FILES" | xargs -n 1 printf -- "-p %s ")
echo "ARGS=$args" >> $GITHUB_ENV
- name: Run Olympix Integrated Security
if: steps.changed-files.outputs.any_changed == 'true'
uses: olympix/integrated-security@main
env:
OLYMPIX_API_TOKEN: ${{ secrets.OLYMPIX_API_TOKEN }}
with:
args: --output-format sarif --output-path ./ ${{ env.ARGS }}

- name: Upload Result to GitHub Code Scanning
if: steps.changed-files.outputs.any_changed == 'true'
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: olympix.sarif
271 changes: 271 additions & 0 deletions .github/workflows/securityAlertsReview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
name: Security Alerts Review

# - ensures that all security alerts from olympix static analysis are properly handled before merging
# - enforces a strict review policy where every alert must be either resolved or dismissed with a justification
# - prevents merging a PR if any alerts are unresolved or dismissed without a comment
# - helps maintain a transparent and collaborative security review process by generating a pr comment summarizing the status of all security alerts
# - automatically reverts the PR to draft status if blocking alerts exist
# - leaves a summary of all alerts in a comment starting with "🤖 GitHub Action: Security Alerts Review 🔍"

on:
pull_request:
types:
- ready_for_review
paths:
- 'src/**/*.sol'
workflow_dispatch:

jobs:
check-security-alerts:
runs-on: ubuntu-latest

steps:
# Ensure that the Olympix Static Analysis workflow has run successfully at least once before proceeding.
# This check is necessary because the Security Alerts Review workflow should not proceed unless
# a valid Olympix Static Analysis report is available for the current branch.
- name: Check if Olympix Static Analysis has run at least once and was successful
id: check-analysis
env:
GITHUB_TOKEN: ${{ secrets.GIT_ACTIONS_BOT_PAT_CLASSIC }}
BRANCH_NAME: ${{ github.head_ref }}
run: |
# Fallback in case BRANCH_NAME is empty.
if [ -z "$BRANCH_NAME" ]; then
BRANCH_NAME="${GITHUB_HEAD_REF:-${GITHUB_REF##*/}}"
echo "BRANCH_NAME was empty, falling back to: $BRANCH_NAME"
fi
echo "Checking latest Olympix Static Analysis run for branch: $BRANCH_NAME"
# Fetch the latest completed runs of the Olympix Static Analysis workflow
LATEST_RUN=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${{ github.repository }}/actions/workflows/olympixStaticAnalysis.yml/runs?status=completed&per_page=10")
# Filter to find the first run with head_branch matching our branch name
WORKFLOW_STATUS=$(echo "$LATEST_RUN" | jq -r --arg branch "$BRANCH_NAME" '.workflow_runs[] | select(.head_branch == $branch) | .conclusion' | head -n1)
if [[ "$WORKFLOW_STATUS" != "success" ]]; then
echo "The Olympix Static Analysis workflow has not been successfully completed for branch: $BRANCH_NAME."
echo "The Security Alerts Review workflow cannot continue because a valid Olympix Static Analysis report is required."
exit 1
fi
- uses: actions/checkout@v4

- uses: jwalton/gh-find-current-pr@master
id: findPr

- name: Validate and set PR Number
id: fetch_pr
env:
GITHUB_TOKEN: ${{ secrets.GIT_ACTIONS_BOT_PAT_CLASSIC }}
run: |
if [ -z "${{ steps.findPr.outputs.number }}" ]; then
echo "Error: No pull request found for this push." >&2
exit 1
fi
echo "Found PR number: ${{ steps.findPr.outputs.number }}"
PR_NUMBER=${{ steps.findPr.outputs.number }}
echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
echo "Pull Request Number is: $PR_NUMBER"
- name: Fetch Security Alerts for PR
env:
GITHUB_TOKEN: ${{ secrets.GIT_ACTIONS_BOT_PAT_CLASSIC }}
run: |
echo "Fetching security alerts for PR #${PR_NUMBER}..."
# Fetch security alerts via GitHub API
ALERTS=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${{ github.repository }}/code-scanning/alerts?pr=${PR_NUMBER}")
# Log raw API response for debugging
echo "Raw API Response:"
echo "$ALERTS"
# Extract unresolved alerts (open alerts)
UNRESOLVED_ALERTS=$(echo "$ALERTS" | jq -c '[.[] | select(.state == "open") ]' || echo "[]")
# Extract dismissed alerts without comments (empty dismissed_comment)
DISMISSED_ALERTS=$(echo "$ALERTS" | jq -c '[.[] | select(.state == "dismissed" and (.dismissed_comment == null or .dismissed_comment == ""))]' || echo "[]")
# Extract dismissed alerts with comments (successful dismissals)
RESOLVED_ALERTS=$(echo "$ALERTS" | jq -c '[.[] | select(.state == "dismissed" and (.dismissed_comment != null and .dismissed_comment != ""))]' || echo "[]")
UNRESOLVED_COUNT=$(echo "$UNRESOLVED_ALERTS" | jq -r 'length')
DISMISSED_COUNT=$(echo "$DISMISSED_ALERTS" | jq -r 'length')
COMMENTED_COUNT=$(echo "$RESOLVED_ALERTS" | jq -r 'length')
# Count dismissed alerts with the invalid reason "Used in tests" (invalid because only production code is analyzed)
INVALID_REASON_COUNT=$(echo "$RESOLVED_ALERTS" | jq -r '[.[] | select(.dismissed_reason == "used in tests")] | length')
# Output for debugging
echo "UNRESOLVED_ALERTS: $UNRESOLVED_ALERTS"
echo "DISMISSED_ALERTS (without comments): $DISMISSED_ALERTS"
echo "RESOLVED_ALERTS (with comments): $RESOLVED_ALERTS"
echo "UNRESOLVED_COUNT: $UNRESOLVED_COUNT"
echo "DISMISSED_COUNT: $DISMISSED_COUNT"
echo "COMMENTED_COUNT: $COMMENTED_COUNT"
echo "INVALID_REASON_COUNT: $INVALID_REASON_COUNT"
# Save values in the environment as single-line JSON
echo "UNRESOLVED_ALERTS=$UNRESOLVED_ALERTS" >> $GITHUB_ENV
echo "DISMISSED_ALERTS=$DISMISSED_ALERTS" >> $GITHUB_ENV
echo "RESOLVED_ALERTS=$RESOLVED_ALERTS" >> $GITHUB_ENV
echo "UNRESOLVED_COUNT=$UNRESOLVED_COUNT" >> $GITHUB_ENV
echo "DISMISSED_COUNT=$DISMISSED_COUNT" >> $GITHUB_ENV
echo "COMMENTED_COUNT=$COMMENTED_COUNT" >> $GITHUB_ENV
echo "INVALID_REASON_COUNT=$INVALID_REASON_COUNT" >> $GITHUB_ENV
- name: Find Existing PR Comment
id: find_comment
env:
GITHUB_TOKEN: ${{ secrets.GIT_ACTIONS_BOT_PAT_CLASSIC }}
run: |
echo "Searching for existing PR comment..."
COMMENT_ID=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" | jq -r \
'.[] | select(.body | startswith("### 🤖 GitHub Action: Security Alerts Review")) | .id')
if [[ -n "$COMMENT_ID" && "$COMMENT_ID" != "null" ]]; then
echo "EXISTING_COMMENT_ID=$COMMENT_ID" >> $GITHUB_ENV
fi
echo "Found comment ID: $COMMENT_ID"
- name: Post or Update PR Comment
env:
GITHUB_TOKEN: ${{ secrets.GIT_ACTIONS_BOT_PAT_CLASSIC }}
run: |
COMMENT_BODY="### 🤖 GitHub Action: Security Alerts Review 🔍\n\n"
# Add Unresolved Alerts
if [[ "$UNRESOLVED_COUNT" -gt 0 ]]; then
COMMENT_BODY+="🚨 **Unresolved Security Alerts Found!** 🚨\n"
COMMENT_BODY+="The following security alerts must be **resolved** before merging:\n\n"
while IFS= read -r row; do
ALERT_URL=$(echo "$row" | jq -r '.html_url')
ALERT_FILE=$(echo "$row" | jq -r '.most_recent_instance.location.path')
ALERT_DESCRIPTION=$(echo "$row" | jq -r '.most_recent_instance.message.text')
COMMENT_BODY+="🔴 [View Alert]($ALERT_URL) - **File:** \`$ALERT_FILE\`\n"
COMMENT_BODY+=" 🔹 $ALERT_DESCRIPTION\n\n"
done < <(echo "$UNRESOLVED_ALERTS" | jq -c '.[]')
fi
# Add Dismissed Alerts Without Comments
if [[ "$DISMISSED_COUNT" -gt 0 ]]; then
COMMENT_BODY+="The following alerts were dismissed but require a dismissal comment:\n\n"
while IFS= read -r row; do
ALERT_URL=$(echo "$row" | jq -r '.html_url')
ALERT_FILE=$(echo "$row" | jq -r '.most_recent_instance.location.path')
ALERT_DESCRIPTION=$(echo "$row" | jq -r '.most_recent_instance.message.text')
COMMENT_BODY+="🟡 [View Alert]($ALERT_URL) - **File:** \`$ALERT_FILE\`\n"
COMMENT_BODY+=" 🔹 $ALERT_DESCRIPTION\n\n"
done < <(echo "$DISMISSED_ALERTS" | jq -c '.[]')
fi
# Add alerts dismissed with an invalid reason ("Used in tests")
if [[ "$INVALID_REASON_COUNT" -gt 0 ]]; then
COMMENT_BODY+="❌ **Invalid Dismissal Reasons Found!** ❌\n"
COMMENT_BODY+="The following alerts were dismissed with the reason **Used in tests**, which is not allowed for production code. Please provide a valid dismissal reason.\n\n"
while IFS= read -r row; do
ALERT_URL=$(echo "$row" | jq -r '.html_url')
ALERT_FILE=$(echo "$row" | jq -r '.most_recent_instance.location.path')
ALERT_DESCRIPTION=$(echo "$row" | jq -r '.most_recent_instance.message.text')
DISMISS_REASON=$(echo "$row" | jq -r '.dismissed_reason')
CAPITALIZED_REASON=$(echo "$DISMISS_REASON" | sed 's/^\(.\)/\U\1/')
COMMENT_BODY+="❌ [View Alert]($ALERT_URL) - **File:** \`$ALERT_FILE\`\n"
COMMENT_BODY+=" 🔹 $ALERT_DESCRIPTION\n"
COMMENT_BODY+=" 🔹 Dismiss Reason: **$CAPITALIZED_REASON** (invalid for production code)\n\n"
done < <(echo "$RESOLVED_ALERTS" | jq -c '.[] | select(.dismissed_reason == "used in tests")')
fi
if [[ "$UNRESOLVED_COUNT" -gt 0 || "$DISMISSED_COUNT" -gt 0 || "$INVALID_REASON_COUNT" -gt 0 ]]; then
COMMENT_BODY+="⚠️ **Please resolve the above issues before merging.**\n\n"
fi
# Add Dismissed alerts With valid comments (successful dismissals)
if [[ "$COMMENTED_COUNT" -gt 0 ]]; then
COMMENT_BODY+="🟢 **Dismissed Security Alerts with Comments**\n"
COMMENT_BODY+="The following alerts were dismissed with proper comments:\n\n"
while IFS= read -r row; do
# Skip alerts that were dismissed with an invalid reason
if echo "$row" | jq -e 'select(.dismissed_reason == "used in tests")' > /dev/null; then
continue
fi
ALERT_URL=$(echo "$row" | jq -r '.html_url')
ALERT_FILE=$(echo "$row" | jq -r '.most_recent_instance.location.path')
ALERT_DESCRIPTION=$(echo "$row" | jq -r '.most_recent_instance.message.text')
DISMISS_REASON=$(echo "$row" | jq -r '.dismissed_reason')
DISMISS_COMMENT=$(echo "$row" | jq -r '.dismissed_comment')
CAPITALIZED_REASON=$(echo "$DISMISS_REASON" | sed 's/^\(.\)/\U\1/')
COMMENT_BODY+="🟢 [View Alert]($ALERT_URL) - **File:** \`$ALERT_FILE\`\n"
COMMENT_BODY+=" 🔹 $ALERT_DESCRIPTION\n"
COMMENT_BODY+=" 🔹 Dismiss Reason: **$CAPITALIZED_REASON**\n"
COMMENT_BODY+=" 🔹 Dismiss Comment: $DISMISS_COMMENT\n\n"
done < <(echo "$RESOLVED_ALERTS" | jq -c '.[]')
fi
# If no unresolved alerts and no dismissed alerts missing comments or with invalid reasons, add overall success message
if [[ "$UNRESOLVED_COUNT" -eq 0 && "$DISMISSED_COUNT" -eq 0 && "$INVALID_REASON_COUNT" -eq 0 ]]; then
COMMENT_BODY+="✅ **No unresolved security alerts!** 🎉\n\n"
fi
# Update existing comment if found; otherwise, post a new one.
if [[ -n "$EXISTING_COMMENT_ID" ]]; then
echo "Updating existing comment ID: $EXISTING_COMMENT_ID"
curl -s -X PATCH -H "Authorization: token ${GITHUB_TOKEN}" -H "Content-Type: application/json" \
-d "{\"body\": \"$COMMENT_BODY\"}" \
"https://api.github.com/repos/${{ github.repository }}/issues/comments/${EXISTING_COMMENT_ID}"
else
echo "Posting new comment to PR..."
curl -s -X POST -H "Authorization: token ${GITHUB_TOKEN}" -H "Content-Type: application/json" \
-d "{\"body\": \"$COMMENT_BODY\"}" \
"https://api.github.com/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments"
fi
- name: Check if Action Should Fail And Revert To Draft
env:
GITHUB_TOKEN: ${{ secrets.GIT_ACTIONS_BOT_PAT_CLASSIC }}
PR_NUMBER: ${{ env.PR_NUMBER }}
run: |
echo "🔍 Checking if the workflow should fail and revert PR to draft based on security alerts..."
# Check if there are any unresolved alerts, dismissed alerts missing comments, or invalid dismissal reasons.
if [[ "$UNRESOLVED_COUNT" -gt 0 || "$DISMISSED_COUNT" -gt 0 || "$INVALID_REASON_COUNT" -gt 0 ]]; then
echo "❌ ERROR: Found issues in the PR:"
if [[ "$UNRESOLVED_COUNT" -gt 0 ]]; then
echo "- $UNRESOLVED_COUNT unresolved security alert(s) found!"
fi
if [[ "$DISMISSED_COUNT" -gt 0 ]]; then
echo "- $DISMISSED_COUNT security alert(s) were dismissed without comments!"
fi
if [[ "$INVALID_REASON_COUNT" -gt 0 ]]; then
echo "- $INVALID_REASON_COUNT alert(s) have an invalid dismissal reason (\"Used in tests\")."
fi
echo "⚠️ These alerts must be resolved before merging."
# Retrieve PR Node ID directly from github event
PULL_REQUEST_NODE_ID="${{ github.event.pull_request.node_id }}"
echo "PR Node ID: $PULL_REQUEST_NODE_ID"
# Revert the PR to draft.
echo "Reverting PR #${PR_NUMBER} to draft state due to blocking security issues..."
curl -H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Content-Type: application/json" \
-X POST \
-d '{"query": "mutation { convertPullRequestToDraft(input: {pullRequestId: \"'"$PULL_REQUEST_NODE_ID"'\"}) { pullRequest { id isDraft } } }"}' \
https://api.github.com/graphql
exit 1
fi
echo "✅ No blocking security issues found. The workflow will pass successfully."
4 changes: 2 additions & 2 deletions .github/workflows/versionControlAndAuditCheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -393,8 +393,8 @@ jobs:
echo "This step will make sure that an audit is logged for each contract modified/added by this PR."
echo "It will also make sure that no information is missing in the audit log and that the information is meaningful."
# load list of protected contracts
PROTECTED_CONTRACTS=$(cat contracts_for_audit.txt)
# convert from comma-separated to newline-separated
PROTECTED_CONTRACTS=$(tr ',' '\n' < contracts_for_audit.txt)
echo "PROTECTED_CONTRACTS: $PROTECTED_CONTRACTS"
##### make sure that there are any protected contracts
Expand Down
10 changes: 9 additions & 1 deletion audit/auditLog.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,13 @@
"auditorGitHandle": "sujithsomraaj",
"auditReportPath": "./audit/reports/2025.01.17_LiFiDexAggregator(v1.4.0).pdf",
"auditCommitHash": "n/a (one deployed contract instance was audited)"
},
"audit20250220": {
"auditCompletedOn": "20.02.2025",
"auditedBy": "Sujith Somraaj (individual security researcher)",
"auditorGitHandle": "sujithsomraaj",
"auditReportPath": "./audit/reports/2025.02.20_CalldataVerificationFacet(v1.3.0).pdf",
"auditCommitHash": "48427d21160585f276d206f0e103ce6bd42c4c03"
}
},
"auditedContracts": {
Expand All @@ -172,7 +179,8 @@
"1.2.0": ["audit20241206"]
},
"CalldataVerificationFacet": {
"1.2.0": ["audit20240902"]
"1.2.0": ["audit20240902"],
"1.3.0": ["audit20250220"]
},
"DeBridgeDlnFacet": {
"1.0.0": ["audit20241205"]
Expand Down
Binary file not shown.
Loading

0 comments on commit a448ccc

Please sign in to comment.