diff --git a/tests/test_function.py b/tests/test_function.py new file mode 100644 index 000000000..37df7380a --- /dev/null +++ b/tests/test_function.py @@ -0,0 +1,83 @@ +from slither import Slither +from slither.core.declarations.function import FunctionType +from slither.core.solidity_types.elementary_type import ElementaryType + +""" +tests for slither.core.declarations.Function. +tests that `tests/functions.sol` gets translated into correct +slither.core.declarations.Function objects or its subclasses +and that these objects behave correctly. +""" + +def test_functions(): + slither = Slither("tests/test_function.sol") + functions = slither.contracts_as_dict["TestFunction"].available_functions_as_dict() + print(functions) + + f = functions["external_payable(uint256)"] + assert f.name == "external_payable" + assert f.full_name == "external_payable(uint256)" + assert f.canonical_name == "TestFunction.external_payable(uint256)" + assert f.solidity_signature == "external_payable(uint256)" + assert f.signature_str == "external_payable(uint256) returns(uint256)" + assert f.function_type == FunctionType.NORMAL + assert not f.contains_assembly + assert not f.can_reenter() + assert not f.can_send_eth() + assert not f.is_constructor + assert not f.is_fallback + assert not f.is_receive + assert f.payable + assert f.visibility == "external" + assert not f.view + assert not f.pure + assert f.is_implemented + assert not f.is_empty + assert f.parameters[0].name == "_a" + assert f.parameters[0].type == ElementaryType("uint256") + assert f.return_type[0] == ElementaryType("uint256") + + f = functions["public_reenter()"] + assert f.name == "public_reenter" + assert f.full_name == "public_reenter()" + assert f.canonical_name == "TestFunction.public_reenter()" + assert f.solidity_signature == "public_reenter()" + assert f.signature_str == "public_reenter() returns()" + assert f.function_type == FunctionType.NORMAL + assert not f.contains_assembly + assert f.can_reenter() + assert not f.can_send_eth() + assert not f.is_constructor + assert not f.is_fallback + assert not f.is_receive + assert not f.payable + assert f.visibility == "public" + assert not f.view + assert not f.pure + assert f.is_implemented + assert not f.is_empty + assert not f.parameters + assert not f.return_type + + f = functions["public_payable_reenter_send(bool)"] + assert f.name == "public_payable_reenter_send" + assert f.full_name == "public_payable_reenter_send(bool)" + assert f.canonical_name == "TestFunction.public_payable_reenter_send(bool)" + assert f.solidity_signature == "public_payable_reenter_send(bool)" + assert f.signature_str == "public_payable_reenter_send(bool) returns()" + assert f.function_type == FunctionType.NORMAL + assert not f.contains_assembly + assert f.can_reenter() + assert f.can_send_eth() + assert not f.is_constructor + assert not f.is_fallback + assert not f.is_receive + assert f.payable + assert f.visibility == "public" + assert not f.view + assert not f.pure + assert f.is_implemented + assert not f.is_empty + assert f.parameters[0].name == "_b" + assert f.parameters[0].type == ElementaryType("bool") + assert not f.return_type diff --git a/tests/test_function.sol b/tests/test_function.sol new file mode 100644 index 000000000..4e26ae999 --- /dev/null +++ b/tests/test_function.sol @@ -0,0 +1,39 @@ +pragma solidity ^0.6.12; + +// solidity source used by tests/test_function.py. +// tests/test_function.py tests that the functions +// below get + +contract TestFunction { + bool entered = false; + + function external_payable(uint _a) external payable returns (uint) { + return 1; + } + + function public_reenter() public { + msg.sender.call(""); + } + + function public_payable_reenter_send(bool _b) public payable { + msg.sender.call{value: 1}(""); + } + + function external_send(uint _a) external { + require(!entered); + entered = true; + msg.sender.call{value: 1}(""); + } + + function _internal(uint _a) internal returns (uint) { + uint256 chain; + assembly { + chain := chainid() + } + return chain; + } + + fallback() external { + + } +}