forked from ccyanxyz/cycle-arb-analysis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
get_all_cycle_arbs.py
106 lines (99 loc) · 3.97 KB
/
get_all_cycle_arbs.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import json
import time
from common import *
sync_topic = "0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"
swap_topic = "0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"
mint_topic = "0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f"
burn_topic = "0xdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496"
c = w3.eth.contract(abi=pairABI)
def to_log_receipt(l):
l['blockHash'] = bytes.fromhex(l['blockHash'][2:])
l['blockNumber'] = int(l['blockNumber'], 16)
l['transactionIndex'] = int(l['transactionIndex'], 16)
l['transactionHash'] = bytes.fromhex(l['transactionHash'][2:])
l['logIndex'] = int(l['logIndex'], 16)
l['address'] = w3.toChecksumAddress(l['address'])
l['topics'] = [bytes.fromhex(t[2:]) for t in l['topics']]
l['data'] = bytes.fromhex(l['data'][2:])
return l
def to_tx_receipt(r):
r['blockHash'] = None if not r['blockHash'] else bytes.fromhex(r['blockHash'][2:])
r['blockNumber'] = None if not r['blockNumber'] else int(r['blockNumber'], 16)
r['transactionIndex'] = None if not r['transactionIndex'] else int(r['transactionIndex'], 16)
r['transactionHash'] = bytes.fromhex(r['transactionHash'][2:])
r['cumulativeGasUsed'] = int(r['cumulativeGasUsed'], 16)
r['status'] = int(r['status'], 16)
r['gasUsed'] = int(r['gasUsed'], 16)
r['contractAddress'] = None if not r['contractAddress'] else w3.toChecksumAddress(r['contractAddress'])
r['logs'] = [to_log_receipt(t) for t in r['logs']]
r['logsBloom'] = bytes.fromhex(r['logsBloom'][2:])
r['from'] = None if not r['from'] else w3.toChecksumAddress(r['from'])
r['to'] = w3.toChecksumAddress(r['to'])
return r
pairs = []
pairs_dict = {}
def to_dict(pairs):
d = {}
for i in range(len(pairs)):
d[pairs[i]['id']] = i
return d
def parse_cycle_arb(info):
receipt = info['receipt']
if len(receipt['logs']) <= 1:
return None
path = []
amounts = []
for log in receipt['logs']:
if not len(log['topics']) or not log['topics'][0] == swap_topic:
continue
pair = None
addr = w3.toChecksumAddress(log['address'])
try:
pair = pairs[pairs_dict[addr]]
except Exception as e:
pass
if not pair:
continue
l = to_log_receipt(log.copy())
event = c.events.Swap().processLog(l)
input_token = pair['token0']['id']
input_amount = event['args']['amount0In']
output_token = pair['token1']['id']
output_amount = event['args']['amount1Out']
if event['args']['amount1In'] > 0:
input_token = pair['token1']['id']
input_amount = event['args']['amount1In']
output_token = pair['token0']['id']
output_amount = event['args']['amount0Out']
path.append(input_token)
amounts.append(input_amount)
path.append(output_token)
amounts.append(output_amount)
if len(path) >= 3 and path[0] == path[-1]:
revenue = amounts[-1] - amounts[0]
tx = info['tx']
cost = int(tx['gasPrice'], 16)*int(receipt['gasUsed'], 16)
return { 'tx': tx, 'receipt': receipt, 'path': path, 'amounts': amounts, 'revenue': revenue, 'cost': cost }
return None
def process_receipts():
with open('/data/receipts_export_new', 'r') as f:
idx = 0
for _ in range(6357186):
idx += 1
next(f)
count = 0
for line in f:
info = json.loads(line)
r = info['receipt']
print('block: ', int(r['blockNumber'], 16), '/ 11709847', 'line:', idx, 'count:', count)
idx += 1
ret = parse_cycle_arb(info)
if not ret:
continue
count += 1
with open('/data/uniarb', 'a') as f1:
f1.write(json.dumps(ret)+"\n")
if __name__ == '__main__':
pairs = json.load(open('data/pairs.json'))
pairs_dict = to_dict(pairs)
process_receipts()