mirror of
https://github.com/crytic/slither.git
synced 2026-10-12 02:12:39 +00:00
Merge remote-tracking branch 'origin/master' into pr-2801-update
# Conflicts: # tests/e2e/detectors/test_detectors.py
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
|
||||
language: "en"
|
||||
early_access: false
|
||||
knowledge_base:
|
||||
learnings:
|
||||
scope: auto
|
||||
issues:
|
||||
scope: global
|
||||
reviews:
|
||||
profile: "chill"
|
||||
request_changes_workflow: false
|
||||
high_level_summary: true
|
||||
poem: false
|
||||
review_status: true
|
||||
collapse_walkthrough: true
|
||||
auto_review:
|
||||
enabled: true
|
||||
ignore_title_keywords:
|
||||
- "WIP"
|
||||
- "DO NOT MERGE"
|
||||
drafts: false
|
||||
base_branches:
|
||||
- dev
|
||||
chat:
|
||||
auto_reply: true
|
||||
@@ -1 +1,56 @@
|
||||
# Git
|
||||
.git/
|
||||
.gitignore
|
||||
.gitattributes
|
||||
|
||||
# Virtual environments
|
||||
.venv/
|
||||
venv/
|
||||
.tox/
|
||||
|
||||
# Build artifacts
|
||||
dist/
|
||||
build/
|
||||
*.egg-info/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
.Python
|
||||
wheels/
|
||||
|
||||
# Tests (not needed in production image)
|
||||
tests/
|
||||
|
||||
# Development tooling
|
||||
.github/
|
||||
.pre-commit-config.yaml
|
||||
.ruff_cache/
|
||||
.mypy_cache/
|
||||
.pytest_cache/
|
||||
.coverage
|
||||
htmlcov/
|
||||
.yamllint
|
||||
|
||||
# Documentation (README needed for pyproject.toml)
|
||||
docs/
|
||||
|
||||
# IDE/Editor
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.DS_Store
|
||||
|
||||
# Docker files
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
docker-compose*.yml
|
||||
|
||||
# CI/CD
|
||||
.coderabbit.yaml
|
||||
CITATION.cff
|
||||
CLAUDE.md
|
||||
CONTRIBUTING.md
|
||||
Makefile
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
---
|
||||
body:
|
||||
-
|
||||
attributes:
|
||||
---
|
||||
body:
|
||||
-
|
||||
attributes:
|
||||
label: "What operating system are you using?"
|
||||
id: os
|
||||
type: textarea
|
||||
validations:
|
||||
validations:
|
||||
required: true
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
label: "How did you install slither?"
|
||||
description: |
|
||||
For example, using git or python's pip.
|
||||
id: install-method
|
||||
type: textarea
|
||||
validations:
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: python
|
||||
@@ -25,14 +25,14 @@ body:
|
||||
- "Yes"
|
||||
- "No"
|
||||
- "Not sure"
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
description: |
|
||||
Please copy and paste any relevant log output. This
|
||||
Please copy and paste any relevant log output. This
|
||||
will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
label: "Output of running `slither-doctor .`:"
|
||||
id: logs
|
||||
labels:
|
||||
labels:
|
||||
- installation-help
|
||||
title: "[Installation-Help]: "
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
---
|
||||
body:
|
||||
-
|
||||
attributes:
|
||||
---
|
||||
body:
|
||||
-
|
||||
attributes:
|
||||
value: |
|
||||
Please check the issues tab to avoid duplicates, and
|
||||
Please check the issues tab to avoid duplicates, and
|
||||
confirm that the bug exists on the latest release (upgrade
|
||||
by running `python3 -m pip install --upgrade slither-analyzer`).
|
||||
|
||||
|
||||
If you are having difficulty installing slither,
|
||||
please head over to the "Discussions" page.
|
||||
|
||||
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
type: markdown
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
label: "Describe the issue:"
|
||||
id: what-happened
|
||||
type: textarea
|
||||
validations:
|
||||
validations:
|
||||
required: true
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
description: "It can be a github repo (preferred), etherscan link, or code snippet."
|
||||
label: "Code example to reproduce the issue:"
|
||||
placeholder: "`contract A {}`\n"
|
||||
id: reproduce
|
||||
type: textarea
|
||||
validations:
|
||||
validations:
|
||||
required: true
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
description: |
|
||||
What version of slither are you running?
|
||||
Run `slither --version`
|
||||
label: "Version:"
|
||||
id: version
|
||||
type: textarea
|
||||
validations:
|
||||
validations:
|
||||
required: true
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
description: |
|
||||
Please copy and paste any relevant log output. This
|
||||
Please copy and paste any relevant log output. This
|
||||
will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
label: "Relevant log output:"
|
||||
id: logs
|
||||
type: textarea
|
||||
description: "File a bug report"
|
||||
labels:
|
||||
labels:
|
||||
- bug-candidate
|
||||
name: "Bug Report"
|
||||
title: "[Bug-Candidate]: "
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
---
|
||||
body:
|
||||
-
|
||||
attributes:
|
||||
---
|
||||
body:
|
||||
-
|
||||
attributes:
|
||||
value: |
|
||||
Please check the issues tab to avoid duplicates.
|
||||
Please check the issues tab to avoid duplicates.
|
||||
Thanks for helping make Slither the best it can be!
|
||||
type: markdown
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
label: "What bug did Slither miss and which detector did you anticipate would catch it?"
|
||||
id: what-happened
|
||||
type: textarea
|
||||
validations:
|
||||
validations:
|
||||
required: true
|
||||
-
|
||||
-
|
||||
attributes:
|
||||
label: Frequency
|
||||
description: How often do you run across this false negative?
|
||||
options:
|
||||
- Very Frequently
|
||||
- Occasionally
|
||||
- Occasionally
|
||||
- Rarely
|
||||
- Not sure
|
||||
id: frequency
|
||||
type: dropdown
|
||||
validations:
|
||||
required: true
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
description: "It can be a github repo, etherscan link, or code snippet."
|
||||
label: "Code example to reproduce the issue:"
|
||||
placeholder: "`contract A {}`\n"
|
||||
id: reproduce
|
||||
type: textarea
|
||||
validations:
|
||||
validations:
|
||||
required: true
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
description: |
|
||||
What version of slither are you running?
|
||||
What version of slither are you running?
|
||||
Run `slither --version`
|
||||
label: "Version:"
|
||||
id: version
|
||||
type: textarea
|
||||
validations:
|
||||
validations:
|
||||
required: true
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
description: |
|
||||
Please copy and paste the result output. This
|
||||
Please copy and paste the result output. This
|
||||
will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
label: "Relevant log output:"
|
||||
id: logs
|
||||
type: textarea
|
||||
description: "Slither missed a bug it should find."
|
||||
labels:
|
||||
labels:
|
||||
- false-negative
|
||||
name: False Negative
|
||||
title: "[False Negative]: "
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
---
|
||||
body:
|
||||
-
|
||||
attributes:
|
||||
---
|
||||
body:
|
||||
-
|
||||
attributes:
|
||||
value: |
|
||||
Please check the issues tab to avoid duplicates.
|
||||
Please check the issues tab to avoid duplicates.
|
||||
Thanks for helping make Slither the best it can be!
|
||||
type: markdown
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
label: "Describe the false alarm that Slither raise and how you know it's inaccurate:"
|
||||
id: what-happened
|
||||
type: textarea
|
||||
validations:
|
||||
validations:
|
||||
required: true
|
||||
-
|
||||
-
|
||||
attributes:
|
||||
label: Frequency
|
||||
description: How often do you run across this false positive?
|
||||
options:
|
||||
- Very Frequently
|
||||
- Occasionally
|
||||
- Occasionally
|
||||
- Rarely
|
||||
- Not sure
|
||||
id: frequency
|
||||
type: dropdown
|
||||
validations:
|
||||
required: true
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
description: "It can be a github repo, etherscan link, or code snippet."
|
||||
label: "Code example to reproduce the issue:"
|
||||
placeholder: "`contract A {}`\n"
|
||||
id: reproduce
|
||||
type: textarea
|
||||
validations:
|
||||
validations:
|
||||
required: true
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
description: |
|
||||
What version of slither are you running?
|
||||
What version of slither are you running?
|
||||
Run `slither --version`
|
||||
label: "Version:"
|
||||
id: version
|
||||
type: textarea
|
||||
validations:
|
||||
validations:
|
||||
required: true
|
||||
-
|
||||
attributes:
|
||||
-
|
||||
attributes:
|
||||
description: |
|
||||
Please copy and paste the result output. This
|
||||
Please copy and paste the result output. This
|
||||
will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
label: "Relevant log output:"
|
||||
id: logs
|
||||
type: textarea
|
||||
description: "Slither warned of an issue that is not legitimate and does not need to be fixed."
|
||||
labels:
|
||||
labels:
|
||||
- false-positive
|
||||
name: "False Positive"
|
||||
title: "[False-Positive]: "
|
||||
|
||||
@@ -14,4 +14,4 @@ body:
|
||||
label: Describe the desired feature
|
||||
description: Explain what the feature solves/ improves.
|
||||
validations:
|
||||
required: true
|
||||
required: true
|
||||
|
||||
+12
-5
@@ -1,8 +1,15 @@
|
||||
---
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
target-branch: "dev"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
target-branch: "master"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "npm"
|
||||
directory: "tests/e2e/compilation/test_data/test_node_modules/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 0
|
||||
ignore:
|
||||
- dependency-name: "*"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
# used to pass --cov=$path and --cov-append to pytest
|
||||
if [ "$1" != "" ]; then
|
||||
pytest "$1" tests/e2e/ -n auto
|
||||
@@ -10,4 +11,4 @@ else
|
||||
status_code=$?
|
||||
fi
|
||||
|
||||
exit "$status_code"
|
||||
exit "$status_code"
|
||||
|
||||
@@ -10,4 +10,4 @@ else
|
||||
status_code=$?
|
||||
fi
|
||||
|
||||
exit "$status_code"
|
||||
exit "$status_code"
|
||||
|
||||
@@ -10,4 +10,4 @@ else
|
||||
status_code=$?
|
||||
fi
|
||||
|
||||
exit "$status_code"
|
||||
exit "$status_code"
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
---
|
||||
name: Run black
|
||||
|
||||
defaults:
|
||||
run:
|
||||
# To load bashrc
|
||||
shell: bash -ieo pipefail {0}
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master, dev]
|
||||
paths:
|
||||
- "**/*.py"
|
||||
schedule:
|
||||
# run CI every day even if no PRs/merges occur
|
||||
- cron: '0 12 * * *'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Black
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# Full git history is needed to get a proper list of changed files within `super-linter`
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.8
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
mkdir -p .github/linters
|
||||
cp pyproject.toml .github/linters
|
||||
|
||||
- name: Black
|
||||
uses: super-linter/super-linter/[email protected]
|
||||
if: always()
|
||||
env:
|
||||
# run linter on everything to catch preexisting problems
|
||||
VALIDATE_ALL_CODEBASE: true
|
||||
DEFAULT_BRANCH: master
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Run only black
|
||||
VALIDATE_PYTHON_BLACK: true
|
||||
PYTHON_BLACK_CONFIG_FILE: pyproject.toml
|
||||
FILTER_REGEX_EXCLUDE: .*tests/.*.(json|zip|sol)
|
||||
@@ -1,43 +0,0 @@
|
||||
---
|
||||
name: Run black (auto)
|
||||
|
||||
defaults:
|
||||
run:
|
||||
# To load bashrc
|
||||
shell: bash -ieo pipefail {0}
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master, dev]
|
||||
paths:
|
||||
- "**/*.py"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Black
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.8
|
||||
|
||||
- name: Run black
|
||||
uses: psf/black@stable
|
||||
with:
|
||||
options: ""
|
||||
summary: false
|
||||
version: "~= 22.3.0"
|
||||
|
||||
- name: Annotate diff changes using reviewdog
|
||||
uses: reviewdog/action-suggester@v1
|
||||
with:
|
||||
tool_name: blackfmt
|
||||
+25
-11
@@ -9,7 +9,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- dev
|
||||
pull_request:
|
||||
schedule:
|
||||
# run CI every day even if no PRs/merges occur
|
||||
@@ -25,28 +24,43 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ${{ (github.event_name == 'pull_request' && fromJSON('["ubuntu-latest"]')) || fromJSON('["ubuntu-latest", "windows-2022"]') }}
|
||||
python: ${{ (github.event_name == 'pull_request' && fromJSON('["3.8", "3.12"]')) || fromJSON('["3.8", "3.9", "3.10", "3.11", "3.12"]') }}
|
||||
type: ${{ (github.event_name == 'pull_request' && fromJSON('["data_dependency", "path_filtering","erc","find_paths","flat","interface", "printers","slither_config","upgradability"]')) || fromJSON('["data_dependency", "path_filtering","erc","find_paths","flat","interface", "printers","slither_config","upgradability", "cli", "dapp", "etherscan", "kspec", "simil", "truffle"]') }}
|
||||
os: >-
|
||||
${{ (github.event_name == 'pull_request' && fromJSON('["ubuntu-latest"]'))
|
||||
|| fromJSON('["ubuntu-latest", "windows-2025"]') }}
|
||||
python: >-
|
||||
${{ (github.event_name == 'pull_request' && fromJSON('["3.9", "3.14"]'))
|
||||
|| fromJSON('["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]') }}
|
||||
type: >-
|
||||
${{ (github.event_name == 'pull_request'
|
||||
&& fromJSON('["data_dependency", "path_filtering", "erc", "find_paths",
|
||||
"flat", "interface", "printers", "slither_config", "upgradability"]'))
|
||||
|| fromJSON('["data_dependency", "path_filtering", "erc", "find_paths",
|
||||
"flat", "interface", "printers", "slither_config", "upgradability",
|
||||
"cli", "dapp", "etherscan", "kspec", "simil", "truffle"]') }}
|
||||
exclude:
|
||||
# Requires nix
|
||||
- os: windows-2022
|
||||
- os: windows-2025
|
||||
type: dapp
|
||||
# Requires nvm
|
||||
- os: windows-2022
|
||||
- os: windows-2025
|
||||
type: truffle
|
||||
# fasttext fails to install on Windows
|
||||
- os: windows-2025
|
||||
type: simil
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python ${{ matrix.python }}
|
||||
uses: actions/setup-python@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install uv and Python ${{ matrix.python }}
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
activate-environment: true
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install ".[test]"
|
||||
solc-select use 0.4.25 --always-install
|
||||
uv sync --group test
|
||||
solc-select use 0.8.0 --always-install
|
||||
solc-select use 0.7.0 --always-install
|
||||
solc-select use 0.5.1 --always-install
|
||||
solc-select use 0.4.25 --always-install
|
||||
|
||||
- name: Set up nix
|
||||
if: matrix.type == 'dapp'
|
||||
|
||||
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- dev
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
@@ -17,7 +16,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
@@ -28,16 +28,18 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
- uses: actions/setup-python@v5
|
||||
- name: Install uv and Python
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
python-version: '3.8'
|
||||
- run: pip install -e ".[doc]"
|
||||
- run: pdoc -o html/ slither '!slither.tools' #TODO fix import errors on pdoc run
|
||||
python-version: "3.9"
|
||||
activate-environment: true
|
||||
- run: uv sync --group doc
|
||||
- run: pdoc -o html/ slither '!slither.tools' # TODO fix import errors on pdoc run
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
uses: actions/upload-pages-artifact@v4
|
||||
with:
|
||||
# Upload the doc
|
||||
path: './html/'
|
||||
|
||||
@@ -22,41 +22,23 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ["ubuntu-latest", "windows-2022"]
|
||||
python: ["3.8", "3.9", "3.10", "3.11", "3.12"]
|
||||
exclude:
|
||||
# strange failure
|
||||
- os: windows-2022
|
||||
python: 3.8
|
||||
os: ["ubuntu-latest", "windows-2025"]
|
||||
python: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Python ${{ matrix.python }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v7
|
||||
|
||||
- name: Try system-wide Slither
|
||||
run: |
|
||||
echo "::group::Install slither"
|
||||
pip3 install .
|
||||
echo "::endgroup::"
|
||||
|
||||
# escape cwd so python doesn't pick up local module
|
||||
cd /
|
||||
|
||||
echo "::group::Via module"
|
||||
python3 -m slither.tools.doctor .
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Via binary"
|
||||
slither-doctor .
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Try user Slither
|
||||
run: |
|
||||
echo "::group::Install slither"
|
||||
pip3 install --user .
|
||||
uv pip install --system .
|
||||
echo "::endgroup::"
|
||||
|
||||
# escape cwd so python doesn't pick up local module
|
||||
@@ -73,10 +55,10 @@ jobs:
|
||||
- name: Try venv Slither
|
||||
run: |
|
||||
echo "::group::Install slither"
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate || source venv/Scripts/activate
|
||||
uv venv
|
||||
uv pip install .
|
||||
source .venv/bin/activate || source .venv/Scripts/activate
|
||||
hash -r
|
||||
pip3 install .
|
||||
echo "::endgroup::"
|
||||
|
||||
# escape cwd so python doesn't pick up local module
|
||||
|
||||
@@ -13,28 +13,30 @@ jobs:
|
||||
name: issue metrics
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get dates for last month
|
||||
shell: bash
|
||||
run: |
|
||||
# Calculate the first day of the previous month
|
||||
first_day=$(date -d "last month" +%Y-%m-01)
|
||||
- name: Get dates for last month
|
||||
shell: bash
|
||||
run: |
|
||||
# Calculate the first day of the previous month
|
||||
first_day=$(date -d "last month" +%Y-%m-01)
|
||||
|
||||
# Calculate the last day of the previous month
|
||||
last_day=$(date -d "$first_day +1 month -1 day" +%Y-%m-%d)
|
||||
# Calculate the last day of the previous month
|
||||
last_day=$(date -d "$first_day +1 month -1 day" +%Y-%m-%d)
|
||||
|
||||
#Set an environment variable with the date range
|
||||
echo "$first_day..$last_day"
|
||||
echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV"
|
||||
# Set an environment variable with the date range
|
||||
echo "$first_day..$last_day"
|
||||
echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Run issue-metrics tool
|
||||
uses: github/issue-metrics@v3
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SEARCH_QUERY: 'repo:crytic/slither is:issue created:${{ env.last_month }} -reason:"not planned" -reason:"duplicate"'
|
||||
- name: Run issue-metrics tool
|
||||
uses: github/issue-metrics@v3
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SEARCH_QUERY: >-
|
||||
repo:crytic/slither is:issue created:${{ env.last_month }}
|
||||
-reason:"not planned" -reason:"duplicate"
|
||||
|
||||
- name: Create issue
|
||||
uses: peter-evans/create-issue-from-file@v5
|
||||
with:
|
||||
title: Monthly issue metrics report
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
content-filepath: ./issue_metrics.md
|
||||
- name: Create issue
|
||||
uses: peter-evans/create-issue-from-file@v6
|
||||
with:
|
||||
title: Monthly issue metrics report
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
content-filepath: ./issue_metrics.md
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
---
|
||||
name: Lint Code Base
|
||||
|
||||
defaults:
|
||||
run:
|
||||
# To load bashrc
|
||||
shell: bash -ieo pipefail {0}
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master, dev]
|
||||
|
||||
schedule:
|
||||
# run CI every day even if no PRs/merges occur
|
||||
- cron: '0 12 * * *'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Superlinter
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# Full git history is needed to get a proper list of changed files within `super-linter`
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.8
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
mkdir -p .github/linters
|
||||
cp pyproject.toml .github/linters
|
||||
|
||||
- name: Register yamllint problem matcher
|
||||
run: |
|
||||
echo "::add-matcher::.github/workflows/matchers/yamllint.json"
|
||||
|
||||
- name: Remove part of the doc
|
||||
run: |
|
||||
rm -rf docs/src/
|
||||
|
||||
- name: Lint everything else
|
||||
uses: super-linter/super-linter/[email protected]
|
||||
if: always()
|
||||
env:
|
||||
# run linter on everything to catch preexisting problems
|
||||
VALIDATE_ALL_CODEBASE: true
|
||||
DEFAULT_BRANCH: master
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Always false
|
||||
VALIDATE_PYTHON: false
|
||||
VALIDATE_PYTHON_PYLINT: false
|
||||
VALIDATE_PYTHON_BLACK: false
|
||||
VALIDATE_PYTHON_ISORT: false
|
||||
VALIDATE_JSON: false
|
||||
VALIDATE_JAVASCRIPT_ES: false
|
||||
VALIDATE_JAVASCRIPT_STANDARD: false
|
||||
VALIDATE_PYTHON_FLAKE8: false
|
||||
VALIDATE_DOCKERFILE: false
|
||||
VALIDATE_DOCKERFILE_HADOLINT: false
|
||||
VALIDATE_EDITORCONFIG: false
|
||||
VALIDATE_JSCPD: false
|
||||
VALIDATE_PYTHON_MYPY: false
|
||||
VALIDATE_CHECKOV: false
|
||||
# TODO: consider enabling
|
||||
VALIDATE_SHELL_SHFMT: false
|
||||
SHELLCHECK_OPTS: "-e SC1090"
|
||||
FILTER_REGEX_EXCLUDE: .*tests/.*.(json|zip|sol)
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "pylint-error",
|
||||
"severity": "error",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^(.+):(\\d+):(\\d+):\\s(([EF]\\d{4}):\\s.+)$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"message": 4,
|
||||
"code": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "pylint-warning",
|
||||
"severity": "warning",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^(.+):(\\d+):(\\d+):\\s(([CRW]\\d{4}):\\s.+)$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"message": 4,
|
||||
"code": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "yamllint",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^(.*\\.ya?ml)$",
|
||||
"file": 1
|
||||
},
|
||||
{
|
||||
"regexp": "^\\s{2}(\\d+):(\\d+)\\s+(error|warning)\\s+(.*?)\\s+\\((.*)\\)$",
|
||||
"line": 1,
|
||||
"column": 2,
|
||||
"severity": 3,
|
||||
"message": 4,
|
||||
"code": 5,
|
||||
"loop": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -3,10 +3,10 @@ name: pip-audit
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ dev, master ]
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [ dev, master ]
|
||||
schedule: [ cron: "0 7 * * 2" ]
|
||||
branches: [master]
|
||||
schedule: [cron: "0 7 * * 2"]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -18,22 +18,18 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v5
|
||||
- name: Install uv and Python
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install Slither
|
||||
run: |
|
||||
python -m venv /tmp/pip-audit-env
|
||||
source /tmp/pip-audit-env/bin/activate
|
||||
|
||||
python -m pip install --upgrade pip setuptools wheel
|
||||
python -m pip install .
|
||||
uv export --format requirements-txt --no-emit-project > requirements.txt
|
||||
|
||||
- name: Run pip-audit
|
||||
uses: pypa/[email protected]
|
||||
with:
|
||||
virtual-environment: /tmp/pip-audit-env
|
||||
inputs: requirements.txt
|
||||
|
||||
@@ -10,20 +10,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
python-version: '3.x'
|
||||
|
||||
activate-environment: true
|
||||
- name: Build distributions
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install build
|
||||
python -m build
|
||||
run: uv build
|
||||
- name: Upload distributions
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: slither-dists
|
||||
path: dist/
|
||||
@@ -38,16 +34,16 @@ jobs:
|
||||
- build-release
|
||||
steps:
|
||||
- name: fetch dists
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: slither-dists
|
||||
path: dist/
|
||||
|
||||
- name: publish
|
||||
uses: pypa/[email protected]2.4
|
||||
uses: pypa/[email protected]3.0
|
||||
|
||||
- name: sign
|
||||
uses: sigstore/gh-action-sigstore-python@v3.0.0
|
||||
uses: sigstore/gh-action-sigstore-python@v3.2.0
|
||||
with:
|
||||
inputs: ./dist/*.tar.gz ./dist/*.whl
|
||||
release-signing-artifacts: true
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
---
|
||||
name: Run pylint
|
||||
|
||||
defaults:
|
||||
run:
|
||||
# To load bashrc
|
||||
shell: bash -ieo pipefail {0}
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master, dev]
|
||||
paths:
|
||||
- "**/*.py"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Lint Code Base
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# Full git history is needed to get a proper list of changed files within `super-linter`
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.8
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
mkdir -p .github/linters
|
||||
cp pyproject.toml .github/linters
|
||||
|
||||
- name: Register pylint problem matcher
|
||||
run: |
|
||||
echo "::add-matcher::.github/workflows/matchers/pylint.json"
|
||||
|
||||
- name: Pylint
|
||||
uses: super-linter/super-linter/[email protected]
|
||||
if: always()
|
||||
env:
|
||||
# Run linters only on new files for pylint to speed up the CI
|
||||
VALIDATE_ALL_CODEBASE: false
|
||||
# Compare against the base branch
|
||||
# This is only accessible on PR
|
||||
DEFAULT_BRANCH: ${{ github.base_ref }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Run only pylint
|
||||
VALIDATE_PYTHON: true
|
||||
VALIDATE_PYTHON_PYLINT: true
|
||||
PYTHON_PYLINT_CONFIG_FILE: pyproject.toml
|
||||
FILTER_REGEX_EXCLUDE: .*tests/.*.(json|zip|sol)
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
name: Lint with Ruff
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
paths:
|
||||
- "**/*.py"
|
||||
- "**/*.yml"
|
||||
- "**/*.yaml"
|
||||
- "pyproject.toml"
|
||||
- ".github/workflows/ruff.yml"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint Code
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Run Ruff linter
|
||||
uses: astral-sh/ruff-action@v3
|
||||
with:
|
||||
version: "0.14.10"
|
||||
args: "check slither/ tests/ scripts/"
|
||||
|
||||
# Formatting check disabled to avoid changes to existing code
|
||||
- name: Run Ruff formatter check
|
||||
run: |
|
||||
echo "::group::Checking formatting with Ruff"
|
||||
ruff format --check slither/ tests/ scripts/ || FORMAT_EXIT=$?
|
||||
echo "::endgroup::"
|
||||
if [ "${FORMAT_EXIT:-0}" -ne 0 ]; then
|
||||
echo "❌ Formatting check failed. Run 'make reformat' or 'ruff format' locally to fix formatting."
|
||||
exit $FORMAT_EXIT
|
||||
fi
|
||||
echo "✅ Formatting check passed"
|
||||
|
||||
- name: Install uv and Python for yamllint
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
python-version: "3.14"
|
||||
activate-environment: true
|
||||
|
||||
- name: Install and run yamllint
|
||||
run: |
|
||||
uv tool install yamllint
|
||||
echo "::group::Running yamllint"
|
||||
uvx yamllint .github/ || YAML_EXIT=$?
|
||||
echo "::endgroup::"
|
||||
if [ "${YAML_EXIT:-0}" -ne 0 ]; then
|
||||
echo "❌ YAML linting failed. Fix the YAML syntax errors shown above."
|
||||
exit $YAML_EXIT
|
||||
fi
|
||||
echo "✅ YAML linting passed"
|
||||
+21
-19
@@ -7,7 +7,7 @@ defaults:
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, dev]
|
||||
branches: [master]
|
||||
pull_request:
|
||||
schedule:
|
||||
# run CI every day even if no PRs/merges occur
|
||||
@@ -23,26 +23,27 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ["ubuntu-latest", "windows-2022"]
|
||||
os: ["ubuntu-latest", "windows-2025"]
|
||||
type: ["unit", "integration", "tool"]
|
||||
python: ${{ (github.event_name == 'pull_request' && fromJSON('["3.8", "3.12"]')) || fromJSON('["3.8", "3.9", "3.10", "3.11", "3.12"]') }}
|
||||
python: >-
|
||||
${{ (github.event_name == 'pull_request' && fromJSON('["3.9", "3.14"]'))
|
||||
|| fromJSON('["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]') }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python ${{ matrix.python }}
|
||||
uses: actions/setup-python@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install uv and Python ${{ matrix.python }}
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
cache: "pip"
|
||||
cache-dependency-path: setup.py
|
||||
activate-environment: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install ".[test]"
|
||||
uv sync --group test
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '16'
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
|
||||
@@ -81,7 +82,7 @@ jobs:
|
||||
run: |
|
||||
if [ ${{ matrix.os }} = "ubuntu-latest" ]; then
|
||||
TEST_ARGS=(--cov=slither --cov-append)
|
||||
elif [ ${{ matrix.os }} = "windows-2022" ]; then
|
||||
elif [ ${{ matrix.os }} = "windows-2025" ]; then
|
||||
TEST_ARGS=()
|
||||
fi
|
||||
bash "./.github/scripts/${TEST_TYPE}_test_runner.sh" "${TEST_ARGS[@]}"
|
||||
@@ -91,7 +92,7 @@ jobs:
|
||||
uses: ./.github/actions/upload-coverage
|
||||
# only aggregate test coverage over linux-based tests to avoid any OS-specific filesystem information stored in
|
||||
# coverage metadata.
|
||||
if: ${{ matrix.os == 'ubuntu-latest' && matrix.python == '3.8' }}
|
||||
if: ${{ matrix.os == 'ubuntu-latest' && matrix.python == '3.9' }}
|
||||
|
||||
coverage:
|
||||
needs:
|
||||
@@ -100,16 +101,17 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install uv and Python
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
python-version: 3.8
|
||||
python-version: "3.9"
|
||||
activate-environment: true
|
||||
|
||||
- run: pip install coverage[toml]
|
||||
- run: uv pip install coverage[toml]
|
||||
|
||||
- name: download coverage data
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: coverage-data-*
|
||||
merge-multiple: true
|
||||
|
||||
+2
-2
@@ -110,8 +110,8 @@ ENV/
|
||||
# Test results
|
||||
test_artifacts/
|
||||
|
||||
# crytic export
|
||||
# crytic export
|
||||
crytic-export/
|
||||
|
||||
# slither.db.json
|
||||
# slither.db.json
|
||||
slither.db.json
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
# Pre-commit hooks for automated code quality checks
|
||||
# Install with: pre-commit install
|
||||
# Run manually: pre-commit run --all-files
|
||||
|
||||
repos:
|
||||
# Ruff - Fast Python linter and formatter
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.14.10 # Use 'pre-commit autoupdate' to get the latest version
|
||||
hooks:
|
||||
# Run ruff linter
|
||||
- id: ruff-check
|
||||
name: ruff lint
|
||||
args: [--fix, --exit-non-zero-on-fix]
|
||||
types_or: [python, pyi]
|
||||
# Run ruff formatter
|
||||
- id: ruff-format
|
||||
name: ruff format
|
||||
types_or: [python, pyi]
|
||||
|
||||
# YAML linting
|
||||
- repo: https://github.com/adrienverge/yamllint
|
||||
rev: v1.37.1
|
||||
hooks:
|
||||
- id: yamllint
|
||||
name: yamllint
|
||||
args: [-c=.yamllint]
|
||||
types: [yaml]
|
||||
exclude: ^(tests/|docs/)
|
||||
|
||||
# General file checks
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v6.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
name: trim trailing whitespace
|
||||
exclude: ^(tests/|.*\.md$)
|
||||
- id: end-of-file-fixer
|
||||
name: fix end of files
|
||||
exclude: ^(tests/|docs/)
|
||||
- id: check-yaml
|
||||
name: check yaml syntax
|
||||
exclude: ^(tests/|docs/)
|
||||
- id: check-added-large-files
|
||||
name: check for large files
|
||||
args: [--maxkb=1000]
|
||||
- id: check-merge-conflict
|
||||
name: check for merge conflicts
|
||||
- id: check-toml
|
||||
name: check toml syntax
|
||||
- id: debug-statements
|
||||
name: check for debug statements
|
||||
exclude: ^(tests/)
|
||||
- id: mixed-line-ending
|
||||
name: fix mixed line endings
|
||||
args: [--fix=lf]
|
||||
|
||||
# Configuration
|
||||
default_language_version:
|
||||
python: python3.11
|
||||
|
||||
# Run hooks on pre-commit and pre-push
|
||||
default_stages: [pre-commit, pre-push]
|
||||
@@ -0,0 +1,24 @@
|
||||
extends: default
|
||||
|
||||
rules:
|
||||
document-start: disable
|
||||
line-length:
|
||||
max: 120
|
||||
allow-non-breakable-words: true
|
||||
allow-non-breakable-inline-mappings: true
|
||||
truthy:
|
||||
allowed-values: ['true', 'false', 'on']
|
||||
check-keys: false
|
||||
comments:
|
||||
min-spaces-from-content: 1
|
||||
comments-indentation: disable
|
||||
octal-values: disable
|
||||
|
||||
ignore: |
|
||||
.github/linters/
|
||||
tests/
|
||||
docs/
|
||||
node_modules/
|
||||
build/
|
||||
dist/
|
||||
*.egg-info/
|
||||
+3
-3
@@ -33,14 +33,14 @@ abstract: >-
|
||||
SlithIR uses Static Single Assignment (SSA) form and a
|
||||
reduced instruction set to ease implementation of analyses
|
||||
while preserving semantic information that would be lost
|
||||
in transforming Solidity to bytecode.
|
||||
in transforming Solidity to bytecode.
|
||||
|
||||
Slither allows for the application of commonly used
|
||||
program analysis techniques like dataflow and taint
|
||||
tracking.
|
||||
|
||||
|
||||
Our framework has four main use cases:
|
||||
Our framework has four main use cases:
|
||||
|
||||
(1) automated detection of vulnerabilities,
|
||||
|
||||
@@ -50,7 +50,7 @@ abstract: >-
|
||||
(3) improvement of the user's understanding of the
|
||||
contracts, and
|
||||
|
||||
(4) assistance with code review.
|
||||
(4) assistance with code review.
|
||||
keywords:
|
||||
- Ethereum
|
||||
- Static Analysis
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# Slither Coding Standards
|
||||
|
||||
## Runtime
|
||||
| lang | version | manager |
|
||||
|--------|---------|---------|
|
||||
| Python | ≥3.9 | uv |
|
||||
|
||||
## Required tooling
|
||||
| purpose | tool |
|
||||
|------------------|----------|
|
||||
| deps & venv | `uv` |
|
||||
| lint & format | `ruff` |
|
||||
| tests | `pytest` |
|
||||
|
||||
## Python guidelines
|
||||
- Always use `uv` instead of pip
|
||||
- Build with `hatchling` (`[build-system]` in pyproject.toml)
|
||||
- Use `astral-sh/ruff-action@v3` or newer in CI
|
||||
- Let tools auto-detect versions from pyproject.toml
|
||||
- Verify builds: `uv build`, `uv tool install dist/*.whl`, `uv tool install -e .`
|
||||
|
||||
## Version Verification
|
||||
When adding or updating dependencies, CI actions, or tool versions:
|
||||
1. **Always web search** for the current stable version before specifying any version number
|
||||
2. Training data versions are stale—never assume a version from memory is current
|
||||
3. Check the official source (PyPI, GitHub releases) for latest stable
|
||||
4. Exception: Only skip web search if user explicitly provides the version to use
|
||||
|
||||
## Hard rules
|
||||
1. ≤ 80 code lines / function
|
||||
2. Cyclomatic complexity ≤ 8
|
||||
3. ≤ 5 positional params, ≤ 12 branches, ≤ 6 returns
|
||||
4. 100‑char line length
|
||||
5. Ban relative ("..") imports
|
||||
6. Tests in `/tests/` mirroring package structure (not beside code)
|
||||
7. No scheduled CI without code changes
|
||||
|
||||
## Bash strict mode
|
||||
All bash scripts must start with:
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
```
|
||||
|
||||
## Common commands
|
||||
```bash
|
||||
make dev # Create venv and install deps
|
||||
make lint # Run ruff check
|
||||
make reformat # Run ruff format
|
||||
make test # Run all tests
|
||||
make test TESTS=unit # Run specific test directory
|
||||
pytest tests/unit/ -q # Fast unit tests only
|
||||
uv run ruff check --fix . # Auto-fix lint issues
|
||||
```
|
||||
|
||||
> Never commit changes that break any rule above—refactor instead.
|
||||
> Never push to GitHub until asked explicitly.
|
||||
> Don't be hyperbolic in PR/Issue writeups.
|
||||
+40
-4
@@ -18,7 +18,7 @@ Slither uses the pull request contribution model. Please make an account on GitH
|
||||
|
||||
Some pull request guidelines:
|
||||
|
||||
- Work from the [`dev`](https://github.com/crytic/slither/tree/dev) branch. We performed extensive tests prior to merging anything to `master`, working from `dev` will allow us to merge your work faster.
|
||||
- Work from the [`master`](https://github.com/crytic/slither/tree/master) branch.
|
||||
- Minimize irrelevant changes (formatting, whitespace, etc) to code that would otherwise not be touched by this patch. Save formatting or style corrections for a separate pull request that does not make any semantic changes.
|
||||
- When possible, large changes should be split up into smaller focused pull requests.
|
||||
- Fill out the pull request description with a summary of what your patch does, key changes that have been made, and any further points of discussion, if applicable.
|
||||
@@ -47,6 +47,16 @@ A code walkthrough is available [here](https://www.youtube.com/watch?v=EUl3UlYSl
|
||||
|
||||
Instructions for installing a development version of Slither can be found in our [wiki](https://github.com/crytic/slither/wiki/Developer-installation).
|
||||
|
||||
For development setup, we use [uv](https://github.com/astral-sh/uv):
|
||||
|
||||
```bash
|
||||
# Install uv if you haven't already
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
|
||||
# Setup development environment
|
||||
make dev # Creates venv and installs all dependencies
|
||||
```
|
||||
|
||||
To run the unit tests, you need to clone this repository and run `make test`. Run a specific test with `make test TESTS=$test_name`. The names of tests can be obtained with `pytest tests --collect-only`.
|
||||
|
||||
### Linters
|
||||
@@ -63,7 +73,33 @@ To automatically reformat the code:
|
||||
|
||||
- `make reformat`
|
||||
|
||||
We use pylint `3.0.3`, black `22.3.0`.
|
||||
We use ruff (latest 0.x version) for linting and formatting, and yamllint for YAML files.
|
||||
|
||||
#### Pre-commit Hooks (Recommended)
|
||||
|
||||
We recommend using pre-commit hooks to automatically check and fix code before committing:
|
||||
|
||||
```bash
|
||||
# Install pre-commit hooks (one-time setup)
|
||||
pre-commit install
|
||||
|
||||
# Run manually on all files
|
||||
pre-commit run --all-files
|
||||
|
||||
# Run on specific files
|
||||
pre-commit run --files slither/core/*.py
|
||||
|
||||
# Update hook versions
|
||||
pre-commit autoupdate
|
||||
```
|
||||
|
||||
The pre-commit hooks will automatically:
|
||||
- Fix linting issues with ruff
|
||||
- Check YAML syntax
|
||||
- Remove trailing whitespace
|
||||
- Fix end-of-file issues
|
||||
- Check for merge conflicts
|
||||
- Prevent large files from being committed
|
||||
|
||||
### Testing
|
||||
|
||||
@@ -111,9 +147,9 @@ For each new detector, at least one regression tests must be present.
|
||||
|
||||
### Synchronization with crytic-compile
|
||||
|
||||
By default, `slither` follows either the latest version of crytic-compile in pip, or `crytic-compile@master` (look for dependencies in [`setup.py`](./setup.py). If crytic-compile development comes with breaking changes, the process to update `slither` is:
|
||||
By default, `slither` follows either the latest version of crytic-compile in pip, or `crytic-compile@master` (look for dependencies in [`pyproject.toml`](./pyproject.toml). If crytic-compile development comes with breaking changes, the process to update `slither` is:
|
||||
|
||||
- Update `slither/setup.py` to point to the related crytic-compile's branch
|
||||
- Update `slither/pyproject.toml` to point to the related crytic-compile's branch
|
||||
- Create a PR in `slither` and ensure it passes the CI
|
||||
- Once the development branch is merged in `crytic-compile@master`, ensure `slither` follows the `master` branch
|
||||
|
||||
|
||||
+47
-29
@@ -1,33 +1,24 @@
|
||||
# syntax=docker/dockerfile:1.3
|
||||
FROM ubuntu:jammy AS python-wheels
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
gcc \
|
||||
git \
|
||||
make \
|
||||
python3-dev \
|
||||
python3-pip \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY . /slither
|
||||
|
||||
RUN cd /slither && \
|
||||
pip3 install --no-cache-dir --upgrade pip && \
|
||||
pip3 wheel -w /wheels . solc-select pip setuptools wheel
|
||||
|
||||
|
||||
# syntax=docker/dockerfile:1.12
|
||||
FROM ubuntu:jammy AS final
|
||||
|
||||
LABEL name=slither
|
||||
LABEL src="https://github.com/trailofbits/slither"
|
||||
LABEL creator=trailofbits
|
||||
LABEL dockerfile_maintenance=trailofbits
|
||||
LABEL desc="Static Analyzer for Solidity"
|
||||
LABEL name=slither \
|
||||
src="https://github.com/trailofbits/slither" \
|
||||
creator=trailofbits \
|
||||
dockerfile_maintenance=trailofbits \
|
||||
desc="Static Analyzer for Solidity"
|
||||
|
||||
RUN export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends python3-pip \
|
||||
&& apt-get install -y --no-install-recommends ca-certificates curl git python3 python3-pip python3-venv \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install uv if available for this architecture (amd64/arm64)
|
||||
# uv doesn't support armv7, so those builds will use pip instead
|
||||
RUN arch=$(uname -m) && \
|
||||
if [ "$arch" = "x86_64" ] || [ "$arch" = "aarch64" ]; then \
|
||||
curl -LsSf https://astral.sh/uv/install.sh | UV_INSTALL_DIR=/usr/local/bin sh; \
|
||||
fi
|
||||
|
||||
# improve compatibility with amd64 solc in non-amd64 environments (e.g. Docker Desktop on M1 Mac)
|
||||
ENV QEMU_LD_PREFIX=/usr/x86_64-linux-gnu
|
||||
RUN if [ ! "$(uname -m)" = "x86_64" ]; then \
|
||||
@@ -36,18 +27,45 @@ RUN if [ ! "$(uname -m)" = "x86_64" ]; then \
|
||||
&& apt-get install -y --no-install-recommends libc6-amd64-cross \
|
||||
&& rm -rf /var/lib/apt/lists/*; fi
|
||||
|
||||
# Install build tools only on armv7 (needed for pip to compile wheels)
|
||||
# amd64/arm64 use uv with pre-built wheels, so they don't need these
|
||||
RUN arch=$(uname -m) && \
|
||||
if [ "$arch" = "armv7l" ]; then \
|
||||
export DEBIAN_FRONTEND=noninteractive && \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends build-essential python3-dev && \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
fi
|
||||
|
||||
RUN useradd -m slither
|
||||
USER slither
|
||||
|
||||
COPY --chown=slither:slither . /home/slither/slither
|
||||
WORKDIR /home/slither/slither
|
||||
|
||||
ENV PATH="/home/slither/.local/bin:${PATH}"
|
||||
# Copy dependency files first for layer caching
|
||||
COPY --chown=slither:slither pyproject.toml uv.lock ./
|
||||
|
||||
# no-index ensures we install the freshly-built wheels
|
||||
RUN --mount=type=bind,target=/mnt,source=/wheels,from=python-wheels \
|
||||
pip3 install --user --no-cache-dir --upgrade --no-index --find-links /mnt --no-deps /mnt/*.whl
|
||||
# Install dependencies - use uv if available (with lockfile), pip otherwise
|
||||
RUN if command -v uv >/dev/null 2>&1; then \
|
||||
uv sync --frozen --no-install-project; \
|
||||
else \
|
||||
python3 -m venv .venv; \
|
||||
fi
|
||||
|
||||
# Copy source code
|
||||
COPY --chown=slither:slither . .
|
||||
|
||||
# Install the project itself and solc-select
|
||||
RUN if command -v uv >/dev/null 2>&1; then \
|
||||
uv sync --frozen && \
|
||||
uv tool install solc-select; \
|
||||
else \
|
||||
. .venv/bin/activate && \
|
||||
pip install --no-cache-dir -e . solc-select; \
|
||||
fi
|
||||
|
||||
ENV PATH="/home/slither/slither/.venv/bin:/home/slither/.local/bin:${PATH}"
|
||||
|
||||
RUN solc-select use latest --always-install
|
||||
|
||||
CMD /bin/bash
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"Optimism": {
|
||||
"op-mainnet": {
|
||||
"ownedBy": "0xc44F30Be3eBBEfdDBB5a85168710b4f0e18f4Ff0"
|
||||
}
|
||||
},
|
||||
"drips": {
|
||||
"ethereum": {
|
||||
"ownedBy": "0xc44F30Be3eBBEfdDBB5a85168710b4f0e18f4Ff0"
|
||||
}
|
||||
},
|
||||
"opRetro": {
|
||||
"projectId": "0xdc3dce33fd5fb50cf932586d4257456ddf5040ba0955d97641646504c73dbd13"
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ SHELL := /bin/bash
|
||||
|
||||
PY_MODULE := slither
|
||||
TEST_MODULE := tests
|
||||
SCRIPT_MODULE := scripts
|
||||
|
||||
ALL_PY_SRCS := $(shell find $(PY_MODULE) -name '*.py') \
|
||||
$(shell find tests -name '*.py')
|
||||
@@ -49,23 +50,20 @@ run: $(VENV)/pyvenv.cfg
|
||||
@. $(VENV_BIN)/activate && slither $(ARGS)
|
||||
|
||||
$(VENV)/pyvenv.cfg: pyproject.toml
|
||||
# Create our Python 3 virtual environment
|
||||
python3 -m venv env
|
||||
$(VENV_BIN)/python -m pip install --upgrade pip
|
||||
$(VENV_BIN)/python -m pip install -e .[$(SLITHER_EXTRA)]
|
||||
# Create virtual environment and install dependencies using uv
|
||||
uv venv $(VENV)
|
||||
uv sync --python $(VENV_BIN)/python --group $(SLITHER_EXTRA)
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(VENV)/pyvenv.cfg
|
||||
. $(VENV_BIN)/activate && \
|
||||
black --check . && \
|
||||
pylint $(PY_MODULE) $(TEST_MODULE)
|
||||
# ruff $(ALL_PY_SRCS) && \
|
||||
# mypy $(PY_MODULE) &&
|
||||
ruff check $(PY_MODULE) $(TEST_MODULE) $(SCRIPT_MODULE) && \
|
||||
yamllint .github/
|
||||
|
||||
.PHONY: reformat
|
||||
reformat:
|
||||
. $(VENV_BIN)/activate && \
|
||||
black .
|
||||
ruff check --fix $(PY_MODULE) $(TEST_MODULE) $(SCRIPT_MODULE)
|
||||
|
||||
.PHONY: test tests
|
||||
test tests: $(VENV)/pyvenv.cfg
|
||||
@@ -81,7 +79,7 @@ doc: $(VENV)/pyvenv.cfg
|
||||
.PHONY: package
|
||||
package: $(VENV)/pyvenv.cfg
|
||||
. $(VENV_BIN)/activate && \
|
||||
python3 -m build
|
||||
uv build
|
||||
|
||||
.PHONY: edit
|
||||
edit:
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
* [Features](#features)
|
||||
* [Usage](#usage)
|
||||
* [How to install](#how-to-install)
|
||||
* [Using uv (Recommended)](#using-uv-recommended)
|
||||
* [Using Pip](#using-pip)
|
||||
* [Using Git](#using-git)
|
||||
* [Using Git](#using-git-development)
|
||||
* [Using Docker](#using-docker)
|
||||
* [Integration](#integration)
|
||||
* [Detectors](#detectors)
|
||||
@@ -67,16 +68,37 @@ slither tests/uninitialized.sol
|
||||
## How to install
|
||||
|
||||
> **Note** <br />
|
||||
> Slither requires Python 3.8+.
|
||||
> Slither requires Python 3.9+.
|
||||
If you're **not** going to use one of the [supported compilation frameworks](https://github.com/crytic/crytic-compile), you need [solc](https://github.com/ethereum/solidity/), the Solidity compiler; we recommend using [solc-select](https://github.com/crytic/solc-select) to conveniently switch between solc versions.
|
||||
|
||||
### Using uv (Recommended)
|
||||
|
||||
[uv](https://github.com/astral-sh/uv) is a fast Python package manager that's 10-100x faster than pip.
|
||||
|
||||
```console
|
||||
# Install uv if you haven't already
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
|
||||
# Install slither as a tool
|
||||
uv tool install slither-analyzer
|
||||
|
||||
# Or run slither without installation
|
||||
uvx slither-analyzer <target>
|
||||
```
|
||||
|
||||
To upgrade:
|
||||
|
||||
```console
|
||||
uv tool upgrade slither-analyzer
|
||||
```
|
||||
|
||||
### Using Pip
|
||||
|
||||
```console
|
||||
python3 -m pip install slither-analyzer
|
||||
```
|
||||
|
||||
#### How to upgrade
|
||||
To upgrade:
|
||||
|
||||
```console
|
||||
python3 -m pip install --upgrade slither-analyzer
|
||||
@@ -88,14 +110,19 @@ python3 -m pip install --upgrade slither-analyzer
|
||||
brew install slither-analyzer
|
||||
```
|
||||
|
||||
### Using Git
|
||||
### Using Git (Development)
|
||||
|
||||
```bash
|
||||
git clone https://github.com/crytic/slither.git && cd slither
|
||||
python3 -m pip install .
|
||||
|
||||
# Install as editable for development
|
||||
uv tool install -e .
|
||||
|
||||
# Or use uv run for testing without installation
|
||||
uv run slither <target>
|
||||
```
|
||||
|
||||
We recommend using a Python virtual environment, as detailed in the [Developer Installation Instructions](https://github.com/crytic/slither/wiki/Developer-installation), if you prefer to install Slither via git.
|
||||
The `-e` flag installs in editable mode, meaning changes to the source code are immediately reflected without reinstalling.
|
||||
|
||||
### Using Docker
|
||||
|
||||
@@ -143,80 +170,80 @@ Num | Detector | What it Detects | Impact | Confidence
|
||||
13 | `uninitialized-state` | [Uninitialized state variables](https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-state-variables) | High | High
|
||||
14 | `uninitialized-storage` | [Uninitialized storage variables](https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-storage-variables) | High | High
|
||||
15 | `unprotected-upgrade` | [Unprotected upgradeable contract](https://github.com/crytic/slither/wiki/Detector-Documentation#unprotected-upgradeable-contract) | High | High
|
||||
16 | `codex` | [Use Codex to find vulnerabilities.](https://github.com/crytic/slither/wiki/Detector-Documentation#codex) | High | Low
|
||||
17 | `arbitrary-send-erc20-permit` | [transferFrom uses arbitrary from with permit](https://github.com/crytic/slither/wiki/Detector-Documentation#arbitrary-from-in-transferfrom-used-with-permit) | High | Medium
|
||||
18 | `arbitrary-send-eth` | [Functions that send Ether to arbitrary destinations](https://github.com/crytic/slither/wiki/Detector-Documentation#functions-that-send-ether-to-arbitrary-destinations) | High | Medium
|
||||
19 | `controlled-array-length` | [Tainted array length assignment](https://github.com/crytic/slither/wiki/Detector-Documentation#array-length-assignment) | High | Medium
|
||||
20 | `controlled-delegatecall` | [Controlled delegatecall destination](https://github.com/crytic/slither/wiki/Detector-Documentation#controlled-delegatecall) | High | Medium
|
||||
21 | `delegatecall-loop` | [Payable functions using `delegatecall` inside a loop](https://github.com/crytic/slither/wiki/Detector-Documentation/#payable-functions-using-delegatecall-inside-a-loop) | High | Medium
|
||||
22 | `incorrect-exp` | [Incorrect exponentiation](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-exponentiation) | High | Medium
|
||||
23 | `incorrect-return` | [If a `return` is incorrectly used in assembly mode.](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-return-in-assembly) | High | Medium
|
||||
24 | `msg-value-loop` | [msg.value inside a loop](https://github.com/crytic/slither/wiki/Detector-Documentation/#msgvalue-inside-a-loop) | High | Medium
|
||||
25 | `reentrancy-eth` | [Reentrancy vulnerabilities (theft of ethers)](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities) | High | Medium
|
||||
26 | `return-leave` | [If a `return` is used instead of a `leave`.](https://github.com/crytic/slither/wiki/Detector-Documentation#return-instead-of-leave-in-assembly) | High | Medium
|
||||
27 | `storage-array` | [Signed storage integer array compiler bug](https://github.com/crytic/slither/wiki/Detector-Documentation#storage-signed-integer-array) | High | Medium
|
||||
28 | `unchecked-transfer` | [Unchecked tokens transfer](https://github.com/crytic/slither/wiki/Detector-Documentation#unchecked-transfer) | High | Medium
|
||||
29 | `weak-prng` | [Weak PRNG](https://github.com/crytic/slither/wiki/Detector-Documentation#weak-PRNG) | High | Medium
|
||||
30 | `domain-separator-collision` | [Detects ERC20 tokens that have a function whose signature collides with EIP-2612's DOMAIN_SEPARATOR()](https://github.com/crytic/slither/wiki/Detector-Documentation#domain-separator-collision) | Medium | High
|
||||
31 | `enum-conversion` | [Detect dangerous enum conversion](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-enum-conversion) | Medium | High
|
||||
32 | `erc20-interface` | [Incorrect ERC20 interfaces](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc20-interface) | Medium | High
|
||||
33 | `erc721-interface` | [Incorrect ERC721 interfaces](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc721-interface) | Medium | High
|
||||
34 | `incorrect-equality` | [Dangerous strict equalities](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities) | Medium | High
|
||||
35 | `locked-ether` | [Contracts that lock ether](https://github.com/crytic/slither/wiki/Detector-Documentation#contracts-that-lock-ether) | Medium | High
|
||||
36 | `mapping-deletion` | [Deletion on mapping containing a structure](https://github.com/crytic/slither/wiki/Detector-Documentation#deletion-on-mapping-containing-a-structure) | Medium | High
|
||||
37 | `pyth-deprecated-functions` | [Detect Pyth deprecated functions](https://github.com/crytic/slither/wiki/Detector-Documentation#pyth-deprecated-functions) | Medium | High
|
||||
38 | `pyth-unchecked-confidence` | [Detect when the confidence level of a Pyth price is not checked](https://github.com/crytic/slither/wiki/Detector-Documentation#pyth-unchecked-confidence-level) | Medium | High
|
||||
39 | `pyth-unchecked-publishtime` | [Detect when the publishTime of a Pyth price is not checked](https://github.com/crytic/slither/wiki/Detector-Documentation#pyth-unchecked-publishtime) | Medium | High
|
||||
40 | `shadowing-abstract` | [State variables shadowing from abstract contracts](https://github.com/crytic/slither/wiki/Detector-Documentation#state-variable-shadowing-from-abstract-contracts) | Medium | High
|
||||
41 | `tautological-compare` | [Comparing a variable to itself always returns true or false, depending on comparison](https://github.com/crytic/slither/wiki/Detector-Documentation#tautological-compare) | Medium | High
|
||||
42 | `tautology` | [Tautology or contradiction](https://github.com/crytic/slither/wiki/Detector-Documentation#tautology-or-contradiction) | Medium | High
|
||||
43 | `write-after-write` | [Unused write](https://github.com/crytic/slither/wiki/Detector-Documentation#write-after-write) | Medium | High
|
||||
44 | `boolean-cst` | [Misuse of Boolean constant](https://github.com/crytic/slither/wiki/Detector-Documentation#misuse-of-a-boolean-constant) | Medium | Medium
|
||||
45 | `chronicle-unchecked-price` | [Detect when Chronicle price is not checked.](https://github.com/crytic/slither/wiki/Detector-Documentation#chronicle-unchecked-price) | Medium | Medium
|
||||
46 | `constant-function-asm` | [Constant functions using assembly code](https://github.com/crytic/slither/wiki/Detector-Documentation#constant-functions-using-assembly-code) | Medium | Medium
|
||||
47 | `constant-function-state` | [Constant functions changing the state](https://github.com/crytic/slither/wiki/Detector-Documentation#constant-functions-changing-the-state) | Medium | Medium
|
||||
48 | `divide-before-multiply` | [Imprecise arithmetic operations order](https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply) | Medium | Medium
|
||||
49 | `gelato-unprotected-randomness` | [Call to `_requestRandomness` within an unprotected function](https://github.com/crytic/slither/wiki/Detector-Documentation#gelato-unprotected-randomness) | Medium | Medium
|
||||
50 | `out-of-order-retryable` | [Out-of-order retryable transactions](https://github.com/crytic/slither/wiki/Detector-Documentation#out-of-order-retryable-transactions) | Medium | Medium
|
||||
51 | `reentrancy-no-eth` | [Reentrancy vulnerabilities (no theft of ethers)](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-1) | Medium | Medium
|
||||
52 | `reused-constructor` | [Reused base constructor](https://github.com/crytic/slither/wiki/Detector-Documentation#reused-base-constructors) | Medium | Medium
|
||||
53 | `tx-origin` | [Dangerous usage of `tx.origin`](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-usage-of-txorigin) | Medium | Medium
|
||||
54 | `unchecked-lowlevel` | [Unchecked low-level calls](https://github.com/crytic/slither/wiki/Detector-Documentation#unchecked-low-level-calls) | Medium | Medium
|
||||
55 | `unchecked-send` | [Unchecked send](https://github.com/crytic/slither/wiki/Detector-Documentation#unchecked-send) | Medium | Medium
|
||||
56 | `uninitialized-local` | [Uninitialized local variables](https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-local-variables) | Medium | Medium
|
||||
57 | `unused-return` | [Unused return values](https://github.com/crytic/slither/wiki/Detector-Documentation#unused-return) | Medium | Medium
|
||||
58 | `chainlink-feed-registry` | [Detect when chainlink feed registry is used](https://github.com/crytic/slither/wiki/Detector-Documentation#chainlink-feed-registry-usage) | Low | High
|
||||
59 | `incorrect-modifier` | [Modifiers that can return the default value](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-modifier) | Low | High
|
||||
60 | `optimism-deprecation` | [Detect when deprecated Optimism predeploy or function is used.](https://github.com/crytic/slither/wiki/Detector-Documentation#optimism-deprecated-predeploy-or-function) | Low | High
|
||||
61 | `shadowing-builtin` | [Built-in symbol shadowing](https://github.com/crytic/slither/wiki/Detector-Documentation#builtin-symbol-shadowing) | Low | High
|
||||
62 | `shadowing-local` | [Local variables shadowing](https://github.com/crytic/slither/wiki/Detector-Documentation#local-variable-shadowing) | Low | High
|
||||
63 | `uninitialized-fptr-cst` | [Uninitialized function pointer calls in constructors](https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-function-pointers-in-constructors) | Low | High
|
||||
64 | `variable-scope` | [Local variables used prior their declaration](https://github.com/crytic/slither/wiki/Detector-Documentation#pre-declaration-usage-of-local-variables) | Low | High
|
||||
65 | `void-cst` | [Constructor called not implemented](https://github.com/crytic/slither/wiki/Detector-Documentation#void-constructor) | Low | High
|
||||
66 | `calls-loop` | [Multiple calls in a loop](https://github.com/crytic/slither/wiki/Detector-Documentation/#calls-inside-a-loop) | Low | Medium
|
||||
67 | `events-access` | [Missing Events Access Control](https://github.com/crytic/slither/wiki/Detector-Documentation#missing-events-access-control) | Low | Medium
|
||||
68 | `events-maths` | [Missing Events Arithmetic](https://github.com/crytic/slither/wiki/Detector-Documentation#missing-events-arithmetic) | Low | Medium
|
||||
69 | `incorrect-unary` | [Dangerous unary expressions](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-unary-expressions) | Low | Medium
|
||||
70 | `missing-zero-check` | [Missing Zero Address Validation](https://github.com/crytic/slither/wiki/Detector-Documentation#missing-zero-address-validation) | Low | Medium
|
||||
71 | `reentrancy-benign` | [Benign reentrancy vulnerabilities](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-2) | Low | Medium
|
||||
72 | `reentrancy-events` | [Reentrancy vulnerabilities leading to out-of-order Events](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3) | Low | Medium
|
||||
73 | `return-bomb` | [A low level callee may consume all callers gas unexpectedly.](https://github.com/crytic/slither/wiki/Detector-Documentation#return-bomb) | Low | Medium
|
||||
74 | `timestamp` | [Dangerous usage of `block.timestamp`](https://github.com/crytic/slither/wiki/Detector-Documentation#block-timestamp) | Low | Medium
|
||||
75 | `assembly` | [Assembly usage](https://github.com/crytic/slither/wiki/Detector-Documentation#assembly-usage) | Informational | High
|
||||
76 | `assert-state-change` | [Assert state change](https://github.com/crytic/slither/wiki/Detector-Documentation#assert-state-change) | Informational | High
|
||||
77 | `boolean-equal` | [Comparison to boolean constant](https://github.com/crytic/slither/wiki/Detector-Documentation#boolean-equality) | Informational | High
|
||||
78 | `cyclomatic-complexity` | [Detects functions with high (> 11) cyclomatic complexity](https://github.com/crytic/slither/wiki/Detector-Documentation#cyclomatic-complexity) | Informational | High
|
||||
79 | `deprecated-standards` | [Deprecated Solidity Standards](https://github.com/crytic/slither/wiki/Detector-Documentation#deprecated-standards) | Informational | High
|
||||
80 | `erc20-indexed` | [Un-indexed ERC20 event parameters](https://github.com/crytic/slither/wiki/Detector-Documentation#unindexed-erc20-event-parameters) | Informational | High
|
||||
81 | `function-init-state` | [Function initializing state variables](https://github.com/crytic/slither/wiki/Detector-Documentation#function-initializing-state) | Informational | High
|
||||
82 | `incorrect-using-for` | [Detects using-for statement usage when no function from a given library matches a given type](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-usage-of-using-for-statement) | Informational | High
|
||||
83 | `low-level-calls` | [Low level calls](https://github.com/crytic/slither/wiki/Detector-Documentation#low-level-calls) | Informational | High
|
||||
84 | `missing-inheritance` | [Missing inheritance](https://github.com/crytic/slither/wiki/Detector-Documentation#missing-inheritance) | Informational | High
|
||||
85 | `naming-convention` | [Conformity to Solidity naming conventions](https://github.com/crytic/slither/wiki/Detector-Documentation#conformance-to-solidity-naming-conventions) | Informational | High
|
||||
86 | `pragma` | [If different pragma directives are used](https://github.com/crytic/slither/wiki/Detector-Documentation#different-pragma-directives-are-used) | Informational | High
|
||||
87 | `redundant-statements` | [Redundant statements](https://github.com/crytic/slither/wiki/Detector-Documentation#redundant-statements) | Informational | High
|
||||
88 | `solc-version` | [Incorrect Solidity version](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-versions-of-solidity) | Informational | High
|
||||
89 | `unimplemented-functions` | [Unimplemented functions](https://github.com/crytic/slither/wiki/Detector-Documentation#unimplemented-functions) | Informational | High
|
||||
16 | `arbitrary-send-erc20-permit` | [transferFrom uses arbitrary from with permit](https://github.com/crytic/slither/wiki/Detector-Documentation#arbitrary-from-in-transferfrom-used-with-permit) | High | Medium
|
||||
17 | `arbitrary-send-eth` | [Functions that send Ether to arbitrary destinations](https://github.com/crytic/slither/wiki/Detector-Documentation#functions-that-send-ether-to-arbitrary-destinations) | High | Medium
|
||||
18 | `controlled-array-length` | [Tainted array length assignment](https://github.com/crytic/slither/wiki/Detector-Documentation#array-length-assignment) | High | Medium
|
||||
19 | `controlled-delegatecall` | [Controlled delegatecall destination](https://github.com/crytic/slither/wiki/Detector-Documentation#controlled-delegatecall) | High | Medium
|
||||
20 | `delegatecall-loop` | [Payable functions using `delegatecall` inside a loop](https://github.com/crytic/slither/wiki/Detector-Documentation/#payable-functions-using-delegatecall-inside-a-loop) | High | Medium
|
||||
21 | `incorrect-exp` | [Incorrect exponentiation](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-exponentiation) | High | Medium
|
||||
22 | `incorrect-return` | [If a `return` is incorrectly used in assembly mode.](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-return-in-assembly) | High | Medium
|
||||
23 | `msg-value-loop` | [msg.value inside a loop](https://github.com/crytic/slither/wiki/Detector-Documentation/#msgvalue-inside-a-loop) | High | Medium
|
||||
24 | `reentrancy-eth` | [Reentrancy vulnerabilities (theft of ethers)](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities) | High | Medium
|
||||
25 | `return-leave` | [If a `return` is used instead of a `leave`.](https://github.com/crytic/slither/wiki/Detector-Documentation#return-instead-of-leave-in-assembly) | High | Medium
|
||||
26 | `storage-array` | [Signed storage integer array compiler bug](https://github.com/crytic/slither/wiki/Detector-Documentation#storage-signed-integer-array) | High | Medium
|
||||
27 | `unchecked-transfer` | [Unchecked tokens transfer](https://github.com/crytic/slither/wiki/Detector-Documentation#unchecked-transfer) | High | Medium
|
||||
28 | `weak-prng` | [Weak PRNG](https://github.com/crytic/slither/wiki/Detector-Documentation#weak-PRNG) | High | Medium
|
||||
29 | `domain-separator-collision` | [Detects ERC20 tokens that have a function whose signature collides with EIP-2612's DOMAIN_SEPARATOR()](https://github.com/crytic/slither/wiki/Detector-Documentation#domain-separator-collision) | Medium | High
|
||||
30 | `enum-conversion` | [Detect dangerous enum conversion](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-enum-conversion) | Medium | High
|
||||
31 | `erc20-interface` | [Incorrect ERC20 interfaces](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc20-interface) | Medium | High
|
||||
32 | `erc721-interface` | [Incorrect ERC721 interfaces](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc721-interface) | Medium | High
|
||||
33 | `incorrect-equality` | [Dangerous strict equalities](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities) | Medium | High
|
||||
34 | `locked-ether` | [Contracts that lock ether](https://github.com/crytic/slither/wiki/Detector-Documentation#contracts-that-lock-ether) | Medium | High
|
||||
35 | `mapping-deletion` | [Deletion on mapping containing a structure](https://github.com/crytic/slither/wiki/Detector-Documentation#deletion-on-mapping-containing-a-structure) | Medium | High
|
||||
36 | `pyth-deprecated-functions` | [Detect Pyth deprecated functions](https://github.com/crytic/slither/wiki/Detector-Documentation#pyth-deprecated-functions) | Medium | High
|
||||
37 | `pyth-unchecked-confidence` | [Detect when the confidence level of a Pyth price is not checked](https://github.com/crytic/slither/wiki/Detector-Documentation#pyth-unchecked-confidence-level) | Medium | High
|
||||
38 | `pyth-unchecked-publishtime` | [Detect when the publishTime of a Pyth price is not checked](https://github.com/crytic/slither/wiki/Detector-Documentation#pyth-unchecked-publishtime) | Medium | High
|
||||
39 | `shadowing-abstract` | [State variables shadowing from abstract contracts](https://github.com/crytic/slither/wiki/Detector-Documentation#state-variable-shadowing-from-abstract-contracts) | Medium | High
|
||||
40 | `tautological-compare` | [Comparing a variable to itself always returns true or false, depending on comparison](https://github.com/crytic/slither/wiki/Detector-Documentation#tautological-compare) | Medium | High
|
||||
41 | `tautology` | [Tautology or contradiction](https://github.com/crytic/slither/wiki/Detector-Documentation#tautology-or-contradiction) | Medium | High
|
||||
42 | `write-after-write` | [Unused write](https://github.com/crytic/slither/wiki/Detector-Documentation#write-after-write) | Medium | High
|
||||
43 | `boolean-cst` | [Misuse of Boolean constant](https://github.com/crytic/slither/wiki/Detector-Documentation#misuse-of-a-boolean-constant) | Medium | Medium
|
||||
44 | `chronicle-unchecked-price` | [Detect when Chronicle price is not checked.](https://github.com/crytic/slither/wiki/Detector-Documentation#chronicle-unchecked-price) | Medium | Medium
|
||||
45 | `constant-function-asm` | [Constant functions using assembly code](https://github.com/crytic/slither/wiki/Detector-Documentation#constant-functions-using-assembly-code) | Medium | Medium
|
||||
46 | `constant-function-state` | [Constant functions changing the state](https://github.com/crytic/slither/wiki/Detector-Documentation#constant-functions-changing-the-state) | Medium | Medium
|
||||
47 | `divide-before-multiply` | [Imprecise arithmetic operations order](https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply) | Medium | Medium
|
||||
48 | `gelato-unprotected-randomness` | [Call to `_requestRandomness` within an unprotected function](https://github.com/crytic/slither/wiki/Detector-Documentation#gelato-unprotected-randomness) | Medium | Medium
|
||||
49 | `out-of-order-retryable` | [Out-of-order retryable transactions](https://github.com/crytic/slither/wiki/Detector-Documentation#out-of-order-retryable-transactions) | Medium | Medium
|
||||
50 | `reentrancy-no-eth` | [Reentrancy vulnerabilities (no theft of ethers)](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-1) | Medium | Medium
|
||||
51 | `reused-constructor` | [Reused base constructor](https://github.com/crytic/slither/wiki/Detector-Documentation#reused-base-constructors) | Medium | Medium
|
||||
52 | `tx-origin` | [Dangerous usage of `tx.origin`](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-usage-of-txorigin) | Medium | Medium
|
||||
53 | `unchecked-lowlevel` | [Unchecked low-level calls](https://github.com/crytic/slither/wiki/Detector-Documentation#unchecked-low-level-calls) | Medium | Medium
|
||||
54 | `unchecked-send` | [Unchecked send](https://github.com/crytic/slither/wiki/Detector-Documentation#unchecked-send) | Medium | Medium
|
||||
55 | `uninitialized-local` | [Uninitialized local variables](https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-local-variables) | Medium | Medium
|
||||
56 | `unused-return` | [Unused return values](https://github.com/crytic/slither/wiki/Detector-Documentation#unused-return) | Medium | Medium
|
||||
57 | `chainlink-feed-registry` | [Detect when chainlink feed registry is used](https://github.com/crytic/slither/wiki/Detector-Documentation#chainlink-feed-registry-usage) | Low | High
|
||||
58 | `incorrect-modifier` | [Modifiers that can return the default value](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-modifier) | Low | High
|
||||
59 | `optimism-deprecation` | [Detect when deprecated Optimism predeploy or function is used.](https://github.com/crytic/slither/wiki/Detector-Documentation#optimism-deprecated-predeploy-or-function) | Low | High
|
||||
60 | `shadowing-builtin` | [Built-in symbol shadowing](https://github.com/crytic/slither/wiki/Detector-Documentation#builtin-symbol-shadowing) | Low | High
|
||||
61 | `shadowing-local` | [Local variables shadowing](https://github.com/crytic/slither/wiki/Detector-Documentation#local-variable-shadowing) | Low | High
|
||||
62 | `uninitialized-fptr-cst` | [Uninitialized function pointer calls in constructors](https://github.com/crytic/slither/wiki/Detector-Documentation#uninitialized-function-pointers-in-constructors) | Low | High
|
||||
63 | `variable-scope` | [Local variables used prior their declaration](https://github.com/crytic/slither/wiki/Detector-Documentation#pre-declaration-usage-of-local-variables) | Low | High
|
||||
64 | `void-cst` | [Constructor called not implemented](https://github.com/crytic/slither/wiki/Detector-Documentation#void-constructor) | Low | High
|
||||
65 | `calls-loop` | [Multiple calls in a loop](https://github.com/crytic/slither/wiki/Detector-Documentation/#calls-inside-a-loop) | Low | Medium
|
||||
66 | `events-access` | [Missing Events Access Control](https://github.com/crytic/slither/wiki/Detector-Documentation#missing-events-access-control) | Low | Medium
|
||||
67 | `events-maths` | [Missing Events Arithmetic](https://github.com/crytic/slither/wiki/Detector-Documentation#missing-events-arithmetic) | Low | Medium
|
||||
68 | `incorrect-unary` | [Dangerous unary expressions](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-unary-expressions) | Low | Medium
|
||||
69 | `missing-zero-check` | [Missing Zero Address Validation](https://github.com/crytic/slither/wiki/Detector-Documentation#missing-zero-address-validation) | Low | Medium
|
||||
70 | `reentrancy-benign` | [Benign reentrancy vulnerabilities](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-2) | Low | Medium
|
||||
71 | `reentrancy-events` | [Reentrancy vulnerabilities leading to out-of-order Events](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3) | Low | Medium
|
||||
72 | `return-bomb` | [A low level callee may consume all callers gas unexpectedly.](https://github.com/crytic/slither/wiki/Detector-Documentation#return-bomb) | Low | Medium
|
||||
73 | `timestamp` | [Dangerous usage of `block.timestamp`](https://github.com/crytic/slither/wiki/Detector-Documentation#block-timestamp) | Low | Medium
|
||||
74 | `assembly` | [Assembly usage](https://github.com/crytic/slither/wiki/Detector-Documentation#assembly-usage) | Informational | High
|
||||
75 | `assert-state-change` | [Assert state change](https://github.com/crytic/slither/wiki/Detector-Documentation#assert-state-change) | Informational | High
|
||||
76 | `boolean-equal` | [Comparison to boolean constant](https://github.com/crytic/slither/wiki/Detector-Documentation#boolean-equality) | Informational | High
|
||||
77 | `cyclomatic-complexity` | [Detects functions with high (> 11) cyclomatic complexity](https://github.com/crytic/slither/wiki/Detector-Documentation#cyclomatic-complexity) | Informational | High
|
||||
78 | `deprecated-standards` | [Deprecated Solidity Standards](https://github.com/crytic/slither/wiki/Detector-Documentation#deprecated-standards) | Informational | High
|
||||
79 | `erc20-indexed` | [Un-indexed ERC20 event parameters](https://github.com/crytic/slither/wiki/Detector-Documentation#unindexed-erc20-event-parameters) | Informational | High
|
||||
80 | `function-init-state` | [Function initializing state variables](https://github.com/crytic/slither/wiki/Detector-Documentation#function-initializing-state) | Informational | High
|
||||
81 | `incorrect-using-for` | [Detects using-for statement usage when no function from a given library matches a given type](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-usage-of-using-for-statement) | Informational | High
|
||||
82 | `low-level-calls` | [Low level calls](https://github.com/crytic/slither/wiki/Detector-Documentation#low-level-calls) | Informational | High
|
||||
83 | `missing-inheritance` | [Missing inheritance](https://github.com/crytic/slither/wiki/Detector-Documentation#missing-inheritance) | Informational | High
|
||||
84 | `naming-convention` | [Conformity to Solidity naming conventions](https://github.com/crytic/slither/wiki/Detector-Documentation#conformance-to-solidity-naming-conventions) | Informational | High
|
||||
85 | `pragma` | [If different pragma directives are used](https://github.com/crytic/slither/wiki/Detector-Documentation#different-pragma-directives-are-used) | Informational | High
|
||||
86 | `redundant-statements` | [Redundant statements](https://github.com/crytic/slither/wiki/Detector-Documentation#redundant-statements) | Informational | High
|
||||
87 | `solc-version` | [Incorrect Solidity version](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-versions-of-solidity) | Informational | High
|
||||
88 | `unimplemented-functions` | [Unimplemented functions](https://github.com/crytic/slither/wiki/Detector-Documentation#unimplemented-functions) | Informational | High
|
||||
89 | `unindexed-event-address` | [Events with address parameters but no indexed parameters](https://github.com/crytic/slither/wiki/Detector-Documentation#unindexed-event-address-parameters) | Informational | High
|
||||
90 | `unused-state` | [Unused state variables](https://github.com/crytic/slither/wiki/Detector-Documentation#unused-state-variable) | Informational | High
|
||||
91 | `costly-loop` | [Costly operations in a loop](https://github.com/crytic/slither/wiki/Detector-Documentation#costly-operations-inside-a-loop) | Informational | Medium
|
||||
92 | `dead-code` | [Functions that are not used](https://github.com/crytic/slither/wiki/Detector-Documentation#dead-code) | Informational | Medium
|
||||
@@ -242,7 +269,7 @@ For more information, see
|
||||
* `inheritance-graph`: [Export the inheritance graph of each contract to a dot file](https://github.com/trailofbits/slither/wiki/Printer-documentation#inheritance-graph)
|
||||
* `contract-summary`: [Print a summary of the contracts](https://github.com/trailofbits/slither/wiki/Printer-documentation#contract-summary)
|
||||
* `loc`: [Count the total number lines of code (LOC), source lines of code (SLOC), and comment lines of code (CLOC) found in source files (SRC), dependencies (DEP), and test files (TEST).](https://github.com/trailofbits/slither/wiki/Printer-documentation#loc)
|
||||
* `entry-points`: [Print all the state-changing entry point functions of the contracts](https://github.com/trailofbits/slither/wiki/Printer-documentation#entry-points)
|
||||
* `entry-points`: [Print all the state-changing entry point functions and their variables of the contracts](https://github.com/trailofbits/slither/wiki/Printer-documentation#entry-points)
|
||||
|
||||
### In-Depth Review Printers
|
||||
|
||||
|
||||
+1
-8
@@ -88,7 +88,7 @@ slither . --filter-paths "openzepellin"
|
||||
Filter all the results only related to openzepellin.
|
||||
|
||||
```
|
||||
slither . --filter-paths "Migrations.sol|ConvertLib.sol"
|
||||
slither . --filter-paths "SafeMath.sol|ConvertLib.sol"
|
||||
```
|
||||
|
||||
Filter all the results only related to the file `SafeMath.sol` or `ConvertLib.sol`.
|
||||
@@ -157,13 +157,6 @@ The following flags are supported:
|
||||
"sarif_input": "export.sarif",
|
||||
"sarif_triage": "export.sarif.sarifexplorer",
|
||||
"triage_database": "slither.db.json",
|
||||
# codex
|
||||
"codex": False,
|
||||
"codex_contracts": "all",
|
||||
"codex_model": "text-davinci-003",
|
||||
"codex_temperature": 0,
|
||||
"codex_max_tokens": 300,
|
||||
"codex_log": False,
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -916,26 +916,6 @@ As a result, Eve wins the game.
|
||||
|
||||
Do not use `block.timestamp`, `now` or `blockhash` as a source of randomness
|
||||
|
||||
## Codex
|
||||
|
||||
### Configuration
|
||||
|
||||
- Check: `codex`
|
||||
- Severity: `High`
|
||||
- Confidence: `Low`
|
||||
|
||||
### Description
|
||||
|
||||
Use [codex](https://openai.com/blog/openai-codex/) to find vulnerabilities
|
||||
|
||||
### Exploit Scenario:
|
||||
|
||||
N/A
|
||||
|
||||
### Recommendation
|
||||
|
||||
Review codex's message.
|
||||
|
||||
## Domain separator collision
|
||||
|
||||
### Configuration
|
||||
@@ -1371,7 +1351,7 @@ Detects variables that are written but never read and written again.
|
||||
}
|
||||
}
|
||||
```
|
||||
`a` is first asigned to `b`, and then to `c`. As a result the first write does nothing.
|
||||
`a` is first assigned to `b`, and then to `c`. As a result the first write does nothing.
|
||||
|
||||
### Recommendation
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ $ slither examples/printers/call_graph.sol --print call-graph
|
||||
<img src="https://raw.githubusercontent.com/crytic/slither/master/examples/printers/call_graph.sol.dot.png">
|
||||
|
||||
The output format is [dot](https://www.graphviz.org/).
|
||||
To vizualize the graph:
|
||||
To visualize the graph:
|
||||
|
||||
```
|
||||
$ xdot examples/printers/call_graph.sol.dot
|
||||
@@ -72,7 +72,7 @@ Export the control flow graph of each function
|
||||
### Example
|
||||
|
||||
The output format is [dot](https://www.graphviz.org/).
|
||||
To vizualize the graph:
|
||||
To visualize the graph:
|
||||
|
||||
```
|
||||
$ xdot function.sol.dot
|
||||
@@ -355,7 +355,7 @@ INFO:PrinterInheritance:Inheritance Graph: examples/DAO.sol.dot
|
||||
```
|
||||
|
||||
The output format is [dot](https://www.graphviz.org/).
|
||||
To vizualize the graph:
|
||||
To visualize the graph:
|
||||
|
||||
```
|
||||
$ xdot examples/printers/inheritances.sol.dot
|
||||
|
||||
@@ -7,7 +7,7 @@ The skeleton util is present in [tools/demo](https://github.com/crytic/slither/t
|
||||
|
||||
## Integration
|
||||
|
||||
To enable an util from the command-line, update `entry_points` in [setup.py](https://github.com/crytic/slither/blob/master/setup.py).
|
||||
To enable an util from the command-line, update `project.scripts` in [pyproject.toml](https://github.com/crytic/slither/blob/master/pyproject.toml).
|
||||
Installing Slither will then install the util.
|
||||
|
||||
## Guidelines
|
||||
|
||||
@@ -98,7 +98,7 @@ INFO:Slither-simil:Saving cache in cache.npz
|
||||
INFO:Slither-simil:Done!
|
||||
```
|
||||
|
||||
After it runs, the `slither-simil` will output the the trained model in `model.bin`, a cache of every function for use in test mode in `cache.npz`, and the SlithIR of every function for debugging in `last_data_train.txt`.
|
||||
After it runs, the `slither-simil` will output the trained model in `model.bin`, a cache of every function for use in test mode in `cache.npz`, and the SlithIR of every function for debugging in `last_data_train.txt`.
|
||||
|
||||
### Plot mode
|
||||
|
||||
@@ -109,7 +109,7 @@ Here's an example to plot all the functions named `add` from contracts named `Sa
|
||||
```
|
||||
$ slither-simil plot etherscan_verified_contracts.bin --fname SafeMath.add --input cache.npz --nsamples 500
|
||||
INFO:Slither-simil:Loading data..
|
||||
INFO:Slither-simil:Procesing data..
|
||||
INFO:Slither-simil:Processing data..
|
||||
INFO:Slither-simil:Plotting data..
|
||||
INFO:Slither-simil:Saving figure to plot.png..
|
||||
```
|
||||
|
||||
@@ -12,6 +12,8 @@ You can provide flags to `forge` as part of the `--test-cmd` parameter or target
|
||||
|
||||
`slither-mutate src/core/MyContract.sol --test-cmd='forge test --match-contract="MyContract"'`
|
||||
|
||||
If a `timout` flag is not provided, slither-mutate will default to using a value that's double the runtime of it's initial test cmd execution. Make sure you run `forge clean` or similar beforehand to ensure cache usage doesn't cause a timeout that's too short to be used; this could lead to false-negatives.
|
||||
|
||||
### CLI Interface
|
||||
|
||||
```shell
|
||||
@@ -30,7 +32,7 @@ options:
|
||||
--test-dir TEST_DIR Tests directory
|
||||
--ignore-dirs IGNORE_DIRS
|
||||
Directories to ignore
|
||||
--timeout TIMEOUT Set timeout for test command (by default 30 seconds)
|
||||
--timeout TIMEOUT Set timeout for test command (by default 2x the initial test runtime)
|
||||
--output-dir OUTPUT_DIR
|
||||
Name of output directory (by default 'mutation_campaign')
|
||||
-v, --verbose log mutants that are caught, uncaught, and fail to compile
|
||||
@@ -38,5 +40,8 @@ options:
|
||||
mutant generators to run
|
||||
--contract-names CONTRACT_NAMES
|
||||
list of contract names you want to mutate
|
||||
--target-functions TARGET_FUNCTIONS
|
||||
Comma-separated list of function selectors (hex like
|
||||
0xa9059cbb or signature like transfer(address,uint256))
|
||||
--comprehensive continue testing minor mutations if severe mutants are uncaught
|
||||
```
|
||||
|
||||
@@ -10,7 +10,7 @@ slither-find-paths file.sol [contract.function targets]
|
||||
|
||||
## Example
|
||||
|
||||
Tested on [tests/possible_paths/paths.sol](https://github.com/trailofbits/slither/blob/master/tests/possible_paths/paths.sol)
|
||||
Tested on [tests/e2e/printers/possible_paths/paths.sol](https://github.com/crytic/slither/blob/master/tests/e2e/printers/possible_paths/paths.sol)
|
||||
|
||||
```
|
||||
$ slither-find-paths paths.sol A.destination
|
||||
|
||||
@@ -271,7 +271,7 @@ contract DerivedDerived is Derived{
|
||||
|
||||
```
|
||||
|
||||
`Base.initialize(uint)` is called two times in `DerivedDerived.initiliaze` execution, leading to a potential corruption.
|
||||
`Base.initialize(uint)` is called two times in `DerivedDerived.initialize` execution, leading to a potential corruption.
|
||||
|
||||
### Recommendation
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ Watch Slither's [code walkthrough](https://www.youtube.com/watch?v=EUl3UlYSluU),
|
||||
|
||||
## Installation
|
||||
|
||||
Slither requires Python >= 3.8. You can install it through pip or by using Docker.
|
||||
Slither requires Python >= 3.9. You can install it through pip or by using Docker.
|
||||
|
||||
Installing Slither through pip:
|
||||
|
||||
|
||||
+1
-1
@@ -6,4 +6,4 @@ contract Example {
|
||||
function reverts() external pure {
|
||||
revert RevertIt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,4 +13,4 @@ contract T {
|
||||
B b = B.a;
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,6 @@ contract MyContract is Owner{
|
||||
|
||||
function mint(uint value) onlyOwner public{
|
||||
balances[msg.sender] += value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,4 +31,4 @@ contract ContractB {
|
||||
function my_second_func_b(){
|
||||
a.val();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,10 @@ label = "ContractB"
|
||||
}
|
||||
subgraph cluster_solidity {
|
||||
label = "[Solidity]"
|
||||
"keccak256()"
|
||||
"keccak256()"
|
||||
"22_my_func_a" -> "keccak256()"
|
||||
}
|
||||
"22_my_func_a" -> "5_library_func"
|
||||
"63_my_func_b" -> "22_my_func_a"
|
||||
"63_my_second_func_b" -> "22_val"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ contract test{
|
||||
constructor()public{
|
||||
a =5;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
contract test2 is test{
|
||||
constructor()public{
|
||||
@@ -23,4 +23,4 @@ contract test3 is test2{
|
||||
b=a;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
pragma solidity >=0.4.24 <0.5.4;
|
||||
|
||||
contract Test {
|
||||
|
||||
|
||||
function foo() public returns (address) {
|
||||
address from = msg.sender;
|
||||
return(from);
|
||||
|
||||
@@ -13,4 +13,4 @@ contract ChildContract2 is BaseContract1, BaseContract2{
|
||||
}
|
||||
|
||||
contract GrandchildContract1 is ChildContract1{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,4 +18,4 @@ contract C is A, B {
|
||||
function f() public pure returns (uint) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,4 +4,4 @@ B[shape="box"label=< <TABLE border="0"><TR><TD align="center"><B>B</B></TD></TR>
|
||||
C -> A [ label="1" ];
|
||||
C -> B [ label="2" ];
|
||||
C[shape="box"label=< <TABLE border="0"><TR><TD align="center"><B>C</B></TD></TR><TR><TD align="left"><I>Public Functions:</I></TD></TR><TR><TD align="left"><font color="#FFA500"> f()</font></TD></TR><TR><TD><BR/></TD></TR><TR><TD align="left" border="1"><font color="#777777" point-size="10">'g()' collides in inherited contracts A, B where B is chosen.</font></TD></TR></TABLE> >];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,4 +123,4 @@ contract SimpleModifier {
|
||||
require(intermediate);
|
||||
_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
contract BaseContract{
|
||||
|
||||
|
||||
function f1() public{
|
||||
|
||||
}
|
||||
@@ -21,7 +21,7 @@ contract Contract is BaseContract{
|
||||
function f2() public{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// not reached from entry_point
|
||||
function f3() public{
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ pragma solidity >=0.4.24 <0.5.4;
|
||||
contract Test {
|
||||
|
||||
address owner;
|
||||
|
||||
|
||||
constructor () public {
|
||||
owner = msg.sender;
|
||||
}
|
||||
|
||||
|
||||
function foo() public returns (uint) {
|
||||
uint i;
|
||||
return(i+10);
|
||||
|
||||
@@ -11,7 +11,7 @@ contract Contract{
|
||||
function call_require() public{
|
||||
require(a==0);
|
||||
}
|
||||
|
||||
|
||||
function read_and_write() public{
|
||||
a = a + 1;
|
||||
}
|
||||
|
||||
@@ -6,13 +6,16 @@ See the [detector documentation](https://github.com/trailofbits/slither/wiki/Add
|
||||
|
||||
## Architecture
|
||||
|
||||
- `setup.py`: Contain the plugin information
|
||||
- `slither_my_plugin/__init__.py`: Contain `make_plugin()`. The function must return the list of new detectors and printers
|
||||
- `pyproject.toml`: Contains the plugin information and dependencies
|
||||
- `slither_my_plugin/__init__.py`: Contains `make_plugin()`. The function must return the list of new detectors and printers
|
||||
- `slither_my_plugin/detectors/example.py`: Detector plugin skeleton.
|
||||
|
||||
Once these files are updated with your plugin, you can install it:
|
||||
```bash
|
||||
python setup.py develop
|
||||
```
|
||||
## Installation
|
||||
|
||||
We recommend to use a Python virtual environment (for example: [virtualenvwrapper](https://virtualenvwrapper.readthedocs.io/en/latest/)).
|
||||
Once these files are updated with your plugin, install it in a virtual environment:
|
||||
|
||||
```bash
|
||||
python -m venv venv
|
||||
source venv/bin/activate # On Windows: venv\Scripts\activate
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "slither-my-plugin"
|
||||
version = "0.0.1"
|
||||
description = "Example detector and printer plugins for Slither."
|
||||
readme = "README.md"
|
||||
license = "AGPL-3.0-only"
|
||||
authors = [{ name = "Trail of Bits" }]
|
||||
requires-python = ">=3.9"
|
||||
dependencies = ["slither-analyzer>=0.6.0"]
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/crytic/slither/tree/master/plugin_example"
|
||||
|
||||
[project.entry-points."slither_analyzer.plugin"]
|
||||
slither_my_plugin = "slither_my_plugin:make_plugin"
|
||||
@@ -1,15 +0,0 @@
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name="slither_my_plugin",
|
||||
description="This is an example of detectors and printers to Slither.",
|
||||
url="https://github.com/trailofbits/slither-plugins",
|
||||
author="Trail of Bits",
|
||||
version="0.0",
|
||||
packages=find_packages(),
|
||||
python_requires=">=3.8",
|
||||
install_requires=["slither-analyzer>=0.6.0"],
|
||||
entry_points={
|
||||
"slither_analyzer.plugin": "slither my-plugin=slither_my_plugin:make_plugin",
|
||||
},
|
||||
)
|
||||
@@ -1,7 +1,7 @@
|
||||
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
|
||||
|
||||
|
||||
class Example(AbstractDetector): # pylint: disable=too-few-public-methods
|
||||
class Example(AbstractDetector):
|
||||
"""
|
||||
Documentation
|
||||
"""
|
||||
|
||||
+221
-21
@@ -1,22 +1,222 @@
|
||||
[tool.black]
|
||||
target-version = ["py36"]
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "slither-analyzer"
|
||||
version = "0.11.4"
|
||||
description = "Slither is a Solidity and Vyper static analysis framework written in Python 3."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.9"
|
||||
license = {text = "AGPL-3.0"}
|
||||
authors = [
|
||||
{name = "Trail of Bits"},
|
||||
]
|
||||
maintainers = [
|
||||
{name = "Trail of Bits"},
|
||||
]
|
||||
urls = {Homepage = "https://github.com/crytic/slither"}
|
||||
keywords = ["solidity", "vyper", "static-analysis", "security", "ethereum", "smart-contracts"]
|
||||
classifiers = [
|
||||
"Development Status :: 4 - Beta",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: GNU Affero General Public License v3",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
"Programming Language :: Python :: 3.14",
|
||||
]
|
||||
dependencies = [
|
||||
"importlib_metadata>=3.6",
|
||||
"packaging",
|
||||
"prettytable>=3.10.2",
|
||||
"pycryptodome>=3.4.6",
|
||||
"crytic-compile>=0.3.9,<0.4.0",
|
||||
"web3>=7.10,<8",
|
||||
"eth-abi>=5.0.1",
|
||||
"eth-typing>=5.0.0",
|
||||
"eth-utils>=5.0.0",
|
||||
]
|
||||
|
||||
# Development dependencies using PEP 735 dependency-groups
|
||||
[dependency-groups]
|
||||
lint = [
|
||||
"ruff==0.14.10",
|
||||
"yamllint==1.37.1"
|
||||
]
|
||||
test = [
|
||||
"pytest",
|
||||
"pytest-cov",
|
||||
"pytest-xdist",
|
||||
"deepdiff",
|
||||
"numpy",
|
||||
"coverage[toml]",
|
||||
"filelock",
|
||||
"pytest-insta",
|
||||
]
|
||||
doc = [
|
||||
"pdoc",
|
||||
]
|
||||
dev = [
|
||||
{include-group = "lint"},
|
||||
{include-group = "test"},
|
||||
{include-group = "doc"},
|
||||
"openai",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
slither = "slither.__main__:main"
|
||||
slither-check-upgradeability = "slither.tools.upgradeability.__main__:main"
|
||||
slither-find-paths = "slither.tools.possible_paths.__main__:main"
|
||||
slither-simil = "slither.tools.similarity.__main__:main"
|
||||
slither-flat = "slither.tools.flattening.__main__:main"
|
||||
slither-format = "slither.tools.slither_format.__main__:main"
|
||||
slither-check-erc = "slither.tools.erc_conformance.__main__:main"
|
||||
slither-check-kspec = "slither.tools.kspec_coverage.__main__:main"
|
||||
slither-prop = "slither.tools.properties.__main__:main"
|
||||
slither-mutate = "slither.tools.mutator.__main__:main"
|
||||
slither-read-storage = "slither.tools.read_storage.__main__:main"
|
||||
slither-doctor = "slither.tools.doctor.__main__:main"
|
||||
slither-documentation = "slither.tools.documentation.__main__:main"
|
||||
slither-interface = "slither.tools.interface.__main__:main"
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["slither"]
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 100
|
||||
[tool.pylint.messages_control]
|
||||
disable = """
|
||||
missing-module-docstring,
|
||||
missing-class-docstring,
|
||||
missing-function-docstring,
|
||||
unnecessary-lambda,
|
||||
cyclic-import,
|
||||
line-too-long,
|
||||
invalid-name,
|
||||
fixme,
|
||||
too-many-return-statements,
|
||||
too-many-ancestors,
|
||||
logging-fstring-interpolation,
|
||||
logging-not-lazy,
|
||||
duplicate-code,
|
||||
import-error,
|
||||
unsubscriptable-object,
|
||||
unnecessary-lambda-assignment
|
||||
"""
|
||||
# Target Python 3.9+ (current minimum version)
|
||||
target-version = "py39"
|
||||
# Additional exclusions beyond defaults and .gitignore
|
||||
extend-exclude = [
|
||||
"docs/",
|
||||
]
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"E", # pycodestyle errors
|
||||
"W", # pycodestyle warnings
|
||||
"F", # pyflakes
|
||||
"I", # isort
|
||||
"B", # flake8-bugbear
|
||||
"C4", # flake8-comprehensions
|
||||
"UP", # pyupgrade
|
||||
"ARG", # flake8-unused-arguments
|
||||
"SIM", # flake8-simplify
|
||||
"TCH", # flake8-type-checking
|
||||
"RUF", # Ruff-specific rules
|
||||
]
|
||||
# NOTE: When updating ruff version range, also update .pre-commit-config.yaml
|
||||
# by running: pre-commit autoupdate
|
||||
# Ignore rules to match previous black + pylint configuration
|
||||
ignore = [
|
||||
# From pylint disabled rules
|
||||
"E501", # line-too-long (was disabled in pylint)
|
||||
"F401", # unused-import (similar to import-error tolerance)
|
||||
"F841", # unused-variable
|
||||
"ARG001", # unused-function-argument
|
||||
"ARG002", # unused-method-argument
|
||||
"ARG003", # unused-class-method-argument
|
||||
"B008", # function-call-in-default-argument
|
||||
"B904", # raise-without-from-inside-except
|
||||
"C408", # unnecessary-collection-call
|
||||
"SIM102", # collapsible-if (complexity tolerance)
|
||||
"SIM103", # needless-bool (allow explicit bool returns)
|
||||
"SIM105", # suppressible-exception
|
||||
"SIM108", # if-else-block-instead-of-if-exp (complexity tolerance)
|
||||
"SIM114", # if-with-same-arms
|
||||
"SIM117", # with-statement (complexity tolerance)
|
||||
"TC001", # typing-only-first-party-import
|
||||
"TC002", # typing-only-third-party-import
|
||||
"TC003", # typing-only-standard-library-import
|
||||
"UP006", # non-pep585-annotation (allow older style)
|
||||
"UP007", # non-pep604-annotation (allow older style)
|
||||
"UP035", # deprecated-import
|
||||
"RUF001", # ambiguous-unicode-character-string
|
||||
"RUF002", # ambiguous-unicode-character-docstring
|
||||
"RUF003", # ambiguous-unicode-character-comment
|
||||
# Additional rules for compatibility
|
||||
"B006", # mutable-argument-default
|
||||
"B007", # unused-loop-control-variable
|
||||
"B018", # useless-expression
|
||||
"C401", # unnecessary-generator-set
|
||||
"C403", # unnecessary-list-comprehension-set
|
||||
"SIM110", # reimplemented-builtin
|
||||
"SIM112", # uncapitalized-environment-variables
|
||||
# Disable additional rules to avoid code changes
|
||||
"I001", # unsorted-imports (453 issues)
|
||||
"UP037", # quoted-annotation (148 issues)
|
||||
"RUF005", # collection-literal-concatenation (57 issues)
|
||||
"W291", # trailing-whitespace (51 issues)
|
||||
"E713", # not-in-test (40 issues)
|
||||
"RUF010", # explicit-f-string-type-conversion (24 issues)
|
||||
"C414", # unnecessary-double-cast-or-process (20 issues)
|
||||
"RUF015", # unnecessary-iterable-allocation-for-first-element (15 issues)
|
||||
"SIM910", # dict-get-with-none-default (15 issues)
|
||||
"E741", # ambiguous-variable-name (14 issues)
|
||||
"UP034", # extraneous-parentheses (13 issues)
|
||||
"UP045", # non-pep604-annotation-optional (13 issues)
|
||||
"RUF012", # mutable-class-default (12 issues)
|
||||
"E731", # lambda-assignment (11 issues)
|
||||
"RUF021", # parenthesize-chained-operators (10 issues)
|
||||
"UP015", # redundant-open-modes (10 issues)
|
||||
"RUF013", # implicit-optional (7 issues)
|
||||
"W293", # blank-line-with-whitespace (7 issues)
|
||||
"C405", # unnecessary-literal-set (6 issues)
|
||||
"UP012", # unnecessary-encode-utf8 (6 issues)
|
||||
"E722", # bare-except (5 issues)
|
||||
"C417", # unnecessary-map (4 issues)
|
||||
"C420", # unnecessary-dict-comprehension-for-iterable (4 issues)
|
||||
"RUF019", # unnecessary-key-check (4 issues)
|
||||
"RUF023", # unsorted-dunder-slots (4 issues)
|
||||
"SIM118", # in-dict-keys (4 issues)
|
||||
"E714", # not-is-test (3 issues)
|
||||
"F821", # undefined-name (3 issues - might be false positives)
|
||||
"RUF046", # unnecessary-cast-to-int (3 issues)
|
||||
"SIM401", # if-else-block-instead-of-dict-get (3 issues)
|
||||
"UP018", # native-literals (2 issues)
|
||||
"B011", # assert-false (1 issue)
|
||||
"B020", # loop-variable-overrides-iterator (1 issue)
|
||||
"B026", # star-arg-unpacking-after-keyword-arg (1 issue)
|
||||
"B034", # re-sub-positional-args (1 issue)
|
||||
"C400", # unnecessary-generator-list (1 issue)
|
||||
"C409", # unnecessary-literal-within-tuple-call (1 issue)
|
||||
"C416", # unnecessary-comprehension (1 issue)
|
||||
"E101", # mixed-spaces-and-tabs (1 issue)
|
||||
"E721", # type-comparison (1 issue)
|
||||
"SIM113", # enumerate-for-loop (1 issue)
|
||||
"SIM201", # negate-equal-op (1 issue)
|
||||
"SIM300", # yoda-conditions (1 issue)
|
||||
"TC005", # empty-type-checking-block (1 issue)
|
||||
"UP011", # lru-cache-without-parameters (1 issue)
|
||||
"UP022", # replace-stdout-stderr (1 issue)
|
||||
"UP031", # printf-string-formatting (1 issue)
|
||||
]
|
||||
# Allow autofix for all enabled rules
|
||||
fixable = ["ALL"]
|
||||
unfixable = []
|
||||
# Allow common variable names that pylint was configured to accept
|
||||
allowed-confusables = ["'", "'", "–", "—"]
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
# Test files can have more relaxed rules
|
||||
"tests/**/*.py" = [
|
||||
"ARG", # Unused arguments are OK in tests
|
||||
"S101", # assert is OK in tests
|
||||
"SIM", # Simplification rules can be relaxed in tests
|
||||
]
|
||||
# Scripts can have different rules
|
||||
"scripts/**/*.py" = [
|
||||
"T201", # print is OK in scripts
|
||||
]
|
||||
|
||||
[tool.ruff.lint.isort]
|
||||
# Match the project's import style
|
||||
force-single-line = false
|
||||
force-sort-within-sections = false
|
||||
lines-after-imports = 2
|
||||
known-first-party = ["slither"]
|
||||
known-third-party = ["crytic_compile"]
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test
|
||||
|
||||
|
||||
solc-select use 0.7.0
|
||||
|
||||
if ! slither "tests/e2e/config/test_json_config/test.sol" --solc-ast --no-fail-pedantic; then
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test Dapp integration
|
||||
|
||||
# work around having two python versions loading libraries from each other in CI
|
||||
OLD_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
|
||||
OLD_LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-}"
|
||||
alias crytic-compile='LD_LIBRARY_PATH=$OLD_LD_LIBRARY_PATH crytic-compile'
|
||||
unset LD_LIBRARY_PATH
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test data dependency
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test embark integration
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test slither-check-erc
|
||||
|
||||
DIR_TESTS="tests/tools/check-erc"
|
||||
DIR_TESTS="tests/tools/check_erc"
|
||||
|
||||
solc-select use 0.5.0
|
||||
slither-check-erc "$DIR_TESTS/erc20.sol" ERC20 > test_1.txt 2>&1
|
||||
solc-select use 0.5.1
|
||||
slither-check-erc "$DIR_TESTS/erc20.sol" ERC20 2>&1 | tee test_1.txt
|
||||
DIFF=$(diff test_1.txt "$DIR_TESTS/test_1.txt")
|
||||
if [ "$DIFF" != "" ]
|
||||
then
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test etherlime integration
|
||||
|
||||
@@ -19,4 +20,4 @@ if ! slither .; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
exit 0
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test etherscan integration
|
||||
|
||||
# Skip when API key is not present
|
||||
if [ "$GITHUB_ETHERSCAN" = "" ]; then
|
||||
echo "Skipped, no Etherscan API key provided"
|
||||
exit
|
||||
fi
|
||||
|
||||
mkdir etherscan
|
||||
cd etherscan || exit 255
|
||||
|
||||
@@ -12,10 +19,4 @@ if ! slither 0x7F37f78cBD74481E593F9C737776F7113d76B315 --etherscan-apikey "$GIT
|
||||
fi
|
||||
echo "::endgroup::"
|
||||
|
||||
# Perform a small sleep when API key is not available (e.g. on PR CI from external contributor)
|
||||
if [ "$GITHUB_ETHERSCAN" = "" ]; then
|
||||
sleep $(( ( RANDOM % 5 ) + 1 ))s
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test slither-check-upgradeability
|
||||
### Test slither-find-paths
|
||||
|
||||
DIR_TESTS="tests/possible_paths"
|
||||
DIR_TESTS="tests/e2e/printers/possible_paths"
|
||||
|
||||
solc-select use "0.5.0"
|
||||
solc-select use "0.5.1"
|
||||
slither-find-paths "$DIR_TESTS/paths.sol" A.destination > test_possible_paths.txt 2>&1
|
||||
DIFF=$(diff test_possible_paths.txt "$DIR_TESTS/paths.txt")
|
||||
if [ "$DIFF" != "" ]
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
shopt -s extglob
|
||||
|
||||
### Test slither-flat
|
||||
@@ -10,7 +12,7 @@ if ! slither-flat b.sol; then
|
||||
echo "slither-flat failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
SUFFIX="@(sol)"
|
||||
if ! solc "crytic-export/flattening/"*$SUFFIX; then
|
||||
echo "solc failed on flattened files"
|
||||
|
||||
@@ -1,24 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test slither-interface
|
||||
|
||||
DIR_TESTS="tests/tools/interface"
|
||||
DIR_TESTS="tests/tools/interface"
|
||||
|
||||
solc-select use 0.8.19 --always-install
|
||||
|
||||
#Test 1 - Etherscan target
|
||||
slither-interface WETH9 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
|
||||
DIFF=$(diff crytic-export/interfaces/IWETH9.sol "$DIR_TESTS/test_1.sol" --strip-trailing-cr)
|
||||
if [ "$DIFF" != "" ]
|
||||
then
|
||||
echo "slither-interface test 1 failed"
|
||||
cat "crytic-export/interfaces/IWETH9.sol"
|
||||
echo ""
|
||||
cat "$DIR_TESTS/test_1.sol"
|
||||
exit 255
|
||||
if [ "$GITHUB_ETHERSCAN" = "" ]; then
|
||||
echo "skipping test 1, no api key for etherscan"
|
||||
else
|
||||
#Test 1 - Etherscan target
|
||||
slither-interface WETH9 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --etherscan-apikey "$GITHUB_ETHERSCAN"
|
||||
DIFF=$(diff crytic-export/interfaces/IWETH9.sol "$DIR_TESTS/test_1.sol" --strip-trailing-cr)
|
||||
if [ "$DIFF" != "" ]
|
||||
then
|
||||
echo "slither-interface test 1 failed"
|
||||
cat "crytic-export/interfaces/IWETH9.sol"
|
||||
echo ""
|
||||
cat "$DIR_TESTS/test_1.sol"
|
||||
exit 255
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
#Test 2 - Local file target
|
||||
slither-interface Mock tests/tools/interface/ContractMock.sol
|
||||
DIFF=$(diff crytic-export/interfaces/IMock.sol "$DIR_TESTS/test_2.sol" --strip-trailing-cr)
|
||||
@@ -92,4 +96,4 @@ then
|
||||
exit 255
|
||||
fi
|
||||
|
||||
rm -r crytic-export
|
||||
rm -r crytic-export
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
DIR_TESTS="tests/check-kspec"
|
||||
DIR_TESTS="tests/tools/check_kspec"
|
||||
|
||||
solc-select use "0.5.0"
|
||||
slither-check-kspec "$DIR_TESTS/safeAdd/safeAdd.sol" "$DIR_TESTS/safeAdd/spec.md" > test_1.txt 2>&1
|
||||
solc-select use "0.5.1"
|
||||
slither-check-kspec "$DIR_TESTS/safeAdd/safeAdd.sol" "$DIR_TESTS/safeAdd/spec.md" 2>&1 | tee test_1.txt
|
||||
DIFF=$(diff test_1.txt "$DIR_TESTS/test_1.txt")
|
||||
if [ "$DIFF" != "" ]
|
||||
then
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test path filtering across POSIX and Windows
|
||||
|
||||
@@ -10,6 +11,6 @@ then
|
||||
echo "Path filtering across POSIX and Windows failed"
|
||||
rm output.txt
|
||||
exit 5
|
||||
else
|
||||
else
|
||||
rm output.txt
|
||||
fi
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test printer
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test slither-prop
|
||||
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Install requisites
|
||||
|
||||
pip3.8 install pybind11
|
||||
pip3.8 install https://github.com/facebookresearch/fastText/archive/0.2.0.zip
|
||||
if [ "$UV_PYTHON" = "" ]; then
|
||||
PIP="pip3"
|
||||
else
|
||||
PIP="uv pip"
|
||||
fi
|
||||
$PIP install fasttext
|
||||
|
||||
### Test slither-simil
|
||||
|
||||
solc-select use "0.4.25"
|
||||
|
||||
DIR_TESTS="tests/simil"
|
||||
slither-simil info "" --filename $DIR_TESTS/../complex_func.sol --fname Complex.complexExternalWrites > test_1.txt 2>&1
|
||||
DIR_TESTS="tests/tools/simil"
|
||||
slither-simil info "" --filename $DIR_TESTS/../../unit/core/test_data/complex_func.sol --fname Complex.complexExternalWrites 2>&1 | tee test_1.txt
|
||||
DIFF=$(diff test_1.txt "$DIR_TESTS/test_1.txt")
|
||||
if [ "$DIFF" != "" ]
|
||||
then
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test
|
||||
|
||||
if ! slither "tests/*.json" --config "tests/config/slither.config.json"; then
|
||||
solc-select use 0.7.0
|
||||
|
||||
if ! slither "tests/e2e/config/test_json_config/test.sol" --config "tests/e2e/config/test_json_config/slither.config.json"; then
|
||||
echo "Config failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
### Test truffle integration
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
### Test slither-check-upgradeability
|
||||
|
||||
|
||||
@@ -24,5 +24,4 @@ if __name__ == "__main__":
|
||||
bugs_by_version = organize_data(bug_data)
|
||||
|
||||
with open(Path.cwd() / Path("slither/utils/buggy_versions.py"), "w", encoding="utf-8") as file:
|
||||
file.write("# pylint: disable=too-many-lines\n")
|
||||
file.write(f"bugs_by_version = {bugs_by_version}")
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
with open("README.md", "r", encoding="utf-8") as f:
|
||||
long_description = f.read()
|
||||
|
||||
setup(
|
||||
name="slither-analyzer",
|
||||
description="Slither is a Solidity and Vyper static analysis framework written in Python 3.",
|
||||
url="https://github.com/crytic/slither",
|
||||
author="Trail of Bits",
|
||||
version="0.11.3",
|
||||
packages=find_packages(),
|
||||
python_requires=">=3.8",
|
||||
install_requires=[
|
||||
"packaging",
|
||||
"prettytable>=3.10.2",
|
||||
"pycryptodome>=3.4.6",
|
||||
"crytic-compile>=0.3.9,<0.4.0",
|
||||
# "crytic-compile@git+https://github.com/crytic/crytic-compile.git@master#egg=crytic-compile",
|
||||
"web3>=7.10,<8",
|
||||
"eth-abi>=5.0.1",
|
||||
"eth-typing>=5.0.0",
|
||||
"eth-utils>=5.0.0",
|
||||
],
|
||||
extras_require={
|
||||
"lint": [
|
||||
"black==22.3.0",
|
||||
"pylint==3.0.3",
|
||||
],
|
||||
"test": [
|
||||
"pytest",
|
||||
"pytest-cov",
|
||||
"pytest-xdist",
|
||||
"deepdiff",
|
||||
"orderly-set==5.3.2", # Temporary fix for https://github.com/seperman/deepdiff/issues/539
|
||||
"numpy",
|
||||
"coverage[toml]",
|
||||
"filelock",
|
||||
"pytest-insta",
|
||||
],
|
||||
"doc": [
|
||||
"pdoc",
|
||||
],
|
||||
"dev": [
|
||||
"slither-analyzer[lint,test,doc]",
|
||||
"openai",
|
||||
],
|
||||
},
|
||||
license="AGPL-3.0",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"slither = slither.__main__:main",
|
||||
"slither-check-upgradeability = slither.tools.upgradeability.__main__:main",
|
||||
"slither-find-paths = slither.tools.possible_paths.__main__:main",
|
||||
"slither-simil = slither.tools.similarity.__main__:main",
|
||||
"slither-flat = slither.tools.flattening.__main__:main",
|
||||
"slither-format = slither.tools.slither_format.__main__:main",
|
||||
"slither-check-erc = slither.tools.erc_conformance.__main__:main",
|
||||
"slither-check-kspec = slither.tools.kspec_coverage.__main__:main",
|
||||
"slither-prop = slither.tools.properties.__main__:main",
|
||||
"slither-mutate = slither.tools.mutator.__main__:main",
|
||||
"slither-read-storage = slither.tools.read_storage.__main__:main",
|
||||
"slither-doctor = slither.tools.doctor.__main__:main",
|
||||
"slither-documentation = slither.tools.documentation.__main__:main",
|
||||
"slither-interface = slither.tools.interface.__main__:main",
|
||||
]
|
||||
},
|
||||
)
|
||||
@@ -1,4 +1,5 @@
|
||||
"""
|
||||
.. include:: ../README.md
|
||||
"""
|
||||
|
||||
from .slither import Slither
|
||||
|
||||
+33
-49
@@ -13,43 +13,43 @@ import traceback
|
||||
from importlib import metadata
|
||||
from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, Type, Union
|
||||
|
||||
|
||||
from crytic_compile import cryticparser, CryticCompile
|
||||
from crytic_compile.platform.standard import generate_standard_export
|
||||
import importlib_metadata
|
||||
from crytic_compile import cryticparser, CryticCompile, compile_all, is_supported
|
||||
from crytic_compile.platform.etherscan import SUPPORTED_NETWORK
|
||||
from crytic_compile import compile_all, is_supported
|
||||
from crytic_compile.platform.standard import generate_standard_export
|
||||
|
||||
from slither.detectors import all_detectors
|
||||
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
|
||||
from slither.exceptions import SlitherException
|
||||
from slither.printers import all_printers
|
||||
from slither.printers.abstract_printer import AbstractPrinter
|
||||
from slither.slither import Slither
|
||||
from slither.utils import codex
|
||||
from slither.utils.output import (
|
||||
output_to_json,
|
||||
output_to_zip,
|
||||
output_to_sarif,
|
||||
ZIP_TYPES_ACCEPTED,
|
||||
Output,
|
||||
)
|
||||
from slither.utils.output_capture import StandardOutputCapture
|
||||
from slither.utils.colors import red, set_colorization_enabled
|
||||
from slither.utils.command_line import (
|
||||
DEFAULT_JSON_OUTPUT_TYPES,
|
||||
JSON_OUTPUT_TYPES,
|
||||
FailOnLevel,
|
||||
check_and_sanitize_markdown_root,
|
||||
defaults_flag_in_config,
|
||||
output_detectors,
|
||||
output_results_to_markdown,
|
||||
output_detectors_json,
|
||||
output_printers,
|
||||
output_printers_json,
|
||||
output_results_to_markdown,
|
||||
output_to_markdown,
|
||||
output_wiki,
|
||||
defaults_flag_in_config,
|
||||
read_config_file,
|
||||
JSON_OUTPUT_TYPES,
|
||||
DEFAULT_JSON_OUTPUT_TYPES,
|
||||
check_and_sanitize_markdown_root,
|
||||
)
|
||||
from slither.exceptions import SlitherException
|
||||
from slither.utils.output import (
|
||||
ZIP_TYPES_ACCEPTED,
|
||||
Output,
|
||||
output_to_json,
|
||||
output_to_sarif,
|
||||
output_to_zip,
|
||||
)
|
||||
from slither.utils.output_capture import StandardOutputCapture
|
||||
|
||||
|
||||
logging.basicConfig()
|
||||
logger = logging.getLogger("Slither")
|
||||
@@ -166,12 +166,7 @@ def get_detectors_and_printers() -> Tuple[
|
||||
printers = [p for p in printers_ if inspect.isclass(p) and issubclass(p, AbstractPrinter)]
|
||||
|
||||
# Handle plugins!
|
||||
if sys.version_info >= (3, 10):
|
||||
entry_points = metadata.entry_points(group="slither_analyzer.plugin")
|
||||
else:
|
||||
from pkg_resources import iter_entry_points # pylint: disable=import-outside-toplevel
|
||||
|
||||
entry_points = iter_entry_points(group="slither_analyzer.plugin", name=None)
|
||||
entry_points = importlib_metadata.entry_points(group="slither_analyzer.plugin")
|
||||
|
||||
for entry_point in entry_points:
|
||||
make_plugin = entry_point.load()
|
||||
@@ -194,7 +189,6 @@ def get_detectors_and_printers() -> Tuple[
|
||||
return detectors, printers
|
||||
|
||||
|
||||
# pylint: disable=too-many-branches
|
||||
def choose_detectors(
|
||||
args: argparse.Namespace, all_detector_classes: List[Type[AbstractDetector]]
|
||||
) -> List[Type[AbstractDetector]]:
|
||||
@@ -289,7 +283,6 @@ def parse_filter_paths(args: argparse.Namespace, filter_path: bool) -> List[str]
|
||||
return []
|
||||
|
||||
|
||||
# pylint: disable=too-many-statements
|
||||
def parse_args(
|
||||
detector_classes: List[Type[AbstractDetector]], printer_classes: List[Type[AbstractPrinter]]
|
||||
) -> argparse.Namespace:
|
||||
@@ -298,7 +291,7 @@ def parse_args(
|
||||
usage += "\t- file.sol // a Solidity file\n"
|
||||
usage += "\t- project_directory // a project directory. See https://github.com/crytic/crytic-compile/#crytic-compile for the supported platforms\n"
|
||||
usage += "\t- 0x.. // a contract on mainnet\n"
|
||||
usage += f"\t- NETWORK:0x.. // a contract on a different network. Supported networks: {','.join(x[:-1] for x in SUPPORTED_NETWORK)}\n"
|
||||
usage += f"\t- NETWORK:0x.. // a contract on a different network. Supported networks: {','.join(x for x in SUPPORTED_NETWORK)}\n"
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="For usage information, see https://github.com/crytic/slither/wiki/Usage",
|
||||
@@ -523,8 +516,8 @@ def parse_args(
|
||||
group_misc.add_argument(
|
||||
"--json-types",
|
||||
help="Comma-separated list of result types to output to JSON, defaults to "
|
||||
+ f'{",".join(output_type for output_type in DEFAULT_JSON_OUTPUT_TYPES)}. '
|
||||
+ f'Available types: {",".join(output_type for output_type in JSON_OUTPUT_TYPES)}',
|
||||
+ f"{','.join(output_type for output_type in DEFAULT_JSON_OUTPUT_TYPES)}. "
|
||||
+ f"Available types: {','.join(output_type for output_type in JSON_OUTPUT_TYPES)}",
|
||||
action="store",
|
||||
default=defaults_flag_in_config["json-types"],
|
||||
)
|
||||
@@ -538,7 +531,7 @@ def parse_args(
|
||||
|
||||
group_misc.add_argument(
|
||||
"--zip-type",
|
||||
help=f'Zip compression type. One of {",".join(ZIP_TYPES_ACCEPTED.keys())}. Default lzma',
|
||||
help=f"Zip compression type. One of {','.join(ZIP_TYPES_ACCEPTED.keys())}. Default lzma",
|
||||
action="store",
|
||||
default=defaults_flag_in_config["zip_type"],
|
||||
)
|
||||
@@ -619,8 +612,6 @@ def parse_args(
|
||||
default=defaults_flag_in_config["include_paths"],
|
||||
)
|
||||
|
||||
codex.init_parser(parser)
|
||||
|
||||
# debugger command
|
||||
parser.add_argument("--debug", help=argparse.SUPPRESS, action="store_true", default=False)
|
||||
|
||||
@@ -683,35 +674,29 @@ def parse_args(
|
||||
return args
|
||||
|
||||
|
||||
class ListDetectors(argparse.Action): # pylint: disable=too-few-public-methods
|
||||
def __call__(
|
||||
self, parser: Any, *args: Any, **kwargs: Any
|
||||
) -> None: # pylint: disable=signature-differs
|
||||
class ListDetectors(argparse.Action):
|
||||
def __call__(self, parser: Any, *args: Any, **kwargs: Any) -> None:
|
||||
detectors, _ = get_detectors_and_printers()
|
||||
output_detectors(detectors)
|
||||
parser.exit()
|
||||
|
||||
|
||||
class ListDetectorsJson(argparse.Action): # pylint: disable=too-few-public-methods
|
||||
def __call__(
|
||||
self, parser: Any, *args: Any, **kwargs: Any
|
||||
) -> None: # pylint: disable=signature-differs
|
||||
class ListDetectorsJson(argparse.Action):
|
||||
def __call__(self, parser: Any, *args: Any, **kwargs: Any) -> None:
|
||||
detectors, _ = get_detectors_and_printers()
|
||||
detector_types_json = output_detectors_json(detectors)
|
||||
print(json.dumps(detector_types_json))
|
||||
parser.exit()
|
||||
|
||||
|
||||
class ListPrinters(argparse.Action): # pylint: disable=too-few-public-methods
|
||||
def __call__(
|
||||
self, parser: Any, *args: Any, **kwargs: Any
|
||||
) -> None: # pylint: disable=signature-differs
|
||||
class ListPrinters(argparse.Action):
|
||||
def __call__(self, parser: Any, *args: Any, **kwargs: Any) -> None:
|
||||
_, printers = get_detectors_and_printers()
|
||||
output_printers(printers)
|
||||
parser.exit()
|
||||
|
||||
|
||||
class OutputMarkdown(argparse.Action): # pylint: disable=too-few-public-methods
|
||||
class OutputMarkdown(argparse.Action):
|
||||
def __call__(
|
||||
self,
|
||||
parser: Any,
|
||||
@@ -725,7 +710,7 @@ class OutputMarkdown(argparse.Action): # pylint: disable=too-few-public-methods
|
||||
parser.exit()
|
||||
|
||||
|
||||
class OutputWiki(argparse.Action): # pylint: disable=too-few-public-methods
|
||||
class OutputWiki(argparse.Action):
|
||||
def __call__(
|
||||
self,
|
||||
parser: Any,
|
||||
@@ -776,7 +761,6 @@ def main() -> None:
|
||||
main_impl(all_detector_classes=detectors, all_printer_classes=printers)
|
||||
|
||||
|
||||
# pylint: disable=too-many-statements,too-many-branches,too-many-locals
|
||||
def main_impl(
|
||||
all_detector_classes: List[Type[AbstractDetector]],
|
||||
all_printer_classes: List[Type[AbstractPrinter]],
|
||||
@@ -806,7 +790,7 @@ def main_impl(
|
||||
outputting_sarif_stdout = args.sarif == "-"
|
||||
outputting_zip = args.zip is not None
|
||||
if args.zip_type not in ZIP_TYPES_ACCEPTED:
|
||||
to_log = f'Zip type not accepted, it must be one of {",".join(ZIP_TYPES_ACCEPTED.keys())}'
|
||||
to_log = f"Zip type not accepted, it must be one of {','.join(ZIP_TYPES_ACCEPTED.keys())}"
|
||||
logger.error(to_log)
|
||||
|
||||
# If we are outputting JSON, capture all standard output. If we are outputting to stdout, we block typical stdout
|
||||
@@ -819,7 +803,7 @@ def main_impl(
|
||||
|
||||
default_log = logging.INFO if not args.debug else logging.DEBUG
|
||||
|
||||
for (l_name, l_level) in [
|
||||
for l_name, l_level in [
|
||||
("Slither", default_log),
|
||||
("Contract", default_log),
|
||||
("Function", default_log),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
This module import all slither exceptions
|
||||
"""
|
||||
# pylint: disable=unused-import
|
||||
|
||||
from slither.slithir.exceptions import SlithIRError
|
||||
from slither.solc_parsing.exceptions import ParsingError, VariableNotFound
|
||||
from slither.core.exceptions import SlitherCoreError
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Compute the data depenency between all the SSA variables
|
||||
Compute the data depenency between all the SSA variables
|
||||
"""
|
||||
|
||||
from collections import defaultdict
|
||||
from typing import Union, Set, Dict, TYPE_CHECKING, List
|
||||
|
||||
@@ -365,7 +366,6 @@ def compute_dependency_contract(
|
||||
propagate_function(contract, function, KEY_SSA, KEY_NON_SSA)
|
||||
propagate_function(contract, function, KEY_SSA_UNPROTECTED, KEY_NON_SSA_UNPROTECTED)
|
||||
|
||||
# pylint: disable=expression-not-assigned
|
||||
if function.visibility in ["public", "external"]:
|
||||
[compilation_unit.context[KEY_INPUT].add(p) for p in function.parameters]
|
||||
[compilation_unit.context[KEY_INPUT_SSA].add(p) for p in function.parameters_ssa]
|
||||
@@ -380,7 +380,7 @@ def propagate_function(
|
||||
transitive_close_dependencies(function, context_key, context_key_non_ssa)
|
||||
# Propage data dependency
|
||||
data_depencencies = function.context[context_key]
|
||||
for (key, values) in data_depencencies.items():
|
||||
for key, values in data_depencencies.items():
|
||||
if not key in contract.context[context_key]:
|
||||
contract.context[context_key][key] = set(values)
|
||||
else:
|
||||
@@ -489,11 +489,11 @@ def convert_variable_to_non_ssa(v: SUPPORTED_TYPES) -> SUPPORTED_TYPES:
|
||||
|
||||
|
||||
def convert_to_non_ssa(
|
||||
data_depencies: Dict[SUPPORTED_TYPES, Set[SUPPORTED_TYPES]]
|
||||
data_depencies: Dict[SUPPORTED_TYPES, Set[SUPPORTED_TYPES]],
|
||||
) -> Dict[SUPPORTED_TYPES, Set[SUPPORTED_TYPES]]:
|
||||
# Need to create new set() as its changed during iteration
|
||||
ret: Dict[SUPPORTED_TYPES, Set[SUPPORTED_TYPES]] = {}
|
||||
for (k, values) in data_depencies.items():
|
||||
for k, values in data_depencies.items():
|
||||
var = convert_variable_to_non_ssa(k)
|
||||
if not var in ret:
|
||||
ret[var] = set()
|
||||
|
||||
@@ -14,7 +14,6 @@ def get_evm_instructions(obj):
|
||||
assert isinstance(obj, (Function, Contract, Node))
|
||||
|
||||
if KEY_EVM_INS not in obj.context:
|
||||
|
||||
CFG = load_evm_cfg_builder()
|
||||
|
||||
slither = obj.slither
|
||||
@@ -159,7 +158,6 @@ def _get_function_evm(cfg, function_name, function_hash):
|
||||
return None
|
||||
|
||||
|
||||
# pylint: disable=too-many-locals
|
||||
def generate_source_to_evm_ins_mapping(evm_instructions, srcmap_runtime, slither, filename):
|
||||
"""
|
||||
Generate Solidity source to EVM instruction mapping using evm_cfg_builder:cfg.instructions
|
||||
|
||||
@@ -7,7 +7,7 @@ logger = logging.getLogger("ConvertToEVM")
|
||||
def load_evm_cfg_builder():
|
||||
try:
|
||||
# Avoiding the addition of evm_cfg_builder as permanent dependency
|
||||
# pylint: disable=import-outside-toplevel
|
||||
|
||||
from evm_cfg_builder.cfg import CFG
|
||||
|
||||
return CFG
|
||||
@@ -15,5 +15,5 @@ def load_evm_cfg_builder():
|
||||
logger.error("To use evm features, you need to install evm-cfg-builder")
|
||||
logger.error("Documentation: https://github.com/crytic/evm_cfg_builder")
|
||||
logger.error("Installation: pip install evm-cfg-builder")
|
||||
# pylint: disable=raise-missing-from
|
||||
|
||||
raise SlitherError("evm-cfg-builder not installed.")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Detect if all the given variables are written in all the paths of the function
|
||||
Detect if all the given variables are written in all the paths of the function
|
||||
"""
|
||||
|
||||
from collections import defaultdict
|
||||
from typing import Dict, Set, List, Any, Optional
|
||||
|
||||
@@ -17,7 +18,7 @@ from slither.slithir.operations import (
|
||||
from slither.slithir.variables import ReferenceVariable, TemporaryVariable
|
||||
|
||||
|
||||
class State: # pylint: disable=too-few-public-methods
|
||||
class State:
|
||||
def __init__(self) -> None:
|
||||
# Map node -> list of variables set
|
||||
# Were each variables set represents a configuration of a path
|
||||
@@ -32,7 +33,6 @@ class State: # pylint: disable=too-few-public-methods
|
||||
self.nodes: Dict[Node, List[Set[Variable]]] = defaultdict(list)
|
||||
|
||||
|
||||
# pylint: disable=too-many-branches
|
||||
def _visit(
|
||||
node: Optional[Node],
|
||||
state: State,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Node module
|
||||
Node module
|
||||
"""
|
||||
|
||||
from enum import Enum
|
||||
from typing import Optional, List, Set, Dict, Tuple, Union, TYPE_CHECKING
|
||||
|
||||
@@ -49,8 +50,6 @@ if TYPE_CHECKING:
|
||||
from slither.core.scope.scope import FileScope
|
||||
|
||||
|
||||
# pylint: disable=too-many-lines,too-many-branches,too-many-instance-attributes
|
||||
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
# region NodeType
|
||||
@@ -99,9 +98,8 @@ class NodeType(Enum):
|
||||
|
||||
# endregion
|
||||
|
||||
# I am not sure why, but pylint reports a lot of "no-member" issue that are not real (Josselin)
|
||||
# pylint: disable=no-member
|
||||
class Node(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
|
||||
class Node(SourceMapping):
|
||||
"""
|
||||
Node class
|
||||
|
||||
@@ -443,7 +441,7 @@ class Node(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
:param callstack: used internally to check for recursion
|
||||
:return bool:
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
|
||||
from slither.slithir.operations import Call
|
||||
|
||||
if self._can_reenter is None:
|
||||
@@ -459,7 +457,7 @@ class Node(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
Check if the node can send eth
|
||||
:return bool:
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
|
||||
from slither.slithir.operations import Call
|
||||
|
||||
if self._can_send_eth is None:
|
||||
@@ -846,10 +844,8 @@ class Node(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
|
||||
def _find_read_write_call(self) -> None: # pylint: disable=too-many-statements
|
||||
|
||||
def _find_read_write_call(self) -> None:
|
||||
for ir in self.irs:
|
||||
|
||||
self._slithir_vars |= {v for v in ir.read if self._is_valid_slithir_var(v)}
|
||||
|
||||
if isinstance(ir, OperationWithLValue):
|
||||
@@ -907,7 +903,6 @@ class Node(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
# Todo this part needs more tests and documentation
|
||||
self._high_level_calls.append((ir.destination.type.type, ir))
|
||||
except AttributeError as error:
|
||||
# pylint: disable=raise-missing-from
|
||||
raise SlitherException(
|
||||
f"Function not found on IR: {ir}.\nNode: {self} ({self.source_mapping})\nFunction: {self.function}\nPlease try compiling with a recent Solidity version. {error}"
|
||||
)
|
||||
@@ -1028,7 +1023,6 @@ class Node(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
self._ssa_vars_written.append(var)
|
||||
|
||||
def update_read_write_using_ssa(self) -> None:
|
||||
|
||||
for ir in self.irs_ssa:
|
||||
if isinstance(ir, PhiCallback):
|
||||
continue
|
||||
|
||||
@@ -5,7 +5,6 @@ if TYPE_CHECKING:
|
||||
from slither.core.declarations.function import Function
|
||||
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
class Scope:
|
||||
def __init__(
|
||||
self, is_checked: bool, is_yul: bool, parent_scope: Union["Scope", "Function"]
|
||||
|
||||
@@ -45,7 +45,6 @@ class Language(Enum):
|
||||
raise ValueError(f"Unknown language: {label}")
|
||||
|
||||
|
||||
# pylint: disable=too-many-instance-attributes,too-many-public-methods
|
||||
class SlitherCompilationUnit(Context):
|
||||
def __init__(self, core: "SlitherCore", crytic_compilation_unit: CompilationUnit) -> None:
|
||||
super().__init__()
|
||||
@@ -300,18 +299,30 @@ class SlitherCompilationUnit(Context):
|
||||
assert self.is_solidity
|
||||
|
||||
for contract in self.contracts_derived:
|
||||
self._compute_storage_layout(contract.name, contract.storage_variables_ordered, False)
|
||||
self._compute_storage_layout(contract.name, contract.transient_variables_ordered, True)
|
||||
self._compute_storage_layout(
|
||||
contract.name,
|
||||
contract.storage_variables_ordered,
|
||||
False,
|
||||
contract.custom_storage_layout,
|
||||
)
|
||||
self._compute_storage_layout(
|
||||
contract.name, contract.transient_variables_ordered, True, None
|
||||
)
|
||||
|
||||
def _compute_storage_layout(
|
||||
self, contract_name: str, state_variables_ordered: List[StateVariable], is_transient: bool
|
||||
self,
|
||||
contract_name: str,
|
||||
state_variables_ordered: List[StateVariable],
|
||||
is_transient: bool,
|
||||
custom_storage_layout: Optional[int],
|
||||
):
|
||||
if is_transient:
|
||||
slot = 0
|
||||
self._transient_storage_layouts[contract_name] = {}
|
||||
else:
|
||||
slot = custom_storage_layout if custom_storage_layout else 0
|
||||
self._persistent_storage_layouts[contract_name] = {}
|
||||
|
||||
slot = 0
|
||||
offset = 0
|
||||
for var in state_variables_ordered:
|
||||
assert var.type
|
||||
|
||||
@@ -2,7 +2,7 @@ from collections import defaultdict
|
||||
from typing import Dict
|
||||
|
||||
|
||||
class Context: # pylint: disable=too-few-public-methods
|
||||
class Context:
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self._context: Dict = {"MEMBERS": defaultdict(None)}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
""""
|
||||
Contract module
|
||||
""" "
|
||||
Contract module
|
||||
"""
|
||||
|
||||
import logging
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
@@ -27,7 +28,7 @@ from slither.utils.erc import (
|
||||
)
|
||||
from slither.utils.tests_pattern import is_test_contract
|
||||
|
||||
# pylint: disable=too-many-lines,too-many-instance-attributes,import-outside-toplevel,too-many-nested-blocks
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from slither.core.declarations import (
|
||||
Enum,
|
||||
@@ -50,7 +51,7 @@ if TYPE_CHECKING:
|
||||
LOGGER = logging.getLogger("Contract")
|
||||
|
||||
|
||||
class Contract(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
class Contract(SourceMapping):
|
||||
"""
|
||||
Contract class
|
||||
"""
|
||||
@@ -62,6 +63,8 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
self._id: Optional[int] = None
|
||||
self._inheritance: List["Contract"] = [] # all contract inherited, c3 linearization
|
||||
self._immediate_inheritance: List["Contract"] = [] # immediate inheritance
|
||||
# Start slot for the persistent storage if custom layout used
|
||||
self._custom_storage_layout: Optional[int] = None
|
||||
|
||||
# Constructors called on contract's definition
|
||||
# contract B is A(1) { ..
|
||||
@@ -228,6 +231,19 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
def is_abstract(self, is_abstract: bool):
|
||||
self._is_abstract = is_abstract
|
||||
|
||||
@property
|
||||
def custom_storage_layout(self) -> Optional[int]:
|
||||
"""
|
||||
Return the persistent storage slot starting position if a custom storage layout is used.
|
||||
Otherwise None.
|
||||
int: Storage slot starting position.
|
||||
"""
|
||||
return self._custom_storage_layout
|
||||
|
||||
@custom_storage_layout.setter
|
||||
def custom_storage_layout(self, slot: int):
|
||||
self._custom_storage_layout = slot
|
||||
|
||||
# endregion
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
@@ -515,9 +531,9 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
|
||||
if self._state_variables_used_in_reentrant_targets is None:
|
||||
reentrant_functions = [f for f in self.functions_entry_points if f.is_reentrant]
|
||||
variables_used: Dict[
|
||||
StateVariable, Set[Union[StateVariable, "Function"]]
|
||||
] = defaultdict(set)
|
||||
variables_used: Dict[StateVariable, Set[Union[StateVariable, "Function"]]] = (
|
||||
defaultdict(set)
|
||||
)
|
||||
for function in reentrant_functions:
|
||||
for ir in function.all_slithir_operations():
|
||||
state_variables = [v for v in ir.used if isinstance(v, StateVariable)]
|
||||
@@ -1042,7 +1058,8 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
list(StateVariable): List all of the state variables written
|
||||
"""
|
||||
all_state_variables_writtens = [
|
||||
f.all_state_variables_written() for f in self.functions + self.modifiers # type: ignore
|
||||
f.all_state_variables_written()
|
||||
for f in self.functions + self.modifiers # type: ignore
|
||||
]
|
||||
all_state_variables_written = [
|
||||
item for sublist in all_state_variables_writtens for item in sublist
|
||||
@@ -1055,7 +1072,8 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
list(StateVariable): List all of the state variables read
|
||||
"""
|
||||
all_state_variables_reads = [
|
||||
f.all_state_variables_read() for f in self.functions + self.modifiers # type: ignore
|
||||
f.all_state_variables_read()
|
||||
for f in self.functions + self.modifiers # type: ignore
|
||||
]
|
||||
all_state_variables_read = [
|
||||
item for sublist in all_state_variables_reads for item in sublist
|
||||
@@ -1373,8 +1391,6 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
else:
|
||||
for contract in self.inheritance + [self]:
|
||||
# This might lead to false positive
|
||||
# Not sure why pylint is having a trouble here
|
||||
# pylint: disable=no-member
|
||||
lower_name = contract.name.lower()
|
||||
if "upgradeable" in lower_name or "upgradable" in lower_name:
|
||||
self._is_upgradeable = True
|
||||
@@ -1448,9 +1464,8 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
from slither.core.declarations.function_contract import FunctionContract
|
||||
|
||||
if self.state_variables:
|
||||
for (idx, variable_candidate) in enumerate(self.state_variables):
|
||||
for idx, variable_candidate in enumerate(self.state_variables):
|
||||
if variable_candidate.expression and not variable_candidate.is_constant:
|
||||
|
||||
constructor_variable = FunctionContract(self.compilation_unit)
|
||||
constructor_variable.set_function_type(FunctionType.CONSTRUCTOR_VARIABLES)
|
||||
constructor_variable.set_contract(self) # type: ignore
|
||||
@@ -1478,9 +1493,8 @@ class Contract(SourceMapping): # pylint: disable=too-many-public-methods
|
||||
counter += 1
|
||||
break
|
||||
|
||||
for (idx, variable_candidate) in enumerate(self.state_variables):
|
||||
for idx, variable_candidate in enumerate(self.state_variables):
|
||||
if variable_candidate.expression and variable_candidate.is_constant:
|
||||
|
||||
constructor_variable = FunctionContract(self.compilation_unit)
|
||||
constructor_variable.set_function_type(
|
||||
FunctionType.CONSTRUCTOR_CONSTANT_VARIABLES
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Function module
|
||||
Function module
|
||||
"""
|
||||
|
||||
import logging
|
||||
from abc import abstractmethod, ABCMeta
|
||||
from collections import namedtuple
|
||||
@@ -28,8 +29,6 @@ from slither.utils.type import convert_type_for_solidity_signature_to_string
|
||||
from slither.utils.utils import unroll
|
||||
|
||||
|
||||
# pylint: disable=import-outside-toplevel,too-many-instance-attributes,too-many-statements,too-many-lines
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from slither.core.declarations import Contract, FunctionContract
|
||||
from slither.core.cfg.node import Node, NodeType
|
||||
@@ -110,7 +109,7 @@ class FunctionLanguage(Enum):
|
||||
Vyper = 2
|
||||
|
||||
|
||||
class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-public-methods
|
||||
class Function(SourceMapping, metaclass=ABCMeta):
|
||||
"""
|
||||
Function class
|
||||
"""
|
||||
@@ -938,7 +937,7 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
|
||||
if self._return_values is None:
|
||||
return_values = []
|
||||
returns = [n for n in self.nodes if n.type == NodeType.RETURN]
|
||||
[ # pylint: disable=expression-not-assigned
|
||||
[
|
||||
return_values.extend(ir.values)
|
||||
for node in returns
|
||||
for ir in node.irs
|
||||
@@ -959,7 +958,7 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
|
||||
if self._return_values_ssa is None:
|
||||
return_values_ssa = []
|
||||
returns = [n for n in self.nodes if n.type == NodeType.RETURN]
|
||||
[ # pylint: disable=expression-not-assigned
|
||||
[
|
||||
return_values_ssa.extend(ir.values)
|
||||
for node in returns
|
||||
for ir in node.irs_ssa
|
||||
@@ -1717,7 +1716,6 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
|
||||
def _get_last_ssa_variable_instances(
|
||||
self, target_state: bool, target_local: bool
|
||||
) -> Dict[str, Set["SlithIRVariable"]]:
|
||||
# pylint: disable=too-many-locals,too-many-branches
|
||||
from slither.slithir.variables import ReferenceVariable
|
||||
from slither.slithir.operations import OperationWithLValue
|
||||
from slither.core.cfg.node import NodeType
|
||||
@@ -1838,7 +1836,6 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
|
||||
node, last_state_variables_instances, initial_state_variables_instances
|
||||
)
|
||||
for ir in node.irs_ssa:
|
||||
|
||||
if isinstance(ir, PhiCallback):
|
||||
callee_ir = ir.callee_ir
|
||||
if isinstance(callee_ir, InternalCall):
|
||||
@@ -1873,7 +1870,6 @@ class Function(SourceMapping, metaclass=ABCMeta): # pylint: disable=too-many-pu
|
||||
node.irs_ssa = [ir for ir in node.irs_ssa if not self._unchange_phi(ir)]
|
||||
|
||||
def generate_slithir_and_analyze(self) -> None:
|
||||
|
||||
for node in self.nodes:
|
||||
node.slithir_generation()
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Function module
|
||||
Function module
|
||||
"""
|
||||
|
||||
from typing import Dict, TYPE_CHECKING, List, Tuple, Optional
|
||||
|
||||
from slither.core.declarations.contract_level import ContractLevel
|
||||
@@ -8,8 +9,6 @@ from slither.core.declarations import Function
|
||||
from slither.utils.code_complexity import compute_cyclomatic_complexity
|
||||
|
||||
|
||||
# pylint: disable=import-outside-toplevel,too-many-instance-attributes,too-many-statements,too-many-lines
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from slither.core.declarations import Contract
|
||||
from slither.core.scope.scope import FileScope
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Function module
|
||||
Function module
|
||||
"""
|
||||
|
||||
from typing import Dict, List, Tuple, TYPE_CHECKING, Optional
|
||||
|
||||
from slither.core.declarations import Function
|
||||
@@ -97,7 +98,6 @@ class FunctionTopLevel(Function, TopLevel):
|
||||
def generate_slithir_ssa(
|
||||
self, all_ssa_state_variables_instances: Dict[str, "StateIRVariable"]
|
||||
) -> None:
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from slither.slithir.utils.ssa import add_ssa_ir, transform_slithir_vars_to_ssa
|
||||
from slither.core.dominators.utils import (
|
||||
compute_dominance_frontier,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Modifier module
|
||||
Modifier module
|
||||
"""
|
||||
|
||||
from .function_contract import FunctionContract
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user