import json, sys, collections sys.argv = [sys.argv[0], "/opt/fw2/h4e34.json", "0"] exec(open("/opt/fw2/dsafe.py").read().split("d = json.load")[0]) SWAP = "0x40e9cecb9f5f1f1c5b9c97dec2917b7ee92e57ba5563708daca94dd84ad7112f" TR = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" DH = "0x9982538f41f2ae29ddb9d3d9307010052984fdbb" pid = sys.argv[3] if len(sys.argv) > 3 else "0x9a39cae63db4a1f5b7f2e1cbae9550ca67bcd1154e3cf84e5cccaa1735ae3ff5" asset = "0x970eb45870c2b5e4519140e68fccce2f0cab1ba3" head = int(rpc("eth_blockNumber", [])["result"], 16) def s(h): v = int(h, 16); return v - (1 << 256) if v >> 255 else v L = [] x = head - 120000 while x <= head: y = min(head, x + 9999) L += rpc("eth_getLogs", [{"address": PM, "topics": [SWAP, pid], "fromBlock": hex(x), "toBlock": hex(y)}]).get("result") or [] x = y + 1 bytx = collections.OrderedDict() for l in L: d = l["data"][2:] bytx.setdefault(l["transactionHash"], []).append((int(l["blockNumber"], 16), "0x" + l["topics"][2][26:], s(d[:64]) / 1e18, s(d[64:128]) / 1e18)) print("swaps", len(L), "txs", len(bytx)) for tx, sw in list(bytx.items())[:40]: print(tx, [(b, snd[:10], round(a0, 6), round(a1, 0)) for b, snd, a0, a1 in sw]) # hook state calls for sig in ("getFeeRoutingMode(bytes32)", "getFeeDistributionInfo(bytes32)", "getHookFees(bytes32)", "getPoolInfo(bytes32)"): from Crypto.Hash import keccak as K h = K.new(digest_bits=256); h.update(sig.encode()) r = call(DH, "0x" + h.hexdigest()[:8] + pid[2:]) print(sig, [int(w, 16) for w in words(r["result"])] if r.get("result") else r.get("error")) # asset transfers to dead / zero (burns) in last window T = [] x = head - 120000 while x <= head: y = min(head, x + 9999) T += rpc("eth_getLogs", [{"address": asset, "topics": [TR], "fromBlock": hex(x), "toBlock": hex(y)}]).get("result") or [] x = y + 1 dst = collections.Counter("0x" + l["topics"][2][26:] for l in T) print("asset transfers", len(T), "top receivers", dst.most_common(6))