-
Notifications
You must be signed in to change notification settings - Fork 2
/
harness.py
83 lines (63 loc) · 2.37 KB
/
harness.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import boa_ancient as boa
import vyper
from vyper.exceptions import VyperException, ParserException
from eth_abi import abi
from eth_abi.exceptions import InsufficientDataBytes
from helpers.environment import Env
from pythonfuzz.main import PythonFuzz
from pythonfuzz.tracer import set_fail
from eth_utils import decode_hex, to_checksum_address
MAIN_CALL_DATA = decode_hex("dffeadd0") # main function selector
env = Env()
def get_bytecode(odict, name):
for item in odict:
if item[0] == name:
return item[1]["bytecode"]
@PythonFuzz
def fuzz(buf):
# typ = "int256"
# try:
# program = buf.decode("ascii")
# vcontract = vyper.compile_codes({"0":program}).items()
# deploy_bytecode = get_bytecode(vcontract, "0")
# addr, _ = env.deploy_code(bytecode=decode_hex(deploy_bytecode))
# contract_addr = to_checksum_address(addr)
# computation = env.execute_code(
# to_address=contract_addr,
# data=MAIN_CALL_DATA
# )
# compiled, = abi.decode([typ], computation.output)
# except:
# return
# compiled_str = f"{typ}:{compiled}"
# interpreted_str = str(boa.loads(program).main())
# if interpreted_str != compiled_str:
# raise Exception(f"interpreted: {interpreted_str} != compiled: {compiled_str}")
try:
program = buf.decode("ascii")
typ = program.split("main() -> ")[1].split(":")[0]
if not typ:
return
# coverage = sys.settrace(tracer.trace)
vcontract = vyper.compile_codes({"0":program}).items()
deploy_bytecode = get_bytecode(vcontract, "0")
addr, _ = env.deploy_code(bytecode=decode_hex(deploy_bytecode))
contract_addr = to_checksum_address(addr)
computation = env.execute_code(
to_address=contract_addr,
data=MAIN_CALL_DATA
)
compiled, = abi.decode([typ], computation.output)
if(typ == "bytes32"):
compiled = int(compiled.hex(), 16)
compiled_str = f"{typ}:{compiled}"
# print(compiled_str)
interpreted_str = str(boa.loads(program).main())
# print(interpreted_str)
except:
set_fail()
return
if interpreted_str != compiled_str:
raise Exception(f"interpreted: {interpreted_str} != compiled: {compiled_str}")
if __name__ == "__main__":
fuzz()