Skip to content

Commit

Permalink
Merge branch 'dev' into dev-named-implicit-returns
Browse files Browse the repository at this point in the history
  • Loading branch information
webthethird authored May 16, 2023
2 parents 30794d0 + 0632751 commit 53f4842
Show file tree
Hide file tree
Showing 22 changed files with 416 additions and 2 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ jobs:
"etherscan",
"find_paths",
"flat",
"interface",
"kspec",
"printers",
# "prop"
Expand Down
95 changes: 95 additions & 0 deletions scripts/ci_test_interface.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env bash

### Test slither-interface

DIR_TESTS="tests/tools/interface"

solc-select use 0.8.19 --always-install

#Test 1 - Etherscan target
slither-interface WETH9 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
DIFF=$(diff crytic-export/interfaces/IWETH9.sol "$DIR_TESTS/test_1.sol" --strip-trailing-cr)
if [ "$DIFF" != "" ]
then
echo "slither-interface test 1 failed"
cat "crytic-export/interfaces/IWETH9.sol"
echo ""
cat "$DIR_TESTS/test_1.sol"
exit 255
fi


#Test 2 - Local file target
slither-interface Mock tests/tools/interface/ContractMock.sol
DIFF=$(diff crytic-export/interfaces/IMock.sol "$DIR_TESTS/test_2.sol" --strip-trailing-cr)
if [ "$DIFF" != "" ]
then
echo "slither-interface test 2 failed"
cat "crytic-export/interfaces/IMock.sol"
echo ""
cat "$DIR_TESTS/test_2.sol"
exit 255
fi


#Test 3 - unroll structs
slither-interface Mock tests/tools/interface/ContractMock.sol --unroll-structs
DIFF=$(diff crytic-export/interfaces/IMock.sol "$DIR_TESTS/test_3.sol" --strip-trailing-cr)
if [ "$DIFF" != "" ]
then
echo "slither-interface test 3 failed"
cat "crytic-export/interfaces/IMock.sol"
echo ""
cat "$DIR_TESTS/test_3.sol"
exit 255
fi

#Test 4 - exclude structs
slither-interface Mock tests/tools/interface/ContractMock.sol --exclude-structs
DIFF=$(diff crytic-export/interfaces/IMock.sol "$DIR_TESTS/test_4.sol" --strip-trailing-cr)
if [ "$DIFF" != "" ]
then
echo "slither-interface test 4 failed"
cat "crytic-export/interfaces/IMock.sol"
echo ""
cat "$DIR_TESTS/test_4.sol"
exit 255
fi

#Test 5 - exclude errors
slither-interface Mock tests/tools/interface/ContractMock.sol --exclude-errors
DIFF=$(diff crytic-export/interfaces/IMock.sol "$DIR_TESTS/test_5.sol" --strip-trailing-cr)
if [ "$DIFF" != "" ]
then
echo "slither-interface test 5 failed"
cat "crytic-export/interfaces/IMock.sol"
echo ""
cat "$DIR_TESTS/test_5.sol"
exit 255
fi

#Test 6 - exclude enums
slither-interface Mock tests/tools/interface/ContractMock.sol --exclude-enums
DIFF=$(diff crytic-export/interfaces/IMock.sol "$DIR_TESTS/test_6.sol" --strip-trailing-cr)
if [ "$DIFF" != "" ]
then
echo "slither-interface test 6 failed"
cat "crytic-export/interfaces/IMock.sol"
echo ""
cat "$DIR_TESTS/test_6.sol"
exit 255
fi

#Test 7 - exclude events
slither-interface Mock tests/tools/interface/ContractMock.sol --exclude-events
DIFF=$(diff crytic-export/interfaces/IMock.sol "$DIR_TESTS/test_7.sol" --strip-trailing-cr)
if [ "$DIFF" != "" ]
then
echo "slither-interface test 7 failed"
cat "crytic-export/interfaces/IMock.sol"
echo ""
cat "$DIR_TESTS/test_7.sol"
exit 255
fi

