Skip to content

fix: accept onlyDelegateCall as protected modifier in unprotected-upgrade#3014

Open
cats2101 wants to merge 1 commit intocrytic:masterfrom
cats2101:fix/upgradeable-only-delegatecall
Open

fix: accept onlyDelegateCall as protected modifier in unprotected-upgrade#3014
cats2101 wants to merge 1 commit intocrytic:masterfrom
cats2101:fix/upgradeable-only-delegatecall

Conversation

@cats2101
Copy link
Copy Markdown

Summary

The unprotected-upgrade detector currently whitelists onlyProxy initializers because that modifier prevents calling the implementation contract directly (the call must go through delegatecall via the proxy). The same protection is commonly expressed by a custom onlyDelegateCall modifier, particularly in minimal-proxy (ERC-1167) templates and other non-UUPS upgradeability patterns.

This PR extends the whitelist to also accept onlyDelegateCall, which is the fix the maintainer suggested in #1136 (comment).

Changes

  • slither/detectors/statements/unprotected_upgradeable.py: extract the whitelist into _WHITELISTED_MODIFIERS = {"onlyProxy", "onlyDelegateCall"} and rewrite _whitelisted_modifiers against it.
  • E2E fixtures for whitelisted.sol across solc 0.4.25 / 0.5.16 / 0.6.11 / 0.7.6 / 0.8.15 now include a second WhitelistedDelegateCall contract using onlyDelegateCall. The OnlyDelegateCall helper contract is added alongside the existing OnlyProxy one. Snapshot stays empty (no findings).

Test plan

  • pytest tests/e2e/detectors/test_detectors.py -k UnprotectedUpgradeable — all 25 cases pass with the fix.
  • Verified the new fixture catches a regression by reverting the detector change and re-running: the test correctly fails reporting WhitelistedDelegateCall.initialize() as unprotected.
  • ruff check / ruff format --check clean on the touched file.

Closes #1136

…rade

The unprotected-upgrade detector whitelists `onlyProxy` initializers
because the modifier prevents calling the implementation contract
directly. `onlyDelegateCall` is a common community-defined synonym
that provides the same protection (e.g. minimal-proxy / ERC-1167
templates) and was reported as a false positive in crytic#1136.

Add `onlyDelegateCall` to the modifier whitelist alongside
`onlyProxy` and extend the existing whitelisted.sol e2e fixtures
across all solc versions to cover it.

Closes crytic#1136
@cats2101 cats2101 requested a review from smonicas as a code owner April 28, 2026 00:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Slither claims an upgradeTo function is exposed when it (likely?) is not

1 participant