Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect when ether is sent in Yul #1909

Merged
merged 5 commits into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions slither/detectors/attributes/locked_ether.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""
from typing import List

from slither.core.declarations.contract import Contract
from slither.core.declarations import Contract, SolidityFunction
from slither.detectors.abstract_detector import (
AbstractDetector,
DetectorClassification,
Expand All @@ -17,7 +17,9 @@
NewContract,
LibraryCall,
InternalCall,
SolidityCall,
)
from slither.slithir.variables import Constant
from slither.utils.output import Output


Expand Down Expand Up @@ -68,8 +70,28 @@ def do_no_send_ether(contract: Contract) -> bool:
):
if ir.call_value and ir.call_value != 0:
return False
if isinstance(ir, (LowLevelCall)):
if ir.function_name in ["delegatecall", "callcode"]:
if isinstance(ir, (LowLevelCall)) and ir.function_name in [
"delegatecall",
"callcode",
]:
return False
if isinstance(ir, SolidityCall):
call_can_send_ether = ir.function in [
SolidityFunction(
"delegatecall(uint256,uint256,uint256,uint256,uint256,uint256)"
),
SolidityFunction(
"callcode(uint256,uint256,uint256,uint256,uint256,uint256,uint256)"
),
SolidityFunction(
"call(uint256,uint256,uint256,uint256,uint256,uint256,uint256)"
),
]
nonzero_call_value = call_can_send_ether and (
not isinstance(ir.arguments[2], Constant)
or ir.arguments[2].value != 0
)
0xalpharush marked this conversation as resolved.
Show resolved Hide resolved
if nonzero_call_value:
return False
# If a new internal call or librarycall
# Add it to the list to explore
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
Contract locking ether found:
Contract OnlyLocked (tests/e2e/detectors/test_data/locked-ether/0.4.25/locked_ether.sol#26) has payable functions:
Contract OnlyLocked (tests/e2e/detectors/test_data/locked-ether/0.4.25/locked_ether.sol#37) has payable functions:
- Locked.receive() (tests/e2e/detectors/test_data/locked-ether/0.4.25/locked_ether.sol#4-6)
But does not have a function to withdraw the ether

Contract locking ether found:
Contract UnlockedAssembly (tests/e2e/detectors/test_data/locked-ether/0.4.25/locked_ether.sol#27-35) has payable functions:
- Locked.receive() (tests/e2e/detectors/test_data/locked-ether/0.4.25/locked_ether.sol#4-6)
But does not have a function to withdraw the ether

Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
Contract locking ether found:
Contract OnlyLocked (tests/e2e/detectors/test_data/locked-ether/0.5.16/locked_ether.sol#26) has payable functions:
Contract OnlyLocked (tests/e2e/detectors/test_data/locked-ether/0.5.16/locked_ether.sol#37) has payable functions:
- Locked.receive() (tests/e2e/detectors/test_data/locked-ether/0.5.16/locked_ether.sol#4-6)
But does not have a function to withdraw the ether

Contract locking ether found:
Contract UnlockedAssembly (tests/e2e/detectors/test_data/locked-ether/0.5.16/locked_ether.sol#27-35) has payable functions:
- Locked.receive() (tests/e2e/detectors/test_data/locked-ether/0.5.16/locked_ether.sol#4-6)
But does not have a function to withdraw the ether

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Contract locking ether found:
Contract OnlyLocked (tests/e2e/detectors/test_data/locked-ether/0.6.11/locked_ether.sol#26) has payable functions:
Contract OnlyLocked (tests/e2e/detectors/test_data/locked-ether/0.6.11/locked_ether.sol#36) has payable functions:
- Locked.receive_eth() (tests/e2e/detectors/test_data/locked-ether/0.6.11/locked_ether.sol#4-6)
But does not have a function to withdraw the ether

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Contract locking ether found:
Contract OnlyLocked (tests/e2e/detectors/test_data/locked-ether/0.7.6/locked_ether.sol#26) has payable functions:
Contract OnlyLocked (tests/e2e/detectors/test_data/locked-ether/0.7.6/locked_ether.sol#36) has payable functions:
- Locked.receive_eth() (tests/e2e/detectors/test_data/locked-ether/0.7.6/locked_ether.sol#4-6)
But does not have a function to withdraw the ether

Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,15 @@ contract Unlocked is Locked, Send{

}

// Still reported because solidity < 0.6.0 doesn't have assembly in the AST
contract UnlockedAssembly is Locked{

function withdraw() public {
assembly {
let success := call(gas(), caller(),100,0,0,0,0)
}
}

}

contract OnlyLocked is Locked{ }
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,15 @@ contract Unlocked is Locked, Send{

}

// Still reported because solidity < 0.6.0 doesn't have assembly in the AST
contract UnlockedAssembly is Locked{

function withdraw() public {
assembly {
let success := call(gas(), caller(),100,0,0,0,0)
}
}

}

contract OnlyLocked is Locked{ }
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,14 @@ contract Unlocked is Locked, Send{

}

contract UnlockedAssembly is Locked{

function withdraw() public {
assembly {
let success := call(gas(), caller(),100,0,0,0,0)
}
}

}

contract OnlyLocked is Locked{ }
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,14 @@ contract Unlocked is Locked, Send{

}

contract UnlockedAssembly is Locked{

function withdraw() public {
assembly {
let success := call(gas(), caller(),100,0,0,0,0)
}
}

}

contract OnlyLocked is Locked{ }
Binary file not shown.