Ejemplo n.º 1
0

slither = Slither('data_dependency_simple_example.sol')

myContract = slither.get_contract_from_name('MyContract')
funcA = myContract.get_function_from_signature('foo()')

a = myContract.get_state_variable_from_name('a')
b = myContract.get_state_variable_from_name('b')
c = myContract.get_state_variable_from_name('c')
d = myContract.get_state_variable_from_name('d')

D = Dependency()

D.compute_contract(myContract, slither)
D.dependencies = funcA.context[D.KEY_NON_SSA]        

R = Refinement()
R.compute_contract(myContract, slither)

guards = []
for var in R.types[R.Typ.GUARD]:
    if var in D.dependencies:
        guards += D.dependencies[var]

R.types[R.Typ.GUARD] += guards

for typ in R.types:
    for var in R.types[typ]:
        if var.name.startswith("REF") or var.name.startswith("TMP"):
            R.types[typ].remove(var)
Ejemplo n.º 2
0
def analyze(fname, cname='MyContract', funcname='foo()'):
    slither = Slither(fname)

    myContract = slither.get_contract_from_name(cname)
    funcA = myContract.get_function_from_signature(funcname)
    
    # Dependency Analysis
    D = Dependency()
    D.compute_contract(myContract, slither)
    D.dependencies = funcA.context[D.KEY_NON_SSA]        

    
    # Refinement Analysis
    R = Refinement()
    R.compute_contract(myContract, slither, fname)

    # Lambda Analysis
    lambdas = get_lambda_analysis(fname, myContract, slither)
    
    # For Guard Types, use Dependency Analysis to fetch all vars which affect
    #   the Guard (i.e. on which the guard depends)
    guards = []
    for var in R.types[R.Typ.GUARD]:
        if var in D.dependencies:
            guards += D.dependencies[var]
    R.types[R.Typ.GUARD] += guards

    # Remove temporary variables and ref vars from types
    to_delete = {}
    for typ in R.types:
        to_delete[typ] = []
        if typ != 6 and typ != 7:
            for var in R.types[typ]:
                if var.name.startswith("REF") or var.name.startswith("TMP"):
                    to_delete[typ].append(var)

    for k,vals in to_delete.items():
        for v in vals:
            R.types[k].remove(v)
                
    # Remove temporary variables and ref vars from dependencies
    to_delete = []
    for var in D.dependencies:
        if var.name.startswith("REF") or var.name.startswith("TMP"):
            to_delete.append(var)
        else:
            to_delete2 = []
            for var2 in D.dependencies[var]:
                if var2.name.startswith("REF") or var2.name.startswith("TMP"):
                    to_delete2.append(var2)
            for x in to_delete2: D.dependencies[var].remove(x)
            if len(D.dependencies[var]) == 0: to_delete.append(var)
    for x in to_delete:
        D.dependencies.pop(x, None)

    # Fetch written and read types from dependencies
    R.types[R.Typ.WRITTEN] += D.dependencies.keys()
    R.types[R.Typ.READ] += [x for vals in D.dependencies.values() for x in vals]

    # Anything that is an index or guard is also read
    R.types[R.Typ.READ] += R.types[R.Typ.INDEX]
    R.types[R.Typ.READ] += R.types[R.Typ.GUARD]
    R.types[R.Typ.READ] += R.types[R.Typ.GUARDSTART]
    R.types[R.Typ.READ] += R.types[R.Typ.GUARDEND]
        
    # Reformat refinement type entries
    R_types_formatted = {}
    for typ, vrs in R.types.items():
        # Special check for lower casing True and False constants
        rhs = set(map(lambda v: v.lower() if v=="True" or v=="False" else v,
                       set(map(str, vrs))))
        typ = typ.lower() if typ == "True" or typ == "False" else typ
        R_types_formatted[typ] = rhs
    R.types = R_types_formatted
        
    # Reformat dependencies entries
    dependencies_formatted = {}
    for v, vrs in D.dependencies.items():
        # Special check for lower casing True and False constants
        lhs = str(v).lower() if str(v) == "True" or str(v) == "False" else str(v)
        rhs = set(map(lambda v: v.lower() if v=="True" or v=="False" else v,
                       set(map(str, vrs))))
        dependencies_formatted[lhs] = rhs
    D.dependencies = dependencies_formatted

    # Add lambdas to dependencies based on sub-parts
    dependencies_lambdas = {}
    for v, vrs in D.dependencies.items():
        dependencies_lambdas[v] = vrs
        for lam in lambdas:
            lam_vrs = re.findall(r"[\w']+", lam[lam.index(":")+1:])
            if any(map(lambda lv: lv in vrs, lam_vrs)):
                dependencies_lambdas[v].add(lam)
    D.dependencies = dependencies_lambdas
    
    # # Transitive Closure of Dependencies
    # D.dependencies = transitive_close(D.dependencies)
        
    return D, R