Skip to content

Instantly share code, notes, and snippets.

@michalisFr
Created February 27, 2024 09:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michalisFr/a59d9da2b346a581aa8dedc171393534 to your computer and use it in GitHub Desktop.
Save michalisFr/a59d9da2b346a581aa8dedc171393534 to your computer and use it in GitHub Desktop.
pool-incorrect-rewards
import http.client
import json
import time
import csv
conn = http.client.HTTPSConnection("polkadot.api.subscan.io")
headers = {
'User-Agent': 'Apidog/1.0.0 (https://apidog.com)',
'Content-Type': 'application/json',
'X-API-KEY': ''
}
tfl = 0
refunds = 0
latest_id = 0
def get_pools_that_have_destroyed():
payload = json.dumps({
"event_id": "statechanged",
"page": 0,
"row": 90
})
conn.request("POST", "/api/v2/scan/events", payload, headers)
res = conn.getresponse()
data = res.read()
data = json.loads(data.decode("utf-8"))
data = data['data']['events']
pools = set()
for i in range(len(data)):
event = data[i]
index = event['event_index']
payload = json.dumps({
"event_index": index
})
conn.request("POST", "/api/scan/event", payload, headers)
res = conn.getresponse()
event_data = res.read()
event_data = event_data.decode("utf-8")
event_data = json.loads(event_data)
pool_id = event_data['data']['params'][0]['value']
target_state = event_data['data']['params'][1]['value']
print(pool_id, target_state)
if target_state == "Destroying":
pools.add(pool_id)
time.sleep(.1)
return list(pools)
def get_extrinsic_info(index):
payload = json.dumps({
"extrinsic_index": index
})
conn.request("POST", "/api/scan/extrinsic", payload, headers)
res = conn.getresponse()
data = res.read()
data = json.loads(data.decode("utf-8"))
return data['data']
def detect_incorrect_unbond(page):
global tfl
global refunds
global latest_id
if page >= 200:
payload = json.dumps({
"call": "unbond",
"module": "nominationpools",
"after_id": latest_id,
"row": 50,
"success": True,
})
else:
payload = json.dumps({
"call": "unbond",
"module": "nominationpools",
"page": page,
"row": 50,
"success": True,
})
conn.request("POST", "/api/v2/scan/extrinsics", payload, headers)
res = conn.getresponse()
data = res.read()
# load into json recursively
data = json.loads(data.decode("utf-8"))
extrinsics = data['data']['extrinsics']
for i in range(len(extrinsics)):
# time.sleep(.1)
extrinsic = extrinsics[i]
latest_id = extrinsic['id']
if not extrinsic['success']:
continue
ext_data = get_extrinsic_info(extrinsic['extrinsic_index'])
if ext_data['params'][0]['type_name'] == 'AccountIdLookupOf':
correct_reward_recipient = ext_data['params'][0]['value']['Id']
else:
correct_reward_recipient = ext_data['params'][0]['value']
events = ext_data['event']
for e in events:
if e['module_id'] == 'nominationpools' and e['event_id'] == 'PaidOut':
params = json.loads(e['params'])
reward_recipient = params[0]['value']
if reward_recipient != correct_reward_recipient:
amount = int(params[2]['value'])
pool_id = params[1]['value']
tfl += amount
refunds += 1
with open('results-polkadot.csv', 'a', newline='') as file:
w = csv.writer(file, delimiter=',')
w.writerow((pool_id, extrinsic['extrinsic_index'], reward_recipient, correct_reward_recipient, amount, tfl, refunds))
print(f"done with page {page}, got {len(extrinsics)} exts, tfl: {tfl}, refunds: {refunds}, last id: {latest_id}")
if len(extrinsics) != 50:
print(f"Extrinsics < 50: {len(extrinsics)}")
return True
if __name__ == '__main__':
with open('results-polkadot.csv', 'w', newline='') as file:
w = csv.writer(file, delimiter=',')
w.writerow(['Pool ID', 'Extrinsic ID', 'Reward recipient', 'Correct reward recipient', 'Amount', 'Total amount', 'Total refunds'])
page = 0
while True:
if detect_incorrect_unbond(page):
break
page += 1
print(f"Total refunds: {refunds}, TFL: {tfl / 1e10}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment