mirror of https://github.com/crytic/slither
parent
16bff0efa8
commit
63b553fcba
@ -0,0 +1,90 @@ |
||||
from slither.core.cfg.node import NodeType |
||||
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||
from slither.slithir.operations import LowLevelCall |
||||
|
||||
|
||||
def detect_delegatecall_in_loop(contract): |
||||
results = [] |
||||
for f in contract.functions + contract.modifiers: |
||||
if f.is_implemented and f.payable: |
||||
delegatecall_in_loop(f.entry_point, False, [], results) |
||||
return results |
||||
|
||||
|
||||
def delegatecall_in_loop(node, in_loop, visited, results): |
||||
if node in visited: |
||||
return |
||||
# shared visited |
||||
visited.append(node) |
||||
|
||||
if node.type == NodeType.STARTLOOP: |
||||
in_loop = True |
||||
elif node.type == NodeType.ENDLOOP: |
||||
in_loop = False |
||||
|
||||
if in_loop: |
||||
for ir in node.all_slithir_operations(): |
||||
if isinstance(ir, (LowLevelCall)) and ir.function_name == "delegatecall": |
||||
results.append(node) |
||||
|
||||
for son in node.sons: |
||||
delegatecall_in_loop(son, in_loop, visited, results) |
||||
|
||||
|
||||
class DelegatecallInLoop(AbstractDetector): |
||||
""" |
||||
Detect the use of delegatecall inside a loop in a payable function |
||||
""" |
||||
|
||||
ARGUMENT = "delegatecall-loop" |
||||
HELP = "Payable functions using `delegatecall` inside a loop" |
||||
IMPACT = DetectorClassification.HIGH |
||||
CONFIDENCE = DetectorClassification.MEDIUM |
||||
|
||||
WIKI = "https://github.com/crytic/slither/wiki/Detector-Documentation/#payable-functions-using-delegatecall-inside-a-loop" |
||||
|
||||
WIKI_TITLE = "Payable functions using `delegatecall` inside a loop" |
||||
WIKI_DESCRIPTION = """ |
||||
Detect the use of `delegatecall` inside a loop in a payable function. |
||||
It's dangerous because `delegatecall` forward the `msg.value` in case the function called is payable. |
||||
""" |
||||
|
||||
# region wiki_exploit_scenario |
||||
WIKI_EXPLOIT_SCENARIO = """ |
||||
```solidity |
||||
contract DelegatecallInLoop{ |
||||
|
||||
mapping (address => uint256) balances; |
||||
|
||||
function bad(address[] memory receivers) public payable { |
||||
for (uint256 i = 0; i < receivers.length; i++) { |
||||
address(this).delegatecall(abi.encodeWithSignature("addBalance(address)", receivers[i])); |
||||
} |
||||
} |
||||
|
||||
function addBalance(address a) public payable { |
||||
balances[a] += msg.value; |
||||
} |
||||
|
||||
} |
||||
``` |
||||
When calling `bad` the same `msg.value` amount will be accredited multiple times.""" |
||||
# endregion wiki_exploit_scenario |
||||
|
||||
WIKI_RECOMMENDATION = """ |
||||
Don't use `delegatecall` inside a loop in a payable function or carefully check that the function called by `delegatecall` is not payable/doesn't use `msg.value`. |
||||
""" |
||||
|
||||
def _detect(self): |
||||
"""""" |
||||
results = [] |
||||
for c in self.compilation_unit.contracts_derived: |
||||
values = detect_delegatecall_in_loop(c) |
||||
for node in values: |
||||
func = node.function |
||||
|
||||
info = [func, " has delegatecall inside a loop in a payable function: ", node, "\n"] |
||||
res = self.generate_result(info) |
||||
results.append(res) |
||||
|
||||
return results |
@ -0,0 +1,15 @@ |
||||
contract C{ |
||||
|
||||
mapping (address => uint256) balances; |
||||
|
||||
function bad(address[] memory receivers) public payable { |
||||
for (uint256 i = 0; i < receivers.length; i++) { |
||||
address(this).delegatecall(abi.encodeWithSignature("addBalance(address)", receivers[i])); |
||||
} |
||||
} |
||||
|
||||
function addBalance(address a) public payable { |
||||
balances[a] += msg.value; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,151 @@ |
||||
[ |
||||
[ |
||||
{ |
||||
"elements": [ |
||||
{ |
||||
"type": "function", |
||||
"name": "bad", |
||||
"source_mapping": { |
||||
"start": 61, |
||||
"length": 232, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9 |
||||
], |
||||
"starting_column": 5, |
||||
"ending_column": 6 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "contract", |
||||
"name": "C", |
||||
"source_mapping": { |
||||
"start": 0, |
||||
"length": 388, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
1, |
||||
2, |
||||
3, |
||||
4, |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9, |
||||
10, |
||||
11, |
||||
12, |
||||
13, |
||||
14, |
||||
15, |
||||
16 |
||||
], |
||||
"starting_column": 1, |
||||
"ending_column": 0 |
||||
} |
||||
}, |
||||
"signature": "bad(address[])" |
||||
} |
||||
}, |
||||
{ |
||||
"type": "node", |
||||
"name": "address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i]))", |
||||
"source_mapping": { |
||||
"start": 188, |
||||
"length": 88, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
7 |
||||
], |
||||
"starting_column": 13, |
||||
"ending_column": 101 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "function", |
||||
"name": "bad", |
||||
"source_mapping": { |
||||
"start": 61, |
||||
"length": 232, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9 |
||||
], |
||||
"starting_column": 5, |
||||
"ending_column": 6 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "contract", |
||||
"name": "C", |
||||
"source_mapping": { |
||||
"start": 0, |
||||
"length": 388, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
1, |
||||
2, |
||||
3, |
||||
4, |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9, |
||||
10, |
||||
11, |
||||
12, |
||||
13, |
||||
14, |
||||
15, |
||||
16 |
||||
], |
||||
"starting_column": 1, |
||||
"ending_column": 0 |
||||
} |
||||
}, |
||||
"signature": "bad(address[])" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
], |
||||
"description": "C.bad(address[]) (tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol#5-9) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol#7)\n", |
||||
"markdown": "[C.bad(address[])](tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol#L5-L9) has delegatecall inside a loop in a payable function: [address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i]))](tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol#L7)\n", |
||||
"first_markdown_element": "tests/detectors/delegatecall-loop/0.4.25/delegatecall_loop.sol#L5-L9", |
||||
"id": "e057dff3814f9be2d5eca53fe80f41323b8ed90d20bb1e33600bb4e043c40b66", |
||||
"check": "delegatecall-loop", |
||||
"impact": "High", |
||||
"confidence": "High" |
||||
} |
||||
] |
||||
] |
@ -0,0 +1,15 @@ |
||||
contract C{ |
||||
|
||||
mapping (address => uint256) balances; |
||||
|
||||
function bad(address[] memory receivers) public payable { |
||||
for (uint256 i = 0; i < receivers.length; i++) { |
||||
address(this).delegatecall(abi.encodeWithSignature("addBalance(address)", receivers[i])); |
||||
} |
||||
} |
||||
|
||||
function addBalance(address a) public payable { |
||||
balances[a] += msg.value; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,151 @@ |
||||
[ |
||||
[ |
||||
{ |
||||
"elements": [ |
||||
{ |
||||
"type": "function", |
||||
"name": "bad", |
||||
"source_mapping": { |
||||
"start": 61, |
||||
"length": 232, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9 |
||||
], |
||||
"starting_column": 5, |
||||
"ending_column": 6 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "contract", |
||||
"name": "C", |
||||
"source_mapping": { |
||||
"start": 0, |
||||
"length": 388, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
1, |
||||
2, |
||||
3, |
||||
4, |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9, |
||||
10, |
||||
11, |
||||
12, |
||||
13, |
||||
14, |
||||
15, |
||||
16 |
||||
], |
||||
"starting_column": 1, |
||||
"ending_column": 0 |
||||
} |
||||
}, |
||||
"signature": "bad(address[])" |
||||
} |
||||
}, |
||||
{ |
||||
"type": "node", |
||||
"name": "address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i]))", |
||||
"source_mapping": { |
||||
"start": 188, |
||||
"length": 88, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
7 |
||||
], |
||||
"starting_column": 13, |
||||
"ending_column": 101 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "function", |
||||
"name": "bad", |
||||
"source_mapping": { |
||||
"start": 61, |
||||
"length": 232, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9 |
||||
], |
||||
"starting_column": 5, |
||||
"ending_column": 6 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "contract", |
||||
"name": "C", |
||||
"source_mapping": { |
||||
"start": 0, |
||||
"length": 388, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
1, |
||||
2, |
||||
3, |
||||
4, |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9, |
||||
10, |
||||
11, |
||||
12, |
||||
13, |
||||
14, |
||||
15, |
||||
16 |
||||
], |
||||
"starting_column": 1, |
||||
"ending_column": 0 |
||||
} |
||||
}, |
||||
"signature": "bad(address[])" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
], |
||||
"description": "C.bad(address[]) (tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol#5-9) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol#7)\n", |
||||
"markdown": "[C.bad(address[])](tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol#L5-L9) has delegatecall inside a loop in a payable function: [address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i]))](tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol#L7)\n", |
||||
"first_markdown_element": "tests/detectors/delegatecall-loop/0.5.16/delegatecall_loop.sol#L5-L9", |
||||
"id": "71bad0e6228b341671dd1cc38d74fb727f9bbc5764104298596986d8f4967c02", |
||||
"check": "delegatecall-loop", |
||||
"impact": "High", |
||||
"confidence": "High" |
||||
} |
||||
] |
||||
] |
@ -0,0 +1,15 @@ |
||||
contract C{ |
||||
|
||||
mapping (address => uint256) balances; |
||||
|
||||
function bad(address[] memory receivers) public payable { |
||||
for (uint256 i = 0; i < receivers.length; i++) { |
||||
address(this).delegatecall(abi.encodeWithSignature("addBalance(address)", receivers[i])); |
||||
} |
||||
} |
||||
|
||||
function addBalance(address a) public payable { |
||||
balances[a] += msg.value; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,151 @@ |
||||
[ |
||||
[ |
||||
{ |
||||
"elements": [ |
||||
{ |
||||
"type": "function", |
||||
"name": "bad", |
||||
"source_mapping": { |
||||
"start": 61, |
||||
"length": 232, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9 |
||||
], |
||||
"starting_column": 5, |
||||
"ending_column": 6 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "contract", |
||||
"name": "C", |
||||
"source_mapping": { |
||||
"start": 0, |
||||
"length": 388, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
1, |
||||
2, |
||||
3, |
||||
4, |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9, |
||||
10, |
||||
11, |
||||
12, |
||||
13, |
||||
14, |
||||
15, |
||||
16 |
||||
], |
||||
"starting_column": 1, |
||||
"ending_column": 0 |
||||
} |
||||
}, |
||||
"signature": "bad(address[])" |
||||
} |
||||
}, |
||||
{ |
||||
"type": "node", |
||||
"name": "address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i]))", |
||||
"source_mapping": { |
||||
"start": 188, |
||||
"length": 88, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
7 |
||||
], |
||||
"starting_column": 13, |
||||
"ending_column": 101 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "function", |
||||
"name": "bad", |
||||
"source_mapping": { |
||||
"start": 61, |
||||
"length": 232, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9 |
||||
], |
||||
"starting_column": 5, |
||||
"ending_column": 6 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "contract", |
||||
"name": "C", |
||||
"source_mapping": { |
||||
"start": 0, |
||||
"length": 388, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
1, |
||||
2, |
||||
3, |
||||
4, |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9, |
||||
10, |
||||
11, |
||||
12, |
||||
13, |
||||
14, |
||||
15, |
||||
16 |
||||
], |
||||
"starting_column": 1, |
||||
"ending_column": 0 |
||||
} |
||||
}, |
||||
"signature": "bad(address[])" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
], |
||||
"description": "C.bad(address[]) (tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol#5-9) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol#7)\n", |
||||
"markdown": "[C.bad(address[])](tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol#L5-L9) has delegatecall inside a loop in a payable function: [address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i]))](tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol#L7)\n", |
||||
"first_markdown_element": "tests/detectors/delegatecall-loop/0.6.11/delegatecall_loop.sol#L5-L9", |
||||
"id": "dfa0a166dfe43235e3fbeab4eadd8b0c7c612cd2fefe3cf281d909129b3b824e", |
||||
"check": "delegatecall-loop", |
||||
"impact": "High", |
||||
"confidence": "High" |
||||
} |
||||
] |
||||
] |
@ -0,0 +1,15 @@ |
||||
contract C{ |
||||
|
||||
mapping (address => uint256) balances; |
||||
|
||||
function bad(address[] memory receivers) public payable { |
||||
for (uint256 i = 0; i < receivers.length; i++) { |
||||
address(this).delegatecall(abi.encodeWithSignature("addBalance(address)", receivers[i])); |
||||
} |
||||
} |
||||
|
||||
function addBalance(address a) public payable { |
||||
balances[a] += msg.value; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,151 @@ |
||||
[ |
||||
[ |
||||
{ |
||||
"elements": [ |
||||
{ |
||||
"type": "function", |
||||
"name": "bad", |
||||
"source_mapping": { |
||||
"start": 61, |
||||
"length": 232, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9 |
||||
], |
||||
"starting_column": 5, |
||||
"ending_column": 6 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "contract", |
||||
"name": "C", |
||||
"source_mapping": { |
||||
"start": 0, |
||||
"length": 388, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
1, |
||||
2, |
||||
3, |
||||
4, |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9, |
||||
10, |
||||
11, |
||||
12, |
||||
13, |
||||
14, |
||||
15, |
||||
16 |
||||
], |
||||
"starting_column": 1, |
||||
"ending_column": 0 |
||||
} |
||||
}, |
||||
"signature": "bad(address[])" |
||||
} |
||||
}, |
||||
{ |
||||
"type": "node", |
||||
"name": "address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i]))", |
||||
"source_mapping": { |
||||
"start": 188, |
||||
"length": 88, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
7 |
||||
], |
||||
"starting_column": 13, |
||||
"ending_column": 101 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "function", |
||||
"name": "bad", |
||||
"source_mapping": { |
||||
"start": 61, |
||||
"length": 232, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9 |
||||
], |
||||
"starting_column": 5, |
||||
"ending_column": 6 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "contract", |
||||
"name": "C", |
||||
"source_mapping": { |
||||
"start": 0, |
||||
"length": 388, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
1, |
||||
2, |
||||
3, |
||||
4, |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9, |
||||
10, |
||||
11, |
||||
12, |
||||
13, |
||||
14, |
||||
15, |
||||
16 |
||||
], |
||||
"starting_column": 1, |
||||
"ending_column": 0 |
||||
} |
||||
}, |
||||
"signature": "bad(address[])" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
], |
||||
"description": "C.bad(address[]) (tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol#5-9) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol#7)\n", |
||||
"markdown": "[C.bad(address[])](tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol#L5-L9) has delegatecall inside a loop in a payable function: [address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i]))](tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol#L7)\n", |
||||
"first_markdown_element": "tests/detectors/delegatecall-loop/0.7.6/delegatecall_loop.sol#L5-L9", |
||||
"id": "33dd934c565095b28b362765c0c885287aaf87741cf31dae44457268f831b7a4", |
||||
"check": "delegatecall-loop", |
||||
"impact": "High", |
||||
"confidence": "High" |
||||
} |
||||
] |
||||
] |
@ -0,0 +1,15 @@ |
||||
contract C{ |
||||
|
||||
mapping (address => uint256) balances; |
||||
|
||||
function bad(address[] memory receivers) public payable { |
||||
for (uint256 i = 0; i < receivers.length; i++) { |
||||
address(this).delegatecall(abi.encodeWithSignature("addBalance(address)", receivers[i])); |
||||
} |
||||
} |
||||
|
||||
function addBalance(address a) public payable { |
||||
balances[a] += msg.value; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,151 @@ |
||||
[ |
||||
[ |
||||
{ |
||||
"elements": [ |
||||
{ |
||||
"type": "function", |
||||
"name": "bad", |
||||
"source_mapping": { |
||||
"start": 61, |
||||
"length": 232, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9 |
||||
], |
||||
"starting_column": 5, |
||||
"ending_column": 6 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "contract", |
||||
"name": "C", |
||||
"source_mapping": { |
||||
"start": 0, |
||||
"length": 388, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
1, |
||||
2, |
||||
3, |
||||
4, |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9, |
||||
10, |
||||
11, |
||||
12, |
||||
13, |
||||
14, |
||||
15, |
||||
16 |
||||
], |
||||
"starting_column": 1, |
||||
"ending_column": 0 |
||||
} |
||||
}, |
||||
"signature": "bad(address[])" |
||||
} |
||||
}, |
||||
{ |
||||
"type": "node", |
||||
"name": "address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i]))", |
||||
"source_mapping": { |
||||
"start": 188, |
||||
"length": 88, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
7 |
||||
], |
||||
"starting_column": 13, |
||||
"ending_column": 101 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "function", |
||||
"name": "bad", |
||||
"source_mapping": { |
||||
"start": 61, |
||||
"length": 232, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9 |
||||
], |
||||
"starting_column": 5, |
||||
"ending_column": 6 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "contract", |
||||
"name": "C", |
||||
"source_mapping": { |
||||
"start": 0, |
||||
"length": 388, |
||||
"filename_used": "/GENERIC_PATH", |
||||
"filename_relative": "tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
1, |
||||
2, |
||||
3, |
||||
4, |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9, |
||||
10, |
||||
11, |
||||
12, |
||||
13, |
||||
14, |
||||
15, |
||||
16 |
||||
], |
||||
"starting_column": 1, |
||||
"ending_column": 0 |
||||
} |
||||
}, |
||||
"signature": "bad(address[])" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
], |
||||
"description": "C.bad(address[]) (tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol#5-9) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i])) (tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol#7)\n", |
||||
"markdown": "[C.bad(address[])](tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol#L5-L9) has delegatecall inside a loop in a payable function: [address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i]))](tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol#L7)\n", |
||||
"first_markdown_element": "tests/detectors/delegatecall-loop/0.8.0/delegatecall_loop.sol#L5-L9", |
||||
"id": "b810117268c82cb0e2ba1fce4549cef820197f59c877fd5f0701661a0f7bbf47", |
||||
"check": "delegatecall-loop", |
||||
"impact": "High", |
||||
"confidence": "High" |
||||
} |
||||
] |
||||
] |
Loading…
Reference in new issue