rm -r crytic-export
6 changes: 5 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@
"prettytable>=3.3.0",
"pycryptodome>=3.4.6",
# "crytic-compile>=0.3.1,<0.4.0",
"crytic-compile@git+https://github.com/crytic/crytic-compile.git@windows-rel-path#egg=crytic-compile",
"crytic-compile@git+https://github.com/crytic/crytic-compile.git@dev#egg=crytic-compile",
"web3>=6.0.0",
"eth-abi>=4.0.0",
"eth-typing>=3.0.0",
"eth-utils>=2.1.0",
],
extras_require={
"lint": [
Expand Down Expand Up @@ -61,6 +64,7 @@
"slither-read-storage = slither.tools.read_storage.__main__:main",
"slither-doctor = slither.tools.doctor.__main__:main",
"slither-documentation = slither.tools.documentation.__main__:main",
"slither-interface = slither.tools.interface.__main__:main",
]
},
)
11 changes: 10 additions & 1 deletion slither/detectors/variables/uninitialized_local_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"""
from typing import List

from slither.core.cfg.node import Node
from slither.core.cfg.node import Node, NodeType
from slither.core.declarations.function_contract import FunctionContract
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.utils.output import Output
Expand Down Expand Up @@ -64,6 +64,15 @@ def _detect_uninitialized(

self.visited_all_paths[node] = list(set(self.visited_all_paths[node] + fathers_context))

# Remove a local variable declared in a for loop header
if (
node.type == NodeType.VARIABLE
and len(node.sons) == 1 # Should always be true for a node that has a STARTLOOP son
and node.sons[0].type == NodeType.STARTLOOP
):
if node.variable_declaration in fathers_context:
fathers_context.remove(node.variable_declaration)

if self.key in node.context:
fathers_context += node.context[self.key]

Expand Down
Empty file.
105 changes: 105 additions & 0 deletions slither/tools/interface/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import argparse
import logging
from pathlib import Path

from crytic_compile import cryticparser

from slither import Slither
from slither.utils.code_generation import generate_interface

logging.basicConfig()
logger = logging.getLogger("Slither-Interface")
logger.setLevel(logging.INFO)


def parse_args() -> argparse.Namespace:
"""
Parse the underlying arguments for the program.
:return: Returns the arguments for the program.
"""
parser = argparse.ArgumentParser(
description="Generates code for a Solidity interface from contract",
usage=("slither-interface <ContractName> <source file or deployment address>"),
)

parser.add_argument(
"contract_source",
help="The name of the contract (case sensitive) followed by the deployed contract address if verified on etherscan or project directory/filename for local contracts.",
nargs="+",
)

parser.add_argument(
"--unroll-structs",
help="Whether to use structures' underlying types instead of the user-defined type",
default=False,
action="store_true",
)

parser.add_argument(
"--exclude-events",
help="Excludes event signatures in the interface",
default=False,
action="store_true",
)

parser.add_argument(
"--exclude-errors",
help="Excludes custom error signatures in the interface",
default=False,
action="store_true",
)

parser.add_argument(
"--exclude-enums",
help="Excludes enum definitions in the interface",
default=False,
action="store_true",
)

parser.add_argument(
"--exclude-structs",
help="Exclude struct definitions in the interface",
default=False,
action="store_true",
)

cryticparser.init(parser)

return parser.parse_args()


def main() -> None:
args = parse_args()

contract_name, target = args.contract_source
slither = Slither(target, **vars(args))

_contract = slither.get_contract_from_name(contract_name)[0]

interface = generate_interface(
contract=_contract,
unroll_structs=args.unroll_structs,
include_events=not args.exclude_events,
include_errors=not args.exclude_errors,
include_enums=not args.exclude_enums,
include_structs=not args.exclude_structs,
)

# add version pragma
interface = (
f"pragma solidity {_contract.compilation_unit.pragma_directives[0].version};\n\n"
+ interface
)

# write interface to file
export = Path("crytic-export", "interfaces")
export.mkdir(parents=True, exist_ok=True)
filename = f"I{contract_name}.sol"
path = Path(export, filename)
logger.info(f" Interface exported to {path}")
with open(path, "w", encoding="utf8") as f:
f.write(interface)


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,15 @@ contract Uninitialized{
return uint_not_init + uint_init;
}

function noreportfor() public {
for(uint i; i < 6; i++) {
uint a = i;
}

for(uint j = 0; j < 6; j++) {
uint b = j;
}

}

}
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,15 @@ contract Uninitialized{
return uint_not_init + uint_init;
}

function noreportfor() public {
for(uint i; i < 6; i++) {
uint a = i;
}

for(uint j = 0; j < 6; j++) {
uint b = j;
}

}

}
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,15 @@ contract Uninitialized{
return uint_not_init + uint_init;
}

function noreportfor() public {
for(uint i; i < 6; i++) {
uint a = i;
}

for(uint j = 0; j < 6; j++) {
uint b = j;
}

}

}
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,15 @@ contract Uninitialized{
return uint_not_init + uint_init;
}

function noreportfor() public {
for(uint i; i < 6; i++) {
uint a = i;
}

for(uint j = 0; j < 6; j++) {
uint b = j;
}

}

}
Binary file not shown.
33 changes: 33 additions & 0 deletions tests/tools/interface/ContractMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
pragma solidity ^0.8.19;

contract Mock {

error Error1();
error Error2();
error Error3();

event Event1();
event Event2(address param);
event Event3(uint256 num1, uint72 num2);

struct Foo {
uint256 bar;
address baz;
}

enum Status {
Active,
Pending,
Canceled
}

Foo public foo;

Status public status;

function function1() public pure returns (address){
return address(0);
}


}
20 changes: 20 additions & 0 deletions tests/tools/interface/test_1.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
pragma solidity ^0.4.18;

interface IWETH9 {
event Approval(address, address, uint256);
event Transfer(address, address, uint256);
event Deposit(address, uint256);
event Withdrawal(address, uint256);
function name() external returns (string memory);
function symbol() external returns (string memory);
function decimals() external returns (uint8);
function balanceOf(address) external returns (uint256);
function allowance(address,address) external returns (uint256);
function deposit() external payable;
function withdraw(uint256) external;
function totalSupply() external view returns (uint256);
function approve(address,uint256) external returns (bool);
function transfer(address,uint256) external returns (bool);
function transferFrom(address,address,uint256) external returns (bool);
}

19 changes: 19 additions & 0 deletions tests/tools/interface/test_2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
pragma solidity ^0.8.19;

interface IMock {
event Event1();
event Event2(address);
event Event3(uint256, uint72);
error Error1();
error Error2();
error Error3();
enum Status { Active, Pending, Canceled }
struct Foo {
uint256 bar;
address baz;
}
function foo() external returns (Foo memory);
function status() external returns (Status);
function function1() external pure returns (address);
}

Loading

0 comments on commit 53f4842

Please sign in to comment.