diff --git a/README.md b/README.md index 5c35967..9d756c3 100644 --- a/README.md +++ b/README.md @@ -130,3 +130,4 @@ use-prefix-increment-not-postfix | The prefix increment expression is cheaper in use-short-revert-string | Shortening revert strings to fit in 32 bytes will decrease gas costs for deployment and gas costs when the revert condition has been met. non-payable-constructor | Consider making costructor payable to save gas. non-optimal-variables-swap | Consider swapping variables using `($VAR1, $VAR2) = ($VAR2, $VAR1)` to save gas. +state-variable-can-be-set-to-immutable | Consider making variable constant or immutable to save gas. diff --git a/solidity/performance/state-variable-can-be-set-to-immutable.sol b/solidity/performance/state-variable-can-be-set-to-immutable.sol new file mode 100644 index 0000000..6e2045d --- /dev/null +++ b/solidity/performance/state-variable-can-be-set-to-immutable.sol @@ -0,0 +1,126 @@ +pragma solidity >=0.7.4; + + + +contract T1{ + //ruleid: state-variable-can-be-set-to-immutable + uint v1 = 1; + + function test() public{ + return true; + } +} + +contract T2{ + //ok: state-variable-can-be-set-to-immutable + uint v1 = 1; + + function test() public{ + v1 = v1 + 1; + } +} + +contract T3{ + //ok: state-variable-can-be-set-to-immutable + uint v1 = 1; + + function test() public{ + v1 += 1; + } +} + +contract T4{ + //ok: state-variable-can-be-set-to-immutable + uint v1 = 1; + + function test() public{ + v1 -= 1; + } +} + +contract T5{ + //ok: state-variable-can-be-set-to-immutable + uint v1 = 1; + + function test() public{ + v1 /= 1; + } +} + +contract T6{ + //ok: state-variable-can-be-set-to-immutable + uint v1 = 1; + + function test() public{ + v1 *= 1; + } +} + +contract T7{ + //ok: state-variable-can-be-set-to-immutable + uint v1 = 1; + + function test() public{ + v1++; + } +} + +contract T8{ + //ok: state-variable-can-be-set-to-immutable + uint v1 = 1; + + function test() public{ + v1--; + } +} + +contract T9{ + //ok: state-variable-can-be-set-to-immutable + uint v1 = 1; + + constructor(){ + v1--; + } +} + + +contract T10{ + //ok: state-variable-can-be-set-to-immutable + uint public immutable v1 = 1; +} + +contract T11{ + //ok: state-variable-can-be-set-to-immutable + uint immutable v1 = 1; +} + +contract T12{ + //ok: state-variable-can-be-set-to-immutable + uint constant v1 = 1; +} + + + +// semgrep can't catch it correctly now + + +// contract T13{ +// //ok: state-variable-can-be-set-to-immutable +// uint v1 = 1; +// } + +// contract T13Child is T12{ +// function test() public{ +// v1 = 2; +// } +// } + + + +contract T14{ + //ok: state-variable-can-be-set-to-immutable + uint v1 = 5; + function kek() { + v1%=10; + } +} \ No newline at end of file diff --git a/solidity/performance/state-variable-can-be-set-to-immutable.yaml b/solidity/performance/state-variable-can-be-set-to-immutable.yaml new file mode 100644 index 0000000..7f29874 --- /dev/null +++ b/solidity/performance/state-variable-can-be-set-to-immutable.yaml @@ -0,0 +1,123 @@ +rules: + - id: state-variable-can-be-set-to-immutable + metadata: + references: + - https://twitter.com/0xAsm0d3us/status/1518960501983936512 + category: performance + tags: + - variable + message: Consider making variable $VARIABLE constant or immutable to save gas. + languages: + - solidity + severity: INFO + patterns: + - pattern: | + $TYPE $VARIABLE = $VALUE; + - pattern-inside: | + contract $CONTRACT{ + ... + $TYPE $VARIABLE = $VALUE; + ... + } + - pattern-not-inside: | + contract $CONTRACT{ + ... + $TYPE immutable $VARIABLE = $VALUE; + ... + } + - pattern-not-inside: | + contract $CONTRACT{ + ... + $TYPE constant $VARIABLE = $VALUE; + ... + } + - pattern-not-inside: | + contract $CONTRACT{ + ... + function $FUNC(...){ + ... + $VARIABLE = $NEWVALUE; + ... + } + } + - pattern-not-inside: | + contract $CONTRACT{ + ... + function $FUNC(...){ + ... + $VARIABLE += $NEWVALUE; + ... + } + } + - pattern-not-inside: | + contract $CONTRACT{ + ... + function $FUNC(...){ + ... + $VARIABLE -= $NEWVALUE; + ... + } + } + - pattern-not-inside: | + contract $CONTRACT{ + ... + function $FUNC(...){ + ... + $VARIABLE *= $NEWVALUE; + ... + } + } + - pattern-not-inside: | + contract $CONTRACT{ + ... + function $FUNC(...){ + ... + $VARIABLE /= $NEWVALUE; + ... + } + } + - pattern-not-inside: | + contract $CONTRACT{ + ... + function $FUNC(...){ + ... + $VARIABLE %= $NEWVALUE; + ... + } + } + - pattern-not-inside: | + contract $CONTRACT{ + ... + function $FUNC(...){ + ... + $VARIABLE++; + ... + } + } + - pattern-not-inside: | + contract $CONTRACT{ + ... + function $FUNC(...){ + ... + ++$VARIABLE; + ... + } + } + - pattern-not-inside: | + contract $CONTRACT{ + ... + function $FUNC(...){ + ... + --$VARIABLE; + ... + } + } + - pattern-not-inside: | + contract $CONTRACT{ + ... + function $FUNC(...){ + ... + $VARIABLE--; + ... + } + }