mirror of https://github.com/crytic/slither
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
2.2 KiB
54 lines
2.2 KiB
'''
|
|
Check for functions collisions between a proxy and the implementation
|
|
More for information: https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357
|
|
'''
|
|
|
|
import logging
|
|
from slither import Slither
|
|
from slither.utils.function import get_function_id
|
|
from slither.utils.colors import red, green
|
|
|
|
logger = logging.getLogger("CompareFunctions")
|
|
logger.setLevel(logging.INFO)
|
|
|
|
def get_signatures(c):
|
|
functions = c.functions
|
|
functions = [f.full_name for f in functions if f.visibility in ['public', 'external'] and not f.is_constructor]
|
|
|
|
variables = c.state_variables
|
|
variables = [variable.name+ '()' for variable in variables if variable.visibility in ['public']]
|
|
return list(set(functions+variables))
|
|
|
|
|
|
def compare_function_ids(implem, implem_name, proxy, proxy_name):
|
|
|
|
logger.info(green('Run function ids checks... (see https://github.com/crytic/slither/wiki/Upgradeability-Checks#functions-ids-checks)'))
|
|
|
|
implem_contract = implem.get_contract_from_name(implem_name)
|
|
if implem_contract is None:
|
|
logger.info(red(f'{implem_name} not found in {implem.filename}'))
|
|
return
|
|
proxy_contract = proxy.get_contract_from_name(proxy_name)
|
|
if proxy_contract is None:
|
|
logger.info(red(f'{proxy_name} not found in {proxy.filename}'))
|
|
return
|
|
|
|
signatures_implem = get_signatures(implem_contract)
|
|
signatures_proxy = get_signatures(proxy_contract)
|
|
|
|
signatures_ids_implem = {get_function_id(s): s for s in signatures_implem}
|
|
signatures_ids_proxy = {get_function_id(s): s for s in signatures_proxy}
|
|
|
|
found = False
|
|
for (k, _) in signatures_ids_implem.items():
|
|
if k in signatures_ids_proxy:
|
|
found = True
|
|
if signatures_ids_implem[k] != signatures_ids_proxy[k]:
|
|
logger.info(red('Function id collision found {} {}'.format(signatures_ids_implem[k],
|
|
signatures_ids_proxy[k])))
|
|
else:
|
|
logger.info(red('Shadowing between proxy and implementation found {}'.format(signatures_ids_implem[k])))
|
|
|
|
if not found:
|
|
logger.info(green('No function ids collision found'))
|
|
|
|
|