Merge remote-tracking branch 'origin/master' into pr-2801-update

# Conflicts:
#	tests/e2e/detectors/test_detectors.py
This commit is contained in:
Dan Guido
2026-01-15 15:55:04 -05:00
610 changed files with 6582 additions and 2520 deletions
-25
View File
@@ -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
+55
View File
@@ -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
+12 -12
View File
@@ -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]: "
+20 -20
View File
@@ -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]: "
+21 -21
View File
@@ -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]: "
+21 -21
View File
@@ -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]: "
+1 -1
View File
@@ -14,4 +14,4 @@ body:
label: Describe the desired feature
description: Explain what the feature solves/ improves.
validations:
required: true
required: true
+12 -5
View File
@@ -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: "*"
+2 -1
View File
@@ -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"
+1 -1
View File
@@ -10,4 +10,4 @@ else
status_code=$?
fi
exit "$status_code"
exit "$status_code"
+1 -1
View File
@@ -10,4 +10,4 @@ else
status_code=$?
fi
exit "$status_code"
exit "$status_code"
-55
View File
@@ -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)
-43
View File
@@ -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
View File
@@ -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'
+1 -2
View File
@@ -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
+8 -6
View File
@@ -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/'
+11 -29
View File
@@ -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
+23 -21
View File
@@ -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
-77
View File
@@ -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)
-32
View File
@@ -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
}
]
}
]
}
-22
View File
@@ -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
}
]
}
]
}
+8 -12
View File
@@ -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
+9 -13
View File
@@ -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
-59
View File
@@ -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)
+67
View File
@@ -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
View File
@@ -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
View File
@@ -110,8 +110,8 @@ ENV/
# Test results
test_artifacts/
# crytic export
# crytic export
crytic-export/
# slither.db.json
# slither.db.json
slither.db.json
+63
View File
@@ -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]
+24
View File
@@ -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
View File
@@ -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
+59
View File
@@ -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
View File
@@ -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
View File
@@ -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"]
-15
View File
@@ -1,15 +0,0 @@
{
"Optimism": {
"op-mainnet": {
"ownedBy": "0xc44F30Be3eBBEfdDBB5a85168710b4f0e18f4Ff0"
}
},
"drips": {
"ethereum": {
"ownedBy": "0xc44F30Be3eBBEfdDBB5a85168710b4f0e18f4Ff0"
}
},
"opRetro": {
"projectId": "0xdc3dce33fd5fb50cf932586d4257456ddf5040ba0955d97641646504c73dbd13"
}
}
+8 -10
View File
@@ -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:
+108 -81
View File
@@ -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
View File
@@ -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,
}
```
+1 -21
View File
@@ -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
+3 -3
View File
@@ -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
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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..
```
+6 -1
View File
@@ -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
```
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -6,4 +6,4 @@ contract Example {
function reverts() external pure {
revert RevertIt();
}
}
}
+1 -1
View File
@@ -13,4 +13,4 @@ contract T {
B b = B.a;
return 4;
}
}
}
+1 -1
View File
@@ -20,6 +20,6 @@ contract MyContract is Owner{
function mint(uint value) onlyOwner public{
balances[msg.sender] += value;
}
}
}
+1 -1
View File
@@ -31,4 +31,4 @@ contract ContractB {
function my_second_func_b(){
a.val();
}
}
}
+2 -2
View File
@@ -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"
}
}
+2 -2
View File
@@ -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 -1
View File
@@ -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);
+1 -1
View File
@@ -13,4 +13,4 @@ contract ChildContract2 is BaseContract1, BaseContract2{
}
contract GrandchildContract1 is ChildContract1{
}
}
+1 -1
View File
@@ -18,4 +18,4 @@ contract C is A, B {
function f() public pure returns (uint) {
return 0;
}
}
}
+1 -1
View File
@@ -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> >];
}
}
+1 -1
View File
@@ -123,4 +123,4 @@ contract SimpleModifier {
require(intermediate);
_;
}
}
}
+2 -2
View File
@@ -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{
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -11,7 +11,7 @@ contract Contract{
function call_require() public{
require(a==0);
}
function read_and_write() public{
a = a + 1;
}
+10 -7
View File
@@ -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 .
```
+19
View File
@@ -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"
-15
View File
@@ -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
View File
@@ -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"]
+2
View File
@@ -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
+2 -1
View File
@@ -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
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
### Test data dependency
+1
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
### Test embark integration
+4 -3
View File
@@ -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
+2 -1
View File
@@ -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
+7 -6
View File
@@ -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
+4 -3
View File
@@ -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" != "" ]
+3 -1
View File
@@ -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"
+17 -13
View File
@@ -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
+5 -4
View File
@@ -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
+2 -1
View File
@@ -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
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
### Test printer
+1
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
### Test slither-prop
+9 -4
View File
@@ -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
+4 -2
View File
@@ -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
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
set -eo pipefail
### Test truffle integration
+1
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
### Test slither-check-upgradeability
-1
View File
@@ -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}")
-70
View File
@@ -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
View File
@@ -1,4 +1,5 @@
"""
.. include:: ../README.md
"""
from .slither import Slither
+33 -49
View File
@@ -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 -1
View File
@@ -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()
-2
View File
@@ -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
+2 -2
View File
@@ -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,
+7 -13
View File
@@ -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
-1
View File
@@ -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"]
+16 -5
View File
@@ -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
+1 -1
View File
@@ -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)}
+29 -15
View File
@@ -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
+5 -9
View File
@@ -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,
+2 -1
View File
@@ -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