mirror of https://github.com/crytic/slither
parent
507795baaa
commit
92c06c4f4a
@ -0,0 +1,93 @@ |
||||
#!/usr/bin/env bash |
||||
|
||||
### Test slither-interface |
||||
|
||||
DIR_TESTS="tests/tools/interface" |
||||
|
||||
#Test 1 - Etherscan target |
||||
slither-interface WETH9 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 |
||||
DIFF=$(diff crytic-export/interfaces/IWETH9.sol "$DIR_TESTS/test_1.sol") |
||||
if [ "$DIFF" != "" ] |
||||
then |
||||
echo "slither-interface test 1 failed" |
||||
cat test_1.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") |
||||
if [ "$DIFF" != "" ] |
||||
then |
||||
echo "slither-interface test 2 failed" |
||||
cat test_2.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") |
||||
if [ "$DIFF" != "" ] |
||||
then |
||||
echo "slither-interface test 3 failed" |
||||
cat test_3.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") |
||||
if [ "$DIFF" != "" ] |
||||
then |
||||
echo "slither-interface test 4 failed" |
||||
cat test_4.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") |
||||
if [ "$DIFF" != "" ] |
||||
then |
||||
echo "slither-interface test 5 failed" |
||||
cat test_5.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") |
||||
if [ "$DIFF" != "" ] |
||||
then |
||||
echo "slither-interface test 6 failed" |
||||
cat test_6.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") |
||||
if [ "$DIFF" != "" ] |
||||
then |
||||
echo "slither-interface test 7 failed" |
||||
cat test_7.sol |
||||
echo "" |
||||
cat "$DIR_TESTS/test_7.sol" |
||||
exit 255 |
||||
fi |
||||
|
||||
rm -r crytic-export |
@ -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() |
@ -0,0 +1,33 @@ |
||||
pragma solidity ^0.8.0; |
||||
|
||||
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); |
||||
} |
||||
|
||||
|
||||
} |
@ -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); |
||||
} |
||||
|
@ -0,0 +1,19 @@ |
||||
pragma solidity ^0.8.0; |
||||
|
||||
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); |
||||
} |
||||
|
@ -0,0 +1,19 @@ |
||||
pragma solidity ^0.8.0; |
||||
|
||||
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 (uint256, address); |
||||
function status() external returns (uint8); |
||||
function function1() external pure returns (address); |
||||
} |
||||
|
@ -0,0 +1,15 @@ |
||||
pragma solidity ^0.8.0; |
||||
|
||||
interface IMock { |
||||
event Event1(); |
||||
event Event2(address); |
||||
event Event3(uint256, uint72); |
||||
error Error1(); |
||||
error Error2(); |
||||
error Error3(); |
||||
enum Status { Active, Pending, Canceled } |
||||
function foo() external returns (Foo memory); |
||||
function status() external returns (Status); |
||||
function function1() external pure returns (address); |
||||
} |
||||
|
@ -0,0 +1,16 @@ |
||||
pragma solidity ^0.8.0; |
||||
|
||||
interface IMock { |
||||
event Event1(); |
||||
event Event2(address); |
||||
event Event3(uint256, uint72); |
||||
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); |
||||
} |
||||
|
@ -0,0 +1,18 @@ |
||||
pragma solidity ^0.8.0; |
||||
|
||||
interface IMock { |
||||
event Event1(); |
||||
event Event2(address); |
||||
event Event3(uint256, uint72); |
||||
error Error1(); |
||||
error Error2(); |
||||
error Error3(); |
||||
struct Foo { |
||||
uint256 bar; |
||||
address baz; |
||||
} |
||||
function foo() external returns (Foo memory); |
||||
function status() external returns (Status); |
||||
function function1() external pure returns (address); |
||||
} |
||||
|
@ -0,0 +1,16 @@ |
||||
pragma solidity ^0.8.0; |
||||
|
||||
interface IMock { |
||||
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…
Reference in new issue