-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #114 from pessimistic-io/add-arb-prevrandao-diffic…
…ulty-detector Arbitrum detectors
- Loading branch information
Showing
14 changed files
with
477 additions
and
3 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Arbitrum block.number/block.timestamp | ||
|
||
## Configuration | ||
|
||
- Check: `pess-arb-solidity-version` | ||
- Severity: `Low` | ||
- Confidence: `High` | ||
|
||
## Description | ||
|
||
`block.number` and `block.timestamp` behave different, than how they behave on Ethereum. For details: [arbitrum docs](https://docs.arbitrum.io/for-devs/concepts/differences-between-arbitrum-ethereum/block-numbers-and-time) | ||
|
||
## Vulnerable Scenario | ||
|
||
[test scenarios](../tests/arbitrum_block_number_timestamp_test.sol) | ||
|
||
## Recommendation | ||
|
||
Verify, that contract's logic does not break because of this difference |
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,15 @@ | ||
# Arbitrum prevRandao/difficulty | ||
|
||
## Configuration | ||
* Check: `pess-arb-prevrandao-difficulty` | ||
* Severity: `Medium` | ||
* Confidence: `High` | ||
|
||
## Description | ||
The detector sees if an Arbitrum contract contains usages of prevRandao/difficulty block context variables or Yul funciton. | ||
|
||
## Vulnerable Scenario | ||
[test scenarios](../tests/arbitrum_prevrandao_difficulty_test.sol) | ||
|
||
## Recommendation | ||
Consider removing usage of prevRandao/difficulty inside Arbitrum contracts as they will constantly return `1` in Arbitrum. |
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,19 @@ | ||
# Arbitrum solidity version | ||
|
||
## Configuration | ||
|
||
- Check: `pess-arb-solidity-version` | ||
- Severity: `High` | ||
- Confidence: `Low` | ||
|
||
## Description | ||
|
||
Checks that sol version >= 0.8.20 is not used inside an Arbitrum contract. Solidity in these versions will utilize PUSH0 opcode, which is not supported on Arbitrum. | ||
|
||
## Vulnerable Scenario | ||
|
||
[test scenarios](../tests/arbitrum_prevrandao_solidity_version_test.sol) | ||
|
||
## Recommendation | ||
|
||
Either, use versions `0.8.19`` and below, or EVM versions below shanghai |
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
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,2 @@ | ||
ARBITRUM_KEY = "SLITHERIN_ARBITRUM" | ||
SLITHERIN_VERSION = "0.5.1" |
81 changes: 81 additions & 0 deletions
81
slitherin/detectors/arbitrum/arbitrum_prevrandao_difficulty.py
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,81 @@ | ||
import os | ||
from typing import List | ||
from slither.utils.output import Output | ||
from slither.core.cfg.node import Node | ||
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification | ||
from slither.core.declarations import Function | ||
from slither.slithir.operations.event_call import EventCall | ||
from slither.analyses.data_dependency.data_dependency import is_dependent | ||
from slither.slithir.operations import SolidityCall | ||
from slither.core.declarations.solidity_variables import ( | ||
SolidityVariableComposed, | ||
SolidityFunction, | ||
) | ||
|
||
from ...consts import ARBITRUM_KEY | ||
|
||
|
||
class ArbitrumPrevrandaoDifficulty(AbstractDetector): | ||
""" | ||
Sees if `prevRandao` or `difficulty` is used inside an Arbitrum contract (as they return constant `1` in Arbitrum) | ||
""" | ||
|
||
ARGUMENT = "pess-arb-prevrandao-difficulty" # slither will launch the detector with slither.py --detect mydetector | ||
HELP = ( | ||
"PrevRandao or difficulty is used in contract that will be deployed to Arbitrum" | ||
) | ||
IMPACT = DetectorClassification.MEDIUM | ||
CONFIDENCE = DetectorClassification.HIGH | ||
|
||
WIKI = "https://github.com/pessimistic-io/slitherin/blob/master/docs/arb_difficulty_randao.md" | ||
WIKI_TITLE = "Usage of prevRandao/difficulty inside the Arbitrum contract" | ||
WIKI_DESCRIPTION = "Arbitrum prevRandao/difficulty" | ||
WIKI_EXPLOIT_SCENARIO = "N/A" | ||
WIKI_RECOMMENDATION = ( | ||
"Do not use prevRandao/difficulty inside the code of an Arbitrum contract" | ||
) | ||
|
||
def _find_randao_or_difficulty(self, f: Function) -> List[Node]: | ||
ret = set() | ||
for node in f.nodes: | ||
for var in node.variables_read: | ||
if is_dependent( | ||
var, SolidityVariableComposed("block.prevrandao"), node | ||
) or is_dependent( | ||
var, SolidityVariableComposed("block.difficulty"), node | ||
): | ||
ret.add(node) | ||
for ir in node.irs: | ||
if ( | ||
isinstance(ir, SolidityCall) | ||
and ir.function == SolidityFunction("prevrandao()") | ||
or isinstance(ir, SolidityCall) | ||
and ir.function == SolidityFunction("difficulty()") | ||
): | ||
ret.add(node) | ||
return list(ret) | ||
|
||
def _detect(self) -> List[Output]: | ||
"""Main function""" | ||
results = [] | ||
|
||
if os.getenv(ARBITRUM_KEY) is None: | ||
return results | ||
|
||
for contract in self.compilation_unit.contracts_derived: | ||
for f in contract.functions_and_modifiers: | ||
nodes = self._find_randao_or_difficulty(f) | ||
if nodes: | ||
info = [ | ||
f, | ||
" function uses prevRandao/difficulty inside the code of the Arbitrum contract\n", | ||
"\tDangerous usages:\n", | ||
] | ||
|
||
nodes.sort(key=lambda x: x.node_id) | ||
|
||
for node in nodes: | ||
info += ["\t- ", node, "\n"] | ||
|
||
results.append(self.generate_result(info)) | ||
return results |
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,81 @@ | ||
import os | ||
from typing import List | ||
from slither.utils.output import Output | ||
from slither.core.cfg.node import Node | ||
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification | ||
from slither.core.declarations import Function | ||
from slither.slithir.operations.event_call import EventCall | ||
from slither.analyses.data_dependency.data_dependency import is_dependent | ||
from slither.slithir.operations import SolidityCall | ||
from slither.core.declarations.solidity_variables import ( | ||
SolidityVariableComposed, | ||
SolidityFunction, | ||
) | ||
|
||
from ...consts import ARBITRUM_KEY | ||
|
||
|
||
class ArbitrumBlockNumberTimestamp(AbstractDetector): | ||
""" | ||
Sees if `block.number` or `block.timtestamp` is used inside an Arbitrum contract | ||
""" | ||
|
||
ARGUMENT = "pess-arb-block-number-timestamp" # slither will launch the detector with slither.py --detect mydetector | ||
HELP = "`block.number` or `block.timtestamp` is used inside an Arbitrum contract" | ||
IMPACT = DetectorClassification.LOW | ||
CONFIDENCE = DetectorClassification.HIGH | ||
|
||
WIKI = "https://github.com/pessimistic-io/slitherin/blob/master/docs/arb_block_number_timestamp.md" | ||
WIKI_TITLE = ( | ||
"Usage of `block.number` or `block.timtestamp` inside the Arbitrum contract" | ||
) | ||
WIKI_DESCRIPTION = "# Arbitrum block.number/block.timestamp" | ||
WIKI_EXPLOIT_SCENARIO = "N/A" | ||
WIKI_RECOMMENDATION = "Look at docs for details" | ||
|
||
def _find_randao_or_difficulty(self, f: Function) -> List[Node]: | ||
ret = set() | ||
for node in f.nodes: | ||
for var in node.variables_read: | ||
if is_dependent( | ||
var, SolidityVariableComposed("block.number"), node | ||
) or is_dependent( | ||
var, SolidityVariableComposed("block.timestamp"), node | ||
): | ||
ret.add(node) | ||
for ir in node.irs: | ||
if ( | ||
isinstance(ir, SolidityCall) | ||
and ir.function == SolidityFunction("number()") | ||
or isinstance(ir, SolidityCall) | ||
and ir.function == SolidityFunction("timestamp()") | ||
): | ||
ret.add(node) | ||
return list(ret) | ||
|
||
def _detect(self) -> List[Output]: | ||
"""Main function""" | ||
results = [] | ||
|
||
if os.getenv(ARBITRUM_KEY) is None: | ||
return results | ||
|
||
for contract in self.compilation_unit.contracts_derived: | ||
for f in contract.functions_and_modifiers: | ||
nodes = self._find_randao_or_difficulty(f) | ||
if nodes: | ||
info = [ | ||
f, | ||
" function uses block.number/block.timestamp inside the code of the Arbitrum contract\n" | ||
"They behave different than on Ethereum, for details: (https://docs.arbitrum.io/for-devs/concepts/differences-between-arbitrum-ethereum/block-numbers-and-time)\n", | ||
"Verify, that contract's logic does not break because of these differences\n" | ||
"\t Usages:\n", | ||
] | ||
|
||
nodes.sort(key=lambda x: x.node_id) | ||
|
||
for node in nodes: | ||
info += ["\t- ", node, "\n"] | ||
|
||
results.append(self.generate_result(info)) | ||
return results |
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,61 @@ | ||
import os | ||
from typing import List | ||
from slither.utils.output import Output | ||
from slither.core.cfg.node import Node | ||
from slither.detectors.abstract_detector import ( | ||
AbstractDetector, | ||
DetectorClassification, | ||
make_solc_versions, | ||
) | ||
from slither.core.declarations import Function | ||
from slither.slithir.operations.event_call import EventCall | ||
from slither.analyses.data_dependency.data_dependency import is_dependent | ||
from slither.slithir.operations import SolidityCall | ||
from slither.core.declarations.solidity_variables import ( | ||
SolidityVariableComposed, | ||
SolidityFunction, | ||
) | ||
|
||
from ...consts import ARBITRUM_KEY | ||
|
||
|
||
class ArbitrumSolidityVersion(AbstractDetector): | ||
""" | ||
Checks that sol version >= 0.8.20 is not used inside an Arbitrum contract | ||
""" | ||
|
||
ARGUMENT = "pess-arb-solidity-version" # slither will launch the detector with slither.py --detect mydetector | ||
HELP = "sol version >= 0.8.20 is used in contract that will be deployed to Arbitrum (Potential usage of PUSH0, which is not supported)" | ||
IMPACT = DetectorClassification.HIGH | ||
CONFIDENCE = DetectorClassification.LOW | ||
|
||
WIKI = "https://github.com/pessimistic-io/slitherin/blob/master/docs/arb_difficulty_randao.md" | ||
WIKI_TITLE = "Arbitrum solidity version" | ||
WIKI_DESCRIPTION = "Potential usage of PUSH0 opcode" | ||
WIKI_EXPLOIT_SCENARIO = "N/A" | ||
WIKI_RECOMMENDATION = ( | ||
"Either, use versions 0.8.19 and below, or EVM versions below shanghai" | ||
) | ||
|
||
def _detect(self) -> List[Output]: | ||
"""Main function""" | ||
results = [] | ||
|
||
if os.getenv(ARBITRUM_KEY) is None: | ||
return results | ||
|
||
if ( | ||
self.compilation_unit.is_solidity | ||
and self.compilation_unit.solc_version in make_solc_versions(8, 20, 99) | ||
): | ||
results.append( | ||
self.generate_result( | ||
[ | ||
"Potential usage of solidity version >= 0.8.20 detected. Solidity in these versions will utilize PUSH0 opcode, ", | ||
"which is not supported on Arbitrum. ", | ||
"Either, use versions 0.8.19 and below, or EVM versions below shanghai", | ||
] | ||
) | ||
) | ||
|
||
return results |
Oops, something went wrong.