Skip to content

Instantly share code, notes, and snippets.

@sbarratt
Created Sep 26, 2022
Embed
What would you like to do?
ERC-20 Transfers as a Sparse Matrix
from ctc import evm
from scipy import sparse
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
transfers = await evm.async_get_erc20_transfers(
token='0x956f47f50a910163d8bf957cf5846d573e7f87ca',
event_name='Transfer',
)
min_block_number = transfers.index.levels[0].min()
max_block_number = transfers.index.levels[0].max()
addresses = pd.concat([transfers.arg__from, transfers.arg__to]).unique()
address_to_id = dict(zip(addresses, range(len(addresses))))
transfers["from_id"] = transfers.arg__from.apply(lambda x: address_to_id[x])
transfers["to_id"] = transfers.arg__to.apply(lambda x: address_to_id[x])
n = max_block_number + 1 - min_block_number
p = len(addresses)
A = sparse.lil_matrix((n, p))
for i, r in transfers.iterrows():
A[i[0] - min_block_number, r.from_id] -= r.arg__amount
A[i[0] - min_block_number, r.to_id] += r.arg__amount
A = A.tocsc()
print("\nMost recent holdings")
balances_recent = A.T @ np.ones(n)
print("address" + " " * 36 + "balance")
for i in np.argsort(-balances_recent)[:10]:
print(addresses[i], "%.2f" % balances_recent[i])
e = np.zeros(n)
e[:14000000-min_block_number] = 1.
balances_14mil = A.T @ e
print("\nHoldings at block 14m")
print("address" + " " * 36 + "balance")
for i in np.argsort(-balances_14mil)[:10]:
print(addresses[i], "%.2f" % balances_14mil[i])
flows = abs(A).sum(axis=1) / 2
flows = pd.DataFrame(flows)
flows.index = min_block_number + np.arange(flows.shape[0])
plt.plot(flows.rolling(100000).mean())
plt.xlabel("block number")
plt.ylabel("100k block rolling flows")
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment