-
Notifications
You must be signed in to change notification settings - Fork 979
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a41f867
commit fd2fb33
Showing
13 changed files
with
3,076 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
from typing import List | ||
from slither.core.declarations import Function, SolidityVariable | ||
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification | ||
from slither.slithir.operations.high_level_call import HighLevelCall | ||
|
||
|
||
class VarReadUsingThis(AbstractDetector): | ||
ARGUMENT = "var-read-using-this" | ||
HELP = "Contract reads its own variable using `this`" | ||
IMPACT = DetectorClassification.OPTIMIZATION | ||
CONFIDENCE = DetectorClassification.MEDIUM | ||
|
||
WIKI = "https://github.com/trailofbits/slither-private/wiki/Vulnerabilities-Description#var-read-using-this" | ||
|
||
WIKI_TITLE = "Variable read using this" | ||
WIKI_DESCRIPTION = "Contract reads its own variable using `this`, adding overhead of an unnecessary STATICCALL." | ||
WIKI_EXPLOIT_SCENARIO = """ | ||
```solidity | ||
contract C { | ||
mapping(uint => address) public myMap; | ||
function test(uint x) external returns(address) { | ||
return this.myMap(x); | ||
} | ||
} | ||
``` | ||
""" | ||
|
||
WIKI_RECOMMENDATION = "Read the variable directly from storage instead of calling the contract." | ||
|
||
def _detect(self): | ||
results = [] | ||
for c in self.contracts: | ||
for func in c.functions: | ||
for node in self._detect_var_read_using_this(func): | ||
info = [ | ||
"The function ", | ||
func, | ||
" reads ", | ||
node, | ||
" with `this` which adds an extra STATICALL.\n", | ||
] | ||
json = self.generate_result(info) | ||
results.append(json) | ||
|
||
return results | ||
|
||
def _detect_var_read_using_this(self, func: Function) -> List: | ||
results = [] | ||
for node in func.nodes: | ||
for ir in node.irs: | ||
if isinstance(ir, HighLevelCall): | ||
if ir.destination == SolidityVariable("this") and ir.is_static_call(): | ||
results.append(node) | ||
return results |
33 changes: 33 additions & 0 deletions
33
tests/detectors/var-read-using-this/0.4.25/var_read_using_this.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
|
||
contract VarReadUsingThis { | ||
address public erc20; | ||
mapping(uint => address) public myMap; | ||
function bad1(uint x) external returns(address) { | ||
return this.myMap(x); | ||
} | ||
function bad2() external returns(address) { | ||
return this.erc20(); | ||
} | ||
function bad3() external returns(address) { | ||
if (this.erc20() == address(0)) revert(); | ||
} | ||
function bad4() internal returns(address) { | ||
for (uint x; x < 10; x++) { | ||
address local = this.erc20(); | ||
} | ||
} | ||
function good1(uint x) external returns(address) { | ||
return myMap[x]; | ||
} | ||
function good2() external returns(address) { | ||
return erc20; | ||
} | ||
function good3() external returns(address) { | ||
if (erc20 == address(0)) revert(); | ||
} | ||
function good4() internal returns(address) { | ||
for (uint x; x < 10; x++) { | ||
address local = erc20; | ||
} | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
...detectors/var-read-using-this/0.4.25/var_read_using_this.sol.0.4.25.VarReadUsingThis.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[ | ||
[] | ||
] |
33 changes: 33 additions & 0 deletions
33
tests/detectors/var-read-using-this/0.5.16/var_read_using_this.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
|
||
contract VarReadUsingThis { | ||
address public erc20; | ||
mapping(uint => address) public myMap; | ||
function bad1(uint x) external returns(address) { | ||
return this.myMap(x); | ||
} | ||
function bad2() external returns(address) { | ||
return this.erc20(); | ||
} | ||
function bad3() external returns(address) { | ||
if (this.erc20() == address(0)) revert(); | ||
} | ||
function bad4() internal returns(address) { | ||
for (uint x; x < 10; x++) { | ||
address local = this.erc20(); | ||
} | ||
} | ||
function good1(uint x) external returns(address) { | ||
return myMap[x]; | ||
} | ||
function good2() external returns(address) { | ||
return erc20; | ||
} | ||
function good3() external returns(address) { | ||
if (erc20 == address(0)) revert(); | ||
} | ||
function good4() internal returns(address) { | ||
for (uint x; x < 10; x++) { | ||
address local = erc20; | ||
} | ||
} | ||
} |
Oops, something went wrong.