Skip to content

fix: fold parenthesized type(X).max/min in IR generation - #3081

Open
innbuld wants to merge 1 commit into
crytic:masterfrom
innbuld:fix/type-minmax-parenthesized
Open

fix: fold parenthesized type(X).max/min in IR generation#3081
innbuld wants to merge 1 commit into
crytic:masterfrom
innbuld:fix/type-minmax-parenthesized

Conversation

@innbuld

@innbuld innbuld commented Aug 13, 2026

Copy link
Copy Markdown

Summary

(type(uint8)).max (redundant parentheses around type(X)) fails IR generation, while the non-parenthesized type(uint8).max works fine:

$ slither A.sol
Failed to generate IR for Test.test ...
slither.slithir.exceptions.SlithIRError: type(uint8).max is unknown

Root cause

type(X).max/.min is folded to a constant in ExpressionToSlithIR._post_member_access, but the check required the accessed sub-expression to be a bare CallExpression. Parentheses wrap the type() call in a single-element TupleExpression, so the fold is skipped. The member access then falls through to convert.py's _convert_type_contract (which only handles creationCode/runtimeCode/interfaceId/name) and raises type(X).max is unknown.

Fix

Unwrap redundant single-element parentheses before the type(X).max/.min check. (type(X)).max, ((type(X))).min, etc. now fold to the correct constant like the non-parenthesized form (elementary signed and unsigned types covered).

Testing

  • New unit test tests/unit/slithir/test_type_minmax.py asserts the folded constants for uint8/uint256/int256, parenthesized and nested, plus the plain form as a regression guard. It fails before the fix (type(uint8).max is unknown) and passes after.
  • Existing tests/unit/slithir and solc_parsing minmax tests pass.

Fixes #2645

`(type(uint8)).max` is parsed with the `type()` call wrapped in a
single-element TupleExpression, so the `type(X).max`/`.min` folding in
`_post_member_access` (which checked for a bare CallExpression) was
skipped. The member access then reached `convert.py` and raised
"type(uint8).max is unknown", failing IR generation for the function.

Unwrap redundant single-element parentheses before the check so
`(type(X)).max`, `((type(X))).min`, etc. fold to the correct constant,
exactly like the non-parenthesized form.

Adds a unit test asserting the folded constants for uint8/uint256/int256,
parenthesized and nested, plus the plain form as a regression guard.

Fixes crytic#2645
@innbuld
innbuld requested a review from smonicas as a code owner August 13, 2026 10:27
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.

[Bug-Candidate]: slither fails to recognize built-in functions like type(uint8).max

1 participant