def extractCallEvents(logEvent): if pyk.isKApply(logEvent) and logEvent['label'] == 'LogNote': caller = solidify(printMCD(logEvent['args'][0])) contract = solidify(printMCD(logEvent['args'][1]['args'][0])) functionCall = logEvent['args'][1]['args'][1] function = functionCall['label'].split('_')[0] if function.startswith('init') or function.startswith('deploy') or function.startswith('constructor') or function.startswith('poke'): return [] if function.endswith('Cage'): function = 'cage' args = "" if function.endswith('file'): fileable = functionCall['args'][0]['label'].split('_')[0] if fileable.endswith('-file'): fileable = fileable[0:-5] fileargs = functionCall['args'][0]['args'] args = '"' + fileable + '", ' + solidityArgs(fileargs) else: args = solidityArgs(functionCall['args']) return [ (caller + '.' + contract + '_' + function + '(' + args + ')', 'succeeds') ] elif pyk.isKApply(logEvent) and logEvent['label'] == 'LogTimeStep': return [ ('this.warpForward(' + printMCD(logEvent['args'][0]) + ')', '') ] elif pyk.isKApply(logEvent) and logEvent['label'] == 'LogException': return [ (ce, 'unimplemented') for (ce, status) in extractCallEvents(pyk.KApply('LogNote', logEvent['args'])) ] elif pyk.isKApply(logEvent) and ( logEvent['label'] in [ 'LogMeasure' , 'LogGenStep' , 'LogGenStepFailed' ] ): return [] elif pyk.isKApply(logEvent) and ( logEvent['label'] in [ 'Bite' , 'Transfer' , 'Approval' , 'FlapKick' , 'FlipKick' , 'FlopKick' , 'Poke' , 'NoPoke' ] ): return [ ('assertEvent( ' + printMCD(logEvent) + ')', 'unimplemented') ] else: return [ (printMCD(logEvent), 'unimplemented') ]
def stateAssertions(contract, field, value, subkeys = []): assertionData = [] if pyk.isKToken(value) and value['sort'] == 'Bool': actual = contract + '.' + functionify(field) + '(' + solidityArgs(subkeys) + ')' comparator = '==' expected = printMCD(intToken(0)) if value['token'] == 'true': comparator = '!=' assertionData.append((actual, comparator, expected, True)) elif pyk.isKApply(value) and value['label'] == 'FInt': actual = contract + '.' + functionify(field) + '(' + solidityArgs(subkeys) + ')' comparator = '==' expected = printMCD(value['args'][0]) assertionData.append((actual, comparator, expected, True)) elif pyk.isKApply(value) and value['label'] == '_Map_': for (k, v) in flattenMap(value): keys = subkeys + [k] if pyk.isKApply(v) and v['label'] == '_Set_': for si in flattenSet(v): assertionData.extend(stateAssertions(contract, field, boolToken(True), subkeys = keys + [si])) elif pyk.isKApply(v) and v['label'] == 'FInt': assertionData.extend(stateAssertions(contract, field, v, subkeys = keys)) else: actual = contract + '.' + functionify(field) + '(' + solidityArgs(keys) + ')' comparator = '==' expected = printMCD(v) assertionData.append((actual, comparator, expected, False)) else: actual = contract + '.' + functionify(field) + '()' assertionData.append((actual, '==', printMCD(value), False)) return assertionData
def extractCallEvent(logEvent): if pyk.isKApply(logEvent) and logEvent[ 'label'] == 'LogNote(_,_)_KMCD-DRIVER_Event_Address_MCDStep': caller = solidify(printMCD(logEvent['args'][0])) contract = solidify(printMCD(logEvent['args'][1]['args'][0])) functionCall = logEvent['args'][1]['args'][1] function = functionCall['label'].split('_')[0] if function.startswith('init'): return [] if function.endswith('Cage'): function = 'cage' args = [] if function.endswith('file'): fileable = functionCall['args'][0]['label'].split('_')[0] if fileable.endswith('-file'): fileable = fileable[0:-5] fileargs = functionCall['args'][0]['args'] args.append('"' + fileable + '"') for arg in fileargs: args.append(argify(printMCD(arg))) else: args = [argify(printMCD(arg)) for arg in functionCall['args']] return [ caller + '.' + contract + '_' + function + '(' + ', '.join(args) + ');' ] elif pyk.isKApply(logEvent) and logEvent[ 'label'] == 'TimeStep(_,_)_KMCD-DRIVER_Event_Int_Int': return ['hevm.warp(' + printMCD(logEvent['args'][0]) + ');'] elif pyk.isKApply(logEvent) and logEvent[ 'label'] == 'Measure(_,_,_,_,_,_,_,_,_,_,_)_KMCD-PROPS_Measure_Rat_Map_Rat_Rat_Rat_Rat_Rat_Rat_Map_Rat_Map': return [] else: return ['UNIMPLEMENTED << ' + printMCD(logEvent) + ' >>']
def solidityKeys(k): if pyk.isKApply(k) and k['label'] == 'CDPID': return [a for a in k['args']] elif pyk.isKApply(k) and k['label'] == 'FInt': return [a for a in [k['args'][0]]] else: return [a for a in [k]]
def extractTermAndConstraint(input): term_and_constraints = flattenAnd(input) term = [ r for r in term_and_constraints if pyk.isKApply(r) and r['label'] == '<generatedTop>' ][0] constraints = [ r for r in term_and_constraints if not (pyk.isKApply(r) and r['label'] == '<generatedTop>') ] constraint = KConstant('#True') for c in constraints: constraint = KApply('#And', [c, constraint]) return (term, constraint)
def flattenAnd(input): if not (pyk.isKApply(input) and input['label'] == '#And'): return [input] output = [] work = [ arg for arg in input['args'] ] while len(work) > 0: first = work.pop(0) if pyk.isKApply(first) and first['label'] == '#And': work.extend(first['args']) else: output.append(first) return output
def flattenList(input): if not (pyk.isKApply(input) and input['label'] == '_List_'): return [fromListItem(input)] output = [] work = input['args'] while len(work) > 0: first = work.pop(0) if pyk.isKApply(first) and first['label'] == '_List_': work.extend(first['args']) else: output.append(fromListItem(first)) return output
def flattenAssoc(input, col, elemConverter=lambda x: x): if not (pyk.isKApply(input) and input['label'] == '_' + col + '_'): return [elemConverter(input)] output = [] work = [arg for arg in input['args']] while len(work) > 0: first = work.pop(0) if pyk.isKApply(first) and first['label'] == '_' + col + '_': work.extend(first['args']) else: output.append(elemConverter(first)) return output
def prettyPrintRule(kRule, symbolTable): newRule = pyk.KRule(pyk.pushDownRewrites(kRule['body']), requires = kRule['requires'], ensures = kRule['ensures'], att = kRule['att']) minRule = pyk.minimizeRule(newRule) ruleBody = minRule['body'] if pyk.isKApply(ruleBody) and ruleBody['label'] == '<generatedTop>': ruleBody = ruleBody['args'][0] minRule['body'] = insertDots(ruleBody) return pyk.prettyPrintKast(minRule, symbolTable)
def detect_violations(config): (_, configSubst) = pyk.splitConfigFrom(config) properties = configSubst['PROPERTIES_CELL'] violations = [] for (prop, value) in flattenMap(properties): if pyk.isKApply(value) and value['label'] == 'Violated(_)_KMCD-PROPS_ViolationFSM_ViolationFSM': violations.append(prop['token']) return violations
def gatherConstInts(input, constants = [], non_constants = []): if pyk.isKApply(input) and input['label'] == '_+Int_': (c0, v0s) = gatherConstInts(input['args'][0]) (c1, v1s) = gatherConstInts(input['args'][1]) return (c0 + c1, v0s + v1s) elif pyk.isKToken(input) and input['sort'] == 'Int': return (int(input['token']), []) else: return (0, [input])
def simplifyPlusInt(k): if pyk.isKApply(k): if not (k['label'] == '_+Int_'): return pyk.onChildren(k, lambda x: simplifyPlusInt(x)) (c, vs) = gatherConstInts(k) if not (c == 0): vs.append(KToken(str(c), 'Int')) return buildPlusInt(vs) return k
def extractTrace(config): (_, subst) = pyk.splitConfigFrom(config) pEvents = subst['PROCESSED_EVENTS_CELL'] log_events = flattenList(pEvents) call_events = [] last_event = None for event in log_events: if pyk.isKApply(event) and event[ 'label'] == 'Measure(_,_,_,_,_,_,_,_,_,_,_)_KMCD-PROPS_Measure_Rat_Map_Rat_Rat_Rat_Rat_Rat_Rat_Map_Rat_Map': if last_event is not None: call_events.extend(extractCallEvent(last_event)) last_event = event return call_events
def fromItem(input): if pyk.isKApply(input) and input['label'] in ['ListItem', 'SetItem']: return input['args'][0] return None
def _gatherViolations(fsmMap): if pyk.isKApply(fsmMap) and fsmMap['label'] == '_|->_': if fsmMap['args'][1] == pyk.KConstant( 'Violated_KMCD-PROPS_ViolationFSM'): violations.append(fsmMap['args'][0]['token']) return fsmMap
def _fromMapItem(mi): if pyk.isKApply(mi) and mi['label'] == '_|->_': return (mi['args'][0], mi['args'][1]) return None
def fromListItem(input): if pyk.isKApply(input) and input['label'] == 'ListItem': return input['args'][0] return input