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

Add support for string.concat #1086

Merged
merged 1 commit into from
Mar 5, 2022
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
1 change: 1 addition & 0 deletions slither/core/declarations/solidity_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"abi.encodeWithSelector()": ["bytes"],
"abi.encodeWithSignature()": ["bytes"],
"bytes.concat()": ["bytes"],
"string.concat()": ["string"],
# abi.decode returns an a list arbitrary types
"abi.decode()": [],
"type(address)": [],
Expand Down
12 changes: 12 additions & 0 deletions slither/slithir/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,18 @@ def extract_tmp_call(ins: TmpCall, contract: Optional[Contract]): # pylint: dis
s.set_expression(ins.expression)
return s

if ins.ori.variable_left == ElementaryType("string") and ins.ori.variable_right == Constant(
"concat"
):
s = SolidityCall(
SolidityFunction("string.concat()"),
ins.nbr_arguments,
ins.lvalue,
ins.type_call,
)
s.set_expression(ins.expression)
return s

msgcall = HighLevelCall(
ins.ori.variable_left,
ins.ori.variable_right,
Expand Down
2 changes: 1 addition & 1 deletion slither/slithir/operations/member.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def __init__(self, variable_left, variable_right, result):
# f.h(1);
# }
# }
# Can be an ElementaryType because of bytes.concat
# Can be an ElementaryType because of bytes.concat, string.concat
assert is_valid_rvalue(variable_left) or isinstance(
variable_left,
(Contract, Enum, Function, CustomError, SolidityImportPlaceHolder, ElementaryType),
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
"Test": {
"ether_unit()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n}\n",
"time_unit()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n2->3;\n3[label=\"Node Type: EXPRESSION 3\n\"];\n3->4;\n4[label=\"Node Type: EXPRESSION 4\n\"];\n4->5;\n5[label=\"Node Type: EXPRESSION 5\n\"];\n}\n",
"block_and_transactions()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n2->3;\n3[label=\"Node Type: EXPRESSION 3\n\"];\n3->4;\n4[label=\"Node Type: EXPRESSION 4\n\"];\n4->5;\n5[label=\"Node Type: EXPRESSION 5\n\"];\n5->6;\n6[label=\"Node Type: EXPRESSION 6\n\"];\n6->7;\n7[label=\"Node Type: EXPRESSION 7\n\"];\n7->8;\n8[label=\"Node Type: EXPRESSION 8\n\"];\n8->9;\n9[label=\"Node Type: EXPRESSION 9\n\"];\n9->10;\n10[label=\"Node Type: EXPRESSION 10\n\"];\n10->11;\n11[label=\"Node Type: EXPRESSION 11\n\"];\n11->12;\n12[label=\"Node Type: EXPRESSION 12\n\"];\n12->13;\n13[label=\"Node Type: EXPRESSION 13\n\"];\n13->14;\n14[label=\"Node Type: EXPRESSION 14\n\"];\n14->15;\n15[label=\"Node Type: EXPRESSION 15\n\"];\n15->16;\n16[label=\"Node Type: EXPRESSION 16\n\"];\n}\n",
"block_and_transactions()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n2->3;\n3[label=\"Node Type: EXPRESSION 3\n\"];\n3->4;\n4[label=\"Node Type: EXPRESSION 4\n\"];\n4->5;\n5[label=\"Node Type: EXPRESSION 5\n\"];\n5->6;\n6[label=\"Node Type: EXPRESSION 6\n\"];\n6->7;\n7[label=\"Node Type: EXPRESSION 7\n\"];\n7->8;\n8[label=\"Node Type: EXPRESSION 8\n\"];\n8->9;\n9[label=\"Node Type: EXPRESSION 9\n\"];\n9->10;\n10[label=\"Node Type: EXPRESSION 10\n\"];\n10->11;\n11[label=\"Node Type: EXPRESSION 11\n\"];\n11->12;\n12[label=\"Node Type: EXPRESSION 12\n\"];\n12->13;\n13[label=\"Node Type: EXPRESSION 13\n\"];\n13->14;\n14[label=\"Node Type: EXPRESSION 14\n\"];\n14->15;\n15[label=\"Node Type: EXPRESSION 15\n\"];\n}\n",
"abi_encode()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n2->3;\n3[label=\"Node Type: EXPRESSION 3\n\"];\n3->4;\n4[label=\"Node Type: EXPRESSION 4\n\"];\n4->5;\n5[label=\"Node Type: NEW VARIABLE 5\n\"];\n5->6;\n6[label=\"Node Type: EXPRESSION 6\n\"];\n6->7;\n7[label=\"Node Type: NEW VARIABLE 7\n\"];\n7->8;\n8[label=\"Node Type: EXPRESSION 8\n\"];\n}\n",
"member()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n1->2;\n2[label=\"Node Type: NEW VARIABLE 2\n\"];\n2->3;\n3[label=\"Node Type: EXPRESSION 3\n\"];\n}\n",
"error_handling()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n2->3;\n3[label=\"Node Type: EXPRESSION 3\n\"];\n3->4;\n4[label=\"Node Type: EXPRESSION 4\n\"];\n4->5;\n5[label=\"Node Type: EXPRESSION 5\n\"];\n}\n",
"math_and_crypto()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n2->3;\n3[label=\"Node Type: EXPRESSION 3\n\"];\n3->4;\n4[label=\"Node Type: EXPRESSION 4\n\"];\n4->5;\n5[label=\"Node Type: EXPRESSION 5\n\"];\n5->6;\n6[label=\"Node Type: NEW VARIABLE 6\n\"];\n6->7;\n7[label=\"Node Type: NEW VARIABLE 7\n\"];\n7->8;\n8[label=\"Node Type: NEW VARIABLE 8\n\"];\n8->9;\n9[label=\"Node Type: NEW VARIABLE 9\n\"];\n9->10;\n10[label=\"Node Type: EXPRESSION 10\n\"];\n}\n",
"address_related()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: NEW VARIABLE 1\n\"];\n1->2;\n2[label=\"Node Type: EXPRESSION 2\n\"];\n2->3;\n3[label=\"Node Type: EXPRESSION 3\n\"];\n3->4;\n4[label=\"Node Type: EXPRESSION 4\n\"];\n4->5;\n5[label=\"Node Type: EXPRESSION 5\n\"];\n5->6;\n6[label=\"Node Type: EXPRESSION 6\n\"];\n6->7;\n7[label=\"Node Type: EXPRESSION 7\n\"];\n7->8;\n8[label=\"Node Type: EXPRESSION 8\n\"];\n8->9;\n9[label=\"Node Type: EXPRESSION 9\n\"];\n}\n",
Expand Down
119 changes: 119 additions & 0 deletions tests/ast-parsing/units_and_global_variables-0.8.12.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
pragma experimental ABIEncoderV2;

contract A{}

interface I{}

contract Test{

function ether_unit() public{
1 wei;
1 ether;
}

function time_unit() public{
1 seconds;
1 minutes;
1 hours;
1 days;
1 weeks;
}

function block_and_transactions() payable public{
blockhash(0);
block.basefee;
block.chainid;
block.coinbase;
block.difficulty;
block.gaslimit;
block.number;
block.timestamp;
gasleft();
msg.data;
msg.sender;
msg.sig;
msg.value;
block.timestamp;
tx.gasprice;
tx.origin;
}

function abi_encode() public{
bytes memory m;
abi.decode(m, (uint, uint));
abi.encode(10);
abi.encodePacked(uint(10));
bytes4 selector;
abi.encodeWithSelector(selector, 10);
string memory signature;
abi.encodeWithSignature(signature, 10);
}

function member() public{
bytes1 b1;
bytes32 b32;
bytes.concat(b1, b32);
string.concat("", "");
}

function error_handling() public{
assert(true);
require(true);
require(true, "something");
revert();
revert("something");
}

function math_and_crypto() public{
addmod(0, 0, 1);
mulmod(0, 0, 1);
keccak256("");
sha256("");
ripemd160("");
bytes32 hash;
uint8 v;
bytes32 r;
bytes32 s;
ecrecover(hash,v,r,s);
}

function address_related() public{
address payable a;
a.balance;
a.code;
a.codehash;
a.send(0);
a.transfer(0);
a.call("");
a.delegatecall("");
a.staticcall("");
}


function return_addr() internal returns(address){}
function address_edge_case() public{
// For now slithIR loss precision on this edge case
// And create a Ref variable instead of a Temporary one
return_addr().balance;
return_addr().code;
return_addr().codehash;
}


function contract_related() public{
this;
address payable a;
selfdestruct(a);
}

function type_related() public{
type(A).name;
type(A).creationCode;
type(A).runtimeCode;
type(I).interfaceId;
type(uint256).min;
type(uint256).min;
}


}