diff --git a/slither/core/declarations/solidity_variables.py b/slither/core/declarations/solidity_variables.py index ceb31a94e9..8094ab7c35 100644 --- a/slither/core/declarations/solidity_variables.py +++ b/slither/core/declarations/solidity_variables.py @@ -116,6 +116,7 @@ "_abi_encode()": [], "slice()": [], "uint2str()": ["string"], + "send()": [], } diff --git a/slither/vyper_parsing/expressions/expression_parsing.py b/slither/vyper_parsing/expressions/expression_parsing.py index d51467fab4..71eb566315 100644 --- a/slither/vyper_parsing/expressions/expression_parsing.py +++ b/slither/vyper_parsing/expressions/expression_parsing.py @@ -153,10 +153,10 @@ def parse_expression( parsed_expr.set_offset(expression.src, caller_context.compilation_unit) return parsed_expr + # `raw_call` and `send` are treated specially in order to force `extract_tmp_call` to treat this as a `HighLevelCall` which will be converted + # to a `LowLevelCall` by `convert_to_low_level`. This is an artifact of the late conversion of Solidity... if called.value.name == "raw_call()": args = [parse_expression(a, caller_context) for a in expression.args] - # This is treated specially in order to force `extract_tmp_call` to treat this as a `HighLevelCall` which will be converted - # to a `LowLevelCall` by `convert_to_low_level`. This is an artifact of the late conversion of Solidity... call = CallExpression( MemberAccess("raw_call", "tuple(bool,bytes32)", args[0]), args[1:], @@ -183,6 +183,17 @@ def parse_expression( return call + if called.value.name == "send()": + args = [parse_expression(a, caller_context) for a in expression.args] + call = CallExpression( + MemberAccess("send", "tuple()", args[0]), + args[1:], + "tuple()", + ) + call.set_offset(expression.src, caller_context.compilation_unit) + + return call + if expression.args and isinstance(expression.args[0], VyDict): arguments = [] for val in expression.args[0].values: diff --git a/tests/e2e/vyper_parsing/snapshots/ast_parsing__vyper_cfgir_builtins_c__0.txt b/tests/e2e/vyper_parsing/snapshots/ast_parsing__vyper_cfgir_builtins_c__0.txt index 1f973fcdb6..572b0d927a 100644 --- a/tests/e2e/vyper_parsing/snapshots/ast_parsing__vyper_cfgir_builtins_c__0.txt +++ b/tests/e2e/vyper_parsing/snapshots/ast_parsing__vyper_cfgir_builtins_c__0.txt @@ -16,12 +16,12 @@ EXPRESSION: user_shares.append(1) IRs: -REF_1 -> LENGTH user_shares -TMP_3(uint256) := REF_1(uint256) -TMP_4(uint256) = TMP_3 (c)+ 1 -REF_1(uint256) (->user_shares) := TMP_4(uint256) -REF_2(uint256) -> user_shares[TMP_3] -REF_2(uint256) (->user_shares) := 1(uint256)"]; +REF_2 -> LENGTH user_shares +TMP_4(uint256) := REF_2(uint256) +TMP_5(uint256) = TMP_4 (c)+ 1 +REF_2(uint256) (->user_shares) := TMP_5(uint256) +REF_3(uint256) -> user_shares[TMP_4] +REF_3(uint256) (->user_shares) := 1(uint256)"]; 2->3; 3[label="Node Type: EXPRESSION 3 @@ -29,10 +29,10 @@ EXPRESSION: user_shares.pop() IRs: -REF_4 -> LENGTH user_shares -TMP_6(uint256) = REF_4 (c)- 1 -REF_5(uint256) -> user_shares[TMP_6] -REF_5 = delete REF_5 -REF_6 -> LENGTH user_shares -REF_6(uint256) (->user_shares) := TMP_6(uint256)"]; +REF_5 -> LENGTH user_shares +TMP_7(uint256) = REF_5 (c)- 1 +REF_6(uint256) -> user_shares[TMP_7] +REF_6 = delete REF_6 +REF_7 -> LENGTH user_shares +REF_7(uint256) (->user_shares) := TMP_7(uint256)"]; } diff --git a/tests/e2e/vyper_parsing/snapshots/ast_parsing__vyper_cfgir_builtins_test_builtins__0.txt b/tests/e2e/vyper_parsing/snapshots/ast_parsing__vyper_cfgir_builtins_test_builtins__0.txt index 4719d99269..9da3718f0f 100644 --- a/tests/e2e/vyper_parsing/snapshots/ast_parsing__vyper_cfgir_builtins_test_builtins__0.txt +++ b/tests/e2e/vyper_parsing/snapshots/ast_parsing__vyper_cfgir_builtins_test_builtins__0.txt @@ -115,4 +115,12 @@ x = self.balance IRs: x(uint256) := self.balance(uint256)"]; +14->15; +15[label="Node Type: EXPRESSION 15 + +EXPRESSION: +msg.sender.send(x) + +IRs: +TMP_2 = SEND dest:msg.sender value:x"]; } diff --git a/tests/e2e/vyper_parsing/test_data/builtins.vy b/tests/e2e/vyper_parsing/test_data/builtins.vy index 4c4a72927c..a49816a092 100644 --- a/tests/e2e/vyper_parsing/test_data/builtins.vy +++ b/tests/e2e/vyper_parsing/test_data/builtins.vy @@ -16,6 +16,7 @@ def test_builtins(): m: address = tx.origin n: uint256 = tx.gasprice x: uint256 = self.balance + send(msg.sender, x) @external def c(x: uint256):