mirror of https://github.com/crytic/slither
Merge pull request #228 from crytic/dev-human-summary-printer
Improve the human summary printerpull/229/head^2
commit
f8244eb1b6
@ -1,8 +1,53 @@ |
|||||||
from .variable import Variable |
from .variable import Variable |
||||||
from slither.core.children.child_contract import ChildContract |
from slither.core.children.child_contract import ChildContract |
||||||
|
from slither.utils.type import export_nested_types_from_variable |
||||||
|
|
||||||
class StateVariable(ChildContract, Variable): |
class StateVariable(ChildContract, Variable): |
||||||
|
|
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
# region Signature |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
|
||||||
|
@property |
||||||
|
def signature(self): |
||||||
|
""" |
||||||
|
Return the signature of the state variable as a function signature |
||||||
|
:return: (str, list(str), list(str)), as (name, list parameters type, list return values type) |
||||||
|
""" |
||||||
|
return self.name, [str(x) for x in export_nested_types_from_variable(self)], self.type |
||||||
|
|
||||||
|
@property |
||||||
|
def signature_str(self): |
||||||
|
""" |
||||||
|
Return the signature of the state variable as a function signature |
||||||
|
:return: str: func_name(type1,type2) returns(type3) |
||||||
|
""" |
||||||
|
name, parameters, returnVars = self.signature |
||||||
|
return name+'('+','.join(parameters)+') returns('+','.join(returnVars)+')' |
||||||
|
|
||||||
|
# endregion |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
# region Name |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
|
||||||
@property |
@property |
||||||
def canonical_name(self): |
def canonical_name(self): |
||||||
return '{}:{}'.format(self.contract.name, self.name) |
return '{}:{}'.format(self.contract.name, self.name) |
||||||
|
|
||||||
|
@property |
||||||
|
def full_name(self): |
||||||
|
""" |
||||||
|
Return the name of the state variable as a function signaure |
||||||
|
str: func_name(type1,type2) |
||||||
|
:return: the function signature without the return values |
||||||
|
""" |
||||||
|
name, parameters, _ = self.signature |
||||||
|
return name+'('+','.join(parameters)+')' |
||||||
|
|
||||||
|
# endregion |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
@ -0,0 +1,96 @@ |
|||||||
|
""" |
||||||
|
Detect incorrect erc721 interface. |
||||||
|
""" |
||||||
|
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||||
|
|
||||||
|
|
||||||
|
class IncorrectERC721InterfaceDetection(AbstractDetector): |
||||||
|
""" |
||||||
|
Incorrect ERC721 Interface |
||||||
|
""" |
||||||
|
|
||||||
|
ARGUMENT = 'erc721-interface' |
||||||
|
HELP = 'Incorrect ERC721 interfaces' |
||||||
|
IMPACT = DetectorClassification.MEDIUM |
||||||
|
CONFIDENCE = DetectorClassification.HIGH |
||||||
|
|
||||||
|
WIKI = 'https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc721-interface' |
||||||
|
|
||||||
|
WIKI_TITLE = 'Incorrect erc721 interface' |
||||||
|
WIKI_DESCRIPTION = 'Incorrect return values for ERC721 functions. A contract compiled with solidity > 0.4.22 interacting with these functions will fail to execute them, as the return value is missing.' |
||||||
|
WIKI_EXPLOIT_SCENARIO = ''' |
||||||
|
```solidity |
||||||
|
contract Token{ |
||||||
|
function ownerOf(uint256 _tokenId) external view returns (bool); |
||||||
|
//... |
||||||
|
} |
||||||
|
``` |
||||||
|
`Token.ownerOf` does not return an address as ERC721 expects. Bob deploys the token. Alice creates a contract that interacts with it but assumes a correct ERC721 interface implementation. Alice's contract is unable to interact with Bob's contract.''' |
||||||
|
|
||||||
|
WIKI_RECOMMENDATION = 'Set the appropriate return values and value-types for the defined ERC721 functions.' |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def incorrect_erc721_interface(signature): |
||||||
|
(name, parameters, returnVars) = signature |
||||||
|
|
||||||
|
# ERC721 |
||||||
|
if name == 'balanceOf' and parameters == ['address'] and returnVars != ['uint256']: |
||||||
|
return True |
||||||
|
if name == 'ownerOf' and parameters == ['uint256'] and returnVars != ['address']: |
||||||
|
return True |
||||||
|
if name == 'safeTransferFrom' and parameters == ['address', 'address', 'uint256', 'bytes'] and returnVars != []: |
||||||
|
return True |
||||||
|
if name == 'safeTransferFrom' and parameters == ['address', 'address', 'uint256'] and returnVars != []: |
||||||
|
return True |
||||||
|
if name == 'transferFrom' and parameters == ['address', 'address', 'uint256'] and returnVars != []: |
||||||
|
return True |
||||||
|
if name == 'approve' and parameters == ['address', 'uint256'] and returnVars != []: |
||||||
|
return True |
||||||
|
if name == 'setApprovalForAll' and parameters == ['address', 'bool'] and returnVars != []: |
||||||
|
return True |
||||||
|
if name == 'getApproved' and parameters == ['uint256'] and returnVars != ['address']: |
||||||
|
return True |
||||||
|
if name == 'isApprovedForAll' and parameters == ['address', 'address'] and returnVars != ['bool']: |
||||||
|
return True |
||||||
|
|
||||||
|
# ERC165 (dependency) |
||||||
|
if name == 'supportsInterface' and parameters == ['bytes4'] and returnVars != ['bool']: |
||||||
|
return True |
||||||
|
|
||||||
|
return False |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def detect_incorrect_erc721_interface(contract): |
||||||
|
""" Detect incorrect ERC721 interface |
||||||
|
|
||||||
|
Returns: |
||||||
|
list(str) : list of incorrect function signatures |
||||||
|
""" |
||||||
|
|
||||||
|
# Verify this is an ERC721 contract. |
||||||
|
if not contract.is_possible_erc721() or not contract.is_possible_erc20(): |
||||||
|
return [] |
||||||
|
|
||||||
|
functions = [f for f in contract.functions if IncorrectERC721InterfaceDetection.incorrect_erc721_interface(f.signature)] |
||||||
|
return functions |
||||||
|
|
||||||
|
def _detect(self): |
||||||
|
""" Detect incorrect erc721 interface |
||||||
|
|
||||||
|
Returns: |
||||||
|
dict: [contract name] = set(str) events |
||||||
|
""" |
||||||
|
results = [] |
||||||
|
for c in self.contracts: |
||||||
|
functions = IncorrectERC721InterfaceDetection.detect_incorrect_erc721_interface(c) |
||||||
|
if functions: |
||||||
|
info = "{} ({}) has incorrect ERC721 function interface(s):\n" |
||||||
|
info = info.format(c.name, |
||||||
|
c.source_mapping_str) |
||||||
|
for function in functions: |
||||||
|
info += "\t-{} ({})\n".format(function.name, function.source_mapping_str) |
||||||
|
json = self.generate_json_result(info) |
||||||
|
self.add_functions_to_json(functions, json) |
||||||
|
results.append(json) |
||||||
|
|
||||||
|
return results |
@ -0,0 +1,69 @@ |
|||||||
|
|
||||||
|
def erc_to_signatures(erc): |
||||||
|
return [f'{e[0]}({",".join(e[1])})' for e in erc] |
||||||
|
|
||||||
|
|
||||||
|
# Final |
||||||
|
# https://eips.ethereum.org/EIPS/eip-20 |
||||||
|
# name, symbolc, decimals are optionals |
||||||
|
ERC20 = [('totalSupply', [], 'uint256'), |
||||||
|
('balanceOf', ['address'], 'uint256'), |
||||||
|
('transfer', ['address', 'uint256'], 'bool'), |
||||||
|
('transferFrom', ['address', 'address', 'uint256'], 'bool'), |
||||||
|
('approve', ['address', 'uint256'], 'bool'), |
||||||
|
('allowance', ['address', 'address'], 'uint256')] |
||||||
|
ERC20_signatures = erc_to_signatures(ERC20) |
||||||
|
|
||||||
|
# Draft |
||||||
|
# https://github.com/ethereum/eips/issues/223 |
||||||
|
ERC223 = [('name', [], 'string'), |
||||||
|
('symbol', [], 'string'), |
||||||
|
('decimals', [], 'uint8'), |
||||||
|
('totalSupply', [], 'uint256'), |
||||||
|
('balanceOf', ['address'], 'uint256'), |
||||||
|
('transfer', ['address', 'uint256'], 'bool'), |
||||||
|
('transfer', ['address', 'uint256', 'bytes'], 'bool'), |
||||||
|
('transfer', ['address', 'uint256', 'bytes', 'string'], 'bool')] |
||||||
|
ERC223_signatures = erc_to_signatures(ERC223) |
||||||
|
|
||||||
|
# Final |
||||||
|
# https://eips.ethereum.org/EIPS/eip-165 |
||||||
|
ERC165 = [('supportsInterface', ['bytes4'], 'bool')] |
||||||
|
ERC165_signatures = erc_to_signatures(ERC165) |
||||||
|
|
||||||
|
# Final |
||||||
|
# https://eips.ethereum.org/EIPS/eip-721 |
||||||
|
# Must have ERC165 |
||||||
|
# name, symbol, tokenURI are optionals |
||||||
|
ERC721 = [('balanceOf', ['address'], 'uint256'), |
||||||
|
('ownerOf', ['uint256'], 'address'), |
||||||
|
('safeTransferFrom', ['address', 'address', 'uint256', 'bytes'], ''), |
||||||
|
('safeTransferFrom', ['address', 'address', 'uint256'], ''), |
||||||
|
('transferFrom', ['address', 'address', 'uint256'], ''), |
||||||
|
('approve', ['address', 'uint256'], ''), |
||||||
|
('setApprovalForAll', ['address', 'bool'], ''), |
||||||
|
('getApproved', ['uint256'], 'address'), |
||||||
|
('isApprovedForAll', ['address', 'address'], 'bool')] + ERC165 |
||||||
|
ERC721_signatures = erc_to_signatures(ERC721) |
||||||
|
|
||||||
|
# Final |
||||||
|
# https://eips.ethereum.org/EIPS/eip-1820 |
||||||
|
ERC1820 = [('canImplementInterfaceForAddress', ['bytes32', 'address'], 'bytes32')] |
||||||
|
ERC1820_signatures = erc_to_signatures(ERC1820) |
||||||
|
|
||||||
|
# Last Call |
||||||
|
# https://eips.ethereum.org/EIPS/eip-777 |
||||||
|
ERC777 = [('name', [], 'string'), |
||||||
|
('symbol', [], 'string'), |
||||||
|
('totalSupply', [], 'uint256'), |
||||||
|
('balanceOf', ['address'], 'uint256'), |
||||||
|
('granularity', [], 'uint256'), |
||||||
|
('defaultOperators', [], 'address[]'), |
||||||
|
('isOperatorFor', ['address', 'address'], 'bool'), |
||||||
|
('authorizeOperator', ['address'], ''), |
||||||
|
('revokeOperator', ['address'], ''), |
||||||
|
('send', ['address', 'uint256', 'bytes'], ''), |
||||||
|
('operatorSend', ['address', 'address', 'uint256', 'bytes', 'bytes'], ''), |
||||||
|
('burn', ['uint256', 'bytes'] , ''), |
||||||
|
('operatorBurn', ['address', 'uint256', 'bytes', 'bytes'] , '')] |
||||||
|
ERC777_signatures = erc_to_signatures(ERC777) |
@ -0,0 +1,193 @@ |
|||||||
|
from pathlib import Path |
||||||
|
|
||||||
|
|
||||||
|
libraries = { |
||||||
|
'Openzeppelin-SafeMath': lambda x: is_openzepellin_safemath(x), |
||||||
|
'Openzeppelin-ECRecovery': lambda x: is_openzepellin_ecrecovery(x), |
||||||
|
'Openzeppelin-Ownable': lambda x: is_openzepellin_ownable(x), |
||||||
|
'Openzeppelin-ERC20': lambda x: is_openzepellin_erc20(x), |
||||||
|
'Openzeppelin-ERC721': lambda x: is_openzepellin_erc721(x), |
||||||
|
'Zos-Upgrade': lambda x: is_zos_initializable(x), |
||||||
|
'Dapphub-DSAuth': lambda x: is_dapphub_ds_auth(x), |
||||||
|
'Dapphub-DSMath': lambda x: is_dapphub_ds_math(x), |
||||||
|
'Dapphub-DSToken': lambda x: is_dapphub_ds_token(x), |
||||||
|
'Dapphub-DSProxy': lambda x: is_dapphub_ds_proxy(x), |
||||||
|
'Dapphub-DSGroup': lambda x: is_dapphub_ds_group(x), |
||||||
|
} |
||||||
|
|
||||||
|
def is_standard_library(contract): |
||||||
|
for name, is_lib in libraries.items(): |
||||||
|
if is_lib(contract): |
||||||
|
return name |
||||||
|
return None |
||||||
|
|
||||||
|
|
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
# region General libraries |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
|
||||||
|
|
||||||
|
def is_openzepellin(contract): |
||||||
|
if not contract.is_from_dependency(): |
||||||
|
return False |
||||||
|
return 'openzeppelin-solidity' in Path(contract.source_mapping['filename_absolute']).parts |
||||||
|
|
||||||
|
|
||||||
|
def is_zos(contract): |
||||||
|
if not contract.is_from_dependency(): |
||||||
|
return False |
||||||
|
return 'zos-lib' in Path(contract.source_mapping['filename_absolute']).parts |
||||||
|
|
||||||
|
|
||||||
|
# endregion |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
# region SafeMath |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
|
||||||
|
|
||||||
|
def is_safemath(contract): |
||||||
|
return contract.name == "SafeMath" |
||||||
|
|
||||||
|
|
||||||
|
def is_openzepellin_safemath(contract): |
||||||
|
return is_safemath(contract) and is_openzepellin(contract) |
||||||
|
|
||||||
|
# endregion |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
# region ECRecovery |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
|
||||||
|
|
||||||
|
def is_ecrecovery(contract): |
||||||
|
return contract.name == 'ECRecovery' |
||||||
|
|
||||||
|
|
||||||
|
def is_openzepellin_ecrecovery(contract): |
||||||
|
return is_ecrecovery(contract) and is_openzepellin(contract) |
||||||
|
|
||||||
|
|
||||||
|
# endregion |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
# region Ownable |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
|
||||||
|
|
||||||
|
def is_ownable(contract): |
||||||
|
return contract.name == 'Ownable' |
||||||
|
|
||||||
|
|
||||||
|
def is_openzepellin_ownable(contract): |
||||||
|
return is_ownable(contract) and is_openzepellin(contract) |
||||||
|
|
||||||
|
|
||||||
|
# endregion |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
# region ERC20 |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
|
||||||
|
|
||||||
|
def is_erc20(contract): |
||||||
|
return contract.name == 'ERC20' |
||||||
|
|
||||||
|
|
||||||
|
def is_openzepellin_erc20(contract): |
||||||
|
return is_erc20(contract) and is_openzepellin(contract) |
||||||
|
|
||||||
|
|
||||||
|
# endregion |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
# region ERC721 |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
|
||||||
|
|
||||||
|
def is_erc721(contract): |
||||||
|
return contract.name == 'ERC721' |
||||||
|
|
||||||
|
|
||||||
|
def is_openzepellin_erc721(contract): |
||||||
|
return is_erc721(contract) and is_openzepellin(contract) |
||||||
|
|
||||||
|
|
||||||
|
# endregion |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
# region Zos Initializable |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
|
||||||
|
|
||||||
|
def is_initializable(contract): |
||||||
|
return contract.name == 'Initializable' |
||||||
|
|
||||||
|
|
||||||
|
def is_zos_initializable(contract): |
||||||
|
return is_initializable(contract) and is_zos(contract) |
||||||
|
|
||||||
|
|
||||||
|
# endregion |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
# region DappHub |
||||||
|
################################################################################### |
||||||
|
################################################################################### |
||||||
|
|
||||||
|
dapphubs = { |
||||||
|
'DSAuth': 'ds-auth', |
||||||
|
'DSMath': 'ds-math', |
||||||
|
'DSToken': 'ds-token', |
||||||
|
'DSProxy': 'ds-proxy', |
||||||
|
'DSGroup': 'ds-group', |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
def _is_ds(contract, name): |
||||||
|
return contract.name == name |
||||||
|
|
||||||
|
def _is_dappdhub_ds(contract, name): |
||||||
|
if not contract.is_from_dependency(): |
||||||
|
return False |
||||||
|
if not dapphubs[name] in Path(contract.source_mapping['filename_absolute']).parts: |
||||||
|
return False |
||||||
|
return _is_ds(contract, name) |
||||||
|
|
||||||
|
def is_ds_auth(contract): |
||||||
|
return _is_ds(contract, 'DSAuth') |
||||||
|
|
||||||
|
def is_dapphub_ds_auth(contract): |
||||||
|
return _is_dappdhub_ds(contract, 'DSAuth') |
||||||
|
|
||||||
|
def is_ds_math(contract): |
||||||
|
return _is_ds(contract, 'DSMath') |
||||||
|
|
||||||
|
def is_dapphub_ds_math(contract): |
||||||
|
return _is_dappdhub_ds(contract, 'DSMath') |
||||||
|
|
||||||
|
def is_ds_token(contract): |
||||||
|
return _is_ds(contract, 'DSToken') |
||||||
|
|
||||||
|
def is_dapphub_ds_token(contract): |
||||||
|
return _is_dappdhub_ds(contract, 'DSToken') |
||||||
|
|
||||||
|
def is_ds_proxy(contract): |
||||||
|
return _is_ds(contract, 'DSProxy') |
||||||
|
|
||||||
|
def is_dapphub_ds_proxy(contract): |
||||||
|
return _is_dappdhub_ds(contract, 'DSProxy') |
||||||
|
|
||||||
|
def is_ds_group(contract): |
||||||
|
return _is_ds(contract, 'DSGroup') |
||||||
|
|
||||||
|
def is_dapphub_ds_group(contract): |
||||||
|
return _is_dappdhub_ds(contract, 'DSGroup') |
@ -0,0 +1,442 @@ |
|||||||
|
[ |
||||||
|
{ |
||||||
|
"check": "erc721-interface", |
||||||
|
"impact": "Medium", |
||||||
|
"confidence": "High", |
||||||
|
"description": "Token (tests/incorrect_erc721_interface.sol#6-16) has incorrect ERC721 function interface(s):\n\t-supportsInterface (tests/incorrect_erc721_interface.sol#4)\n\t-balanceOf (tests/incorrect_erc721_interface.sol#7)\n\t-ownerOf (tests/incorrect_erc721_interface.sol#8)\n\t-safeTransferFrom (tests/incorrect_erc721_interface.sol#9)\n\t-safeTransferFrom (tests/incorrect_erc721_interface.sol#10)\n\t-transferFrom (tests/incorrect_erc721_interface.sol#11)\n\t-approve (tests/incorrect_erc721_interface.sol#12)\n\t-setApprovalForAll (tests/incorrect_erc721_interface.sol#13)\n\t-getApproved (tests/incorrect_erc721_interface.sol#14)\n\t-isApprovedForAll (tests/incorrect_erc721_interface.sol#15)\n", |
||||||
|
"elements": [ |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "approve", |
||||||
|
"source_mapping": { |
||||||
|
"start": 549, |
||||||
|
"length": 78, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
12 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 83 |
||||||
|
}, |
||||||
|
"contract": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Token", |
||||||
|
"source_mapping": { |
||||||
|
"start": 109, |
||||||
|
"length": 739, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "balanceOf", |
||||||
|
"source_mapping": { |
||||||
|
"start": 140, |
||||||
|
"length": 44, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
7 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 49 |
||||||
|
}, |
||||||
|
"contract": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Token", |
||||||
|
"source_mapping": { |
||||||
|
"start": 109, |
||||||
|
"length": 739, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "getApproved", |
||||||
|
"source_mapping": { |
||||||
|
"start": 723, |
||||||
|
"length": 48, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
14 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 53 |
||||||
|
}, |
||||||
|
"contract": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Token", |
||||||
|
"source_mapping": { |
||||||
|
"start": 109, |
||||||
|
"length": 739, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "isApprovedForAll", |
||||||
|
"source_mapping": { |
||||||
|
"start": 776, |
||||||
|
"length": 70, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
15 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 75 |
||||||
|
}, |
||||||
|
"contract": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Token", |
||||||
|
"source_mapping": { |
||||||
|
"start": 109, |
||||||
|
"length": 739, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "ownerOf", |
||||||
|
"source_mapping": { |
||||||
|
"start": 189, |
||||||
|
"length": 44, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
8 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 49 |
||||||
|
}, |
||||||
|
"contract": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Token", |
||||||
|
"source_mapping": { |
||||||
|
"start": 109, |
||||||
|
"length": 739, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "safeTransferFrom", |
||||||
|
"source_mapping": { |
||||||
|
"start": 238, |
||||||
|
"length": 108, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
9 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 113 |
||||||
|
}, |
||||||
|
"contract": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Token", |
||||||
|
"source_mapping": { |
||||||
|
"start": 109, |
||||||
|
"length": 739, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "safeTransferFrom", |
||||||
|
"source_mapping": { |
||||||
|
"start": 351, |
||||||
|
"length": 96, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
10 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 101 |
||||||
|
}, |
||||||
|
"contract": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Token", |
||||||
|
"source_mapping": { |
||||||
|
"start": 109, |
||||||
|
"length": 739, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "setApprovalForAll", |
||||||
|
"source_mapping": { |
||||||
|
"start": 632, |
||||||
|
"length": 86, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
13 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 91 |
||||||
|
}, |
||||||
|
"contract": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Token", |
||||||
|
"source_mapping": { |
||||||
|
"start": 109, |
||||||
|
"length": 739, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "supportsInterface", |
||||||
|
"source_mapping": { |
||||||
|
"start": 50, |
||||||
|
"length": 56, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
4 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 61 |
||||||
|
}, |
||||||
|
"contract": { |
||||||
|
"type": "contract", |
||||||
|
"name": "IERC165", |
||||||
|
"source_mapping": { |
||||||
|
"start": 26, |
||||||
|
"length": 82, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
3, |
||||||
|
4, |
||||||
|
5 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "function", |
||||||
|
"name": "transferFrom", |
||||||
|
"source_mapping": { |
||||||
|
"start": 452, |
||||||
|
"length": 92, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
11 |
||||||
|
], |
||||||
|
"starting_column": 5, |
||||||
|
"ending_column": 97 |
||||||
|
}, |
||||||
|
"contract": { |
||||||
|
"type": "contract", |
||||||
|
"name": "Token", |
||||||
|
"source_mapping": { |
||||||
|
"start": 109, |
||||||
|
"length": 739, |
||||||
|
"filename_used": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_relative": "tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_absolute": "/home/travis/build/crytic/slither/tests/incorrect_erc721_interface.sol", |
||||||
|
"filename_short": "tests/incorrect_erc721_interface.sol", |
||||||
|
"lines": [ |
||||||
|
6, |
||||||
|
7, |
||||||
|
8, |
||||||
|
9, |
||||||
|
10, |
||||||
|
11, |
||||||
|
12, |
||||||
|
13, |
||||||
|
14, |
||||||
|
15, |
||||||
|
16 |
||||||
|
], |
||||||
|
"starting_column": 1, |
||||||
|
"ending_column": 2 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
] |
@ -1,7 +1,10 @@ |
|||||||
pragma solidity ^0.4.24; |
pragma solidity ^0.4.24; |
||||||
|
|
||||||
contract Token{ |
contract Token{ |
||||||
|
|
||||||
function transfer(address to, uint value) external; |
function transfer(address to, uint value) external; |
||||||
|
function approve(address spender, uint value) external; |
||||||
|
function transferFrom(address from, address to, uint value) external; |
||||||
|
function totalSupply() external; |
||||||
|
function balanceOf(address who) external; |
||||||
|
function allowance(address owner, address spender) external; |
||||||
} |
} |
||||||
|
@ -0,0 +1,16 @@ |
|||||||
|
pragma solidity ^0.4.24; |
||||||
|
|
||||||
|
interface IERC165 { |
||||||
|
function supportsInterface(bytes4 interfaceID) external; |
||||||
|
} |
||||||
|
contract Token is IERC165{ |
||||||
|
function balanceOf(address _owner) external; |
||||||
|
function ownerOf(uint256 _tokenId) external; |
||||||
|
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external returns (bool); |
||||||
|
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external returns (bool); |
||||||
|
function transferFrom(address _from, address _to, uint256 _tokenId) external returns (bool); |
||||||
|
function approve(address _approved, uint256 _tokenId) external returns (bool); |
||||||
|
function setApprovalForAll(address _operator, bool _approved) external returns (bool); |
||||||
|
function getApproved(uint256 _tokenId) external; |
||||||
|
function isApprovedForAll(address _owner, address _operator) external; |
||||||
|
} |
Loading…
Reference in new issue