-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaudit_tezos.py
More file actions
107 lines (96 loc) · 4.81 KB
/
Copy pathaudit_tezos.py
File metadata and controls
107 lines (96 loc) · 4.81 KB
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
107
#!/usr/bin/env python3
"""Audit the Tezos NFT spend CSV — look for double-counting, DeFi mis-classification,
and provide top-N tx for user verification.
"""
from __future__ import annotations
import csv
import sys
from collections import defaultdict, Counter
from pathlib import Path
sys.stdout.reconfigure(encoding="utf-8")
CSV = Path(__file__).parent / "nft_spend_tezos.csv"
rows = list(csv.DictReader(CSV.open(encoding="utf-8")))
for r in rows:
r["xtz"] = float(r["xtz"])
r["usd"] = float(r["usd"]) if r["usd"] else 0.0
print(f"Total rows: {len(rows)}")
print(f"Total XTZ: {sum(r['xtz'] for r in rows):,.2f}")
print(f"Total USD: ${sum(r['usd'] for r in rows):,.2f}\n")
# ---- 1. Double-counting check: does same hash appear in multiple rows? ----
hash_counts = Counter(r["hash"] for r in rows)
dups = {h: c for h, c in hash_counts.items() if c > 1}
print(f"=== DUPLICATE HASH CHECK ===")
print(f" Unique tx hashes: {len(hash_counts)}")
print(f" Hashes appearing >1 time: {len(dups)}")
if dups:
# show a sample
print(f" Sample duplicates:")
for h, c in list(dups.items())[:5]:
same_hash_rows = [r for r in rows if r["hash"] == h]
total_xtz = sum(r["xtz"] for r in same_hash_rows)
print(f" {h} -> {c} rows, total {total_xtz:.2f} XTZ")
for r in same_hash_rows[:3]:
print(f" {r['marketplace']:30s} {r['entrypoint']:20s} {r['xtz']:.2f} XTZ -> {r['target_alias'] or r['target'][:15]}")
print()
# ---- 2. Top 25 single biggest tx ----
print("=== TOP 25 INDIVIDUAL OPERATIONS BY USD ===")
print(f" {'time':20s} {'marketplace':28s} {'entrypoint':20s} {'XTZ':>10s} {'USD':>10s} hash")
for r in sorted(rows, key=lambda x: -x["usd"])[:25]:
print(f" {r['timestamp'][:19]:20s} {r['marketplace'][:28]:28s} {(r['entrypoint'] or '')[:20]:20s} {r['xtz']:>10.2f} ${r['usd']:>9,.2f} {r['hash']}")
print()
# ---- 3. fxhash V2 entrypoint breakdown ----
print("=== fxhash MARKETPLACE V2 ENTRYPOINTS ===")
fx = [r for r in rows if "fxhash (mkt v2)" in r["marketplace"]]
ep_breakdown = defaultdict(lambda: {"count": 0, "xtz": 0.0, "usd": 0.0})
for r in fx:
e = r["entrypoint"] or "(none)"
ep_breakdown[e]["count"] += 1
ep_breakdown[e]["xtz"] += r["xtz"]
ep_breakdown[e]["usd"] += r["usd"]
for ep, v in sorted(ep_breakdown.items(), key=lambda x: -x[1]["usd"]):
print(f" {ep:25s} {v['count']:>4d} tx {v['xtz']:>9.2f} XTZ ${v['usd']:>9,.2f}")
print()
# ---- 4. fxhash (by alias) entrypoint breakdown ----
print("=== fxhash (by alias) ENTRYPOINTS ===")
fxa = [r for r in rows if r["marketplace"] == "fxhash (by alias)"]
ep_b = defaultdict(lambda: {"count": 0, "xtz": 0.0, "usd": 0.0, "targets": Counter()})
for r in fxa:
e = r["entrypoint"] or "(none)"
ep_b[e]["count"] += 1
ep_b[e]["xtz"] += r["xtz"]
ep_b[e]["usd"] += r["usd"]
ep_b[e]["targets"][r["target"]] += 1
for ep, v in sorted(ep_b.items(), key=lambda x: -x[1]["usd"]):
top_targets = ", ".join(f"{a[:12]}..({c})" for a, c in v["targets"].most_common(3))
print(f" {ep:25s} {v['count']:>4d} tx {v['xtz']:>9.2f} XTZ ${v['usd']:>9,.2f} top targets: {top_targets}")
print()
# ---- 5. "other NFT mint/claim" suspicious bucket: list which contracts ----
print("=== 'other NFT mint/claim (custom contract)' BREAKDOWN ===")
other = [r for r in rows if r["marketplace"] == "other NFT mint/claim (custom contract)"]
by_target = defaultdict(lambda: {"count": 0, "xtz": 0.0, "usd": 0.0, "eps": Counter(), "alias": None})
for r in other:
by_target[r["target"]]["count"] += 1
by_target[r["target"]]["xtz"] += r["xtz"]
by_target[r["target"]]["usd"] += r["usd"]
by_target[r["target"]]["eps"][r["entrypoint"] or "(none)"] += 1
by_target[r["target"]]["alias"] = r["target_alias"]
for addr, v in sorted(by_target.items(), key=lambda x: -x[1]["usd"])[:20]:
eps = ", ".join(f"{e}({c})" for e, c in v["eps"].most_common(3))
print(f" {addr} {(v['alias'] or '')[:25]:25s} {v['count']:>3d} tx {v['xtz']:>7.2f} XTZ ${v['usd']:>8,.2f} eps: {eps}")
print()
# ---- 6. JWT pay contract detail ----
print("=== USD-pegged NFT pay (KT1QKCVV36RX...) — detailed tx list ===")
jwt = [r for r in rows if r["target"] == "KT1QKCVV36RXtsaarVYTda4spdH7c8R6j3am"]
for r in sorted(jwt, key=lambda x: x["timestamp"]):
print(f" {r['timestamp'][:19]} {r['xtz']:>8.2f} XTZ ${r['usd']:>6.2f} {r['hash']}")
print()
# ---- 7. By target_alias to spot any DeFi-looking aliases that snuck in ----
print("=== ALL TARGET ALIASES SEEN (sorted by total USD) ===")
by_alias = defaultdict(lambda: {"count": 0, "xtz": 0.0, "usd": 0.0})
for r in rows:
a = r["target_alias"] or "(no alias)"
by_alias[a]["count"] += 1
by_alias[a]["xtz"] += r["xtz"]
by_alias[a]["usd"] += r["usd"]
for a, v in sorted(by_alias.items(), key=lambda x: -x[1]["usd"]):
print(f" {a[:50]:50s} {v['count']:>4d} tx {v['xtz']:>9.2f} XTZ ${v['usd']:>9,.2f}")