gauravlochab commited on
Commit
174e0f0
·
1 Parent(s): e165379

feat: refactore code and add corrected apr and roi values

Browse files
.gitignore ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Virtual Environment
2
+ modius_env/
3
+
4
+ # Python
5
+ __pycache__/
6
+ *.py[cod]
7
+ *$py.class
8
+ *.so
9
+ .Python
10
+ build/
11
+ develop-eggs/
12
+ dist/
13
+ downloads/
14
+ eggs/
15
+ .eggs/
16
+ lib/
17
+ lib64/
18
+ parts/
19
+ sdist/
20
+ var/
21
+ wheels/
22
+ pip-wheel-metadata/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ *.manifest
31
+ *.spec
32
+
33
+ # Installer logs
34
+ pip-log.txt
35
+ pip-delete-this-directory.txt
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ *.py,cover
48
+ .hypothesis/
49
+ .pytest_cache/
50
+
51
+ # Jupyter Notebook
52
+ .ipynb_checkpoints
53
+
54
+ # IPython
55
+ profile_default/
56
+ ipython_config.py
57
+
58
+ # pyenv
59
+ .python-version
60
+
61
+ # pipenv
62
+ Pipfile.lock
63
+
64
+ # PEP 582
65
+ __pypackages__/
66
+
67
+ # Celery stuff
68
+ celerybeat-schedule
69
+ celerybeat.pid
70
+
71
+ # SageMath parsed files
72
+ *.sage.py
73
+
74
+ # Environments
75
+ .env
76
+ .venv
77
+ env/
78
+ venv/
79
+ modius_env/
80
+ ENV/
81
+ env.bak/
82
+ venv.bak/
83
+
84
+ # Spyder project settings
85
+ .spyderproject
86
+ .spyproject
87
+
88
+ # Rope project settings
89
+ .ropeproject
90
+
91
+ # mkdocs documentation
92
+ /site
93
+
94
+ # mypy
95
+ .mypy_cache/
96
+ .dmypy.json
97
+ dmypy.json
98
+
99
+ # Pyre type checker
100
+ .pyre/
101
+
102
+ # IDE
103
+ .vscode/
104
+ .idea/
105
+ *.swp
106
+ *.swo
107
+ *~
108
+
109
+ # OS
110
+ .DS_Store
111
+ .DS_Store?
112
+ ._*
113
+ .Spotlight-V100
114
+ .Trashes
115
+ ehthumbs.db
116
+ Thumbs.db
117
+
118
+ # Logs
119
+ *.log
120
+ logs/
121
+
122
+ # Cache files
123
+ cache/
124
+ *.cache
125
+
126
+ # Temporary files
127
+ *.tmp
128
+ *.temp
129
+ temp/
130
+ tmp/
131
+
132
+ # Generated files
133
+ *.html
134
+ *.png
135
+ *.csv
app.py CHANGED
The diff for this file is too large to render. See raw diff
 
app_trans_new.py DELETED
@@ -1,570 +0,0 @@
1
- import requests
2
- import pandas as pd
3
- import gradio as gr
4
- import plotly.express as px
5
- from datetime import datetime, timedelta
6
- import plotly.graph_objects as go
7
- import numpy as np
8
- import json
9
- from web3 import Web3
10
- import time
11
- import os
12
- from itertools import product
13
- # RPC URLs
14
- from dotenv import load_dotenv
15
- load_dotenv()
16
-
17
- OPTIMISM_RPC_URL = os.getenv('OPTIMISM_RPC_URL')
18
- BASE_RPC_URL = os.getenv('BASE_RPC_URL')
19
- ETH_RPC_URL = os.getenv('ETH_RPC_URL')
20
- MODE_RPC_URL = os.getenv('MODE_RPC_URL')
21
-
22
- print(f"Optimism RPC URL: {OPTIMISM_RPC_URL}")
23
-
24
- # Initialize Web3 instances
25
- print("Initializing Web3 instances...")
26
- web3_optimism = Web3(Web3.HTTPProvider(OPTIMISM_RPC_URL))
27
- web3_base = Web3(Web3.HTTPProvider(BASE_RPC_URL))
28
- web3_eth = Web3(Web3.HTTPProvider(ETH_RPC_URL))
29
- web3_mode = Web3(Web3.HTTPProvider(MODE_RPC_URL)) # New chain
30
-
31
- # Contract addresses for service registries
32
- contract_address_optimism = '0x3d77596beb0f130a4415df3D2D8232B3d3D31e44'
33
- contract_address_base = '0x3C1fF68f5aa342D296d4DEe4Bb1cACCA912D95fE'
34
- contract_address_eth = '0x48b6af7B12C71f09e2fC8aF4855De4Ff54e775cA'
35
- contract_address_mode = '0x3C1fF68f5aa342D296d4DEe4Bb1cACCA912D95fE' # New chain
36
-
37
- # Load the ABI from a local JSON file
38
- with open('./contracts/service_registry_abi.json', 'r') as abi_file:
39
- contract_abi = json.load(abi_file)
40
-
41
- # Create the contract instances
42
- service_registry_optimism = web3_optimism.eth.contract(address=contract_address_optimism, abi=contract_abi)
43
- service_registry_base = web3_base.eth.contract(address=contract_address_base, abi=contract_abi)
44
- service_registry_eth = web3_eth.eth.contract(address=contract_address_eth, abi=contract_abi)
45
- service_registry_mode = web3_mode.eth.contract(address=contract_address_mode, abi=contract_abi) # New chain
46
- print("Service registry contracts loaded.")
47
-
48
- # Check if connection is successful
49
- if not web3_optimism.is_connected():
50
- raise Exception("Failed to connect to the Optimism network.")
51
- if not web3_base.is_connected():
52
- raise Exception("Failed to connect to the Base network.")
53
- if not web3_eth.is_connected():
54
- raise Exception("Failed to connect to the ETH network.")
55
- if not web3_mode.is_connected():
56
- raise Exception("Failed to connect to the Mode network.") # New chain
57
- print("Successfully connected to Ethereum, Optimism, Base, and Mode networks.")
58
-
59
-
60
-
61
- def fetch_service_safes(web3, registry_contract):
62
- print("\nFetching service safes...")
63
- total_services = registry_contract.functions.totalSupply().call()
64
- print(f"Total services: {total_services}")
65
- service_safes_dict = {}
66
- zero_address = '0x0000000000000000000000000000000000000000'
67
-
68
- for service_id in range(1, total_services + 1):
69
- print(f"Processing service ID: {service_id}")
70
- service = registry_contract.functions.getService(service_id).call()
71
- agent_ids = service[-1] # Assuming the last element is the list of agent IDs
72
- print(f"Agent IDs: {agent_ids}")
73
-
74
- if 40 in agent_ids or 25 in agent_ids:
75
- agent_instance_data = registry_contract.functions.getAgentInstances(service_id).call()
76
- service_safe = service[1]
77
- agent_addresses = agent_instance_data[1]
78
- if agent_addresses:
79
- agent_address = agent_addresses[0]
80
- if service_safe != zero_address:
81
- print(f"Found agent_address: {agent_address}")
82
- print(f"Found service safe: {service_safe}")
83
- service_safes_dict[agent_address] = service_safe
84
- else:
85
- print(f"Found zero address for service safe, skipping for agent: {agent_address}")
86
- else:
87
- print(f"No agent address found for service ID: {service_id}")
88
-
89
- print(f"Total unique agent addresses found (excluding zero safe addresses): {len(service_safes_dict)}")
90
- return service_safes_dict
91
-
92
- # Fetch service safes for each network
93
- service_safes_optimism = fetch_service_safes(web3_optimism, service_registry_optimism)
94
- service_safes_base = fetch_service_safes(web3_base, service_registry_base)
95
- service_safes_eth = fetch_service_safes(web3_eth, service_registry_eth)
96
- service_safes_mode = fetch_service_safes(web3_mode, service_registry_mode)
97
- # service_safes_eth = {safe for safe in service_safes_eth if safe.lower() != '0x0000000000000000000000000000000000000000'}
98
- print(f"Service safes for Mode: {service_safes_mode}")
99
- def get_block_range_for_date(chain_id, date_str, api_key, base_url):
100
- """Get the block range for a specific date."""
101
- target_date = datetime.strptime(date_str, "%Y-%m-%d").date()
102
- start_of_day = datetime.combine(target_date, datetime.min.time())
103
-
104
- if target_date == datetime.now().date():
105
- end_of_day = datetime.now() # Use the current time if the target date is today
106
- else:
107
- end_of_day = datetime.combine(target_date, datetime.max.time())
108
-
109
- start_timestamp = int(start_of_day.timestamp())
110
- end_timestamp = int(end_of_day.timestamp())
111
-
112
- # Get start block
113
- start_response = requests.get(
114
- f"{base_url}?module=block&action=getblocknobytime&timestamp={start_timestamp}&closest=before&apikey={api_key}"
115
- )
116
- if start_response.status_code == 200:
117
- start_data = start_response.json()
118
- start_block = start_data.get('result')
119
- else:
120
- print(f"Error fetching start block for {date_str} on chain {chain_id}")
121
- return None, None
122
-
123
- if start_block is None:
124
- print(f"No start block found for chain {chain_id} on {date_str}")
125
- return None, None
126
- print(f"Start block for chain {chain_id} on {date_str}: {start_block}")
127
-
128
- # Get end block
129
- time.sleep(1)
130
- end_response = requests.get(
131
- f"{base_url}?module=block&action=getblocknobytime&timestamp={end_timestamp}&closest=before&apikey={api_key}"
132
- )
133
- if end_response.status_code == 200:
134
- end_data = end_response.json()
135
- end_block = end_data.get('result')
136
- else:
137
- print(f"Error fetching end block for {date_str} on chain {chain_id}")
138
- return None, None
139
-
140
- if end_block is None:
141
- print(f"No end block found for chain {chain_id} on {date_str}")
142
- return None, None
143
- print(f"End block for chain {chain_id} on {date_str}: {end_block}")
144
-
145
- return start_block, end_block
146
-
147
- def get_transactions_mode_all(address):
148
- url = f'https://explorer.mode.network/api/v2/addresses/{address}/transactions'
149
- headers = {
150
- 'accept': 'application/json'
151
- }
152
-
153
- response = requests.get(url, headers=headers)
154
- return response.json()['items']
155
-
156
- def get_transactions(api_keys, wallet_address, chain_name, start_block, end_block):
157
- """Retrieve transactions for the given wallet address, chain, and block range using the Etherscan or similar API."""
158
- base_url = {
159
- 'optimism': "https://api-optimistic.etherscan.io/api",
160
- 'base': "https://api.basescan.org/api",
161
- 'ethereum': "https://api.etherscan.io/api",
162
- 'mode': "https://eth-sepolia.blockscout.com/api"
163
- }.get(chain_name)
164
-
165
- if not base_url:
166
- print(f"Invalid chain name: {chain_name}")
167
- return []
168
-
169
- params = {
170
- 'module': 'account',
171
- 'action': 'txlist',
172
- 'address': wallet_address,
173
- 'startblock': start_block,
174
- 'endblock': end_block,
175
- 'sort': 'asc',
176
- 'apikey': api_keys.get(chain_name)
177
- }
178
-
179
- response = requests.get(base_url, params=params)
180
- data = response.json()
181
-
182
- time.sleep(1)
183
-
184
- if data['status'] != '1':
185
- print(f"Error: {data['message']}")
186
- return []
187
-
188
- valid_transactions = [tx for tx in data['result'] if tx['isError'] == '0']
189
-
190
- return valid_transactions
191
-
192
- def get_mode_transactions(transactions_all_base,date_str):
193
- target_date = datetime.strptime(date_str, "%Y-%m-%d").date()
194
- start_of_day = datetime.combine(target_date, datetime.min.time())
195
-
196
- if target_date == datetime.now().date():
197
- end_of_day = datetime.now() # Use the current time if the target date is today
198
- else:
199
- end_of_day = datetime.combine(target_date, datetime.max.time())
200
-
201
- start_timestamp = start_of_day.isoformat()
202
- end_timestamp = end_of_day.isoformat()
203
- processed_list = []
204
- for transaction in transactions_all_base:
205
- # Filter transactions based on the timestamp
206
- if start_timestamp <= transaction['timestamp'] <= end_timestamp:
207
- transaction_timestamp = datetime.strptime(transaction['timestamp'], "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S")
208
- processed_transaction = {
209
- 'hash': transaction['hash'],
210
- 'timeStamp': transaction_timestamp,
211
- 'from': transaction['from']['hash'],
212
- 'to': transaction['to']['hash'],
213
- 'value': transaction['value']
214
- }
215
- processed_list.append(processed_transaction)
216
-
217
- return processed_list
218
-
219
-
220
- def date_range(start_date, end_date):
221
- """Generates a range of dates from start_date to end_date inclusive."""
222
- start_dt = datetime.strptime(start_date, "%Y-%m-%d")
223
- end_dt = datetime.strptime(end_date, "%Y-%m-%d")
224
- delta = timedelta(days=1)
225
- current_dt = start_dt
226
- while current_dt <= end_dt:
227
- yield current_dt.strftime("%Y-%m-%d")
228
- current_dt += delta
229
-
230
- def fetch_transactions():
231
- api_keys = {
232
- 'optimism': 'XQ72JA5XZ51QC7TG1W295AAIF4KTV92K1K',
233
- 'base': '4BFQMVW1QUKEPVDA4VW711CF4462682CY8',
234
- 'ethereum': '3GRYJGX55W3QWCEKGREF4H53AFHCAIVVR7',
235
- 'mode': 'f651444d-2916-4f37-bfd8-e70cc8232eb7'
236
- }
237
-
238
- base_urls = {
239
- 10: "https://api-optimistic.etherscan.io/api",
240
- 8453: "https://api.basescan.org/api",
241
- 1: "https://api.etherscan.io/api",
242
- 3443: "https://eth-sepolia.blockscout.com/api"
243
- }
244
-
245
- current_date = datetime.today().strftime("%Y-%m-%d")
246
- csv_filename = 'daily_transactions_new.csv'
247
-
248
- if os.path.exists(csv_filename):
249
- df_existing = pd.read_csv(csv_filename)
250
- if 'date' in df_existing:
251
- last_date_in_csv = df_existing['date'].max()
252
- else:
253
- df_existing['date'] = pd.to_datetime(df_existing['timestamp']).dt.date
254
- last_date_in_csv = df_existing['date'].max()
255
- else:
256
- df_existing = pd.DataFrame()
257
- last_date_in_csv = '2024-09-19'
258
-
259
- start_date = (datetime.strptime(last_date_in_csv, "%Y-%m-%d") + timedelta(days=1)).strftime("%Y-%m-%d")
260
-
261
- chains = {
262
- 10: ('optimism', service_safes_optimism),
263
- 8453: ('base', service_safes_base),
264
- 1: ('ethereum', service_safes_eth),
265
- 3443: ('mode', service_safes_mode)
266
- }
267
-
268
- all_transactions = df_existing.to_dict('records') if not df_existing.empty else []
269
-
270
- for chain_id, (chain_name, service_safes) in chains.items():
271
- base_url = base_urls[chain_id]
272
- api_key = api_keys[chain_name]
273
-
274
- for agent_address, safe_address in service_safes.items():
275
- print(f"\nProcessing {chain_name.capitalize()} for agent address {agent_address} (safe address {safe_address})...")
276
- if chain_name == 'mode':
277
- transactions_all_base = get_transactions_mode_all(safe_address)
278
-
279
- for single_date in date_range(start_date, current_date):
280
- if chain_name == 'mode':
281
- print(f"Processing date {single_date} for chain {chain_name}...")
282
- transactions = get_mode_transactions(transactions_all_base,single_date)
283
-
284
- else:
285
- print(f"Processing date {single_date} for chain {chain_name}...")
286
- start_block, end_block = get_block_range_for_date(chain_id, single_date, api_key, base_url)
287
- if start_block is None or end_block is None:
288
- print(f"Skipping date {single_date} for chain {chain_name} due to missing block data.")
289
- continue
290
- print(f"Start Block: {start_block}, End Block: {end_block} for date {single_date}")
291
- transactions = get_transactions(api_keys, safe_address, chain_name, start_block, end_block)
292
-
293
- if transactions:
294
- print(f"Found {len(transactions)} transactions on {single_date} for {chain_name.capitalize()} safe address {safe_address}:")
295
- for tx in transactions:
296
- if chain_name != 'mode':
297
- print(f"Transaction Hash: {tx['hash']} on {chain_name.capitalize()} at {tx['timeStamp']}")
298
- tx_time = datetime.fromtimestamp(int(tx['timeStamp']))
299
- all_transactions.append({
300
- 'chain': chain_name,
301
- 'agent_address': agent_address,
302
- 'safe_address': safe_address,
303
- 'date': single_date,
304
- 'transaction_hash': tx['hash'],
305
- 'timestamp': tx_time,
306
- 'from': tx['from'],
307
- 'to': tx['to'],
308
- 'value_eth': int(tx['value']) / 1e18 # Convert value to ETH
309
- })
310
- else:
311
- all_transactions.append({
312
- 'chain': chain_name,
313
- 'agent_address': agent_address,
314
- 'safe_address': safe_address,
315
- 'date': single_date,
316
- 'transaction_hash': tx['hash'],
317
- 'timestamp': tx['timeStamp'],
318
- 'from': tx['from'],
319
- 'to': tx['to'],
320
- 'value_eth': int(tx['value']) / 1e18 # Convert value to ETH
321
- })
322
-
323
- else:
324
- print(f"No transactions found for agent address {agent_address} (safe address {safe_address}) on {single_date} on {chain_name.capitalize()}.")
325
-
326
- df_transactions_new = pd.DataFrame(all_transactions)
327
- df_transactions_new.to_csv(csv_filename, index=False)
328
- return df_transactions_new
329
-
330
-
331
- def create_transcation_visualizations():
332
- df_transactions_new = fetch_transactions()
333
- df_transactions_new['timestamp'] = pd.to_datetime(df_transactions_new['timestamp'])
334
-
335
- # Group by date and chain, count transactions
336
- daily_counts = df_transactions_new.groupby([df_transactions_new['timestamp'].dt.date, 'chain']).size().unstack(fill_value=0)
337
-
338
- # Ensure required chains are present
339
- chains = ['optimism', 'base', 'ethereum', 'mode']
340
- for chain in chains:
341
- if chain not in daily_counts.columns:
342
- daily_counts[chain] = 0
343
-
344
- daily_counts = daily_counts[chains]
345
-
346
- # Read the original data
347
- daily_counts['timestamp'] = daily_counts.index
348
- daily_counts['timestamp'] = pd.to_datetime(daily_counts['timestamp'])
349
- daily_counts = daily_counts.reset_index(drop=True)
350
- # Get min and max dates
351
- min_date = daily_counts['timestamp'].min()
352
- max_date = daily_counts['timestamp'].max()
353
-
354
- # Create complete date range
355
- full_date_range = pd.date_range(start=min_date, end=max_date, freq='D')
356
-
357
- # Create a new dataframe with all dates
358
- complete_df = pd.DataFrame({'timestamp': full_date_range})
359
- complete_df = complete_df.merge(daily_counts, on='timestamp', how='left')
360
- complete_df = complete_df.fillna(0)
361
- daily_counts = complete_df
362
- # Convert timestamp to datetime
363
- daily_counts['timestamp'] = pd.to_datetime(daily_counts['timestamp'])
364
-
365
- # Create a new dataframe with 12-hour slots
366
- new_rows = []
367
-
368
- for _, row in daily_counts.iterrows():
369
- # Create first 12-hour slot (0-12)
370
- slot1 = row.copy()
371
- # slot1['timestamp'] = row['timestamp'].replace(hour=0)
372
-
373
- # # Create second 12-hour slot (12-24)
374
- new_rows.extend([slot1])
375
- slot2 = row.copy()
376
- if slot2['timestamp'].dayofweek == 6: # 6 represents Sunday
377
- slot2[chains] = 0
378
- slot2['timestamp'] = row['timestamp'].replace(hour=12)
379
- new_rows.extend([slot2])
380
-
381
-
382
-
383
- # Create new dataframe with 12-hour slots
384
- hourly_counts = pd.DataFrame(new_rows).sort_values('timestamp')
385
-
386
- # Prepare data for plotting
387
- dates = hourly_counts['timestamp'].tolist()
388
- values = hourly_counts[chains].to_numpy()
389
-
390
- # Create the figure
391
- fig = go.Figure()
392
- # Create arrays for positioning and width
393
- # Convert dates to datetime objects first
394
- date_objects = pd.to_datetime(dates)
395
-
396
- # Create numeric indices for x-axis
397
- x_numeric = np.arange(len(dates))
398
-
399
- # Create arrays for positioning and width
400
- width_array = []
401
-
402
- for i, date in enumerate(date_objects):
403
- width_array.append(1.0) # Full width for other days
404
-
405
- # Get Monday indices for tick positions
406
- monday_indices = [i for i, date in enumerate(date_objects) if date.dayofweek == 0]
407
- monday_labels = [date_objects[i].strftime('%m-%d') for i in monday_indices]
408
-
409
- # Add traces for each series
410
- fig.add_trace(go.Bar(
411
- name='Optimism',
412
- x=x_numeric,
413
- y=values[:,0],
414
- marker_color='blue',
415
- opacity=0.7,
416
- text=None,
417
- width=width_array,
418
- textposition='none',
419
- ))
420
-
421
- fig.add_trace(go.Bar(
422
- name='Base',
423
- x=x_numeric,
424
- y=values[:,1],
425
- marker_color='purple',
426
- opacity=0.7,
427
- text=None,
428
- textposition='none',
429
- width=width_array,
430
- ))
431
-
432
- fig.add_trace(go.Bar(
433
- name='Ethereum',
434
- x=x_numeric,
435
- y=values[:,2],
436
- marker_color='darkgreen',
437
- opacity=0.7,
438
- text=None,
439
- width=width_array,
440
- textposition='none',
441
- ))
442
-
443
- fig.add_trace(go.Bar(
444
- name='Mode',
445
- x=x_numeric,
446
- y=values[:,3],
447
- marker_color='orange',
448
- opacity=0.7,
449
- text=None,
450
- width=width_array,
451
- textposition='none',
452
- ))
453
-
454
- # Update layout with numeric x-axis
455
- fig.update_layout(
456
- title='Chain Daily Activity : Transactions',
457
- xaxis_title='Date',
458
- yaxis_title='Daily Transactions Count',
459
- barmode='stack',
460
- showlegend=True,
461
- legend_title_text='Transaction Chain',
462
- height=600,
463
- bargap=0,
464
- bargroupgap=0,
465
- xaxis=dict(
466
- tickangle=-45,
467
- tickmode='array',
468
- ticktext=monday_labels,
469
- tickvals=monday_indices,
470
- ),
471
- template='plotly_white',
472
- hoverlabel=dict(
473
- font_size=12,
474
- ),
475
- )
476
-
477
- # Update hover template
478
- for trace in fig.data:
479
- trace.update(
480
- hovertemplate="<b>Date:</b> %{text}<br>" +
481
- "<b>" + trace.name + ":</b> %{y}<br>" +
482
- "<extra></extra>",
483
- text=[d.strftime('%Y-%m-%d') for d in date_objects] # Add date text for hover
484
- )
485
-
486
- # Show the plot
487
- return fig
488
-
489
- def create_active_agents_visualizations():
490
- df_transactions_new = fetch_transactions()
491
- df_transactions_new['timestamp'] = pd.to_datetime(df_transactions_new['timestamp'])
492
- # Extract week and day information
493
- df_transactions_new['week_start'] = df_transactions_new['timestamp'].dt.to_period('W').apply(lambda r: r.start_time)
494
- df_transactions_new['weekday'] = df_transactions_new['timestamp'].dt.weekday
495
-
496
- # Count unique agents per day
497
- daily_agents = df_transactions_new.groupby(['week_start', 'weekday'])['agent_address'].nunique().reset_index()
498
-
499
- # Generate all possible combinations of week_start and weekday up to today
500
- today = datetime.today()
501
- yesterday = today - timedelta(days=1)
502
- valid_weekdays = [(ws, wd) for ws, wd in product(daily_agents['week_start'].unique(), range(7)) if ws + timedelta(days=wd) <= yesterday]
503
-
504
- all_combinations = pd.DataFrame(valid_weekdays, columns=['week_start', 'weekday'])
505
-
506
- # Merge with daily_agents to fill missing days with zero
507
- daily_agents = all_combinations.merge(daily_agents, on=['week_start', 'weekday'], how='left').fillna(0)
508
-
509
- # Compute average unique agents per week
510
- weekly_avg_agents = daily_agents.groupby('week_start')['agent_address'].mean().reset_index()
511
- weekly_avg_agents.rename(columns={'agent_address': 'avg_daily_active_agents'}, inplace=True)
512
-
513
- # Prepare data for plotting
514
- weeks = weekly_avg_agents['week_start'].unique()
515
- avg_agents_per_week = weekly_avg_agents['avg_daily_active_agents']
516
-
517
- # Create the bar chart
518
- fig = go.Figure()
519
-
520
- fig.add_trace(go.Bar(
521
- x=[f'{week.strftime("%b %d")}' for week in weeks],
522
- y=avg_agents_per_week,
523
-
524
- marker_color='blue',
525
- opacity=0.7,
526
- text=None,
527
- hoverlabel=dict(
528
- font_size=12,
529
- ),
530
- ))
531
-
532
- # Update layout
533
- fig.update_layout(
534
- title='Daily Active Agents: Weekly Average Number of Agents with at Least 1 Transaction Daily',
535
- xaxis_title='Week',
536
- yaxis_title='Average Number of Active Agents',
537
- xaxis=dict(
538
- tickangle=-45 # Rotate x-axis labels to 45 degrees
539
- ),
540
- height=600,
541
- width=1000,
542
- bargap=0,
543
- bargroupgap=0.2,
544
- template='plotly_white'
545
- )
546
-
547
- return fig
548
-
549
-
550
- # Gradio interface
551
- def dashboard():
552
- with gr.Blocks() as demo:
553
- gr.Markdown("# Valory Transactions Dashboard")
554
-
555
- # Fetch and display visualizations
556
- with gr.Tab("Transactions"):
557
- fig_tx_chain = create_transcation_visualizations()
558
- gr.Plot(fig_tx_chain)
559
- with gr.Tab("DAA"):
560
- fig_active_agents = create_active_agents_visualizations()
561
- gr.Plot(fig_active_agents)
562
-
563
- # Add more tabs as needed...
564
-
565
- return demo
566
-
567
-
568
- # Launch the dashboard
569
- if __name__ == "__main__":
570
- dashboard().launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app_value_locked.py DELETED
@@ -1,405 +0,0 @@
1
- import json
2
- import requests
3
- from web3 import Web3
4
- from datetime import datetime, timedelta
5
- from typing import List, Dict, Optional
6
- import pandas as pd
7
- import time
8
- import requests
9
- from requests.adapters import HTTPAdapter
10
- from requests.packages.urllib3.util.retry import Retry
11
- import time
12
- import os
13
-
14
- ADDRESSES = {
15
- "optimism": {
16
- "balancer_vault": "0xBA12222222228d8Ba445958a75a0704d566BF2C8",
17
- "uniswap_position_manager": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88"
18
- },
19
- "base": {
20
- "balancer_vault": "0xBA12222222228d8Ba445958a75a0704d566BF2C8",
21
- "uniswap_position_manager": "0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1"
22
- }
23
- }
24
-
25
- # Defining RPC URLs and initializing Web3 instances
26
- OPTIMISM_RPC_URL = os.getenv('OPTIMISM_RPC_URL')
27
- BASE_RPC_URL = os.getenv('BASE_RPC_URL')
28
- ETH_RPC_URL = os.getenv('ETH_RPC_URL')
29
-
30
- print("Initializing Web3 instances...")
31
- web3_optimism = Web3(Web3.HTTPProvider(OPTIMISM_RPC_URL))
32
- web3_base = Web3(Web3.HTTPProvider(BASE_RPC_URL))
33
-
34
- # Contract addresses for service registries
35
- contract_address_optimism = '0x3d77596beb0f130a4415df3D2D8232B3d3D31e44'
36
- contract_address_base = '0x3C1fF68f5aa342D296d4DEe4Bb1cACCA912D95fE'
37
-
38
- # Load the ABI from a local JSON file
39
- with open('./contracts/service_registry_abi.json', 'r') as abi_file:
40
- contract_abi = json.load(abi_file)
41
-
42
- # Create the contract instances
43
- service_registry_optimism = web3_optimism.eth.contract(address=contract_address_optimism, abi=contract_abi)
44
- service_registry_base = web3_base.eth.contract(address=contract_address_base, abi=contract_abi)
45
- print("Service registry contracts loaded.")
46
-
47
- def load_abi(filename):
48
- with open(filename, 'r') as file:
49
- contract_json = json.load(file)
50
- return contract_json['abi']
51
-
52
- UNISWAP_ABI = load_abi('./contracts/NonfungiblePositionManager.json')
53
-
54
- def get_logs(api_key, chain_name, from_block, to_block, contract_address, service_safe):
55
- """Fetch logs for the given contract and wallet address with specified topics."""
56
- base_url = {
57
- 'optimism': "https://api-optimistic.etherscan.io/api",
58
- 'base': "https://api.basescan.org/api"
59
- }.get(chain_name)
60
-
61
- if not base_url:
62
- print(f"Invalid chain name: {chain_name}")
63
- return []
64
- print('formatted safe address for topic', f"0x000000000000000000000000{service_safe[2:].lower()}")
65
- params = {
66
- 'module': 'logs',
67
- 'action': 'getLogs',
68
- 'address': contract_address,
69
- 'fromBlock': from_block,
70
- 'toBlock': to_block,
71
- 'apikey': api_key,
72
- 'topic2': f"0x000000000000000000000000{service_safe[2:].lower()}" # Properly formatted topic2
73
- }
74
-
75
- response = requests.get(base_url, params=params)
76
- data = response.json()
77
-
78
- if data['status'] != '1':
79
- print(f"Error: {data['message']}")
80
- return []
81
-
82
- return data['result']
83
-
84
- def get_block_range_for_date(chain_id, date_str, api_key, base_url):
85
- """Get the block range for a specific date."""
86
- target_date = datetime.strptime(date_str, "%Y-%m-%d")
87
- start_of_day = datetime.combine(target_date, datetime.min.time())
88
- end_of_day = datetime.combine(target_date, datetime.max.time())
89
-
90
- start_timestamp = int(start_of_day.timestamp())
91
- end_timestamp = int(end_of_day.timestamp())
92
-
93
- # Get start block
94
- start_response = requests.get(
95
- f"{base_url}?module=block&action=getblocknobytime&timestamp={start_timestamp}&closest=before&apikey={api_key}"
96
- )
97
- if start_response.status_code == 200:
98
- start_data = start_response.json()
99
- start_block = start_data.get('result')
100
- else:
101
- print(f"Error fetching start block for {date_str} on chain {chain_id}")
102
- return None, None
103
-
104
- if start_block is None:
105
- print(f"No start block found for chain {chain_id} on {date_str}")
106
- return None, None
107
- print(f"Start block for chain {chain_id} on {date_str}: {start_block}")
108
-
109
- # Get end block
110
- end_response = requests.get(
111
- f"{base_url}?module=block&action=getblocknobytime&timestamp={end_timestamp}&closest=before&apikey={api_key}"
112
- )
113
- if end_response.status_code == 200:
114
- end_data = end_response.json()
115
- end_block = end_data.get('result')
116
- else:
117
- print(f"Error fetching end block for {date_str} on chain {chain_id}")
118
- return None, None
119
-
120
- if end_block is None:
121
- print(f"No end block found for chain {chain_id} on {date_str}")
122
- return None, None
123
- print(f"End block for chain {chain_id} on {date_str}: {end_block}")
124
-
125
- return start_block, end_block
126
-
127
- def date_range(start_date, end_date):
128
- """Generates a range of dates from start_date to end_date inclusive."""
129
- start_dt = datetime.strptime(start_date, "%Y-%m-%d")
130
- end_dt = datetime.strptime(end_date, "%Y-%m-%d")
131
- delta = timedelta(days=1)
132
- current_dt = start_dt
133
- while current_dt <= end_dt:
134
- yield current_dt.strftime("%Y-%m-%d")
135
- current_dt += delta
136
-
137
- def parse_transfer_log(chain_name, single_date, log):
138
- # ERC-721 Transfer event signature
139
- TRANSFER_EVENT_SIGNATURE = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
140
-
141
- if log['topics'][0].lower() == TRANSFER_EVENT_SIGNATURE.lower():
142
- # This is a Transfer event
143
- return {
144
- "chain_name": chain_name,
145
- "date": single_date,
146
- "event": "Transfer",
147
- "topic_0": log['topics'][0],
148
- "from": "0x" + log['topics'][1][-40:], # Extract the address from the padded topic
149
- "to": "0x" + log['topics'][2][-40:], # Extract the address from the padded topic
150
- "token_id": int(log['topics'][3], 16) # Convert hex to decimal
151
- }
152
-
153
- # If no Transfer event is found
154
- return None
155
-
156
- def parse_pool_balance_log(chain_name, single_date, log):
157
- POOL_BALANCE_SIGNATURE = "0xe5ce249087ce04f05a957192435400fd97868dba0e6a4b4c049abf8af80dae78"
158
- if log['topics'][0].lower() == POOL_BALANCE_SIGNATURE.lower():
159
- # Event PoolBalanceChanged: (bytes32 poolId, address liquidityProvider, address[] tokens, int256[] deltas, uint256[] protocolFeeAmounts)
160
- return {
161
- "chain_name": chain_name,
162
- "date": single_date,
163
- "event": "PoolBalanceChanged",
164
- "poolId": log['topics'][1],
165
- "liquidityProvider": "0x" + log['topics'][2][-40:], # Extract the address from the padded topic
166
- "tokens": [log['data'][i:i + 64] for i in range(0, len(log['data']), 64)],
167
- "deltas": [int(log['data'][i:i + 64], 16) for i in range(0, len(log['data']), 64)],
168
- "protocolFeeAmounts": [int(log['data'][i:i + 64], 16) for i in range(0, len(log['data']), 64)]
169
- }
170
-
171
- def fetch_service_safes(web3, registry_contract):
172
- print("\nFetching service safes...")
173
- total_services = registry_contract.functions.totalSupply().call()
174
- print(f"Total services: {total_services}")
175
- service_safes = set()
176
-
177
- for service_id in range(1, total_services + 1):
178
- service = registry_contract.functions.getService(service_id).call()
179
- agent_ids = service[-1] # Assuming the last element is the list of agent IDs
180
-
181
- if 40 in agent_ids:
182
- service_safe = service[1]
183
- service_safes.add(service_safe)
184
-
185
- print(f"Total service safes found: {len(service_safes)}")
186
- return service_safes
187
-
188
- def get_uniswap_v3_position(web3, contract_address, token_id):
189
- """Fetch the Uniswap V3 position details including `token0`, `token1`."""
190
- position_manager_contract = web3.eth.contract(address=contract_address, abi=UNISWAP_ABI)
191
- position_data = position_manager_contract.functions.positions(token_id).call()
192
- return {
193
- 'token0': position_data[2],
194
- 'token1': position_data[3]
195
- }
196
-
197
- def get_uniswap_increase_liquidity(api_key, chain_name, token_id):
198
- """Fetch the IncreaseLiquidity event details including `amount0`, `amount1`."""
199
- base_url = {
200
- 'optimism': "https://api-optimistic.etherscan.io/api",
201
- 'base': "https://api.basescan.org/api"
202
- }.get(chain_name)
203
-
204
- if not base_url:
205
- print(f"Invalid chain name: {chain_name}")
206
- return {}
207
-
208
- params = {
209
- 'module': 'logs',
210
- 'action': 'getLogs',
211
- 'address': ADDRESSES[chain_name]['uniswap_position_manager'],
212
- 'topic0': "0x3067048beee31b25b2f1681f88dac838c8bba36af25bfb2b7cf7473a5847e35f",
213
- 'topic1': f"0x{token_id:064x}",
214
- 'apikey': api_key
215
- }
216
-
217
- response = requests.get(base_url, params=params)
218
- data = response.json()
219
-
220
- if data['status'] != '1':
221
- print(f"Error: {data['message']}")
222
- return {}
223
-
224
- log = data['result'][0] if data['result'] else None
225
- if not log:
226
- return {}
227
-
228
- # Extracting amounts from the data hex-string
229
- data_hex = log['data'][2:] # Remove '0x' prefix
230
- liquidity = int(data_hex[0:64], 16)
231
- amount0 = int(data_hex[64:128], 16)
232
- amount1 = int(data_hex[128:192], 16)
233
-
234
- return {
235
- 'liquidity': liquidity,
236
- 'amount0': amount0,
237
- 'amount1': amount1
238
- }
239
-
240
- def get_token_decimals(web3, token_address):
241
- """Fetch the number of decimals for a given ERC-20 token."""
242
- token_contract = web3.eth.contract(address=token_address, abi=[
243
- {"constant":True,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":False,"stateMutability":"view","type":"function"}
244
- ])
245
- return token_contract.functions.decimals().call()
246
-
247
-
248
-
249
- def requests_retry_session(
250
- retries=3,
251
- backoff_factor=0.3,
252
- status_forcelist=(500, 502, 504),
253
- session=None,
254
- ):
255
- session = session or requests.Session()
256
- retry = Retry(
257
- total=retries,
258
- read=retries,
259
- connect=retries,
260
- backoff_factor=backoff_factor,
261
- status_forcelist=status_forcelist,
262
- )
263
- adapter = HTTPAdapter(max_retries=retry)
264
- session.mount('http://', adapter)
265
- session.mount('https://', adapter)
266
- return session
267
-
268
- def get_token_price_usd(chain, token_address):
269
- chain_dict = {"optimism": "optimistic-ethereum", "base": "base", "ethereum": "ethereum"}
270
- chain_name = chain_dict.get(chain, chain)
271
- time.sleep(4)
272
- url = f"https://api.coingecko.com/api/v3/simple/token_price/{chain_name}?contract_addresses={token_address}&vs_currencies=usd"
273
-
274
- headers = {
275
- "accept": "application/json",
276
- "x-cg-api-key": "CG-mf5xZnGELpSXeSqmHDLY2nNU"
277
- }
278
-
279
- try:
280
- response = requests_retry_session().get(url, headers=headers, timeout=10)
281
- response.raise_for_status()
282
- data = response.json()
283
-
284
- # Extract USD price
285
- key = token_address.lower()
286
- return data.get(key, {}).get('usd', None)
287
- except requests.exceptions.RequestException as e:
288
- print(f"An error occurred: {e}")
289
- return None
290
-
291
- def load_existing_transactions(file_path):
292
- """Load existing transactions from a CSV file."""
293
- try:
294
- return pd.read_csv(file_path)
295
- except FileNotFoundError:
296
- return pd.DataFrame()
297
-
298
- def get_last_processed_date(df):
299
- """Get the last processed date from the DataFrame."""
300
- if df.empty:
301
- return None
302
- return df['date'].max()
303
-
304
- # Main function to integrate the above based on provided context
305
- def fetch_daily_value_locked():
306
- api_keys = {
307
- 'optimism': 'XQ72JA5XZ51QC7TG1W295AAIF4KTV92K1K',
308
- 'base': '4BFQMVW1QUKEPVDA4VW711CF4462682CY8'
309
- }
310
-
311
- base_urls = {
312
- 10: "https://api-optimistic.etherscan.io/api",
313
- 8453: "https://api.basescan.org/api"
314
- }
315
-
316
- # Load existing transactions if any
317
- existing_transactions_path = 'daily_value_locked.csv'
318
- df_existing_transactions = load_existing_transactions(existing_transactions_path)
319
- last_processed_date = get_last_processed_date(df_existing_transactions)
320
-
321
- # Determine the start date based on the last processed date
322
- start_date = (pd.to_datetime(last_processed_date) + timedelta(days=1)).strftime('%Y-%m-%d') if last_processed_date else '2024-09-19'
323
- current_date = datetime.now().strftime('%Y-%m-%d') # Till present date
324
-
325
- chains = {
326
- 10: ('optimism', 'uniswap_position_manager', 'balancer_vault'),
327
- 8453: ('base', 'uniswap_position_manager', 'balancer_vault')
328
- }
329
-
330
- # Example service safe addresses - Replace these with actual addresses
331
- print("Fetching service safes for Optimism...")
332
- service_safes_optimism = fetch_service_safes(web3_optimism, service_registry_optimism)
333
- print(service_safes_optimism)
334
- print("Fetching service safes for Base...")
335
- service_safes_base = fetch_service_safes(web3_base, service_registry_base)
336
- print(service_safes_base)
337
-
338
- service_safes = {
339
- 'optimism': service_safes_optimism,
340
- 'base': service_safes_base
341
- }
342
-
343
- all_transactions = [] # List to hold all parsed logs
344
-
345
- for chain_id, (chain_name, uniswap_contract_key, balancer_contract_key) in chains.items():
346
- base_url = base_urls[chain_id]
347
- api_key = api_keys[chain_name]
348
-
349
- for service_safe in service_safes[chain_name]:
350
- print(f"Checking service safe {service_safe} for chain {chain_name}")
351
- for single_date in date_range(start_date, current_date):
352
- start_block, end_block = get_block_range_for_date(chain_id, single_date, api_key, base_url)
353
- if start_block is None or end_block is None:
354
- print(f"Skipping date {single_date} for chain {chain_name} due to missing block data.")
355
- continue
356
-
357
- print(f"Start Block: {start_block}, End Block: {end_block} for date {single_date} on chain {chain_name} for service safe {service_safe}")
358
-
359
- # Get logs for Uniswap and Balancer contracts
360
- for contract_key, topic_key in [(uniswap_contract_key, "transfer"), (balancer_contract_key, "pool_balance_changed")]:
361
- contract_address = ADDRESSES[chain_name][contract_key]
362
- print(api_key, chain_name, start_block, end_block, contract_address, service_safe)
363
- logs = get_logs(api_key, chain_name, start_block, end_block, contract_address, service_safe)
364
-
365
- for log in logs:
366
- parsed_log = parse_pool_balance_log(chain_name, single_date, log) if topic_key == "pool_balance_changed" else parse_transfer_log(chain_name, single_date, log)
367
- if parsed_log:
368
- if topic_key == "transfer":
369
- # If the event is a Transfer event, fetch uniswap position details and increase liquidity event details
370
- uniswap_v3_data = get_uniswap_v3_position(web3_base if chain_name == 'base' else web3_optimism, contract_address, parsed_log['token_id'])
371
- increase_liquidity_data = get_uniswap_increase_liquidity(api_key, chain_name, parsed_log['token_id'])
372
-
373
- token0_address = uniswap_v3_data['token0']
374
- token1_address = uniswap_v3_data['token1']
375
- decimals_token0 = get_token_decimals(web3_base if chain_name == 'base' else web3_optimism, token0_address)
376
- decimals_token1 = get_token_decimals(web3_base if chain_name == 'base' else web3_optimism, token1_address)
377
- print(decimals_token0,decimals_token1)
378
- increase_liquidity_data['amount0'] /= 10**decimals_token0
379
- increase_liquidity_data['amount1'] /= 10**decimals_token1
380
-
381
- usd_price_token0 = get_token_price_usd(chain_name, token0_address)
382
- usd_price_token1 = get_token_price_usd(chain_name, token1_address)
383
-
384
- if usd_price_token0 is not None and usd_price_token1 is not None:
385
- increase_liquidity_data['amount0_usd'] = increase_liquidity_data['amount0'] * usd_price_token0
386
- increase_liquidity_data['amount1_usd'] = increase_liquidity_data['amount1'] * usd_price_token1
387
-
388
- parsed_log.update(uniswap_v3_data)
389
- parsed_log.update(increase_liquidity_data)
390
- all_transactions.append(parsed_log)
391
-
392
- # Convert to DataFrame and append to existing transactions
393
- df_new_transactions = pd.DataFrame(all_transactions)
394
-
395
- if not df_existing_transactions.empty:
396
- all_data = pd.concat([df_existing_transactions, df_new_transactions])
397
- else:
398
- all_data = df_new_transactions
399
-
400
- all_data.to_csv(existing_transactions_path, index=False)
401
- print("Data saved to", existing_transactions_path)
402
-
403
- return all_data
404
-
405
- #print(df_transactions)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
apr_visualization.py DELETED
@@ -1,592 +0,0 @@
1
- import pandas as pd
2
- import numpy as np
3
- import matplotlib.pyplot as plt
4
- import matplotlib.dates as mdates
5
- import plotly.graph_objects as go
6
- import plotly.express as px
7
- from plotly.subplots import make_subplots
8
- import random
9
- from datetime import datetime, timedelta
10
- import requests
11
- import sys
12
- import json
13
- from typing import List, Dict, Any
14
- import logging
15
-
16
- logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
17
- logger = logging.getLogger(__name__)
18
-
19
- # Global variable to store the data for reuse
20
- global_df = None
21
-
22
- # Configuration
23
- API_BASE_URL = "https://afmdb.autonolas.tech"
24
-
25
- def get_agent_type_by_name(type_name: str) -> Dict[str, Any]:
26
- """Get agent type by name"""
27
- response = requests.get(f"{API_BASE_URL}/api/agent-types/name/{type_name}")
28
- if response.status_code == 404:
29
- logger.error(f"Agent type '{type_name}' not found")
30
- return None
31
- response.raise_for_status()
32
- return response.json()
33
-
34
- def get_attribute_definition_by_name(attr_name: str) -> Dict[str, Any]:
35
- """Get attribute definition by name"""
36
- response = requests.get(f"{API_BASE_URL}/api/attributes/name/{attr_name}")
37
- if response.status_code == 404:
38
- logger.error(f"Attribute definition '{attr_name}' not found")
39
- return None
40
- response.raise_for_status()
41
- return response.json()
42
-
43
- def get_agents_by_type(type_id: int) -> List[Dict[str, Any]]:
44
- """Get all agents of a specific type"""
45
- response = requests.get(f"{API_BASE_URL}/api/agent-types/{type_id}/agents/")
46
- if response.status_code == 404:
47
- logger.error(f"No agents found for type ID {type_id}")
48
- return []
49
- response.raise_for_status()
50
- return response.json()
51
-
52
- def get_attribute_values_by_type_and_attr(agents: List[Dict[str, Any]], attr_def_id: int) -> List[Dict[str, Any]]:
53
- """Get all attribute values for a specific attribute definition across all agents of a given list"""
54
- all_attributes = []
55
-
56
- # For each agent, get their attributes and filter for the one we want
57
- for agent in agents:
58
- agent_id = agent["agent_id"]
59
-
60
- # Call the /api/agents/{agent_id}/attributes/ endpoint
61
- response = requests.get(f"{API_BASE_URL}/api/agents/{agent_id}/attributes/", params={"limit": 1000})
62
- if response.status_code == 404:
63
- logger.error(f"No attributes found for agent ID {agent_id}")
64
- continue
65
-
66
- try:
67
- response.raise_for_status()
68
- agent_attrs = response.json()
69
-
70
- # Filter for the specific attribute definition ID
71
- filtered_attrs = [attr for attr in agent_attrs if attr.get("attr_def_id") == attr_def_id]
72
- all_attributes.extend(filtered_attrs)
73
- except requests.exceptions.RequestException as e:
74
- logger.error(f"Error fetching attributes for agent ID {agent_id}: {e}")
75
-
76
- return all_attributes
77
-
78
- def get_agent_name(agent_id: int, agents: List[Dict[str, Any]]) -> str:
79
- """Get agent name from agent ID"""
80
- for agent in agents:
81
- if agent["agent_id"] == agent_id:
82
- return agent["agent_name"]
83
- return "Unknown"
84
-
85
- def extract_apr_value(attr: Dict[str, Any]) -> Dict[str, Any]:
86
- """Extract APR value and timestamp from JSON value"""
87
- try:
88
- # The APR value is stored in the json_value field
89
- if attr["json_value"] is None:
90
- return {"apr": None, "timestamp": None, "agent_id": attr["agent_id"], "is_dummy": False}
91
-
92
- # If json_value is a string, parse it
93
- if isinstance(attr["json_value"], str):
94
- json_data = json.loads(attr["json_value"])
95
- else:
96
- json_data = attr["json_value"]
97
-
98
- apr = json_data.get("apr")
99
- timestamp = json_data.get("timestamp")
100
-
101
- # Convert timestamp to datetime if it exists
102
- timestamp_dt = None
103
- if timestamp:
104
- timestamp_dt = datetime.fromtimestamp(timestamp)
105
-
106
- return {"apr": apr, "timestamp": timestamp_dt, "agent_id": attr["agent_id"], "is_dummy": False}
107
- except (json.JSONDecodeError, KeyError, TypeError) as e:
108
- logger.error(f"Error parsing JSON value: {e} for agent_id: {attr.get('agent_id')}")
109
- return {"apr": None, "timestamp": None, "agent_id": attr["agent_id"], "is_dummy": False}
110
-
111
- def fetch_apr_data_from_db():
112
- """
113
- Fetch APR data from database using the API.
114
- """
115
- global global_df
116
-
117
- try:
118
- # Step 1: Find the Modius agent type
119
- modius_type = get_agent_type_by_name("Modius")
120
- if not modius_type:
121
- logger.error("Modius agent type not found, using placeholder data")
122
- global_df = pd.DataFrame([])
123
- return global_df
124
-
125
- type_id = modius_type["type_id"]
126
-
127
- # Step 2: Find the APR attribute definition
128
- apr_attr_def = get_attribute_definition_by_name("APR")
129
- if not apr_attr_def:
130
- logger.error("APR attribute definition not found, using placeholder data")
131
- global_df = pd.DataFrame([])
132
- return global_df
133
-
134
- attr_def_id = apr_attr_def["attr_def_id"]
135
-
136
- # Step 3: Get all agents of type Modius
137
- modius_agents = get_agents_by_type(type_id)
138
- if not modius_agents:
139
- logger.error("No agents of type 'Modius' found")
140
- global_df = pd.DataFrame([])
141
- return global_df
142
-
143
- # Step 4: Fetch all APR values for Modius agents
144
- apr_attributes = get_attribute_values_by_type_and_attr(modius_agents, attr_def_id)
145
- if not apr_attributes:
146
- logger.error("No APR values found for 'Modius' agents")
147
- global_df = pd.DataFrame([])
148
- return global_df
149
-
150
- # Step 5: Extract APR data
151
- apr_data_list = []
152
- for attr in apr_attributes:
153
- apr_data = extract_apr_value(attr)
154
- if apr_data["apr"] is not None and apr_data["timestamp"] is not None:
155
- # Get agent name
156
- agent_name = get_agent_name(attr["agent_id"], modius_agents)
157
- # Add agent name to the data
158
- apr_data["agent_name"] = agent_name
159
- # Add is_dummy flag (all real data)
160
- apr_data["is_dummy"] = False
161
-
162
- # Mark negative values as "Performance" metrics
163
- if apr_data["apr"] < 0:
164
- apr_data["metric_type"] = "Performance"
165
- else:
166
- apr_data["metric_type"] = "APR"
167
-
168
- apr_data_list.append(apr_data)
169
-
170
- # Convert list of dictionaries to DataFrame
171
- if not apr_data_list:
172
- logger.error("No valid APR data extracted")
173
- global_df = pd.DataFrame([])
174
- return global_df
175
-
176
- global_df = pd.DataFrame(apr_data_list)
177
- return global_df
178
-
179
- except requests.exceptions.RequestException as e:
180
- logger.error(f"API request error: {e}")
181
- global_df = pd.DataFrame([])
182
- return global_df
183
- except Exception as e:
184
- logger.error(f"Error fetching APR data: {e}")
185
- global_df = pd.DataFrame([])
186
- return global_df
187
-
188
- def generate_apr_visualizations():
189
- """Generate APR visualizations with real data only (no dummy data)"""
190
- global global_df
191
-
192
- # Fetch data from database
193
- df = fetch_apr_data_from_db()
194
-
195
- # If we got no data at all, return placeholder figures
196
- if df.empty:
197
- logger.info("No APR data available. Using fallback visualization.")
198
- # Create empty visualizations with a message using Plotly
199
- fig = go.Figure()
200
- fig.add_annotation(
201
- x=0.5, y=0.5,
202
- text="No APR data available",
203
- font=dict(size=20),
204
- showarrow=False
205
- )
206
- fig.update_layout(
207
- xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
208
- yaxis=dict(showgrid=False, zeroline=False, showticklabels=False)
209
- )
210
-
211
- # Save as static files for reference
212
- fig.write_html("modius_apr_per_agent_graph.html")
213
- fig.write_image("modius_apr_per_agent_graph.png")
214
- fig.write_html("modius_apr_combined_graph.html")
215
- fig.write_image("modius_apr_combined_graph.png")
216
-
217
- csv_file = None
218
- return fig, fig, csv_file
219
-
220
- # No longer generating dummy data
221
- # Set global_df for access by other functions
222
- global_df = df
223
-
224
- # Save to CSV before creating visualizations
225
- csv_file = save_to_csv(df)
226
-
227
- # Create per-agent time series graph (returns figure object)
228
- per_agent_fig = create_time_series_graph_per_agent(df)
229
-
230
- # Create combined time series graph (returns figure object)
231
- combined_fig = create_combined_time_series_graph(df)
232
-
233
- return per_agent_fig, combined_fig, csv_file
234
-
235
- def create_time_series_graph_per_agent(df):
236
- """Create a time series graph for each agent using Plotly"""
237
- # Get unique agents
238
- unique_agents = df['agent_id'].unique()
239
-
240
- if len(unique_agents) == 0:
241
- logger.error("No agent data to plot")
242
- fig = go.Figure()
243
- fig.add_annotation(
244
- text="No agent data available",
245
- x=0.5, y=0.5,
246
- showarrow=False, font=dict(size=20)
247
- )
248
- return fig
249
-
250
- # Create a subplot figure for each agent
251
- fig = make_subplots(rows=len(unique_agents), cols=1,
252
- subplot_titles=[f"Agent: {df[df['agent_id'] == agent_id]['agent_name'].iloc[0]}"
253
- for agent_id in unique_agents],
254
- vertical_spacing=0.1)
255
-
256
- # Plot data for each agent
257
- for i, agent_id in enumerate(unique_agents):
258
- agent_data = df[df['agent_id'] == agent_id].copy()
259
- agent_name = agent_data['agent_name'].iloc[0]
260
- row = i + 1
261
-
262
- # Add zero line to separate APR and Performance
263
- fig.add_shape(
264
- type="line", line=dict(dash="solid", width=1.5, color="black"),
265
- y0=0, y1=0, x0=agent_data['timestamp'].min(), x1=agent_data['timestamp'].max(),
266
- row=row, col=1
267
- )
268
-
269
- # Add background colors
270
- fig.add_shape(
271
- type="rect", fillcolor="rgba(230, 243, 255, 0.3)", line=dict(width=0),
272
- y0=0, y1=1000, x0=agent_data['timestamp'].min(), x1=agent_data['timestamp'].max(),
273
- row=row, col=1, layer="below"
274
- )
275
- fig.add_shape(
276
- type="rect", fillcolor="rgba(255, 230, 230, 0.3)", line=dict(width=0),
277
- y0=-1000, y1=0, x0=agent_data['timestamp'].min(), x1=agent_data['timestamp'].max(),
278
- row=row, col=1, layer="below"
279
- )
280
-
281
- # Create separate dataframes for different data types
282
- apr_data = agent_data[agent_data['metric_type'] == 'APR']
283
- perf_data = agent_data[agent_data['metric_type'] == 'Performance']
284
-
285
- # Sort all data by timestamp for the line plots
286
- combined_agent_data = agent_data.sort_values('timestamp')
287
-
288
- # Add main line connecting all points
289
- fig.add_trace(
290
- go.Scatter(
291
- x=combined_agent_data['timestamp'],
292
- y=combined_agent_data['apr'],
293
- mode='lines',
294
- line=dict(color='purple', width=2),
295
- name=f'{agent_name}',
296
- legendgroup=agent_name,
297
- showlegend=(i == 0), # Only show in legend once
298
- hovertemplate='Time: %{x}<br>Value: %{y:.2f}<extra></extra>'
299
- ),
300
- row=row, col=1
301
- )
302
-
303
- # Add scatter points for APR values
304
- if not apr_data.empty:
305
- fig.add_trace(
306
- go.Scatter(
307
- x=apr_data['timestamp'],
308
- y=apr_data['apr'],
309
- mode='markers',
310
- marker=dict(color='blue', size=10, symbol='circle'),
311
- name='APR',
312
- legendgroup='APR',
313
- showlegend=(i == 0),
314
- hovertemplate='Time: %{x}<br>APR: %{y:.2f}<extra></extra>'
315
- ),
316
- row=row, col=1
317
- )
318
-
319
- # Add scatter points for Performance values
320
- if not perf_data.empty:
321
- fig.add_trace(
322
- go.Scatter(
323
- x=perf_data['timestamp'],
324
- y=perf_data['apr'],
325
- mode='markers',
326
- marker=dict(color='red', size=10, symbol='square'),
327
- name='Performance',
328
- legendgroup='Performance',
329
- showlegend=(i == 0),
330
- hovertemplate='Time: %{x}<br>Performance: %{y:.2f}<extra></extra>'
331
- ),
332
- row=row, col=1
333
- )
334
-
335
- # Update axes
336
- fig.update_xaxes(title_text="Time", row=row, col=1)
337
- fig.update_yaxes(title_text="Value", row=row, col=1, gridcolor='rgba(0,0,0,0.1)')
338
-
339
- # Update layout
340
- fig.update_layout(
341
- height=400 * len(unique_agents),
342
- width=1000,
343
- title_text="APR and Performance Values per Agent",
344
- template="plotly_white",
345
- legend=dict(
346
- orientation="h",
347
- yanchor="bottom",
348
- y=1.02,
349
- xanchor="right",
350
- x=1
351
- ),
352
- margin=dict(r=20, l=20, t=30, b=20),
353
- hovermode="closest"
354
- )
355
-
356
- # Save the figure (still useful for reference)
357
- graph_file = "modius_apr_per_agent_graph.html"
358
- fig.write_html(graph_file, include_plotlyjs='cdn', full_html=False)
359
-
360
- # Also save as image for compatibility
361
- img_file = "modius_apr_per_agent_graph.png"
362
- fig.write_image(img_file)
363
-
364
- logger.info(f"Per-agent graph saved to {graph_file} and {img_file}")
365
-
366
- # Return the figure object for direct use in Gradio
367
- return fig
368
-
369
- def create_combined_time_series_graph(df):
370
- """Create a combined time series graph for all agents using Plotly"""
371
- if len(df) == 0:
372
- logger.error("No data to plot combined graph")
373
- fig = go.Figure()
374
- fig.add_annotation(
375
- text="No data available",
376
- x=0.5, y=0.5,
377
- showarrow=False, font=dict(size=20)
378
- )
379
- return fig
380
-
381
- # Create Plotly figure
382
- fig = go.Figure()
383
-
384
- # Get unique agents
385
- unique_agents = df['agent_id'].unique()
386
-
387
- # Define a color scale for different agents
388
- colors = px.colors.qualitative.Plotly[:len(unique_agents)]
389
-
390
- # Add background shapes for APR and Performance regions
391
- min_time = df['timestamp'].min()
392
- max_time = df['timestamp'].max()
393
-
394
- # Add shape for APR region (above zero)
395
- fig.add_shape(
396
- type="rect",
397
- fillcolor="rgba(230, 243, 255, 0.3)",
398
- line=dict(width=0),
399
- y0=0, y1=1000,
400
- x0=min_time, x1=max_time,
401
- layer="below"
402
- )
403
-
404
- # Add shape for Performance region (below zero)
405
- fig.add_shape(
406
- type="rect",
407
- fillcolor="rgba(255, 230, 230, 0.3)",
408
- line=dict(width=0),
409
- y0=-1000, y1=0,
410
- x0=min_time, x1=max_time,
411
- layer="below"
412
- )
413
-
414
- # Add zero line
415
- fig.add_shape(
416
- type="line",
417
- line=dict(dash="solid", width=1.5, color="black"),
418
- y0=0, y1=0,
419
- x0=min_time, x1=max_time
420
- )
421
-
422
- # Add data for each agent
423
- for i, agent_id in enumerate(unique_agents):
424
- agent_data = df[df['agent_id'] == agent_id].copy()
425
- agent_name = agent_data['agent_name'].iloc[0]
426
- color = colors[i % len(colors)]
427
-
428
- # Sort the data by timestamp
429
- agent_data = agent_data.sort_values('timestamp')
430
-
431
- # Add the combined line for both APR and Performance
432
- fig.add_trace(
433
- go.Scatter(
434
- x=agent_data['timestamp'],
435
- y=agent_data['apr'],
436
- mode='lines',
437
- line=dict(color=color, width=2),
438
- name=f'{agent_name}',
439
- legendgroup=agent_name,
440
- hovertemplate='Time: %{x}<br>Value: %{y:.2f}<br>Agent: ' + agent_name + '<extra></extra>'
441
- )
442
- )
443
-
444
- # Add scatter points for APR values
445
- apr_data = agent_data[agent_data['metric_type'] == 'APR']
446
- if not apr_data.empty:
447
- fig.add_trace(
448
- go.Scatter(
449
- x=apr_data['timestamp'],
450
- y=apr_data['apr'],
451
- mode='markers',
452
- marker=dict(color=color, symbol='circle', size=8),
453
- name=f'{agent_name} APR',
454
- legendgroup=agent_name,
455
- showlegend=False,
456
- hovertemplate='Time: %{x}<br>APR: %{y:.2f}<br>Agent: ' + agent_name + '<extra></extra>'
457
- )
458
- )
459
-
460
- # Add scatter points for Performance values
461
- perf_data = agent_data[agent_data['metric_type'] == 'Performance']
462
- if not perf_data.empty:
463
- fig.add_trace(
464
- go.Scatter(
465
- x=perf_data['timestamp'],
466
- y=perf_data['apr'],
467
- mode='markers',
468
- marker=dict(color=color, symbol='square', size=8),
469
- name=f'{agent_name} Perf',
470
- legendgroup=agent_name,
471
- showlegend=False,
472
- hovertemplate='Time: %{x}<br>Performance: %{y:.2f}<br>Agent: ' + agent_name + '<extra></extra>'
473
- )
474
- )
475
-
476
- # Update layout
477
- fig.update_layout(
478
- title="APR and Performance Values for All Agents",
479
- xaxis_title="Time",
480
- yaxis_title="Value",
481
- template="plotly_white",
482
- height=600,
483
- width=1000,
484
- legend=dict(
485
- orientation="h",
486
- yanchor="bottom",
487
- y=1.02,
488
- xanchor="right",
489
- x=1,
490
- groupclick="toggleitem"
491
- ),
492
- margin=dict(r=20, l=20, t=30, b=20),
493
- hovermode="closest"
494
- )
495
-
496
- # Update axes
497
- fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='rgba(0,0,0,0.1)')
498
- fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='rgba(0,0,0,0.1)')
499
-
500
- # Save the figure (still useful for reference)
501
- graph_file = "modius_apr_combined_graph.html"
502
- fig.write_html(graph_file, include_plotlyjs='cdn', full_html=False)
503
-
504
- # Also save as image for compatibility
505
- img_file = "modius_apr_combined_graph.png"
506
- fig.write_image(img_file)
507
-
508
- logger.info(f"Combined graph saved to {graph_file} and {img_file}")
509
-
510
- # Return the figure object for direct use in Gradio
511
- return fig
512
-
513
- def save_to_csv(df):
514
- """Save the APR data DataFrame to a CSV file and return the file path"""
515
- if df.empty:
516
- logger.error("No APR data to save to CSV")
517
- return None
518
-
519
- # Define the CSV file path
520
- csv_file = "modius_apr_values.csv"
521
-
522
- # Save to CSV
523
- df.to_csv(csv_file, index=False)
524
- logger.info(f"APR data saved to {csv_file}")
525
-
526
- # Also generate a statistics CSV file
527
- stats_df = generate_statistics_from_data(df)
528
- stats_csv = "modius_apr_statistics.csv"
529
- stats_df.to_csv(stats_csv, index=False)
530
- logger.info(f"Statistics saved to {stats_csv}")
531
-
532
- return csv_file
533
-
534
- def generate_statistics_from_data(df):
535
- """Generate statistics from the APR data"""
536
- if df.empty:
537
- return pd.DataFrame()
538
-
539
- # Get unique agents
540
- unique_agents = df['agent_id'].unique()
541
- stats_list = []
542
-
543
- # Generate per-agent statistics
544
- for agent_id in unique_agents:
545
- agent_data = df[df['agent_id'] == agent_id]
546
- agent_name = agent_data['agent_name'].iloc[0]
547
-
548
- # APR statistics
549
- apr_data = agent_data[agent_data['metric_type'] == 'APR']
550
- real_apr = apr_data[apr_data['is_dummy'] == False]
551
-
552
- # Performance statistics
553
- perf_data = agent_data[agent_data['metric_type'] == 'Performance']
554
- real_perf = perf_data[perf_data['is_dummy'] == False]
555
-
556
- stats = {
557
- 'agent_id': agent_id,
558
- 'agent_name': agent_name,
559
- 'total_points': len(agent_data),
560
- 'apr_points': len(apr_data),
561
- 'performance_points': len(perf_data),
562
- 'real_apr_points': len(real_apr),
563
- 'real_performance_points': len(real_perf),
564
- 'avg_apr': apr_data['apr'].mean() if not apr_data.empty else None,
565
- 'avg_performance': perf_data['apr'].mean() if not perf_data.empty else None,
566
- 'max_apr': apr_data['apr'].max() if not apr_data.empty else None,
567
- 'min_apr': apr_data['apr'].min() if not apr_data.empty else None,
568
- 'latest_timestamp': agent_data['timestamp'].max().strftime('%Y-%m-%d %H:%M:%S') if not agent_data.empty else None
569
- }
570
- stats_list.append(stats)
571
-
572
- # Generate overall statistics
573
- apr_only = df[df['metric_type'] == 'APR']
574
- perf_only = df[df['metric_type'] == 'Performance']
575
-
576
- overall_stats = {
577
- 'agent_id': 'ALL',
578
- 'agent_name': 'All Agents',
579
- 'total_points': len(df),
580
- 'apr_points': len(apr_only),
581
- 'performance_points': len(perf_only),
582
- 'real_apr_points': len(apr_only[apr_only['is_dummy'] == False]),
583
- 'real_performance_points': len(perf_only[perf_only['is_dummy'] == False]),
584
- 'avg_apr': apr_only['apr'].mean() if not apr_only.empty else None,
585
- 'avg_performance': perf_only['apr'].mean() if not perf_only.empty else None,
586
- 'max_apr': apr_only['apr'].max() if not apr_only.empty else None,
587
- 'min_apr': apr_only['apr'].min() if not apr_only.empty else None,
588
- 'latest_timestamp': df['timestamp'].max().strftime('%Y-%m-%d %H:%M:%S') if not df.empty else None
589
- }
590
- stats_list.append(overall_stats)
591
-
592
- return pd.DataFrame(stats_list)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
apr_vs_agent_hash.py DELETED
@@ -1,475 +0,0 @@
1
- import pandas as pd
2
- import plotly.graph_objects as go
3
- import plotly.express as px
4
- from datetime import datetime
5
- import logging
6
- import json
7
- import os
8
-
9
- # Set up logging
10
- logger = logging.getLogger(__name__)
11
-
12
- def create_apr_vs_agent_hash_graph(df):
13
- """
14
- Create a box plot showing APR values distribution for each agent hash version.
15
-
16
- Args:
17
- df: DataFrame containing the APR data with agent_hash column
18
-
19
- Returns:
20
- A Plotly figure object
21
- """
22
- if len(df) == 0 or 'agent_hash' not in df.columns:
23
- logger.error("No data or agent_hash column not found to plot APR vs agent hash graph")
24
- fig = go.Figure()
25
- fig.add_annotation(
26
- text="No agent hash data available",
27
- x=0.5, y=0.5,
28
- showarrow=False, font=dict(size=20)
29
- )
30
- return fig
31
-
32
- # Filter for APR data only and ensure agent_hash is not null
33
- apr_data = df[(df['metric_type'] == 'APR') & (df['agent_hash'].notna())].copy()
34
-
35
- if len(apr_data) == 0:
36
- logger.error("No valid APR data with agent_hash found")
37
- fig = go.Figure()
38
- fig.add_annotation(
39
- text="No valid APR data with agent_hash found",
40
- x=0.5, y=0.5,
41
- showarrow=False, font=dict(size=20)
42
- )
43
- return fig
44
-
45
- # Filter out outliers (APR values above 200 or below -200)
46
- outlier_data = apr_data[(apr_data['apr'] > 200) | (apr_data['apr'] < -200)].copy()
47
- apr_data_filtered = apr_data[(apr_data['apr'] <= 200) & (apr_data['apr'] >= -200)].copy()
48
-
49
- # Log the outliers for better debugging
50
- if len(outlier_data) > 0:
51
- excluded_count = len(outlier_data)
52
- logger.info(f"Excluded {excluded_count} data points with outlier APR values (>200 or <-200)")
53
-
54
- # Group outliers by agent for detailed logging
55
- outlier_agents = outlier_data.groupby('agent_name')
56
- for agent_name, agent_outliers in outlier_agents:
57
- logger.info(f"Agent '{agent_name}' has {len(agent_outliers)} outlier values:")
58
- for idx, row in agent_outliers.iterrows():
59
- logger.info(f" - APR: {row['apr']}, timestamp: {row['timestamp']}, agent_hash: {row['agent_hash']}")
60
-
61
- # Use the filtered data for all subsequent operations
62
- apr_data = apr_data_filtered
63
-
64
- # Create Plotly figure
65
- fig = go.Figure()
66
-
67
- # Add a zero line that spans the entire width
68
- fig.add_shape(
69
- type="line",
70
- line=dict(dash="solid", width=1.5, color="black"),
71
- y0=0, y1=0,
72
- x0=-0.5, x1=10, # Will be adjusted later based on number of boxes
73
- layer="below"
74
- )
75
-
76
- # Add background shapes for positive and negative regions
77
- # These will be adjusted later based on the actual x-axis range
78
- fig.add_shape(
79
- type="rect",
80
- fillcolor="rgba(230, 243, 255, 0.3)",
81
- line=dict(width=0),
82
- y0=0, y1=100, # Use a fixed positive value
83
- x0=-0.5, x1=10, # Will be adjusted later
84
- layer="below"
85
- )
86
-
87
- fig.add_shape(
88
- type="rect",
89
- fillcolor="rgba(255, 230, 230, 0.3)",
90
- line=dict(width=0),
91
- y0=-100, y1=0, # Use a fixed negative value
92
- x0=-0.5, x1=10, # Will be adjusted later
93
- layer="below"
94
- )
95
-
96
- # Group by agent_hash
97
- unique_hashes = apr_data['agent_hash'].unique()
98
-
99
- # Map for version labels based on hash endings
100
- version_map = {}
101
- for hash_val in unique_hashes:
102
- if hash_val.endswith("tby"):
103
- version_map[hash_val] = "v0.4.1"
104
- elif hash_val.endswith("vq"):
105
- version_map[hash_val] = "v0.4.2"
106
- else:
107
- # For any other hashes, use the last 6 characters
108
- version_map[hash_val] = f"Hash: {hash_val[-6:]}"
109
-
110
- # Sort hashes by version (v0.4.1 first, then v0.4.2)
111
- sorted_hashes = sorted(unique_hashes, key=lambda h: "1" if h.endswith("tby") else "2" if h.endswith("vq") else h)
112
-
113
- # Colors for different versions
114
- version_colors = {
115
- "v0.4.1": "rgba(31, 119, 180, 0.7)", # Blue
116
- "v0.4.2": "rgba(44, 160, 44, 0.7)", # Green
117
- }
118
-
119
- # Default color for other hashes
120
- default_color = "rgba(214, 39, 40, 0.7)" # Red
121
-
122
- # Prepare data for box plots and statistics
123
- box_data = []
124
- version_stats = {}
125
-
126
- # X-axis positions and labels
127
- x_positions = []
128
- x_labels = []
129
-
130
- # Process each hash to create box plot data
131
- for i, agent_hash in enumerate(sorted_hashes):
132
- hash_data = apr_data[apr_data['agent_hash'] == agent_hash]
133
-
134
- # Get agent name for this hash (should be the same for all records with this hash)
135
- agent_name = hash_data['agent_name'].iloc[0] if not hash_data.empty else "Unknown"
136
-
137
- # Get version label
138
- version = version_map[agent_hash]
139
-
140
- # Choose color based on version
141
- if version in version_colors:
142
- color = version_colors[version]
143
- else:
144
- color = default_color
145
-
146
- # Calculate statistics for this hash
147
- apr_values = hash_data['apr'].tolist()
148
- median_apr = hash_data['apr'].median()
149
- mean_apr = hash_data['apr'].mean()
150
- min_apr = hash_data['apr'].min()
151
- max_apr = hash_data['apr'].max()
152
- count = len(apr_values)
153
-
154
- # Store statistics for later use
155
- if version not in version_stats:
156
- version_stats[version] = {
157
- 'apr_values': [],
158
- 'count': 0,
159
- 'hashes': []
160
- }
161
-
162
- version_stats[version]['apr_values'].extend(apr_values)
163
- version_stats[version]['count'] += count
164
- version_stats[version]['hashes'].append(agent_hash)
165
-
166
- # Create label with version only (no hash)
167
- label = f"{version}"
168
-
169
- # Add to x-axis positions and labels
170
- x_positions.append(i)
171
- x_labels.append(label)
172
-
173
- # Create hover text with detailed statistics
174
- hover_text = (
175
- f"Version: {version}<br>"
176
- f"Agent: {agent_name}<br>"
177
- f"Hash: {agent_hash}<br>"
178
- f"Median APR: {median_apr:.2f}%<br>"
179
- f"Mean APR: {mean_apr:.2f}%<br>"
180
- f"Min APR: {min_apr:.2f}%<br>"
181
- f"Max APR: {max_apr:.2f}%<br>"
182
- f"Data points: {count}"
183
- )
184
-
185
- # Add box plot for this hash
186
- fig.add_trace(
187
- go.Box(
188
- y=apr_values,
189
- x=[i] * len(apr_values), # Position on x-axis
190
- name=label,
191
- boxpoints='outliers', # Show only outlier points instead of all points
192
- jitter=0.1, # Reduced jitter for less horizontal spread
193
- pointpos=0, # Position of points relative to box
194
- marker=dict(
195
- color=color,
196
- size=6, # Smaller point size
197
- opacity=0.7, # Add transparency
198
- line=dict(width=1, color='black')
199
- ),
200
- line=dict(
201
- color='black',
202
- width=2 # Thicker line for better visibility
203
- ),
204
- fillcolor=color,
205
- hoverinfo='text',
206
- hovertext=hover_text,
207
- showlegend=False,
208
- boxmean=True, # Show mean as a dashed line
209
- whiskerwidth=0.8, # Slightly thinner whiskers
210
- width=0.6 # Wider boxes
211
- )
212
- )
213
-
214
- logger.info(f"Added box plot for agent hash {agent_hash} ({version}) with {count} points")
215
-
216
- # Add text annotation with median value above each box
217
- fig.add_annotation(
218
- x=i,
219
- y=median_apr + 5, # Position above the box
220
- text=f"{median_apr:.1f}%",
221
- showarrow=False,
222
- font=dict(
223
- family="Arial, sans-serif",
224
- size=12,
225
- color="black",
226
- weight="bold"
227
- )
228
- )
229
-
230
- # Calculate improvement metrics between versions
231
- if "v0.4.1" in version_stats and "v0.4.2" in version_stats:
232
- v041_values = version_stats["v0.4.1"]["apr_values"]
233
- v042_values = version_stats["v0.4.2"]["apr_values"]
234
-
235
- v041_median = pd.Series(v041_values).median()
236
- v042_median = pd.Series(v042_values).median()
237
-
238
- improvement = v042_median - v041_median
239
- improvement_pct = (improvement / abs(v041_median)) * 100 if v041_median != 0 else float('inf')
240
-
241
- # Determine if the change is positive or negative
242
- is_improvement = improvement > 0
243
- change_color = "green" if is_improvement else "red"
244
- change_text = "improvement" if is_improvement else "decrease"
245
-
246
- # Add annotation showing improvement with better styling (black color)
247
- fig.add_annotation(
248
- x=(len(sorted_hashes) - 1) / 2, # Center of the x-axis
249
- y=90, # Top of the chart
250
- text=f"<b>Version Comparison:</b> {abs(improvement):.2f}% {change_text} from v0.4.1 to v0.4.2",
251
- showarrow=False,
252
- font=dict(
253
- family="Arial, sans-serif",
254
- size=16,
255
- color="black", # Changed to black
256
- weight="bold"
257
- ),
258
- bgcolor="rgba(255, 255, 255, 0.9)",
259
- bordercolor="black", # Changed to black
260
- borderwidth=2,
261
- borderpad=6,
262
- opacity=0.9
263
- )
264
-
265
- # Update the shapes to match the actual x-axis range
266
- num_boxes = len(sorted_hashes)
267
- fig.update_shapes(
268
- dict(x0=-0.5, x1=num_boxes - 0.5),
269
- selector=dict(type='rect')
270
- )
271
- fig.update_shapes(
272
- dict(x0=-0.5, x1=num_boxes - 0.5),
273
- selector=dict(type='line')
274
- )
275
-
276
- # Update layout with improved styling
277
- fig.update_layout(
278
- title=dict(
279
- text="Performance Graph",
280
- font=dict(
281
- family="Arial, sans-serif",
282
- size=24, # Larger title
283
- color="black",
284
- weight="bold"
285
- ),
286
- x=0.5, # Center the title
287
- y=0.95 # Position slightly higher
288
- ),
289
- xaxis_title=dict(
290
- text="Agent Version",
291
- font=dict(
292
- family="Arial, sans-serif",
293
- size=18, # Larger axis title
294
- color="black",
295
- weight="bold"
296
- )
297
- ),
298
- yaxis_title=None, # Remove the y-axis title as we'll use annotations instead
299
- template="plotly_white",
300
- height=900, # Increased height for better visualization and more vertical space
301
- # width parameter removed to allow full responsiveness
302
- autosize=True, # Enable auto-sizing for responsiveness
303
- boxmode='group', # Group boxes together
304
- margin=dict(r=50, l=120, t=100, b=100), # Reduced right margin since guide was removed
305
- hovermode="closest",
306
- plot_bgcolor='rgba(250,250,250,0.9)', # Slightly off-white background
307
- paper_bgcolor='white',
308
- font=dict(
309
- family="Arial, sans-serif",
310
- size=14,
311
- color="black"
312
- ),
313
- showlegend=False
314
- )
315
-
316
- # Add single annotation for y-axis
317
- fig.add_annotation(
318
- x=-0.08, # Position further from the y-axis to avoid overlapping with tick labels
319
- y=0, # Center of the y-axis
320
- xref="paper",
321
- yref="y",
322
- text="Agent APR [%]",
323
- showarrow=False,
324
- font=dict(size=16, family="Arial, sans-serif", color="black", weight="bold"), # Adjusted font size
325
- textangle=-90, # Rotate text to be vertical
326
- align="center"
327
- )
328
-
329
- # Box plot guide removed as per user request
330
-
331
- # Update y-axis with autoscaling
332
- fig.update_yaxes(
333
- showgrid=True,
334
- gridwidth=1,
335
- gridcolor='rgba(0,0,0,0.1)',
336
- # Use autoscaling
337
- autorange=True, # Enable autoscaling
338
- tickformat=".2f", # Format tick labels with 2 decimal places
339
- tickfont=dict(size=14, family="Arial, sans-serif", color="black", weight="bold"), # Adjusted font size
340
- title=None # Remove the built-in axis title since we're using annotations
341
- )
342
-
343
- # Update x-axis with custom labels
344
- fig.update_xaxes(
345
- showgrid=True,
346
- gridwidth=1,
347
- gridcolor='rgba(0,0,0,0.1)',
348
- tickmode='array',
349
- tickvals=x_positions,
350
- ticktext=x_labels,
351
- tickangle=-45, # Angle the labels for better readability
352
- tickfont=dict(size=14, family="Arial, sans-serif", color="black", weight="bold") # Adjusted font size
353
- )
354
-
355
- try:
356
- # Save the figure
357
- graph_file = "modius_apr_vs_agent_hash_graph.html"
358
- fig.write_html(graph_file, include_plotlyjs='cdn', full_html=False)
359
-
360
- # Also save as image for compatibility
361
- img_file = "modius_apr_vs_agent_hash_graph.png"
362
- try:
363
- fig.write_image(img_file)
364
- logger.info(f"APR vs agent hash graph saved to {graph_file} and {img_file}")
365
- except Exception as e:
366
- logger.error(f"Error saving image: {e}")
367
- logger.info(f"APR vs agent hash graph saved to {graph_file} only")
368
-
369
- # Return the figure object for direct use in Gradio
370
- return fig
371
- except Exception as e:
372
- logger.error(f"Error creating APR vs agent hash graph: {e}")
373
-
374
- # Create a simpler graph as fallback
375
- simple_fig = go.Figure()
376
-
377
- # Add zero line
378
- simple_fig.add_shape(
379
- type="line",
380
- line=dict(dash="solid", width=1.5, color="black"),
381
- y0=0, y1=0,
382
- x0=-0.5, x1=1.5 # Fixed values for error case
383
- )
384
-
385
- # Add a note about the error
386
- simple_fig.add_annotation(
387
- text=f"Error creating graph: {str(e)}",
388
- x=0.5, y=0.5,
389
- showarrow=False,
390
- font=dict(size=15, color="red")
391
- )
392
-
393
- return simple_fig
394
-
395
- def save_apr_vs_agent_hash_to_csv(df):
396
- """
397
- Save the APR vs agent hash data to a CSV file.
398
-
399
- Args:
400
- df: DataFrame containing the APR data with agent_hash column
401
-
402
- Returns:
403
- The path to the saved CSV file, or None if no data was saved
404
- """
405
- if df.empty or 'agent_hash' not in df.columns:
406
- logger.error("No data or agent_hash column not found to save to CSV")
407
- return None
408
-
409
- # Filter for APR data only and ensure agent_hash is not null
410
- apr_data = df[(df['metric_type'] == 'APR') & (df['agent_hash'].notna())].copy()
411
-
412
- if apr_data.empty:
413
- logger.error("No valid APR data with agent_hash found to save to CSV")
414
- return None
415
-
416
- # Define the CSV file path
417
- csv_file = "modius_apr_vs_agent_hash.csv"
418
-
419
- # Save to CSV
420
- apr_data.to_csv(csv_file, index=False)
421
- logger.info(f"APR vs agent hash data saved to {csv_file}")
422
-
423
- return csv_file
424
-
425
- def generate_apr_vs_agent_hash_visualizations(df):
426
- """
427
- Generate APR vs agent hash visualizations.
428
-
429
- Args:
430
- df: DataFrame containing the APR data
431
-
432
- Returns:
433
- A tuple containing the Plotly figure object and the path to the saved CSV file
434
- """
435
- if df.empty:
436
- logger.info("No APR data available for agent hash visualization.")
437
- # Create empty visualization with a message using Plotly
438
- fig = go.Figure()
439
- fig.add_annotation(
440
- x=0.5, y=0.5,
441
- text="No APR data available for agent hash visualization",
442
- font=dict(size=20),
443
- showarrow=False
444
- )
445
- fig.update_layout(
446
- xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
447
- yaxis=dict(showgrid=False, zeroline=False, showticklabels=False)
448
- )
449
-
450
- return fig, None
451
-
452
- # Check if agent_hash column exists
453
- if 'agent_hash' not in df.columns:
454
- logger.error("agent_hash column not found in DataFrame")
455
- fig = go.Figure()
456
- fig.add_annotation(
457
- x=0.5, y=0.5,
458
- text="agent_hash column not found in data",
459
- font=dict(size=20),
460
- showarrow=False
461
- )
462
- fig.update_layout(
463
- xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
464
- yaxis=dict(showgrid=False, zeroline=False, showticklabels=False)
465
- )
466
-
467
- return fig, None
468
-
469
- # Save to CSV before creating visualization
470
- csv_file = save_apr_vs_agent_hash_to_csv(df)
471
-
472
- # Create the visualization
473
- fig = create_apr_vs_agent_hash_graph(df)
474
-
475
- return fig, csv_file
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
contracts/NonfungiblePositionManager.json DELETED
@@ -1,1228 +0,0 @@
1
- {
2
- "contractName": "",
3
- "abi": [
4
- {
5
- "inputs": [
6
- {
7
- "internalType": "address",
8
- "name": "_factory",
9
- "type": "address"
10
- },
11
- {
12
- "internalType": "address",
13
- "name": "_WETH9",
14
- "type": "address"
15
- },
16
- {
17
- "internalType": "address",
18
- "name": "_tokenDescriptor_",
19
- "type": "address"
20
- }
21
- ],
22
- "stateMutability": "nonpayable",
23
- "type": "constructor"
24
- },
25
- {
26
- "anonymous": false,
27
- "inputs": [
28
- {
29
- "indexed": true,
30
- "internalType": "address",
31
- "name": "owner",
32
- "type": "address"
33
- },
34
- {
35
- "indexed": true,
36
- "internalType": "address",
37
- "name": "approved",
38
- "type": "address"
39
- },
40
- {
41
- "indexed": true,
42
- "internalType": "uint256",
43
- "name": "tokenId",
44
- "type": "uint256"
45
- }
46
- ],
47
- "name": "Approval",
48
- "type": "event"
49
- },
50
- {
51
- "anonymous": false,
52
- "inputs": [
53
- {
54
- "indexed": true,
55
- "internalType": "address",
56
- "name": "owner",
57
- "type": "address"
58
- },
59
- {
60
- "indexed": true,
61
- "internalType": "address",
62
- "name": "operator",
63
- "type": "address"
64
- },
65
- {
66
- "indexed": false,
67
- "internalType": "bool",
68
- "name": "approved",
69
- "type": "bool"
70
- }
71
- ],
72
- "name": "ApprovalForAll",
73
- "type": "event"
74
- },
75
- {
76
- "anonymous": false,
77
- "inputs": [
78
- {
79
- "indexed": true,
80
- "internalType": "uint256",
81
- "name": "tokenId",
82
- "type": "uint256"
83
- },
84
- {
85
- "indexed": false,
86
- "internalType": "address",
87
- "name": "recipient",
88
- "type": "address"
89
- },
90
- {
91
- "indexed": false,
92
- "internalType": "uint256",
93
- "name": "amount0",
94
- "type": "uint256"
95
- },
96
- {
97
- "indexed": false,
98
- "internalType": "uint256",
99
- "name": "amount1",
100
- "type": "uint256"
101
- }
102
- ],
103
- "name": "Collect",
104
- "type": "event"
105
- },
106
- {
107
- "anonymous": false,
108
- "inputs": [
109
- {
110
- "indexed": true,
111
- "internalType": "uint256",
112
- "name": "tokenId",
113
- "type": "uint256"
114
- },
115
- {
116
- "indexed": false,
117
- "internalType": "uint128",
118
- "name": "liquidity",
119
- "type": "uint128"
120
- },
121
- {
122
- "indexed": false,
123
- "internalType": "uint256",
124
- "name": "amount0",
125
- "type": "uint256"
126
- },
127
- {
128
- "indexed": false,
129
- "internalType": "uint256",
130
- "name": "amount1",
131
- "type": "uint256"
132
- }
133
- ],
134
- "name": "DecreaseLiquidity",
135
- "type": "event"
136
- },
137
- {
138
- "anonymous": false,
139
- "inputs": [
140
- {
141
- "indexed": true,
142
- "internalType": "uint256",
143
- "name": "tokenId",
144
- "type": "uint256"
145
- },
146
- {
147
- "indexed": false,
148
- "internalType": "uint128",
149
- "name": "liquidity",
150
- "type": "uint128"
151
- },
152
- {
153
- "indexed": false,
154
- "internalType": "uint256",
155
- "name": "amount0",
156
- "type": "uint256"
157
- },
158
- {
159
- "indexed": false,
160
- "internalType": "uint256",
161
- "name": "amount1",
162
- "type": "uint256"
163
- }
164
- ],
165
- "name": "IncreaseLiquidity",
166
- "type": "event"
167
- },
168
- {
169
- "anonymous": false,
170
- "inputs": [
171
- {
172
- "indexed": true,
173
- "internalType": "address",
174
- "name": "from",
175
- "type": "address"
176
- },
177
- {
178
- "indexed": true,
179
- "internalType": "address",
180
- "name": "to",
181
- "type": "address"
182
- },
183
- {
184
- "indexed": true,
185
- "internalType": "uint256",
186
- "name": "tokenId",
187
- "type": "uint256"
188
- }
189
- ],
190
- "name": "Transfer",
191
- "type": "event"
192
- },
193
- {
194
- "inputs": [],
195
- "name": "DOMAIN_SEPARATOR",
196
- "outputs": [
197
- {
198
- "internalType": "bytes32",
199
- "name": "",
200
- "type": "bytes32"
201
- }
202
- ],
203
- "stateMutability": "view",
204
- "type": "function"
205
- },
206
- {
207
- "inputs": [],
208
- "name": "PERMIT_TYPEHASH",
209
- "outputs": [
210
- {
211
- "internalType": "bytes32",
212
- "name": "",
213
- "type": "bytes32"
214
- }
215
- ],
216
- "stateMutability": "view",
217
- "type": "function"
218
- },
219
- {
220
- "inputs": [],
221
- "name": "WETH9",
222
- "outputs": [
223
- {
224
- "internalType": "address",
225
- "name": "",
226
- "type": "address"
227
- }
228
- ],
229
- "stateMutability": "view",
230
- "type": "function"
231
- },
232
- {
233
- "inputs": [
234
- {
235
- "internalType": "address",
236
- "name": "to",
237
- "type": "address"
238
- },
239
- {
240
- "internalType": "uint256",
241
- "name": "tokenId",
242
- "type": "uint256"
243
- }
244
- ],
245
- "name": "approve",
246
- "outputs": [],
247
- "stateMutability": "nonpayable",
248
- "type": "function"
249
- },
250
- {
251
- "inputs": [
252
- {
253
- "internalType": "address",
254
- "name": "owner",
255
- "type": "address"
256
- }
257
- ],
258
- "name": "balanceOf",
259
- "outputs": [
260
- {
261
- "internalType": "uint256",
262
- "name": "",
263
- "type": "uint256"
264
- }
265
- ],
266
- "stateMutability": "view",
267
- "type": "function"
268
- },
269
- {
270
- "inputs": [],
271
- "name": "baseURI",
272
- "outputs": [
273
- {
274
- "internalType": "string",
275
- "name": "",
276
- "type": "string"
277
- }
278
- ],
279
- "stateMutability": "pure",
280
- "type": "function"
281
- },
282
- {
283
- "inputs": [
284
- {
285
- "internalType": "uint256",
286
- "name": "tokenId",
287
- "type": "uint256"
288
- }
289
- ],
290
- "name": "burn",
291
- "outputs": [],
292
- "stateMutability": "payable",
293
- "type": "function"
294
- },
295
- {
296
- "inputs": [
297
- {
298
- "components": [
299
- {
300
- "internalType": "uint256",
301
- "name": "tokenId",
302
- "type": "uint256"
303
- },
304
- {
305
- "internalType": "address",
306
- "name": "recipient",
307
- "type": "address"
308
- },
309
- {
310
- "internalType": "uint128",
311
- "name": "amount0Max",
312
- "type": "uint128"
313
- },
314
- {
315
- "internalType": "uint128",
316
- "name": "amount1Max",
317
- "type": "uint128"
318
- }
319
- ],
320
- "internalType": "struct INonfungiblePositionManager.CollectParams",
321
- "name": "params",
322
- "type": "tuple"
323
- }
324
- ],
325
- "name": "collect",
326
- "outputs": [
327
- {
328
- "internalType": "uint256",
329
- "name": "amount0",
330
- "type": "uint256"
331
- },
332
- {
333
- "internalType": "uint256",
334
- "name": "amount1",
335
- "type": "uint256"
336
- }
337
- ],
338
- "stateMutability": "payable",
339
- "type": "function"
340
- },
341
- {
342
- "inputs": [
343
- {
344
- "internalType": "address",
345
- "name": "token0",
346
- "type": "address"
347
- },
348
- {
349
- "internalType": "address",
350
- "name": "token1",
351
- "type": "address"
352
- },
353
- {
354
- "internalType": "uint24",
355
- "name": "fee",
356
- "type": "uint24"
357
- },
358
- {
359
- "internalType": "uint160",
360
- "name": "sqrtPriceX96",
361
- "type": "uint160"
362
- }
363
- ],
364
- "name": "createAndInitializePoolIfNecessary",
365
- "outputs": [
366
- {
367
- "internalType": "address",
368
- "name": "pool",
369
- "type": "address"
370
- }
371
- ],
372
- "stateMutability": "payable",
373
- "type": "function"
374
- },
375
- {
376
- "inputs": [
377
- {
378
- "components": [
379
- {
380
- "internalType": "uint256",
381
- "name": "tokenId",
382
- "type": "uint256"
383
- },
384
- {
385
- "internalType": "uint128",
386
- "name": "liquidity",
387
- "type": "uint128"
388
- },
389
- {
390
- "internalType": "uint256",
391
- "name": "amount0Min",
392
- "type": "uint256"
393
- },
394
- {
395
- "internalType": "uint256",
396
- "name": "amount1Min",
397
- "type": "uint256"
398
- },
399
- {
400
- "internalType": "uint256",
401
- "name": "deadline",
402
- "type": "uint256"
403
- }
404
- ],
405
- "internalType": "struct INonfungiblePositionManager.DecreaseLiquidityParams",
406
- "name": "params",
407
- "type": "tuple"
408
- }
409
- ],
410
- "name": "decreaseLiquidity",
411
- "outputs": [
412
- {
413
- "internalType": "uint256",
414
- "name": "amount0",
415
- "type": "uint256"
416
- },
417
- {
418
- "internalType": "uint256",
419
- "name": "amount1",
420
- "type": "uint256"
421
- }
422
- ],
423
- "stateMutability": "payable",
424
- "type": "function"
425
- },
426
- {
427
- "inputs": [],
428
- "name": "factory",
429
- "outputs": [
430
- {
431
- "internalType": "address",
432
- "name": "",
433
- "type": "address"
434
- }
435
- ],
436
- "stateMutability": "view",
437
- "type": "function"
438
- },
439
- {
440
- "inputs": [
441
- {
442
- "internalType": "uint256",
443
- "name": "tokenId",
444
- "type": "uint256"
445
- }
446
- ],
447
- "name": "getApproved",
448
- "outputs": [
449
- {
450
- "internalType": "address",
451
- "name": "",
452
- "type": "address"
453
- }
454
- ],
455
- "stateMutability": "view",
456
- "type": "function"
457
- },
458
- {
459
- "inputs": [
460
- {
461
- "components": [
462
- {
463
- "internalType": "uint256",
464
- "name": "tokenId",
465
- "type": "uint256"
466
- },
467
- {
468
- "internalType": "uint256",
469
- "name": "amount0Desired",
470
- "type": "uint256"
471
- },
472
- {
473
- "internalType": "uint256",
474
- "name": "amount1Desired",
475
- "type": "uint256"
476
- },
477
- {
478
- "internalType": "uint256",
479
- "name": "amount0Min",
480
- "type": "uint256"
481
- },
482
- {
483
- "internalType": "uint256",
484
- "name": "amount1Min",
485
- "type": "uint256"
486
- },
487
- {
488
- "internalType": "uint256",
489
- "name": "deadline",
490
- "type": "uint256"
491
- }
492
- ],
493
- "internalType": "struct INonfungiblePositionManager.IncreaseLiquidityParams",
494
- "name": "params",
495
- "type": "tuple"
496
- }
497
- ],
498
- "name": "increaseLiquidity",
499
- "outputs": [
500
- {
501
- "internalType": "uint128",
502
- "name": "liquidity",
503
- "type": "uint128"
504
- },
505
- {
506
- "internalType": "uint256",
507
- "name": "amount0",
508
- "type": "uint256"
509
- },
510
- {
511
- "internalType": "uint256",
512
- "name": "amount1",
513
- "type": "uint256"
514
- }
515
- ],
516
- "stateMutability": "payable",
517
- "type": "function"
518
- },
519
- {
520
- "inputs": [
521
- {
522
- "internalType": "address",
523
- "name": "owner",
524
- "type": "address"
525
- },
526
- {
527
- "internalType": "address",
528
- "name": "operator",
529
- "type": "address"
530
- }
531
- ],
532
- "name": "isApprovedForAll",
533
- "outputs": [
534
- {
535
- "internalType": "bool",
536
- "name": "",
537
- "type": "bool"
538
- }
539
- ],
540
- "stateMutability": "view",
541
- "type": "function"
542
- },
543
- {
544
- "inputs": [
545
- {
546
- "components": [
547
- {
548
- "internalType": "address",
549
- "name": "token0",
550
- "type": "address"
551
- },
552
- {
553
- "internalType": "address",
554
- "name": "token1",
555
- "type": "address"
556
- },
557
- {
558
- "internalType": "uint24",
559
- "name": "fee",
560
- "type": "uint24"
561
- },
562
- {
563
- "internalType": "int24",
564
- "name": "tickLower",
565
- "type": "int24"
566
- },
567
- {
568
- "internalType": "int24",
569
- "name": "tickUpper",
570
- "type": "int24"
571
- },
572
- {
573
- "internalType": "uint256",
574
- "name": "amount0Desired",
575
- "type": "uint256"
576
- },
577
- {
578
- "internalType": "uint256",
579
- "name": "amount1Desired",
580
- "type": "uint256"
581
- },
582
- {
583
- "internalType": "uint256",
584
- "name": "amount0Min",
585
- "type": "uint256"
586
- },
587
- {
588
- "internalType": "uint256",
589
- "name": "amount1Min",
590
- "type": "uint256"
591
- },
592
- {
593
- "internalType": "address",
594
- "name": "recipient",
595
- "type": "address"
596
- },
597
- {
598
- "internalType": "uint256",
599
- "name": "deadline",
600
- "type": "uint256"
601
- }
602
- ],
603
- "internalType": "struct INonfungiblePositionManager.MintParams",
604
- "name": "params",
605
- "type": "tuple"
606
- }
607
- ],
608
- "name": "mint",
609
- "outputs": [
610
- {
611
- "internalType": "uint256",
612
- "name": "tokenId",
613
- "type": "uint256"
614
- },
615
- {
616
- "internalType": "uint128",
617
- "name": "liquidity",
618
- "type": "uint128"
619
- },
620
- {
621
- "internalType": "uint256",
622
- "name": "amount0",
623
- "type": "uint256"
624
- },
625
- {
626
- "internalType": "uint256",
627
- "name": "amount1",
628
- "type": "uint256"
629
- }
630
- ],
631
- "stateMutability": "payable",
632
- "type": "function"
633
- },
634
- {
635
- "inputs": [
636
- {
637
- "internalType": "bytes[]",
638
- "name": "data",
639
- "type": "bytes[]"
640
- }
641
- ],
642
- "name": "multicall",
643
- "outputs": [
644
- {
645
- "internalType": "bytes[]",
646
- "name": "results",
647
- "type": "bytes[]"
648
- }
649
- ],
650
- "stateMutability": "payable",
651
- "type": "function"
652
- },
653
- {
654
- "inputs": [],
655
- "name": "name",
656
- "outputs": [
657
- {
658
- "internalType": "string",
659
- "name": "",
660
- "type": "string"
661
- }
662
- ],
663
- "stateMutability": "view",
664
- "type": "function"
665
- },
666
- {
667
- "inputs": [
668
- {
669
- "internalType": "uint256",
670
- "name": "tokenId",
671
- "type": "uint256"
672
- }
673
- ],
674
- "name": "ownerOf",
675
- "outputs": [
676
- {
677
- "internalType": "address",
678
- "name": "",
679
- "type": "address"
680
- }
681
- ],
682
- "stateMutability": "view",
683
- "type": "function"
684
- },
685
- {
686
- "inputs": [
687
- {
688
- "internalType": "address",
689
- "name": "spender",
690
- "type": "address"
691
- },
692
- {
693
- "internalType": "uint256",
694
- "name": "tokenId",
695
- "type": "uint256"
696
- },
697
- {
698
- "internalType": "uint256",
699
- "name": "deadline",
700
- "type": "uint256"
701
- },
702
- {
703
- "internalType": "uint8",
704
- "name": "v",
705
- "type": "uint8"
706
- },
707
- {
708
- "internalType": "bytes32",
709
- "name": "r",
710
- "type": "bytes32"
711
- },
712
- {
713
- "internalType": "bytes32",
714
- "name": "s",
715
- "type": "bytes32"
716
- }
717
- ],
718
- "name": "permit",
719
- "outputs": [],
720
- "stateMutability": "payable",
721
- "type": "function"
722
- },
723
- {
724
- "inputs": [
725
- {
726
- "internalType": "uint256",
727
- "name": "tokenId",
728
- "type": "uint256"
729
- }
730
- ],
731
- "name": "positions",
732
- "outputs": [
733
- {
734
- "internalType": "uint96",
735
- "name": "nonce",
736
- "type": "uint96"
737
- },
738
- {
739
- "internalType": "address",
740
- "name": "operator",
741
- "type": "address"
742
- },
743
- {
744
- "internalType": "address",
745
- "name": "token0",
746
- "type": "address"
747
- },
748
- {
749
- "internalType": "address",
750
- "name": "token1",
751
- "type": "address"
752
- },
753
- {
754
- "internalType": "uint24",
755
- "name": "fee",
756
- "type": "uint24"
757
- },
758
- {
759
- "internalType": "int24",
760
- "name": "tickLower",
761
- "type": "int24"
762
- },
763
- {
764
- "internalType": "int24",
765
- "name": "tickUpper",
766
- "type": "int24"
767
- },
768
- {
769
- "internalType": "uint128",
770
- "name": "liquidity",
771
- "type": "uint128"
772
- },
773
- {
774
- "internalType": "uint256",
775
- "name": "feeGrowthInside0LastX128",
776
- "type": "uint256"
777
- },
778
- {
779
- "internalType": "uint256",
780
- "name": "feeGrowthInside1LastX128",
781
- "type": "uint256"
782
- },
783
- {
784
- "internalType": "uint128",
785
- "name": "tokensOwed0",
786
- "type": "uint128"
787
- },
788
- {
789
- "internalType": "uint128",
790
- "name": "tokensOwed1",
791
- "type": "uint128"
792
- }
793
- ],
794
- "stateMutability": "view",
795
- "type": "function"
796
- },
797
- {
798
- "inputs": [],
799
- "name": "refundETH",
800
- "outputs": [],
801
- "stateMutability": "payable",
802
- "type": "function"
803
- },
804
- {
805
- "inputs": [
806
- {
807
- "internalType": "address",
808
- "name": "from",
809
- "type": "address"
810
- },
811
- {
812
- "internalType": "address",
813
- "name": "to",
814
- "type": "address"
815
- },
816
- {
817
- "internalType": "uint256",
818
- "name": "tokenId",
819
- "type": "uint256"
820
- }
821
- ],
822
- "name": "safeTransferFrom",
823
- "outputs": [],
824
- "stateMutability": "nonpayable",
825
- "type": "function"
826
- },
827
- {
828
- "inputs": [
829
- {
830
- "internalType": "address",
831
- "name": "from",
832
- "type": "address"
833
- },
834
- {
835
- "internalType": "address",
836
- "name": "to",
837
- "type": "address"
838
- },
839
- {
840
- "internalType": "uint256",
841
- "name": "tokenId",
842
- "type": "uint256"
843
- },
844
- {
845
- "internalType": "bytes",
846
- "name": "_data",
847
- "type": "bytes"
848
- }
849
- ],
850
- "name": "safeTransferFrom",
851
- "outputs": [],
852
- "stateMutability": "nonpayable",
853
- "type": "function"
854
- },
855
- {
856
- "inputs": [
857
- {
858
- "internalType": "address",
859
- "name": "token",
860
- "type": "address"
861
- },
862
- {
863
- "internalType": "uint256",
864
- "name": "value",
865
- "type": "uint256"
866
- },
867
- {
868
- "internalType": "uint256",
869
- "name": "deadline",
870
- "type": "uint256"
871
- },
872
- {
873
- "internalType": "uint8",
874
- "name": "v",
875
- "type": "uint8"
876
- },
877
- {
878
- "internalType": "bytes32",
879
- "name": "r",
880
- "type": "bytes32"
881
- },
882
- {
883
- "internalType": "bytes32",
884
- "name": "s",
885
- "type": "bytes32"
886
- }
887
- ],
888
- "name": "selfPermit",
889
- "outputs": [],
890
- "stateMutability": "payable",
891
- "type": "function"
892
- },
893
- {
894
- "inputs": [
895
- {
896
- "internalType": "address",
897
- "name": "token",
898
- "type": "address"
899
- },
900
- {
901
- "internalType": "uint256",
902
- "name": "nonce",
903
- "type": "uint256"
904
- },
905
- {
906
- "internalType": "uint256",
907
- "name": "expiry",
908
- "type": "uint256"
909
- },
910
- {
911
- "internalType": "uint8",
912
- "name": "v",
913
- "type": "uint8"
914
- },
915
- {
916
- "internalType": "bytes32",
917
- "name": "r",
918
- "type": "bytes32"
919
- },
920
- {
921
- "internalType": "bytes32",
922
- "name": "s",
923
- "type": "bytes32"
924
- }
925
- ],
926
- "name": "selfPermitAllowed",
927
- "outputs": [],
928
- "stateMutability": "payable",
929
- "type": "function"
930
- },
931
- {
932
- "inputs": [
933
- {
934
- "internalType": "address",
935
- "name": "token",
936
- "type": "address"
937
- },
938
- {
939
- "internalType": "uint256",
940
- "name": "nonce",
941
- "type": "uint256"
942
- },
943
- {
944
- "internalType": "uint256",
945
- "name": "expiry",
946
- "type": "uint256"
947
- },
948
- {
949
- "internalType": "uint8",
950
- "name": "v",
951
- "type": "uint8"
952
- },
953
- {
954
- "internalType": "bytes32",
955
- "name": "r",
956
- "type": "bytes32"
957
- },
958
- {
959
- "internalType": "bytes32",
960
- "name": "s",
961
- "type": "bytes32"
962
- }
963
- ],
964
- "name": "selfPermitAllowedIfNecessary",
965
- "outputs": [],
966
- "stateMutability": "payable",
967
- "type": "function"
968
- },
969
- {
970
- "inputs": [
971
- {
972
- "internalType": "address",
973
- "name": "token",
974
- "type": "address"
975
- },
976
- {
977
- "internalType": "uint256",
978
- "name": "value",
979
- "type": "uint256"
980
- },
981
- {
982
- "internalType": "uint256",
983
- "name": "deadline",
984
- "type": "uint256"
985
- },
986
- {
987
- "internalType": "uint8",
988
- "name": "v",
989
- "type": "uint8"
990
- },
991
- {
992
- "internalType": "bytes32",
993
- "name": "r",
994
- "type": "bytes32"
995
- },
996
- {
997
- "internalType": "bytes32",
998
- "name": "s",
999
- "type": "bytes32"
1000
- }
1001
- ],
1002
- "name": "selfPermitIfNecessary",
1003
- "outputs": [],
1004
- "stateMutability": "payable",
1005
- "type": "function"
1006
- },
1007
- {
1008
- "inputs": [
1009
- {
1010
- "internalType": "address",
1011
- "name": "operator",
1012
- "type": "address"
1013
- },
1014
- {
1015
- "internalType": "bool",
1016
- "name": "approved",
1017
- "type": "bool"
1018
- }
1019
- ],
1020
- "name": "setApprovalForAll",
1021
- "outputs": [],
1022
- "stateMutability": "nonpayable",
1023
- "type": "function"
1024
- },
1025
- {
1026
- "inputs": [
1027
- {
1028
- "internalType": "bytes4",
1029
- "name": "interfaceId",
1030
- "type": "bytes4"
1031
- }
1032
- ],
1033
- "name": "supportsInterface",
1034
- "outputs": [
1035
- {
1036
- "internalType": "bool",
1037
- "name": "",
1038
- "type": "bool"
1039
- }
1040
- ],
1041
- "stateMutability": "view",
1042
- "type": "function"
1043
- },
1044
- {
1045
- "inputs": [
1046
- {
1047
- "internalType": "address",
1048
- "name": "token",
1049
- "type": "address"
1050
- },
1051
- {
1052
- "internalType": "uint256",
1053
- "name": "amountMinimum",
1054
- "type": "uint256"
1055
- },
1056
- {
1057
- "internalType": "address",
1058
- "name": "recipient",
1059
- "type": "address"
1060
- }
1061
- ],
1062
- "name": "sweepToken",
1063
- "outputs": [],
1064
- "stateMutability": "payable",
1065
- "type": "function"
1066
- },
1067
- {
1068
- "inputs": [],
1069
- "name": "symbol",
1070
- "outputs": [
1071
- {
1072
- "internalType": "string",
1073
- "name": "",
1074
- "type": "string"
1075
- }
1076
- ],
1077
- "stateMutability": "view",
1078
- "type": "function"
1079
- },
1080
- {
1081
- "inputs": [
1082
- {
1083
- "internalType": "uint256",
1084
- "name": "index",
1085
- "type": "uint256"
1086
- }
1087
- ],
1088
- "name": "tokenByIndex",
1089
- "outputs": [
1090
- {
1091
- "internalType": "uint256",
1092
- "name": "",
1093
- "type": "uint256"
1094
- }
1095
- ],
1096
- "stateMutability": "view",
1097
- "type": "function"
1098
- },
1099
- {
1100
- "inputs": [
1101
- {
1102
- "internalType": "address",
1103
- "name": "owner",
1104
- "type": "address"
1105
- },
1106
- {
1107
- "internalType": "uint256",
1108
- "name": "index",
1109
- "type": "uint256"
1110
- }
1111
- ],
1112
- "name": "tokenOfOwnerByIndex",
1113
- "outputs": [
1114
- {
1115
- "internalType": "uint256",
1116
- "name": "",
1117
- "type": "uint256"
1118
- }
1119
- ],
1120
- "stateMutability": "view",
1121
- "type": "function"
1122
- },
1123
- {
1124
- "inputs": [
1125
- {
1126
- "internalType": "uint256",
1127
- "name": "tokenId",
1128
- "type": "uint256"
1129
- }
1130
- ],
1131
- "name": "tokenURI",
1132
- "outputs": [
1133
- {
1134
- "internalType": "string",
1135
- "name": "",
1136
- "type": "string"
1137
- }
1138
- ],
1139
- "stateMutability": "view",
1140
- "type": "function"
1141
- },
1142
- {
1143
- "inputs": [],
1144
- "name": "totalSupply",
1145
- "outputs": [
1146
- {
1147
- "internalType": "uint256",
1148
- "name": "",
1149
- "type": "uint256"
1150
- }
1151
- ],
1152
- "stateMutability": "view",
1153
- "type": "function"
1154
- },
1155
- {
1156
- "inputs": [
1157
- {
1158
- "internalType": "address",
1159
- "name": "from",
1160
- "type": "address"
1161
- },
1162
- {
1163
- "internalType": "address",
1164
- "name": "to",
1165
- "type": "address"
1166
- },
1167
- {
1168
- "internalType": "uint256",
1169
- "name": "tokenId",
1170
- "type": "uint256"
1171
- }
1172
- ],
1173
- "name": "transferFrom",
1174
- "outputs": [],
1175
- "stateMutability": "nonpayable",
1176
- "type": "function"
1177
- },
1178
- {
1179
- "inputs": [
1180
- {
1181
- "internalType": "uint256",
1182
- "name": "amount0Owed",
1183
- "type": "uint256"
1184
- },
1185
- {
1186
- "internalType": "uint256",
1187
- "name": "amount1Owed",
1188
- "type": "uint256"
1189
- },
1190
- {
1191
- "internalType": "bytes",
1192
- "name": "data",
1193
- "type": "bytes"
1194
- }
1195
- ],
1196
- "name": "uniswapV3MintCallback",
1197
- "outputs": [],
1198
- "stateMutability": "nonpayable",
1199
- "type": "function"
1200
- },
1201
- {
1202
- "inputs": [
1203
- {
1204
- "internalType": "uint256",
1205
- "name": "amountMinimum",
1206
- "type": "uint256"
1207
- },
1208
- {
1209
- "internalType": "address",
1210
- "name": "recipient",
1211
- "type": "address"
1212
- }
1213
- ],
1214
- "name": "unwrapWETH9",
1215
- "outputs": [],
1216
- "stateMutability": "payable",
1217
- "type": "function"
1218
- },
1219
- {
1220
- "stateMutability": "payable",
1221
- "type": "receive"
1222
- }
1223
- ],
1224
- "bytecode": "",
1225
- "deployedBytecode": "",
1226
- "linkReferences": {},
1227
- "deployedLinkReferences": {}
1228
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
contracts/ServiceRegistryTokenUtility.json DELETED
@@ -1,926 +0,0 @@
1
- {
2
- "_format": "hh-sol-artifact-1",
3
- "contractName": "ServiceRegistryTokenUtility",
4
- "sourceName": "contracts/ServiceRegistryTokenUtility.sol",
5
- "abi": [
6
- {
7
- "inputs": [
8
- {
9
- "internalType": "address",
10
- "name": "_serviceRegistry",
11
- "type": "address"
12
- }
13
- ],
14
- "stateMutability": "nonpayable",
15
- "type": "constructor"
16
- },
17
- {
18
- "inputs": [
19
- {
20
- "internalType": "address",
21
- "name": "operator",
22
- "type": "address"
23
- }
24
- ],
25
- "name": "AgentInstanceRegistered",
26
- "type": "error"
27
- },
28
- {
29
- "inputs": [
30
- {
31
- "internalType": "uint256",
32
- "name": "serviceId",
33
- "type": "uint256"
34
- }
35
- ],
36
- "name": "AgentInstancesSlotsFilled",
37
- "type": "error"
38
- },
39
- {
40
- "inputs": [
41
- {
42
- "internalType": "uint256",
43
- "name": "agentId",
44
- "type": "uint256"
45
- }
46
- ],
47
- "name": "AgentNotFound",
48
- "type": "error"
49
- },
50
- {
51
- "inputs": [
52
- {
53
- "internalType": "uint256",
54
- "name": "agentId",
55
- "type": "uint256"
56
- },
57
- {
58
- "internalType": "uint256",
59
- "name": "serviceId",
60
- "type": "uint256"
61
- }
62
- ],
63
- "name": "AgentNotInService",
64
- "type": "error"
65
- },
66
- {
67
- "inputs": [
68
- {
69
- "internalType": "uint256",
70
- "name": "componentId",
71
- "type": "uint256"
72
- }
73
- ],
74
- "name": "ComponentNotFound",
75
- "type": "error"
76
- },
77
- {
78
- "inputs": [],
79
- "name": "HashExists",
80
- "type": "error"
81
- },
82
- {
83
- "inputs": [
84
- {
85
- "internalType": "uint256",
86
- "name": "sent",
87
- "type": "uint256"
88
- },
89
- {
90
- "internalType": "uint256",
91
- "name": "expected",
92
- "type": "uint256"
93
- },
94
- {
95
- "internalType": "uint256",
96
- "name": "serviceId",
97
- "type": "uint256"
98
- }
99
- ],
100
- "name": "IncorrectAgentBondingValue",
101
- "type": "error"
102
- },
103
- {
104
- "inputs": [
105
- {
106
- "internalType": "uint256",
107
- "name": "sent",
108
- "type": "uint256"
109
- },
110
- {
111
- "internalType": "uint256",
112
- "name": "expected",
113
- "type": "uint256"
114
- },
115
- {
116
- "internalType": "uint256",
117
- "name": "serviceId",
118
- "type": "uint256"
119
- }
120
- ],
121
- "name": "IncorrectRegistrationDepositValue",
122
- "type": "error"
123
- },
124
- {
125
- "inputs": [
126
- {
127
- "internalType": "address",
128
- "name": "sender",
129
- "type": "address"
130
- },
131
- {
132
- "internalType": "address",
133
- "name": "manager",
134
- "type": "address"
135
- }
136
- ],
137
- "name": "ManagerOnly",
138
- "type": "error"
139
- },
140
- {
141
- "inputs": [
142
- {
143
- "internalType": "address",
144
- "name": "provided",
145
- "type": "address"
146
- },
147
- {
148
- "internalType": "address",
149
- "name": "expected",
150
- "type": "address"
151
- },
152
- {
153
- "internalType": "uint256",
154
- "name": "serviceId",
155
- "type": "uint256"
156
- }
157
- ],
158
- "name": "OnlyOwnServiceMultisig",
159
- "type": "error"
160
- },
161
- {
162
- "inputs": [
163
- {
164
- "internalType": "address",
165
- "name": "operator",
166
- "type": "address"
167
- },
168
- {
169
- "internalType": "uint256",
170
- "name": "serviceId",
171
- "type": "uint256"
172
- }
173
- ],
174
- "name": "OperatorHasNoInstances",
175
- "type": "error"
176
- },
177
- {
178
- "inputs": [
179
- {
180
- "internalType": "uint256",
181
- "name": "provided",
182
- "type": "uint256"
183
- },
184
- {
185
- "internalType": "uint256",
186
- "name": "max",
187
- "type": "uint256"
188
- }
189
- ],
190
- "name": "Overflow",
191
- "type": "error"
192
- },
193
- {
194
- "inputs": [
195
- {
196
- "internalType": "address",
197
- "name": "sender",
198
- "type": "address"
199
- },
200
- {
201
- "internalType": "address",
202
- "name": "owner",
203
- "type": "address"
204
- }
205
- ],
206
- "name": "OwnerOnly",
207
- "type": "error"
208
- },
209
- {
210
- "inputs": [],
211
- "name": "Paused",
212
- "type": "error"
213
- },
214
- {
215
- "inputs": [],
216
- "name": "ReentrancyGuard",
217
- "type": "error"
218
- },
219
- {
220
- "inputs": [
221
- {
222
- "internalType": "uint256",
223
- "name": "serviceId",
224
- "type": "uint256"
225
- }
226
- ],
227
- "name": "ServiceMustBeInactive",
228
- "type": "error"
229
- },
230
- {
231
- "inputs": [
232
- {
233
- "internalType": "address",
234
- "name": "token",
235
- "type": "address"
236
- }
237
- ],
238
- "name": "TokenRejected",
239
- "type": "error"
240
- },
241
- {
242
- "inputs": [
243
- {
244
- "internalType": "address",
245
- "name": "token",
246
- "type": "address"
247
- },
248
- {
249
- "internalType": "address",
250
- "name": "from",
251
- "type": "address"
252
- },
253
- {
254
- "internalType": "address",
255
- "name": "to",
256
- "type": "address"
257
- },
258
- {
259
- "internalType": "uint256",
260
- "name": "value",
261
- "type": "uint256"
262
- }
263
- ],
264
- "name": "TransferFailed",
265
- "type": "error"
266
- },
267
- {
268
- "inputs": [
269
- {
270
- "internalType": "address",
271
- "name": "multisig",
272
- "type": "address"
273
- }
274
- ],
275
- "name": "UnauthorizedMultisig",
276
- "type": "error"
277
- },
278
- {
279
- "inputs": [
280
- {
281
- "internalType": "uint256",
282
- "name": "agentId",
283
- "type": "uint256"
284
- }
285
- ],
286
- "name": "WrongAgentId",
287
- "type": "error"
288
- },
289
- {
290
- "inputs": [
291
- {
292
- "internalType": "uint256",
293
- "name": "numValues1",
294
- "type": "uint256"
295
- },
296
- {
297
- "internalType": "uint256",
298
- "name": "numValues2",
299
- "type": "uint256"
300
- }
301
- ],
302
- "name": "WrongArrayLength",
303
- "type": "error"
304
- },
305
- {
306
- "inputs": [
307
- {
308
- "internalType": "uint256",
309
- "name": "serviceId",
310
- "type": "uint256"
311
- }
312
- ],
313
- "name": "WrongOperator",
314
- "type": "error"
315
- },
316
- {
317
- "inputs": [
318
- {
319
- "internalType": "uint256",
320
- "name": "state",
321
- "type": "uint256"
322
- },
323
- {
324
- "internalType": "uint256",
325
- "name": "serviceId",
326
- "type": "uint256"
327
- }
328
- ],
329
- "name": "WrongServiceState",
330
- "type": "error"
331
- },
332
- {
333
- "inputs": [
334
- {
335
- "internalType": "uint256",
336
- "name": "currentThreshold",
337
- "type": "uint256"
338
- },
339
- {
340
- "internalType": "uint256",
341
- "name": "minThreshold",
342
- "type": "uint256"
343
- },
344
- {
345
- "internalType": "uint256",
346
- "name": "maxThreshold",
347
- "type": "uint256"
348
- }
349
- ],
350
- "name": "WrongThreshold",
351
- "type": "error"
352
- },
353
- {
354
- "inputs": [],
355
- "name": "ZeroAddress",
356
- "type": "error"
357
- },
358
- {
359
- "inputs": [],
360
- "name": "ZeroValue",
361
- "type": "error"
362
- },
363
- {
364
- "anonymous": false,
365
- "inputs": [
366
- {
367
- "indexed": true,
368
- "internalType": "address",
369
- "name": "drainer",
370
- "type": "address"
371
- }
372
- ],
373
- "name": "DrainerUpdated",
374
- "type": "event"
375
- },
376
- {
377
- "anonymous": false,
378
- "inputs": [
379
- {
380
- "indexed": true,
381
- "internalType": "address",
382
- "name": "manager",
383
- "type": "address"
384
- }
385
- ],
386
- "name": "ManagerUpdated",
387
- "type": "event"
388
- },
389
- {
390
- "anonymous": false,
391
- "inputs": [
392
- {
393
- "indexed": false,
394
- "internalType": "uint256",
395
- "name": "amount",
396
- "type": "uint256"
397
- },
398
- {
399
- "indexed": true,
400
- "internalType": "address",
401
- "name": "operator",
402
- "type": "address"
403
- },
404
- {
405
- "indexed": true,
406
- "internalType": "uint256",
407
- "name": "serviceId",
408
- "type": "uint256"
409
- }
410
- ],
411
- "name": "OperatorTokenSlashed",
412
- "type": "event"
413
- },
414
- {
415
- "anonymous": false,
416
- "inputs": [
417
- {
418
- "indexed": true,
419
- "internalType": "address",
420
- "name": "owner",
421
- "type": "address"
422
- }
423
- ],
424
- "name": "OwnerUpdated",
425
- "type": "event"
426
- },
427
- {
428
- "anonymous": false,
429
- "inputs": [
430
- {
431
- "indexed": true,
432
- "internalType": "address",
433
- "name": "account",
434
- "type": "address"
435
- },
436
- {
437
- "indexed": true,
438
- "internalType": "address",
439
- "name": "token",
440
- "type": "address"
441
- },
442
- {
443
- "indexed": false,
444
- "internalType": "uint256",
445
- "name": "amount",
446
- "type": "uint256"
447
- }
448
- ],
449
- "name": "TokenDeposit",
450
- "type": "event"
451
- },
452
- {
453
- "anonymous": false,
454
- "inputs": [
455
- {
456
- "indexed": true,
457
- "internalType": "address",
458
- "name": "drainer",
459
- "type": "address"
460
- },
461
- {
462
- "indexed": true,
463
- "internalType": "address",
464
- "name": "token",
465
- "type": "address"
466
- },
467
- {
468
- "indexed": false,
469
- "internalType": "uint256",
470
- "name": "amount",
471
- "type": "uint256"
472
- }
473
- ],
474
- "name": "TokenDrain",
475
- "type": "event"
476
- },
477
- {
478
- "anonymous": false,
479
- "inputs": [
480
- {
481
- "indexed": true,
482
- "internalType": "address",
483
- "name": "account",
484
- "type": "address"
485
- },
486
- {
487
- "indexed": true,
488
- "internalType": "address",
489
- "name": "token",
490
- "type": "address"
491
- },
492
- {
493
- "indexed": false,
494
- "internalType": "uint256",
495
- "name": "amount",
496
- "type": "uint256"
497
- }
498
- ],
499
- "name": "TokenRefund",
500
- "type": "event"
501
- },
502
- {
503
- "inputs": [
504
- {
505
- "internalType": "uint256",
506
- "name": "serviceId",
507
- "type": "uint256"
508
- }
509
- ],
510
- "name": "activateRegistrationTokenDeposit",
511
- "outputs": [
512
- {
513
- "internalType": "bool",
514
- "name": "isTokenSecured",
515
- "type": "bool"
516
- }
517
- ],
518
- "stateMutability": "nonpayable",
519
- "type": "function"
520
- },
521
- {
522
- "inputs": [
523
- {
524
- "internalType": "address",
525
- "name": "newDrainer",
526
- "type": "address"
527
- }
528
- ],
529
- "name": "changeDrainer",
530
- "outputs": [],
531
- "stateMutability": "nonpayable",
532
- "type": "function"
533
- },
534
- {
535
- "inputs": [
536
- {
537
- "internalType": "address",
538
- "name": "newManager",
539
- "type": "address"
540
- }
541
- ],
542
- "name": "changeManager",
543
- "outputs": [],
544
- "stateMutability": "nonpayable",
545
- "type": "function"
546
- },
547
- {
548
- "inputs": [
549
- {
550
- "internalType": "address",
551
- "name": "newOwner",
552
- "type": "address"
553
- }
554
- ],
555
- "name": "changeOwner",
556
- "outputs": [],
557
- "stateMutability": "nonpayable",
558
- "type": "function"
559
- },
560
- {
561
- "inputs": [
562
- {
563
- "internalType": "uint256",
564
- "name": "serviceId",
565
- "type": "uint256"
566
- },
567
- {
568
- "internalType": "address",
569
- "name": "token",
570
- "type": "address"
571
- },
572
- {
573
- "internalType": "uint32[]",
574
- "name": "agentIds",
575
- "type": "uint32[]"
576
- },
577
- {
578
- "internalType": "uint256[]",
579
- "name": "bonds",
580
- "type": "uint256[]"
581
- }
582
- ],
583
- "name": "createWithToken",
584
- "outputs": [],
585
- "stateMutability": "nonpayable",
586
- "type": "function"
587
- },
588
- {
589
- "inputs": [
590
- {
591
- "internalType": "address",
592
- "name": "token",
593
- "type": "address"
594
- }
595
- ],
596
- "name": "drain",
597
- "outputs": [
598
- {
599
- "internalType": "uint256",
600
- "name": "amount",
601
- "type": "uint256"
602
- }
603
- ],
604
- "stateMutability": "nonpayable",
605
- "type": "function"
606
- },
607
- {
608
- "inputs": [],
609
- "name": "drainer",
610
- "outputs": [
611
- {
612
- "internalType": "address",
613
- "name": "",
614
- "type": "address"
615
- }
616
- ],
617
- "stateMutability": "view",
618
- "type": "function"
619
- },
620
- {
621
- "inputs": [
622
- {
623
- "internalType": "uint256",
624
- "name": "serviceId",
625
- "type": "uint256"
626
- },
627
- {
628
- "internalType": "uint256",
629
- "name": "agentId",
630
- "type": "uint256"
631
- }
632
- ],
633
- "name": "getAgentBond",
634
- "outputs": [
635
- {
636
- "internalType": "uint256",
637
- "name": "bond",
638
- "type": "uint256"
639
- }
640
- ],
641
- "stateMutability": "view",
642
- "type": "function"
643
- },
644
- {
645
- "inputs": [
646
- {
647
- "internalType": "address",
648
- "name": "operator",
649
- "type": "address"
650
- },
651
- {
652
- "internalType": "uint256",
653
- "name": "serviceId",
654
- "type": "uint256"
655
- }
656
- ],
657
- "name": "getOperatorBalance",
658
- "outputs": [
659
- {
660
- "internalType": "uint256",
661
- "name": "balance",
662
- "type": "uint256"
663
- }
664
- ],
665
- "stateMutability": "view",
666
- "type": "function"
667
- },
668
- {
669
- "inputs": [
670
- {
671
- "internalType": "uint256",
672
- "name": "serviceId",
673
- "type": "uint256"
674
- }
675
- ],
676
- "name": "isTokenSecuredService",
677
- "outputs": [
678
- {
679
- "internalType": "bool",
680
- "name": "",
681
- "type": "bool"
682
- }
683
- ],
684
- "stateMutability": "view",
685
- "type": "function"
686
- },
687
- {
688
- "inputs": [],
689
- "name": "manager",
690
- "outputs": [
691
- {
692
- "internalType": "address",
693
- "name": "",
694
- "type": "address"
695
- }
696
- ],
697
- "stateMutability": "view",
698
- "type": "function"
699
- },
700
- {
701
- "inputs": [
702
- {
703
- "internalType": "uint256",
704
- "name": "",
705
- "type": "uint256"
706
- }
707
- ],
708
- "name": "mapOperatorAndServiceIdOperatorBalances",
709
- "outputs": [
710
- {
711
- "internalType": "uint256",
712
- "name": "",
713
- "type": "uint256"
714
- }
715
- ],
716
- "stateMutability": "view",
717
- "type": "function"
718
- },
719
- {
720
- "inputs": [
721
- {
722
- "internalType": "uint256",
723
- "name": "",
724
- "type": "uint256"
725
- }
726
- ],
727
- "name": "mapServiceAndAgentIdAgentBond",
728
- "outputs": [
729
- {
730
- "internalType": "uint256",
731
- "name": "",
732
- "type": "uint256"
733
- }
734
- ],
735
- "stateMutability": "view",
736
- "type": "function"
737
- },
738
- {
739
- "inputs": [
740
- {
741
- "internalType": "uint256",
742
- "name": "",
743
- "type": "uint256"
744
- }
745
- ],
746
- "name": "mapServiceIdTokenDeposit",
747
- "outputs": [
748
- {
749
- "internalType": "address",
750
- "name": "token",
751
- "type": "address"
752
- },
753
- {
754
- "internalType": "uint96",
755
- "name": "securityDeposit",
756
- "type": "uint96"
757
- }
758
- ],
759
- "stateMutability": "view",
760
- "type": "function"
761
- },
762
- {
763
- "inputs": [
764
- {
765
- "internalType": "address",
766
- "name": "",
767
- "type": "address"
768
- }
769
- ],
770
- "name": "mapSlashedFunds",
771
- "outputs": [
772
- {
773
- "internalType": "uint256",
774
- "name": "",
775
- "type": "uint256"
776
- }
777
- ],
778
- "stateMutability": "view",
779
- "type": "function"
780
- },
781
- {
782
- "inputs": [],
783
- "name": "owner",
784
- "outputs": [
785
- {
786
- "internalType": "address",
787
- "name": "",
788
- "type": "address"
789
- }
790
- ],
791
- "stateMutability": "view",
792
- "type": "function"
793
- },
794
- {
795
- "inputs": [
796
- {
797
- "internalType": "address",
798
- "name": "operator",
799
- "type": "address"
800
- },
801
- {
802
- "internalType": "uint256",
803
- "name": "serviceId",
804
- "type": "uint256"
805
- },
806
- {
807
- "internalType": "uint32[]",
808
- "name": "agentIds",
809
- "type": "uint32[]"
810
- }
811
- ],
812
- "name": "registerAgentsTokenDeposit",
813
- "outputs": [
814
- {
815
- "internalType": "bool",
816
- "name": "isTokenSecured",
817
- "type": "bool"
818
- }
819
- ],
820
- "stateMutability": "nonpayable",
821
- "type": "function"
822
- },
823
- {
824
- "inputs": [
825
- {
826
- "internalType": "uint256",
827
- "name": "serviceId",
828
- "type": "uint256"
829
- }
830
- ],
831
- "name": "resetServiceToken",
832
- "outputs": [],
833
- "stateMutability": "nonpayable",
834
- "type": "function"
835
- },
836
- {
837
- "inputs": [],
838
- "name": "serviceRegistry",
839
- "outputs": [
840
- {
841
- "internalType": "address",
842
- "name": "",
843
- "type": "address"
844
- }
845
- ],
846
- "stateMutability": "view",
847
- "type": "function"
848
- },
849
- {
850
- "inputs": [
851
- {
852
- "internalType": "address[]",
853
- "name": "agentInstances",
854
- "type": "address[]"
855
- },
856
- {
857
- "internalType": "uint256[]",
858
- "name": "amounts",
859
- "type": "uint256[]"
860
- },
861
- {
862
- "internalType": "uint256",
863
- "name": "serviceId",
864
- "type": "uint256"
865
- }
866
- ],
867
- "name": "slash",
868
- "outputs": [
869
- {
870
- "internalType": "bool",
871
- "name": "success",
872
- "type": "bool"
873
- }
874
- ],
875
- "stateMutability": "nonpayable",
876
- "type": "function"
877
- },
878
- {
879
- "inputs": [
880
- {
881
- "internalType": "uint256",
882
- "name": "serviceId",
883
- "type": "uint256"
884
- }
885
- ],
886
- "name": "terminateTokenRefund",
887
- "outputs": [
888
- {
889
- "internalType": "uint256",
890
- "name": "securityRefund",
891
- "type": "uint256"
892
- }
893
- ],
894
- "stateMutability": "nonpayable",
895
- "type": "function"
896
- },
897
- {
898
- "inputs": [
899
- {
900
- "internalType": "address",
901
- "name": "operator",
902
- "type": "address"
903
- },
904
- {
905
- "internalType": "uint256",
906
- "name": "serviceId",
907
- "type": "uint256"
908
- }
909
- ],
910
- "name": "unbondTokenRefund",
911
- "outputs": [
912
- {
913
- "internalType": "uint256",
914
- "name": "refund",
915
- "type": "uint256"
916
- }
917
- ],
918
- "stateMutability": "nonpayable",
919
- "type": "function"
920
- }
921
- ],
922
- "bytecode": "0x60a0604052600160035534801561001557600080fd5b5060405162001f3a38038062001f3a83398101604081905261003691610080565b6001600160a01b03811661005d5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052600080546001600160a01b031916331790556100b0565b60006020828403121561009257600080fd5b81516001600160a01b03811681146100a957600080fd5b9392505050565b608051611e52620000e8600039600081816103be015281816105c1015281816106bd015281816108470152610b630152611e526000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c806375c1f934116100d8578063b0f4c2481161008c578063dc4f8bc511610066578063dc4f8bc514610400578063e3ce9a8414610413578063ece531321461042657600080fd5b8063b0f4c248146103a6578063cbcf252a146103b9578063cbd413a5146103e057600080fd5b80638da5cb5b116100bd5780638da5cb5b1461036d578063a3fbbaae14610380578063a6f9dae11461039357600080fd5b806375c1f934146103165780638a2bd86f1461033e57600080fd5b806346d7836d1161013a578063542db44911610114578063542db449146102dd57806357838e85146102f05780635f3662581461030357600080fd5b806346d7836d14610264578063481c6a751461029f5780635419bb8c146102ca57600080fd5b806325e1afc31161016b57806325e1afc3146101cf5780633cebfa4f146101e2578063421448541461024457600080fd5b806310c6aa191461018757806313f824d81461019c575b600080fd5b61019a610195366004611956565b610439565b005b6101bc6101aa36600461197a565b60056020526000908152604090205481565b6040519081526020015b60405180910390f35b6101bc6101dd36600461197a565b6104fc565b61021d6101f036600461197a565b6004602052600090815260409020546001600160a01b03811690600160a01b90046001600160601b031682565b604080516001600160a01b0390931683526001600160601b039091166020830152016101c6565b6101bc61025236600461197a565b60066020526000908152604090205481565b61028f61027236600461197a565b6000908152600460205260409020546001600160a01b0316151590565b60405190151581526020016101c6565b6001546102b2906001600160a01b031681565b6040516001600160a01b0390911681526020016101c6565b61028f6102d8366004611a69565b6106b6565b61028f6102eb36600461197a565b610a88565b6002546102b2906001600160a01b031681565b61019a61031136600461197a565b610e0e565b6101bc610324366004611b34565b602090811b90911760009081526005909152604090205490565b6101bc61034c366004611b56565b60a01b6001600160a01b039091161760009081526006602052604090205490565b6000546102b2906001600160a01b031681565b61019a61038e366004611956565b610e5f565b61019a6103a1366004611956565b610f1d565b6101bc6103b4366004611b56565b610fd9565b6102b27f000000000000000000000000000000000000000000000000000000000000000081565b6101bc6103ee366004611956565b60076020526000908152604090205481565b61028f61040e366004611bf8565b6110ff565b61019a610421366004611c51565b611464565b6101bc610434366004611956565b611708565b6000546001600160a01b0316331461047e5760005460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b6001600160a01b0381166104a55760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f8d1e8547016120917daad7f81c42b48f7fee379badc48f1889f0f43bb619472590600090a250565b600060016003541115610522576040516345f5ce8b60e11b815260040160405180910390fd5b60026003556001546001600160a01b031633146105675760015460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610475565b6000828152600460209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160601b03169183019190915280156106aa5781602001516001600160601b0316925060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636352211e866040518263ffffffff1660e01b815260040161060d91815260200190565b602060405180830381865afa15801561062a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064e9190611cd1565b905061065b828286611831565b816001600160a01b0316816001600160a01b03167fb5ea3bd24bc48df54cdc99f11e448ab16503a3e16f46c363202f5fff4891acba866040516106a091815260200190565b60405180910390a3505b50506001600355919050565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634236aff8856040518263ffffffff1660e01b815260040161070991815260200190565b60e060405180830381865afa158015610726573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074a9190611cee565b9650505050509250508060ff1660041461078357604051633c053f9d60e21b815260ff8216600482015260248101859052604401610475565b8551158061079357508451865114155b156107be57855185516040516308151c1160e41b815260048101929092526024820152604401610475565b336001600160a01b038316146107ff576040516379f91cd360e01b81523360048201526001600160a01b038316602482015260448101859052606401610475565b6000848152600460205260409020546001600160a01b0316806108355760405163d92e233d60e01b815260040160405180910390fd5b86516000805b82811015610a395760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634eb780da8c848151811061088657610886611d92565b60200260200101516040518263ffffffff1660e01b81526004016108b991906001600160a01b0391909116815260200190565b602060405180830381865afa1580156108d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fa9190611cd1565b60a08a901b6001600160a01b0382161760008181526006602052604081205492935090919081900361092e57505050610a29565b808c858151811061094157610941611d92565b602002602001015110610963576109588186611dbe565b9450600090506109b2565b8b848151811061097557610975611d92565b6020026020010151856109889190611dbe565b94508b848151811061099c5761099c611d92565b6020026020010151816109af9190611dd7565b90505b60008281526006602052604090208190558b518b906001600160a01b038516907fd79658b314eb967321e5e6a82ab39f6f7ffc567d38c6feee527761aca406a597908f9088908110610a0657610a06611d92565b6020026020010151604051610a1d91815260200190565b60405180910390a35050505b610a3281611dea565b905061083b565b506001600160a01b038316600090815260076020526040902054610a5d9082611dbe565b6001600160a01b03909316600090815260076020526040902092909255506001979650505050505050565b600060016003541115610aae576040516345f5ce8b60e11b815260040160405180910390fd5b60026003556001546001600160a01b03163314610af35760015460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610475565b6000828152600460209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160601b03169183019190915280156106aa5760208201516040516331a9108f60e11b8152600481018690526001600160601b03909116906000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015610bb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd69190611cd1565b604051636eb1769f60e11b81526001600160a01b03808316600483015230602483015291925060009185169063dd62ed3e90604401602060405180830381865afa158015610c28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4c9190611e03565b905082811015610c8057604051631c30abbb60e31b8152600481018290526024810184905260448101889052606401610475565b6040516370a0823160e01b8152306004820152600196506000906001600160a01b038616906370a0823190602401602060405180830381865afa158015610ccb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cef9190611e03565b9050610cfd858430876118b4565b6040516370a0823160e01b81523060048201526000906001600160a01b038716906370a0823190602401602060405180830381865afa158015610d44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d689190611e03565b905080821180610d81575084610d7e8383611dd7565b14155b15610db057604051631c30abbb60e31b81526000600482015260248101869052604481018a9052606401610475565b856001600160a01b0316846001600160a01b03167f98c09d9949722bae4bd0d988d4050091c3ae7ec6d51d3c6bbfe4233593944e9e87604051610df591815260200190565b60405180910390a3505050505050506001600355919050565b6001546001600160a01b03163314610e4e5760015460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610475565b600090815260046020526040812055565b6000546001600160a01b03163314610e9f5760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610475565b6001600160a01b038116610ec65760405163d92e233d60e01b815260040160405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f2c1c11af44aa5608f1dca38c00275c30ea091e02417d36e70e9a1538689c433d90600090a250565b6000546001600160a01b03163314610f5d5760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610475565b6001600160a01b038116610f845760405163d92e233d60e01b815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b600060016003541115610fff576040516345f5ce8b60e11b815260040160405180910390fd5b60026003556001546001600160a01b031633146110445760015460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610475565b6000828152600460205260409020546001600160a01b031680156110f35760a083901b6001600160a01b03851617600081815260066020526040902054925082156110f1576000818152600660205260408120556110a3828685611831565b816001600160a01b0316856001600160a01b03167fb5ea3bd24bc48df54cdc99f11e448ab16503a3e16f46c363202f5fff4891acba856040516110e891815260200190565b60405180910390a35b505b50600160035592915050565b600060016003541115611125576040516345f5ce8b60e11b815260040160405180910390fd5b60026003556001546001600160a01b0316331461116a5760015460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610475565b6000838152600460205260409020546001600160a01b031680156114575782516000805b828110156111f757600087905060208783815181106111af576111af611d92565b60209081029190910181015163ffffffff1690911b91909117600081815260059092526040909120546111e28185611dbe565b93505050806111f090611dea565b905061118e565b50604051636eb1769f60e11b81526001600160a01b0388811660048301523060248301526000919085169063dd62ed3e90604401602060405180830381865afa158015611248573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126c9190611e03565b9050818110156112a057604051637ebbcab960e11b8152600481018290526024810183905260448101889052606401610475565b60a087901b6001600160a01b03891617600081815260066020526040812080548592906112ce908490611dbe565b90915550506040516370a0823160e01b8152306004820152600196506000906001600160a01b038716906370a0823190602401602060405180830381865afa15801561131e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113429190611e03565b9050611350868b30876118b4565b6040516370a0823160e01b81523060048201526000906001600160a01b038816906370a0823190602401602060405180830381865afa158015611397573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bb9190611e03565b9050808211806113d45750846113d18383611dd7565b14155b1561140357604051637ebbcab960e11b81526000600482015260248101869052604481018b9052606401610475565b866001600160a01b03168b6001600160a01b03167f98c09d9949722bae4bd0d988d4050091c3ae7ec6d51d3c6bbfe4233593944e9e8760405161144891815260200190565b60405180910390a35050505050505b5060016003559392505050565b6001546001600160a01b031633146114a45760015460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610475565b60408051600060248083018290528351808403909101815260449092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166370a0823160e01b1790527f70a08231b98ef4ca268c9cc3f6b4590e4bfec28280db06bb5d45e689f2a360be91906001600160a01b0386163b1561153557600080825160208401895afa91505b8161155e5760405163e77376f360e01b81526001600160a01b0387166004820152602401610475565b6000805b86518110156116b45785818151811061157d5761157d611d92565b6020026020010151600003156116a4576001600160601b0380168682815181106115a9576115a9611d92565b60200260200101511115611606578581815181106115c9576115c9611d92565b60200260200101516001600160601b03604051637ae5968560e01b81526004016104759291909182526001600160601b0316602082015260400190565b6000899050602088838151811061161f5761161f611d92565b602002602001015163ffffffff16901b8117905086828151811061164557611645611d92565b602002602001015160056000838152602001908152602001600020819055508287838151811061167757611677611d92565b602002602001015111156116a25786828151811061169757611697611d92565b602002602001015192505b505b6116ad81611dea565b9050611562565b506040805180820182526001600160a01b0398891681526001600160601b03928316602080830191825260009b8c52600490529190992098519051909116600160a01b029616959095179095555050505050565b60006001600354111561172e576040516345f5ce8b60e11b815260040160405180910390fd5b60026003556000546001600160a01b031633146117735760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610475565b6002546001600160a01b031661179c5760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b0381166000908152600760205260409020548015611827576001600160a01b038083166000908152600760205260408120556002546117e69184911683611831565b6040518181526001600160a01b0383169033907feb64d3e0fe21df59e0edd78e9749e4bc9f3cf593a842d487fe40f29ef45fdad69060200160405180910390a35b6001600355919050565b600060405163a9059cbb60e01b6000528360045282602452602060006044600080895af13d15601f3d11600160005114161716915060006060528060405250806118ae5760405163cd3f165960e01b81526001600160a01b0380861660048301523060248301528416604482015260648101839052608401610475565b50505050565b60006040516323b872dd60e01b6000528460045283602452826044526020600060646000808a5af13d15601f3d11600160005114161716915060006060528060405250806119375760405163cd3f165960e01b81526001600160a01b03808716600483015280861660248301528416604482015260648101839052608401610475565b5050505050565b6001600160a01b038116811461195357600080fd5b50565b60006020828403121561196857600080fd5b81356119738161193e565b9392505050565b60006020828403121561198c57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156119d2576119d2611993565b604052919050565b600067ffffffffffffffff8211156119f4576119f4611993565b5060051b60200190565b600082601f830112611a0f57600080fd5b81356020611a24611a1f836119da565b6119a9565b82815260059290921b84018101918181019086841115611a4357600080fd5b8286015b84811015611a5e5780358352918301918301611a47565b509695505050505050565b600080600060608486031215611a7e57600080fd5b833567ffffffffffffffff80821115611a9657600080fd5b818601915086601f830112611aaa57600080fd5b81356020611aba611a1f836119da565b82815260059290921b8401810191818101908a841115611ad957600080fd5b948201945b83861015611b00578535611af18161193e565b82529482019490820190611ade565b97505087013592505080821115611b1657600080fd5b50611b23868287016119fe565b925050604084013590509250925092565b60008060408385031215611b4757600080fd5b50508035926020909101359150565b60008060408385031215611b6957600080fd5b8235611b748161193e565b946020939093013593505050565b63ffffffff8116811461195357600080fd5b600082601f830112611ba557600080fd5b81356020611bb5611a1f836119da565b82815260059290921b84018101918181019086841115611bd457600080fd5b8286015b84811015611a5e578035611beb81611b82565b8352918301918301611bd8565b600080600060608486031215611c0d57600080fd5b8335611c188161193e565b925060208401359150604084013567ffffffffffffffff811115611c3b57600080fd5b611c4786828701611b94565b9150509250925092565b60008060008060808587031215611c6757600080fd5b843593506020850135611c798161193e565b9250604085013567ffffffffffffffff80821115611c9657600080fd5b611ca288838901611b94565b93506060870135915080821115611cb857600080fd5b50611cc5878288016119fe565b91505092959194509250565b600060208284031215611ce357600080fd5b81516119738161193e565b600080600080600080600060e0888a031215611d0957600080fd5b87516001600160601b0381168114611d2057600080fd5b6020890151909750611d318161193e565b604089015160608a01519197509550611d4981611b82565b6080890151909450611d5a81611b82565b60a0890151909350611d6b81611b82565b60c089015190925060ff81168114611d8257600080fd5b8091505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115611dd157611dd1611da8565b92915050565b81810381811115611dd157611dd1611da8565b600060018201611dfc57611dfc611da8565b5060010190565b600060208284031215611e1557600080fd5b505191905056fea2646970667358221220e38aad42f76663645ad01adefd7b54c3c3a128669aadd1939110bdc298d0532264736f6c63430008130033",
923
- "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101825760003560e01c806375c1f934116100d8578063b0f4c2481161008c578063dc4f8bc511610066578063dc4f8bc514610400578063e3ce9a8414610413578063ece531321461042657600080fd5b8063b0f4c248146103a6578063cbcf252a146103b9578063cbd413a5146103e057600080fd5b80638da5cb5b116100bd5780638da5cb5b1461036d578063a3fbbaae14610380578063a6f9dae11461039357600080fd5b806375c1f934146103165780638a2bd86f1461033e57600080fd5b806346d7836d1161013a578063542db44911610114578063542db449146102dd57806357838e85146102f05780635f3662581461030357600080fd5b806346d7836d14610264578063481c6a751461029f5780635419bb8c146102ca57600080fd5b806325e1afc31161016b57806325e1afc3146101cf5780633cebfa4f146101e2578063421448541461024457600080fd5b806310c6aa191461018757806313f824d81461019c575b600080fd5b61019a610195366004611956565b610439565b005b6101bc6101aa36600461197a565b60056020526000908152604090205481565b6040519081526020015b60405180910390f35b6101bc6101dd36600461197a565b6104fc565b61021d6101f036600461197a565b6004602052600090815260409020546001600160a01b03811690600160a01b90046001600160601b031682565b604080516001600160a01b0390931683526001600160601b039091166020830152016101c6565b6101bc61025236600461197a565b60066020526000908152604090205481565b61028f61027236600461197a565b6000908152600460205260409020546001600160a01b0316151590565b60405190151581526020016101c6565b6001546102b2906001600160a01b031681565b6040516001600160a01b0390911681526020016101c6565b61028f6102d8366004611a69565b6106b6565b61028f6102eb36600461197a565b610a88565b6002546102b2906001600160a01b031681565b61019a61031136600461197a565b610e0e565b6101bc610324366004611b34565b602090811b90911760009081526005909152604090205490565b6101bc61034c366004611b56565b60a01b6001600160a01b039091161760009081526006602052604090205490565b6000546102b2906001600160a01b031681565b61019a61038e366004611956565b610e5f565b61019a6103a1366004611956565b610f1d565b6101bc6103b4366004611b56565b610fd9565b6102b27f000000000000000000000000000000000000000000000000000000000000000081565b6101bc6103ee366004611956565b60076020526000908152604090205481565b61028f61040e366004611bf8565b6110ff565b61019a610421366004611c51565b611464565b6101bc610434366004611956565b611708565b6000546001600160a01b0316331461047e5760005460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b6001600160a01b0381166104a55760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f8d1e8547016120917daad7f81c42b48f7fee379badc48f1889f0f43bb619472590600090a250565b600060016003541115610522576040516345f5ce8b60e11b815260040160405180910390fd5b60026003556001546001600160a01b031633146105675760015460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610475565b6000828152600460209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160601b03169183019190915280156106aa5781602001516001600160601b0316925060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636352211e866040518263ffffffff1660e01b815260040161060d91815260200190565b602060405180830381865afa15801561062a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064e9190611cd1565b905061065b828286611831565b816001600160a01b0316816001600160a01b03167fb5ea3bd24bc48df54cdc99f11e448ab16503a3e16f46c363202f5fff4891acba866040516106a091815260200190565b60405180910390a3505b50506001600355919050565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634236aff8856040518263ffffffff1660e01b815260040161070991815260200190565b60e060405180830381865afa158015610726573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074a9190611cee565b9650505050509250508060ff1660041461078357604051633c053f9d60e21b815260ff8216600482015260248101859052604401610475565b8551158061079357508451865114155b156107be57855185516040516308151c1160e41b815260048101929092526024820152604401610475565b336001600160a01b038316146107ff576040516379f91cd360e01b81523360048201526001600160a01b038316602482015260448101859052606401610475565b6000848152600460205260409020546001600160a01b0316806108355760405163d92e233d60e01b815260040160405180910390fd5b86516000805b82811015610a395760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634eb780da8c848151811061088657610886611d92565b60200260200101516040518263ffffffff1660e01b81526004016108b991906001600160a01b0391909116815260200190565b602060405180830381865afa1580156108d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fa9190611cd1565b60a08a901b6001600160a01b0382161760008181526006602052604081205492935090919081900361092e57505050610a29565b808c858151811061094157610941611d92565b602002602001015110610963576109588186611dbe565b9450600090506109b2565b8b848151811061097557610975611d92565b6020026020010151856109889190611dbe565b94508b848151811061099c5761099c611d92565b6020026020010151816109af9190611dd7565b90505b60008281526006602052604090208190558b518b906001600160a01b038516907fd79658b314eb967321e5e6a82ab39f6f7ffc567d38c6feee527761aca406a597908f9088908110610a0657610a06611d92565b6020026020010151604051610a1d91815260200190565b60405180910390a35050505b610a3281611dea565b905061083b565b506001600160a01b038316600090815260076020526040902054610a5d9082611dbe565b6001600160a01b03909316600090815260076020526040902092909255506001979650505050505050565b600060016003541115610aae576040516345f5ce8b60e11b815260040160405180910390fd5b60026003556001546001600160a01b03163314610af35760015460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610475565b6000828152600460209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160601b03169183019190915280156106aa5760208201516040516331a9108f60e11b8152600481018690526001600160601b03909116906000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015610bb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd69190611cd1565b604051636eb1769f60e11b81526001600160a01b03808316600483015230602483015291925060009185169063dd62ed3e90604401602060405180830381865afa158015610c28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4c9190611e03565b905082811015610c8057604051631c30abbb60e31b8152600481018290526024810184905260448101889052606401610475565b6040516370a0823160e01b8152306004820152600196506000906001600160a01b038616906370a0823190602401602060405180830381865afa158015610ccb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cef9190611e03565b9050610cfd858430876118b4565b6040516370a0823160e01b81523060048201526000906001600160a01b038716906370a0823190602401602060405180830381865afa158015610d44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d689190611e03565b905080821180610d81575084610d7e8383611dd7565b14155b15610db057604051631c30abbb60e31b81526000600482015260248101869052604481018a9052606401610475565b856001600160a01b0316846001600160a01b03167f98c09d9949722bae4bd0d988d4050091c3ae7ec6d51d3c6bbfe4233593944e9e87604051610df591815260200190565b60405180910390a3505050505050506001600355919050565b6001546001600160a01b03163314610e4e5760015460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610475565b600090815260046020526040812055565b6000546001600160a01b03163314610e9f5760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610475565b6001600160a01b038116610ec65760405163d92e233d60e01b815260040160405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f2c1c11af44aa5608f1dca38c00275c30ea091e02417d36e70e9a1538689c433d90600090a250565b6000546001600160a01b03163314610f5d5760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610475565b6001600160a01b038116610f845760405163d92e233d60e01b815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b600060016003541115610fff576040516345f5ce8b60e11b815260040160405180910390fd5b60026003556001546001600160a01b031633146110445760015460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610475565b6000828152600460205260409020546001600160a01b031680156110f35760a083901b6001600160a01b03851617600081815260066020526040902054925082156110f1576000818152600660205260408120556110a3828685611831565b816001600160a01b0316856001600160a01b03167fb5ea3bd24bc48df54cdc99f11e448ab16503a3e16f46c363202f5fff4891acba856040516110e891815260200190565b60405180910390a35b505b50600160035592915050565b600060016003541115611125576040516345f5ce8b60e11b815260040160405180910390fd5b60026003556001546001600160a01b0316331461116a5760015460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610475565b6000838152600460205260409020546001600160a01b031680156114575782516000805b828110156111f757600087905060208783815181106111af576111af611d92565b60209081029190910181015163ffffffff1690911b91909117600081815260059092526040909120546111e28185611dbe565b93505050806111f090611dea565b905061118e565b50604051636eb1769f60e11b81526001600160a01b0388811660048301523060248301526000919085169063dd62ed3e90604401602060405180830381865afa158015611248573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126c9190611e03565b9050818110156112a057604051637ebbcab960e11b8152600481018290526024810183905260448101889052606401610475565b60a087901b6001600160a01b03891617600081815260066020526040812080548592906112ce908490611dbe565b90915550506040516370a0823160e01b8152306004820152600196506000906001600160a01b038716906370a0823190602401602060405180830381865afa15801561131e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113429190611e03565b9050611350868b30876118b4565b6040516370a0823160e01b81523060048201526000906001600160a01b038816906370a0823190602401602060405180830381865afa158015611397573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bb9190611e03565b9050808211806113d45750846113d18383611dd7565b14155b1561140357604051637ebbcab960e11b81526000600482015260248101869052604481018b9052606401610475565b866001600160a01b03168b6001600160a01b03167f98c09d9949722bae4bd0d988d4050091c3ae7ec6d51d3c6bbfe4233593944e9e8760405161144891815260200190565b60405180910390a35050505050505b5060016003559392505050565b6001546001600160a01b031633146114a45760015460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610475565b60408051600060248083018290528351808403909101815260449092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166370a0823160e01b1790527f70a08231b98ef4ca268c9cc3f6b4590e4bfec28280db06bb5d45e689f2a360be91906001600160a01b0386163b1561153557600080825160208401895afa91505b8161155e5760405163e77376f360e01b81526001600160a01b0387166004820152602401610475565b6000805b86518110156116b45785818151811061157d5761157d611d92565b6020026020010151600003156116a4576001600160601b0380168682815181106115a9576115a9611d92565b60200260200101511115611606578581815181106115c9576115c9611d92565b60200260200101516001600160601b03604051637ae5968560e01b81526004016104759291909182526001600160601b0316602082015260400190565b6000899050602088838151811061161f5761161f611d92565b602002602001015163ffffffff16901b8117905086828151811061164557611645611d92565b602002602001015160056000838152602001908152602001600020819055508287838151811061167757611677611d92565b602002602001015111156116a25786828151811061169757611697611d92565b602002602001015192505b505b6116ad81611dea565b9050611562565b506040805180820182526001600160a01b0398891681526001600160601b03928316602080830191825260009b8c52600490529190992098519051909116600160a01b029616959095179095555050505050565b60006001600354111561172e576040516345f5ce8b60e11b815260040160405180910390fd5b60026003556000546001600160a01b031633146117735760005460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610475565b6002546001600160a01b031661179c5760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b0381166000908152600760205260409020548015611827576001600160a01b038083166000908152600760205260408120556002546117e69184911683611831565b6040518181526001600160a01b0383169033907feb64d3e0fe21df59e0edd78e9749e4bc9f3cf593a842d487fe40f29ef45fdad69060200160405180910390a35b6001600355919050565b600060405163a9059cbb60e01b6000528360045282602452602060006044600080895af13d15601f3d11600160005114161716915060006060528060405250806118ae5760405163cd3f165960e01b81526001600160a01b0380861660048301523060248301528416604482015260648101839052608401610475565b50505050565b60006040516323b872dd60e01b6000528460045283602452826044526020600060646000808a5af13d15601f3d11600160005114161716915060006060528060405250806119375760405163cd3f165960e01b81526001600160a01b03808716600483015280861660248301528416604482015260648101839052608401610475565b5050505050565b6001600160a01b038116811461195357600080fd5b50565b60006020828403121561196857600080fd5b81356119738161193e565b9392505050565b60006020828403121561198c57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156119d2576119d2611993565b604052919050565b600067ffffffffffffffff8211156119f4576119f4611993565b5060051b60200190565b600082601f830112611a0f57600080fd5b81356020611a24611a1f836119da565b6119a9565b82815260059290921b84018101918181019086841115611a4357600080fd5b8286015b84811015611a5e5780358352918301918301611a47565b509695505050505050565b600080600060608486031215611a7e57600080fd5b833567ffffffffffffffff80821115611a9657600080fd5b818601915086601f830112611aaa57600080fd5b81356020611aba611a1f836119da565b82815260059290921b8401810191818101908a841115611ad957600080fd5b948201945b83861015611b00578535611af18161193e565b82529482019490820190611ade565b97505087013592505080821115611b1657600080fd5b50611b23868287016119fe565b925050604084013590509250925092565b60008060408385031215611b4757600080fd5b50508035926020909101359150565b60008060408385031215611b6957600080fd5b8235611b748161193e565b946020939093013593505050565b63ffffffff8116811461195357600080fd5b600082601f830112611ba557600080fd5b81356020611bb5611a1f836119da565b82815260059290921b84018101918181019086841115611bd457600080fd5b8286015b84811015611a5e578035611beb81611b82565b8352918301918301611bd8565b600080600060608486031215611c0d57600080fd5b8335611c188161193e565b925060208401359150604084013567ffffffffffffffff811115611c3b57600080fd5b611c4786828701611b94565b9150509250925092565b60008060008060808587031215611c6757600080fd5b843593506020850135611c798161193e565b9250604085013567ffffffffffffffff80821115611c9657600080fd5b611ca288838901611b94565b93506060870135915080821115611cb857600080fd5b50611cc5878288016119fe565b91505092959194509250565b600060208284031215611ce357600080fd5b81516119738161193e565b600080600080600080600060e0888a031215611d0957600080fd5b87516001600160601b0381168114611d2057600080fd5b6020890151909750611d318161193e565b604089015160608a01519197509550611d4981611b82565b6080890151909450611d5a81611b82565b60a0890151909350611d6b81611b82565b60c089015190925060ff81168114611d8257600080fd5b8091505092959891949750929550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115611dd157611dd1611da8565b92915050565b81810381811115611dd157611dd1611da8565b600060018201611dfc57611dfc611da8565b5060010190565b600060208284031215611e1557600080fd5b505191905056fea2646970667358221220e38aad42f76663645ad01adefd7b54c3c3a128669aadd1939110bdc298d0532264736f6c63430008130033",
924
- "linkReferences": {},
925
- "deployedLinkReferences": {}
926
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
contracts/StakingActivityChecker.json DELETED
@@ -1,87 +0,0 @@
1
- {
2
- "_format": "hh-sol-artifact-1",
3
- "contractName": "StakingActivityChecker",
4
- "sourceName": "contracts/staking/StakingActivityChecker.sol",
5
- "abi": [
6
- {
7
- "inputs": [
8
- {
9
- "internalType": "uint256",
10
- "name": "_livenessRatio",
11
- "type": "uint256"
12
- }
13
- ],
14
- "stateMutability": "nonpayable",
15
- "type": "constructor"
16
- },
17
- {
18
- "inputs": [],
19
- "name": "ZeroValue",
20
- "type": "error"
21
- },
22
- {
23
- "inputs": [
24
- {
25
- "internalType": "address",
26
- "name": "multisig",
27
- "type": "address"
28
- }
29
- ],
30
- "name": "getMultisigNonces",
31
- "outputs": [
32
- {
33
- "internalType": "uint256[]",
34
- "name": "nonces",
35
- "type": "uint256[]"
36
- }
37
- ],
38
- "stateMutability": "view",
39
- "type": "function"
40
- },
41
- {
42
- "inputs": [
43
- {
44
- "internalType": "uint256[]",
45
- "name": "curNonces",
46
- "type": "uint256[]"
47
- },
48
- {
49
- "internalType": "uint256[]",
50
- "name": "lastNonces",
51
- "type": "uint256[]"
52
- },
53
- {
54
- "internalType": "uint256",
55
- "name": "ts",
56
- "type": "uint256"
57
- }
58
- ],
59
- "name": "isRatioPass",
60
- "outputs": [
61
- {
62
- "internalType": "bool",
63
- "name": "ratioPass",
64
- "type": "bool"
65
- }
66
- ],
67
- "stateMutability": "view",
68
- "type": "function"
69
- },
70
- {
71
- "inputs": [],
72
- "name": "livenessRatio",
73
- "outputs": [
74
- {
75
- "internalType": "uint256",
76
- "name": "",
77
- "type": "uint256"
78
- }
79
- ],
80
- "stateMutability": "view",
81
- "type": "function"
82
- }
83
- ],
84
- "bytecode": "0x608060405234801561000f575f80fd5b506004361061003f575f3560e01c8063184023a514610043578063592cf3fb1461006b578063d564c4bf146100a0575b5f80fd5b610056610051366004610328565b6100c0565b60405190151581526020015b60405180910390f35b6100927f00000000000000000000000000000000000000000000000000002a1b324b8f6881565b604051908152602001610062565b6100b36100ae366004610390565b610190565b60405161006291906103c3565b5f80821180156101015750825f815181106100dd576100dd610406565b6020026020010151845f815181106100f7576100f7610406565b6020026020010151115b15610189575f82845f8151811061011a5761011a610406565b6020026020010151865f8151811061013457610134610406565b60200260200101516101469190610460565b61015890670de0b6b3a7640000610479565b6101629190610490565b7f00000000000000000000000000000000000000000000000000002a1b324b8f6811159150505b9392505050565b604080516001808252818301909252606091602080830190803683370190505090508173ffffffffffffffffffffffffffffffffffffffff1663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061021f91906104c8565b815f8151811061023157610231610406565b602002602001018181525050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f83011261027e575f80fd5b8135602067ffffffffffffffff8083111561029b5761029b610242565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811084821117156102de576102de610242565b60405293845260208187018101949081019250878511156102fd575f80fd5b6020870191505b8482101561031d57813583529183019190830190610304565b979650505050505050565b5f805f6060848603121561033a575f80fd5b833567ffffffffffffffff80821115610351575f80fd5b61035d8783880161026f565b94506020860135915080821115610372575f80fd5b5061037f8682870161026f565b925050604084013590509250925092565b5f602082840312156103a0575f80fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610189575f80fd5b602080825282518282018190525f9190848201906040850190845b818110156103fa578351835292840192918401916001016103de565b50909695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8181038181111561047357610473610433565b92915050565b808202811582820484141761047357610473610433565b5f826104c3577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b5f602082840312156104d8575f80fd5b505191905056fea26469706673582212205cd6cde3d106d475558793ccc0670f4af07e2e69e437eff007791837f35d016464736f6c63430008190033",
85
- "linkReferences": {},
86
- "deployedLinkReferences": {}
87
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
contracts/StakingToken.json DELETED
@@ -1,1274 +0,0 @@
1
- {
2
- "_format": "hh-sol-artifact-1",
3
- "contractName": "ServiceStakingToken",
4
- "sourceName": "contracts/staking/ServiceStakingToken.sol",
5
- "abi": [
6
- {
7
- "inputs": [],
8
- "name": "AlreadyInitialized",
9
- "type": "error"
10
- },
11
- {
12
- "inputs": [
13
- {
14
- "internalType": "address",
15
- "name": "activityChecker",
16
- "type": "address"
17
- }
18
- ],
19
- "name": "ContractOnly",
20
- "type": "error"
21
- },
22
- {
23
- "inputs": [
24
- {
25
- "internalType": "uint256",
26
- "name": "provided",
27
- "type": "uint256"
28
- },
29
- {
30
- "internalType": "uint256",
31
- "name": "expected",
32
- "type": "uint256"
33
- }
34
- ],
35
- "name": "LowerThan",
36
- "type": "error"
37
- },
38
- {
39
- "inputs": [
40
- {
41
- "internalType": "uint256",
42
- "name": "maxNumServices",
43
- "type": "uint256"
44
- }
45
- ],
46
- "name": "MaxNumServicesReached",
47
- "type": "error"
48
- },
49
- {
50
- "inputs": [],
51
- "name": "NoRewardsAvailable",
52
- "type": "error"
53
- },
54
- {
55
- "inputs": [
56
- {
57
- "internalType": "uint256",
58
- "name": "serviceId",
59
- "type": "uint256"
60
- },
61
- {
62
- "internalType": "uint256",
63
- "name": "tsProvided",
64
- "type": "uint256"
65
- },
66
- {
67
- "internalType": "uint256",
68
- "name": "tsExpected",
69
- "type": "uint256"
70
- }
71
- ],
72
- "name": "NotEnoughTimeStaked",
73
- "type": "error"
74
- },
75
- {
76
- "inputs": [
77
- {
78
- "internalType": "address",
79
- "name": "sender",
80
- "type": "address"
81
- },
82
- {
83
- "internalType": "address",
84
- "name": "owner",
85
- "type": "address"
86
- }
87
- ],
88
- "name": "OwnerOnly",
89
- "type": "error"
90
- },
91
- {
92
- "inputs": [
93
- {
94
- "internalType": "uint256",
95
- "name": "serviceId",
96
- "type": "uint256"
97
- }
98
- ],
99
- "name": "ServiceNotUnstaked",
100
- "type": "error"
101
- },
102
- {
103
- "inputs": [
104
- {
105
- "internalType": "address",
106
- "name": "token",
107
- "type": "address"
108
- },
109
- {
110
- "internalType": "address",
111
- "name": "from",
112
- "type": "address"
113
- },
114
- {
115
- "internalType": "address",
116
- "name": "to",
117
- "type": "address"
118
- },
119
- {
120
- "internalType": "uint256",
121
- "name": "value",
122
- "type": "uint256"
123
- }
124
- ],
125
- "name": "TokenTransferFailed",
126
- "type": "error"
127
- },
128
- {
129
- "inputs": [
130
- {
131
- "internalType": "address",
132
- "name": "multisig",
133
- "type": "address"
134
- }
135
- ],
136
- "name": "UnauthorizedMultisig",
137
- "type": "error"
138
- },
139
- {
140
- "inputs": [
141
- {
142
- "internalType": "uint256",
143
- "name": "provided",
144
- "type": "uint256"
145
- },
146
- {
147
- "internalType": "uint256",
148
- "name": "expected",
149
- "type": "uint256"
150
- }
151
- ],
152
- "name": "ValueLowerThan",
153
- "type": "error"
154
- },
155
- {
156
- "inputs": [
157
- {
158
- "internalType": "uint256",
159
- "name": "agentId",
160
- "type": "uint256"
161
- }
162
- ],
163
- "name": "WrongAgentId",
164
- "type": "error"
165
- },
166
- {
167
- "inputs": [
168
- {
169
- "internalType": "uint256",
170
- "name": "serviceId",
171
- "type": "uint256"
172
- }
173
- ],
174
- "name": "WrongServiceConfiguration",
175
- "type": "error"
176
- },
177
- {
178
- "inputs": [
179
- {
180
- "internalType": "uint256",
181
- "name": "state",
182
- "type": "uint256"
183
- },
184
- {
185
- "internalType": "uint256",
186
- "name": "serviceId",
187
- "type": "uint256"
188
- }
189
- ],
190
- "name": "WrongServiceState",
191
- "type": "error"
192
- },
193
- {
194
- "inputs": [
195
- {
196
- "internalType": "address",
197
- "name": "expected",
198
- "type": "address"
199
- },
200
- {
201
- "internalType": "address",
202
- "name": "provided",
203
- "type": "address"
204
- }
205
- ],
206
- "name": "WrongStakingToken",
207
- "type": "error"
208
- },
209
- {
210
- "inputs": [],
211
- "name": "ZeroAddress",
212
- "type": "error"
213
- },
214
- {
215
- "inputs": [],
216
- "name": "ZeroTokenAddress",
217
- "type": "error"
218
- },
219
- {
220
- "inputs": [],
221
- "name": "ZeroValue",
222
- "type": "error"
223
- },
224
- {
225
- "anonymous": false,
226
- "inputs": [
227
- {
228
- "indexed": true,
229
- "internalType": "uint256",
230
- "name": "epoch",
231
- "type": "uint256"
232
- },
233
- {
234
- "indexed": false,
235
- "internalType": "uint256",
236
- "name": "availableRewards",
237
- "type": "uint256"
238
- },
239
- {
240
- "indexed": false,
241
- "internalType": "uint256[]",
242
- "name": "serviceIds",
243
- "type": "uint256[]"
244
- },
245
- {
246
- "indexed": false,
247
- "internalType": "uint256[]",
248
- "name": "rewards",
249
- "type": "uint256[]"
250
- },
251
- {
252
- "indexed": false,
253
- "internalType": "uint256",
254
- "name": "epochLength",
255
- "type": "uint256"
256
- }
257
- ],
258
- "name": "Checkpoint",
259
- "type": "event"
260
- },
261
- {
262
- "anonymous": false,
263
- "inputs": [
264
- {
265
- "indexed": true,
266
- "internalType": "address",
267
- "name": "sender",
268
- "type": "address"
269
- },
270
- {
271
- "indexed": false,
272
- "internalType": "uint256",
273
- "name": "amount",
274
- "type": "uint256"
275
- },
276
- {
277
- "indexed": false,
278
- "internalType": "uint256",
279
- "name": "balance",
280
- "type": "uint256"
281
- },
282
- {
283
- "indexed": false,
284
- "internalType": "uint256",
285
- "name": "availableRewards",
286
- "type": "uint256"
287
- }
288
- ],
289
- "name": "Deposit",
290
- "type": "event"
291
- },
292
- {
293
- "anonymous": false,
294
- "inputs": [
295
- {
296
- "indexed": false,
297
- "internalType": "uint256",
298
- "name": "epoch",
299
- "type": "uint256"
300
- },
301
- {
302
- "indexed": true,
303
- "internalType": "uint256",
304
- "name": "serviceId",
305
- "type": "uint256"
306
- },
307
- {
308
- "indexed": true,
309
- "internalType": "address",
310
- "name": "owner",
311
- "type": "address"
312
- },
313
- {
314
- "indexed": true,
315
- "internalType": "address",
316
- "name": "multisig",
317
- "type": "address"
318
- },
319
- {
320
- "indexed": false,
321
- "internalType": "uint256[]",
322
- "name": "nonces",
323
- "type": "uint256[]"
324
- },
325
- {
326
- "indexed": false,
327
- "internalType": "uint256",
328
- "name": "reward",
329
- "type": "uint256"
330
- }
331
- ],
332
- "name": "RewardClaimed",
333
- "type": "event"
334
- },
335
- {
336
- "anonymous": false,
337
- "inputs": [
338
- {
339
- "indexed": false,
340
- "internalType": "uint256",
341
- "name": "epoch",
342
- "type": "uint256"
343
- },
344
- {
345
- "indexed": true,
346
- "internalType": "uint256",
347
- "name": "serviceId",
348
- "type": "uint256"
349
- },
350
- {
351
- "indexed": false,
352
- "internalType": "uint256",
353
- "name": "serviceInactivity",
354
- "type": "uint256"
355
- }
356
- ],
357
- "name": "ServiceInactivityWarning",
358
- "type": "event"
359
- },
360
- {
361
- "anonymous": false,
362
- "inputs": [
363
- {
364
- "indexed": false,
365
- "internalType": "uint256",
366
- "name": "epoch",
367
- "type": "uint256"
368
- },
369
- {
370
- "indexed": true,
371
- "internalType": "uint256",
372
- "name": "serviceId",
373
- "type": "uint256"
374
- },
375
- {
376
- "indexed": true,
377
- "internalType": "address",
378
- "name": "owner",
379
- "type": "address"
380
- },
381
- {
382
- "indexed": true,
383
- "internalType": "address",
384
- "name": "multisig",
385
- "type": "address"
386
- },
387
- {
388
- "indexed": false,
389
- "internalType": "uint256[]",
390
- "name": "nonces",
391
- "type": "uint256[]"
392
- }
393
- ],
394
- "name": "ServiceStaked",
395
- "type": "event"
396
- },
397
- {
398
- "anonymous": false,
399
- "inputs": [
400
- {
401
- "indexed": false,
402
- "internalType": "uint256",
403
- "name": "epoch",
404
- "type": "uint256"
405
- },
406
- {
407
- "indexed": true,
408
- "internalType": "uint256",
409
- "name": "serviceId",
410
- "type": "uint256"
411
- },
412
- {
413
- "indexed": true,
414
- "internalType": "address",
415
- "name": "owner",
416
- "type": "address"
417
- },
418
- {
419
- "indexed": true,
420
- "internalType": "address",
421
- "name": "multisig",
422
- "type": "address"
423
- },
424
- {
425
- "indexed": false,
426
- "internalType": "uint256[]",
427
- "name": "nonces",
428
- "type": "uint256[]"
429
- },
430
- {
431
- "indexed": false,
432
- "internalType": "uint256",
433
- "name": "reward",
434
- "type": "uint256"
435
- }
436
- ],
437
- "name": "ServiceUnstaked",
438
- "type": "event"
439
- },
440
- {
441
- "anonymous": false,
442
- "inputs": [
443
- {
444
- "indexed": true,
445
- "internalType": "uint256",
446
- "name": "epoch",
447
- "type": "uint256"
448
- },
449
- {
450
- "indexed": false,
451
- "internalType": "uint256[]",
452
- "name": "serviceIds",
453
- "type": "uint256[]"
454
- },
455
- {
456
- "indexed": false,
457
- "internalType": "address[]",
458
- "name": "owners",
459
- "type": "address[]"
460
- },
461
- {
462
- "indexed": false,
463
- "internalType": "address[]",
464
- "name": "multisigs",
465
- "type": "address[]"
466
- },
467
- {
468
- "indexed": false,
469
- "internalType": "uint256[]",
470
- "name": "serviceInactivity",
471
- "type": "uint256[]"
472
- }
473
- ],
474
- "name": "ServicesEvicted",
475
- "type": "event"
476
- },
477
- {
478
- "anonymous": false,
479
- "inputs": [
480
- {
481
- "indexed": true,
482
- "internalType": "address",
483
- "name": "to",
484
- "type": "address"
485
- },
486
- {
487
- "indexed": false,
488
- "internalType": "uint256",
489
- "name": "amount",
490
- "type": "uint256"
491
- }
492
- ],
493
- "name": "Withdraw",
494
- "type": "event"
495
- },
496
- {
497
- "inputs": [],
498
- "name": "VERSION",
499
- "outputs": [
500
- {
501
- "internalType": "string",
502
- "name": "",
503
- "type": "string"
504
- }
505
- ],
506
- "stateMutability": "view",
507
- "type": "function"
508
- },
509
- {
510
- "inputs": [],
511
- "name": "activityChecker",
512
- "outputs": [
513
- {
514
- "internalType": "address",
515
- "name": "",
516
- "type": "address"
517
- }
518
- ],
519
- "stateMutability": "view",
520
- "type": "function"
521
- },
522
- {
523
- "inputs": [
524
- {
525
- "internalType": "uint256",
526
- "name": "",
527
- "type": "uint256"
528
- }
529
- ],
530
- "name": "agentIds",
531
- "outputs": [
532
- {
533
- "internalType": "uint256",
534
- "name": "",
535
- "type": "uint256"
536
- }
537
- ],
538
- "stateMutability": "view",
539
- "type": "function"
540
- },
541
- {
542
- "inputs": [],
543
- "name": "availableRewards",
544
- "outputs": [
545
- {
546
- "internalType": "uint256",
547
- "name": "",
548
- "type": "uint256"
549
- }
550
- ],
551
- "stateMutability": "view",
552
- "type": "function"
553
- },
554
- {
555
- "inputs": [],
556
- "name": "balance",
557
- "outputs": [
558
- {
559
- "internalType": "uint256",
560
- "name": "",
561
- "type": "uint256"
562
- }
563
- ],
564
- "stateMutability": "view",
565
- "type": "function"
566
- },
567
- {
568
- "inputs": [
569
- {
570
- "internalType": "uint256",
571
- "name": "serviceId",
572
- "type": "uint256"
573
- }
574
- ],
575
- "name": "calculateStakingLastReward",
576
- "outputs": [
577
- {
578
- "internalType": "uint256",
579
- "name": "reward",
580
- "type": "uint256"
581
- }
582
- ],
583
- "stateMutability": "view",
584
- "type": "function"
585
- },
586
- {
587
- "inputs": [
588
- {
589
- "internalType": "uint256",
590
- "name": "serviceId",
591
- "type": "uint256"
592
- }
593
- ],
594
- "name": "calculateStakingReward",
595
- "outputs": [
596
- {
597
- "internalType": "uint256",
598
- "name": "reward",
599
- "type": "uint256"
600
- }
601
- ],
602
- "stateMutability": "view",
603
- "type": "function"
604
- },
605
- {
606
- "inputs": [],
607
- "name": "checkpoint",
608
- "outputs": [
609
- {
610
- "internalType": "uint256[]",
611
- "name": "",
612
- "type": "uint256[]"
613
- },
614
- {
615
- "internalType": "uint256[][]",
616
- "name": "",
617
- "type": "uint256[][]"
618
- },
619
- {
620
- "internalType": "uint256[]",
621
- "name": "",
622
- "type": "uint256[]"
623
- },
624
- {
625
- "internalType": "uint256[]",
626
- "name": "",
627
- "type": "uint256[]"
628
- },
629
- {
630
- "internalType": "uint256[]",
631
- "name": "evictServiceIds",
632
- "type": "uint256[]"
633
- }
634
- ],
635
- "stateMutability": "nonpayable",
636
- "type": "function"
637
- },
638
- {
639
- "inputs": [
640
- {
641
- "internalType": "uint256",
642
- "name": "serviceId",
643
- "type": "uint256"
644
- }
645
- ],
646
- "name": "checkpointAndClaim",
647
- "outputs": [
648
- {
649
- "internalType": "uint256",
650
- "name": "",
651
- "type": "uint256"
652
- }
653
- ],
654
- "stateMutability": "nonpayable",
655
- "type": "function"
656
- },
657
- {
658
- "inputs": [
659
- {
660
- "internalType": "uint256",
661
- "name": "serviceId",
662
- "type": "uint256"
663
- }
664
- ],
665
- "name": "claim",
666
- "outputs": [
667
- {
668
- "internalType": "uint256",
669
- "name": "",
670
- "type": "uint256"
671
- }
672
- ],
673
- "stateMutability": "nonpayable",
674
- "type": "function"
675
- },
676
- {
677
- "inputs": [],
678
- "name": "configHash",
679
- "outputs": [
680
- {
681
- "internalType": "bytes32",
682
- "name": "",
683
- "type": "bytes32"
684
- }
685
- ],
686
- "stateMutability": "view",
687
- "type": "function"
688
- },
689
- {
690
- "inputs": [
691
- {
692
- "internalType": "uint256",
693
- "name": "amount",
694
- "type": "uint256"
695
- }
696
- ],
697
- "name": "deposit",
698
- "outputs": [],
699
- "stateMutability": "nonpayable",
700
- "type": "function"
701
- },
702
- {
703
- "inputs": [],
704
- "name": "emissionsAmount",
705
- "outputs": [
706
- {
707
- "internalType": "uint256",
708
- "name": "",
709
- "type": "uint256"
710
- }
711
- ],
712
- "stateMutability": "view",
713
- "type": "function"
714
- },
715
- {
716
- "inputs": [],
717
- "name": "epochCounter",
718
- "outputs": [
719
- {
720
- "internalType": "uint256",
721
- "name": "",
722
- "type": "uint256"
723
- }
724
- ],
725
- "stateMutability": "view",
726
- "type": "function"
727
- },
728
- {
729
- "inputs": [],
730
- "name": "getAgentIds",
731
- "outputs": [
732
- {
733
- "internalType": "uint256[]",
734
- "name": "",
735
- "type": "uint256[]"
736
- }
737
- ],
738
- "stateMutability": "view",
739
- "type": "function"
740
- },
741
- {
742
- "inputs": [],
743
- "name": "getNextRewardCheckpointTimestamp",
744
- "outputs": [
745
- {
746
- "internalType": "uint256",
747
- "name": "tsNext",
748
- "type": "uint256"
749
- }
750
- ],
751
- "stateMutability": "view",
752
- "type": "function"
753
- },
754
- {
755
- "inputs": [],
756
- "name": "getServiceIds",
757
- "outputs": [
758
- {
759
- "internalType": "uint256[]",
760
- "name": "",
761
- "type": "uint256[]"
762
- }
763
- ],
764
- "stateMutability": "view",
765
- "type": "function"
766
- },
767
- {
768
- "inputs": [
769
- {
770
- "internalType": "uint256",
771
- "name": "serviceId",
772
- "type": "uint256"
773
- }
774
- ],
775
- "name": "getServiceInfo",
776
- "outputs": [
777
- {
778
- "components": [
779
- {
780
- "internalType": "address",
781
- "name": "multisig",
782
- "type": "address"
783
- },
784
- {
785
- "internalType": "address",
786
- "name": "owner",
787
- "type": "address"
788
- },
789
- {
790
- "internalType": "uint256[]",
791
- "name": "nonces",
792
- "type": "uint256[]"
793
- },
794
- {
795
- "internalType": "uint256",
796
- "name": "tsStart",
797
- "type": "uint256"
798
- },
799
- {
800
- "internalType": "uint256",
801
- "name": "reward",
802
- "type": "uint256"
803
- },
804
- {
805
- "internalType": "uint256",
806
- "name": "inactivity",
807
- "type": "uint256"
808
- }
809
- ],
810
- "internalType": "struct ServiceInfo",
811
- "name": "sInfo",
812
- "type": "tuple"
813
- }
814
- ],
815
- "stateMutability": "view",
816
- "type": "function"
817
- },
818
- {
819
- "inputs": [
820
- {
821
- "internalType": "uint256",
822
- "name": "serviceId",
823
- "type": "uint256"
824
- }
825
- ],
826
- "name": "getStakingState",
827
- "outputs": [
828
- {
829
- "internalType": "enum StakingBase.StakingState",
830
- "name": "stakingState",
831
- "type": "uint8"
832
- }
833
- ],
834
- "stateMutability": "view",
835
- "type": "function"
836
- },
837
- {
838
- "inputs": [
839
- {
840
- "components": [
841
- {
842
- "internalType": "bytes32",
843
- "name": "metadataHash",
844
- "type": "bytes32"
845
- },
846
- {
847
- "internalType": "uint256",
848
- "name": "maxNumServices",
849
- "type": "uint256"
850
- },
851
- {
852
- "internalType": "uint256",
853
- "name": "rewardsPerSecond",
854
- "type": "uint256"
855
- },
856
- {
857
- "internalType": "uint256",
858
- "name": "minStakingDeposit",
859
- "type": "uint256"
860
- },
861
- {
862
- "internalType": "uint256",
863
- "name": "minNumStakingPeriods",
864
- "type": "uint256"
865
- },
866
- {
867
- "internalType": "uint256",
868
- "name": "maxNumInactivityPeriods",
869
- "type": "uint256"
870
- },
871
- {
872
- "internalType": "uint256",
873
- "name": "livenessPeriod",
874
- "type": "uint256"
875
- },
876
- {
877
- "internalType": "uint256",
878
- "name": "timeForEmissions",
879
- "type": "uint256"
880
- },
881
- {
882
- "internalType": "uint256",
883
- "name": "numAgentInstances",
884
- "type": "uint256"
885
- },
886
- {
887
- "internalType": "uint256[]",
888
- "name": "agentIds",
889
- "type": "uint256[]"
890
- },
891
- {
892
- "internalType": "uint256",
893
- "name": "threshold",
894
- "type": "uint256"
895
- },
896
- {
897
- "internalType": "bytes32",
898
- "name": "configHash",
899
- "type": "bytes32"
900
- },
901
- {
902
- "internalType": "bytes32",
903
- "name": "proxyHash",
904
- "type": "bytes32"
905
- },
906
- {
907
- "internalType": "address",
908
- "name": "serviceRegistry",
909
- "type": "address"
910
- },
911
- {
912
- "internalType": "address",
913
- "name": "activityChecker",
914
- "type": "address"
915
- }
916
- ],
917
- "internalType": "struct StakingBase.StakingParams",
918
- "name": "_stakingParams",
919
- "type": "tuple"
920
- },
921
- {
922
- "internalType": "address",
923
- "name": "_serviceRegistryTokenUtility",
924
- "type": "address"
925
- },
926
- {
927
- "internalType": "address",
928
- "name": "_stakingToken",
929
- "type": "address"
930
- }
931
- ],
932
- "name": "initialize",
933
- "outputs": [],
934
- "stateMutability": "nonpayable",
935
- "type": "function"
936
- },
937
- {
938
- "inputs": [],
939
- "name": "livenessPeriod",
940
- "outputs": [
941
- {
942
- "internalType": "uint256",
943
- "name": "",
944
- "type": "uint256"
945
- }
946
- ],
947
- "stateMutability": "view",
948
- "type": "function"
949
- },
950
- {
951
- "inputs": [
952
- {
953
- "internalType": "uint256",
954
- "name": "",
955
- "type": "uint256"
956
- }
957
- ],
958
- "name": "mapServiceInfo",
959
- "outputs": [
960
- {
961
- "internalType": "address",
962
- "name": "multisig",
963
- "type": "address"
964
- },
965
- {
966
- "internalType": "address",
967
- "name": "owner",
968
- "type": "address"
969
- },
970
- {
971
- "internalType": "uint256",
972
- "name": "tsStart",
973
- "type": "uint256"
974
- },
975
- {
976
- "internalType": "uint256",
977
- "name": "reward",
978
- "type": "uint256"
979
- },
980
- {
981
- "internalType": "uint256",
982
- "name": "inactivity",
983
- "type": "uint256"
984
- }
985
- ],
986
- "stateMutability": "view",
987
- "type": "function"
988
- },
989
- {
990
- "inputs": [],
991
- "name": "maxInactivityDuration",
992
- "outputs": [
993
- {
994
- "internalType": "uint256",
995
- "name": "",
996
- "type": "uint256"
997
- }
998
- ],
999
- "stateMutability": "view",
1000
- "type": "function"
1001
- },
1002
- {
1003
- "inputs": [],
1004
- "name": "maxNumInactivityPeriods",
1005
- "outputs": [
1006
- {
1007
- "internalType": "uint256",
1008
- "name": "",
1009
- "type": "uint256"
1010
- }
1011
- ],
1012
- "stateMutability": "view",
1013
- "type": "function"
1014
- },
1015
- {
1016
- "inputs": [],
1017
- "name": "maxNumServices",
1018
- "outputs": [
1019
- {
1020
- "internalType": "uint256",
1021
- "name": "",
1022
- "type": "uint256"
1023
- }
1024
- ],
1025
- "stateMutability": "view",
1026
- "type": "function"
1027
- },
1028
- {
1029
- "inputs": [],
1030
- "name": "metadataHash",
1031
- "outputs": [
1032
- {
1033
- "internalType": "bytes32",
1034
- "name": "",
1035
- "type": "bytes32"
1036
- }
1037
- ],
1038
- "stateMutability": "view",
1039
- "type": "function"
1040
- },
1041
- {
1042
- "inputs": [],
1043
- "name": "minStakingDeposit",
1044
- "outputs": [
1045
- {
1046
- "internalType": "uint256",
1047
- "name": "",
1048
- "type": "uint256"
1049
- }
1050
- ],
1051
- "stateMutability": "view",
1052
- "type": "function"
1053
- },
1054
- {
1055
- "inputs": [],
1056
- "name": "minStakingDuration",
1057
- "outputs": [
1058
- {
1059
- "internalType": "uint256",
1060
- "name": "",
1061
- "type": "uint256"
1062
- }
1063
- ],
1064
- "stateMutability": "view",
1065
- "type": "function"
1066
- },
1067
- {
1068
- "inputs": [],
1069
- "name": "numAgentInstances",
1070
- "outputs": [
1071
- {
1072
- "internalType": "uint256",
1073
- "name": "",
1074
- "type": "uint256"
1075
- }
1076
- ],
1077
- "stateMutability": "view",
1078
- "type": "function"
1079
- },
1080
- {
1081
- "inputs": [
1082
- {
1083
- "internalType": "address",
1084
- "name": "",
1085
- "type": "address"
1086
- },
1087
- {
1088
- "internalType": "address",
1089
- "name": "",
1090
- "type": "address"
1091
- },
1092
- {
1093
- "internalType": "uint256",
1094
- "name": "",
1095
- "type": "uint256"
1096
- },
1097
- {
1098
- "internalType": "bytes",
1099
- "name": "",
1100
- "type": "bytes"
1101
- }
1102
- ],
1103
- "name": "onERC721Received",
1104
- "outputs": [
1105
- {
1106
- "internalType": "bytes4",
1107
- "name": "",
1108
- "type": "bytes4"
1109
- }
1110
- ],
1111
- "stateMutability": "nonpayable",
1112
- "type": "function"
1113
- },
1114
- {
1115
- "inputs": [],
1116
- "name": "proxyHash",
1117
- "outputs": [
1118
- {
1119
- "internalType": "bytes32",
1120
- "name": "",
1121
- "type": "bytes32"
1122
- }
1123
- ],
1124
- "stateMutability": "view",
1125
- "type": "function"
1126
- },
1127
- {
1128
- "inputs": [],
1129
- "name": "rewardsPerSecond",
1130
- "outputs": [
1131
- {
1132
- "internalType": "uint256",
1133
- "name": "",
1134
- "type": "uint256"
1135
- }
1136
- ],
1137
- "stateMutability": "view",
1138
- "type": "function"
1139
- },
1140
- {
1141
- "inputs": [],
1142
- "name": "serviceRegistry",
1143
- "outputs": [
1144
- {
1145
- "internalType": "address",
1146
- "name": "",
1147
- "type": "address"
1148
- }
1149
- ],
1150
- "stateMutability": "view",
1151
- "type": "function"
1152
- },
1153
- {
1154
- "inputs": [],
1155
- "name": "serviceRegistryTokenUtility",
1156
- "outputs": [
1157
- {
1158
- "internalType": "address",
1159
- "name": "",
1160
- "type": "address"
1161
- }
1162
- ],
1163
- "stateMutability": "view",
1164
- "type": "function"
1165
- },
1166
- {
1167
- "inputs": [
1168
- {
1169
- "internalType": "uint256",
1170
- "name": "",
1171
- "type": "uint256"
1172
- }
1173
- ],
1174
- "name": "setServiceIds",
1175
- "outputs": [
1176
- {
1177
- "internalType": "uint256",
1178
- "name": "",
1179
- "type": "uint256"
1180
- }
1181
- ],
1182
- "stateMutability": "view",
1183
- "type": "function"
1184
- },
1185
- {
1186
- "inputs": [
1187
- {
1188
- "internalType": "uint256",
1189
- "name": "serviceId",
1190
- "type": "uint256"
1191
- }
1192
- ],
1193
- "name": "stake",
1194
- "outputs": [],
1195
- "stateMutability": "nonpayable",
1196
- "type": "function"
1197
- },
1198
- {
1199
- "inputs": [],
1200
- "name": "stakingToken",
1201
- "outputs": [
1202
- {
1203
- "internalType": "address",
1204
- "name": "",
1205
- "type": "address"
1206
- }
1207
- ],
1208
- "stateMutability": "view",
1209
- "type": "function"
1210
- },
1211
- {
1212
- "inputs": [],
1213
- "name": "threshold",
1214
- "outputs": [
1215
- {
1216
- "internalType": "uint256",
1217
- "name": "",
1218
- "type": "uint256"
1219
- }
1220
- ],
1221
- "stateMutability": "view",
1222
- "type": "function"
1223
- },
1224
- {
1225
- "inputs": [],
1226
- "name": "timeForEmissions",
1227
- "outputs": [
1228
- {
1229
- "internalType": "uint256",
1230
- "name": "",
1231
- "type": "uint256"
1232
- }
1233
- ],
1234
- "stateMutability": "view",
1235
- "type": "function"
1236
- },
1237
- {
1238
- "inputs": [],
1239
- "name": "tsCheckpoint",
1240
- "outputs": [
1241
- {
1242
- "internalType": "uint256",
1243
- "name": "",
1244
- "type": "uint256"
1245
- }
1246
- ],
1247
- "stateMutability": "view",
1248
- "type": "function"
1249
- },
1250
- {
1251
- "inputs": [
1252
- {
1253
- "internalType": "uint256",
1254
- "name": "serviceId",
1255
- "type": "uint256"
1256
- }
1257
- ],
1258
- "name": "unstake",
1259
- "outputs": [
1260
- {
1261
- "internalType": "uint256",
1262
- "name": "reward",
1263
- "type": "uint256"
1264
- }
1265
- ],
1266
- "stateMutability": "nonpayable",
1267
- "type": "function"
1268
- }
1269
- ],
1270
- "bytecode": "0x6102606040523480156200001257600080fd5b506040516200383a3803806200383a833981016040819052620000359162000453565b8484828260000151600014806200004e57506020830151155b806200005c575060a0830151155b806200006a575060c0830151155b8062000078575060e0830151155b806200008657506060830151155b806200009457506080830151155b15620000b357604051637c946ed760e01b815260040160405180910390fd5b826080015183606001511015620000f5576060830151608084015160405163491a2bb160e01b8152600481019290925260248201526044015b60405180910390fd5b6002836040015110156200012d57604080840151905163491a2bb160e01b8152600481019190915260026024820152604401620000ec565b6001600160a01b038216620001555760405163d92e233d60e01b815260040160405180910390fd5b82516080908152602084015160a0908152604085015160c09081529185015160e0908152908501516101005290840151610120908152908401516101409081526001600160a01b0384166101a0529084015161016052830151610180526000805b846101000151518110156200029257818561010001518281518110620001e057620001e062000576565b6020026020010151116200022d57846101000151818151811062000208576200020862000576565b6020026020010151604051632ab10b0b60e21b8152600401620000ec91815260200190565b846101000151818151811062000247576200024762000576565b602090810291909101015160048054600181810183556000929092527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0182905590925001620001b6565b5081620002b257604051637c946ed760e01b815260040160405180910390fd5b6101c0829052610100516060850151620002cd91906200058c565b6101e052610100516080850151620002e691906200058c565b6102005250504260035550506001600160a01b03821615806200031057506001600160a01b038316155b156200032f5760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b0390811661024052166102205250620005b89050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b03811182821017156200038957620003896200034d565b60405290565b600082601f830112620003a157600080fd5b815160206001600160401b0380831115620003c057620003c06200034d565b8260051b604051601f19603f83011681018181108482111715620003e857620003e86200034d565b60405293845260208187018101949081019250878511156200040957600080fd5b6020870191505b848210156200042b5781518352918301919083019062000410565b979650505050505050565b80516001600160a01b03811681146200044e57600080fd5b919050565b600080600080600060a086880312156200046c57600080fd5b85516001600160401b03808211156200048457600080fd5b90870190610160828a0312156200049a57600080fd5b620004a462000363565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e082015261010080840151838111156200050357600080fd5b620005118c8287016200038f565b918301919091525061012083810151908201526101409283015192810192909252509450620005436020870162000436565b9350620005536040870162000436565b9250620005636060870162000436565b9150608086015190509295509295909350565b634e487b7160e01b600052603260045260246000fd5b8082028115828204841417620005b257634e487b7160e01b600052601160045260246000fd5b92915050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610220516102405161311962000721600039600081816104110152818161130901528181611c1401528181611d1e0152611d6201526000818161030501528181611ca40152611e0e01526000818161068e015281816118a50152611b1401526000818161024b0152818161074d015261079f01526000818161044b0152610fca0152600081816105cf01528181610a0101528181610d8601526111bd0152600081816105f601528181610e4e0152610e7d01526000818161036201528181610ec40152610ef80152600081816103c30152610e0c0152600081816103ea015261294a01526000818161038901528181611bc60152611fb80152600061049b01526000818161061d0152611d9901526000818161064401526122ae0152600081816102de01528181610d0d0152610d4101526131196000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c8063a0ed60e011610145578063cbcf252a116100bd578063eb338c961161008c578063f4dce71411610071578063f4dce71414610681578063f86ad2b614610689578063ffa1ad74146106b057600080fd5b8063eb338c9614610666578063f189e85a1461067957600080fd5b8063cbcf252a146105ca578063e1f1176d146105f1578063e77cdcc914610618578063eacdaabc1461063f57600080fd5b8063b69ef8a811610114578063c2c4c5c1116100f9578063c2c4c5c11461057e578063c889921d14610597578063cae2a5f0146105aa57600080fd5b8063b69ef8a814610562578063b6b55f251461056b57600080fd5b8063a0ed60e014610496578063a694fc3a146104bd578063a74466ad146104d0578063b15087601461054d57600080fd5b806352c824f5116101d857806372f702f3116101a7578063809cee2f1161018c578063809cee2f1461044657806382a8ea581461046d578063879d90901461048d57600080fd5b806372f702f31461040c57806378e061361461043357600080fd5b806352c824f51461038457806356e76058146103ab5780635829c5ec146103be578063592cf3fb146103e557600080fd5b8063287140511161021457806328714051146103005780632e17de781461033f5780633e7329971461035457806342cde4e81461035d57600080fd5b806308ae7e541461024657806314b19c5a14610280578063150b7a021461028957806316a75172146102d9575b600080fd5b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61026d60005481565b6102a8610297366004612a0a565b630a85bd0160e11b95945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610277565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b61035261034d366004612aa9565b6106e1565b005b61026d60035481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d6103b9366004612aa9565b610acf565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d610441366004612aa9565b610af0565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61048061047b366004612aa9565b610bba565b6040516102779190612afe565b61026d60025481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103526104cb366004612aa9565b610cb1565b61051a6104de366004612aa9565b6005602081905260009182526040909120805460018201546003830154600484015493909401546001600160a01b039283169492909116929085565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610277565b61055561127e565b6040516102779190612b65565b61026d60015481565b610352610579366004612aa9565b6112d6565b610586611378565b604051610277959493929190612b78565b61026d6105a5366004612aa9565b6119ad565b6105bd6105b8366004612aa9565b611a69565b6040516102779190612c3d565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d610674366004612aa9565b611b5c565b610555611b6c565b61026d611bc2565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6106d4604051806040016040528060058152602001640302e312e360dc1b81525081565b6040516102779190612c65565b600081815260056020526040902060018101546001600160a01b0316331461073857600181015460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b600381015460006107498242612cca565b90507f0000000000000000000000000000000000000000000000000000000000000000811115801561077d57506000600254115b156107cb5760405163ba2bbc6b60e01b815260048101859052602481018290527f0000000000000000000000000000000000000000000000000000000000000000604482015260640161072f565b6000806107d6611378565b945050505091508151600003610837576107ee611b6c565b9150815167ffffffffffffffff81111561080a5761080a612cdd565b604051908082528060200260200182016040528015610833578160200160208202803683370190505b5090505b6000805b8351821015610898578783838151811061085757610857612cf3565b60200260200101510315610898578784838151811061087857610878612cf3565b60200260200101510361088d57506001610898565b81600101915061083b565b600487015460028801805460408051602080840282018101909252828152600093909290918301828280156108ec57602002820191906000526020600020905b8154815260200190600101908083116108d8575b50508c5460008f8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff19908116825560018201805490911690559596506001600160a01b03909116949350915061094890506002830182612974565b506000600382018190556004820181905560059091015583156109d7576006805461097590600190612cca565b8154811061098557610985612cf3565b9060005260206000200154600686815481106109a3576109a3612cf3565b60009182526020909120015560068054806109c0576109c0612d09565b600190038181906000526020600020016000905590555b604051632142170760e11b8152306004820152336024820152604481018c90526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342842e0e90606401600060405180830381600087803b158015610a4557600080fd5b505af1158015610a59573d6000803e3d6000fd5b505050506000831115610a7057610a708184611bf7565b806001600160a01b0316336001600160a01b03168c7f950733f4c0bf951b8e770f3cc619a4288e7b59b1236d59aeaf2c238488e8ae816000548688604051610aba93929190612d1f565b60405180910390a45050505050505050505050565b60048181548110610adf57600080fd5b600091825260209091200154905081565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015610b7057602002820191906000526020600020905b815481526020019060010190808311610b5c575b505050505081526020016003820154815260200160048201548152602001600582015481525050905080608001519150610ba9836119ad565b610bb39083612d48565b9392505050565b610c056040518060c0016040528060006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016000815260200160008152602001600081525090565b600082815260056020908152604091829020825160c08101845281546001600160a01b0390811682526001830154168184015260028201805485518186028101860187528181529295939493860193830182828015610c8357602002820191906000526020600020905b815481526020019060010190808311610c6f575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050919050565b600254600003610cd45760405163afb0be3360e01b815260040160405180910390fd5b6000818152600560205260409020600381015415610d085760405163b4817ce760e01b81526004810183905260240161072f565b6006547f00000000000000000000000000000000000000000000000000000000000000008103610d6d5760405163fd20861560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260240161072f565b60405163ef0e239b60e01b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ef0e239b90602401600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610dfd9190810190612e79565b9050806080015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014610e4c57604051637ad404bf60e11b81526004810185905260240161072f565b7f000000000000000000000000000000000000000000000000000000000000000015801590610e9f575080604001517f000000000000000000000000000000000000000000000000000000000000000014155b15610ec057604051637ad404bf60e11b81526004810185905260240161072f565b60007f0000000000000000000000000000000000000000000000000000000000000000118015610f1a5750806060015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014155b15610f3b57604051637ad404bf60e11b81526004810185905260240161072f565b60048160c001516005811115610f5357610f53612c27565b14610f92578060c001516005811115610f6e57610f6e612c27565b604051633c053f9d60e21b815260048101919091526024810185905260440161072f565b600081602001516001600160a01b0316803b806020016040519081016040528181526000908060200190933c805190602001209050807f00000000000000000000000000000000000000000000000000000000000000001461101757602082015160405162a2307960e51b81526001600160a01b03909116600482015260240161072f565b60045480156110e05760e08301515181811461104957604051637ad404bf60e11b81526004810188905260240161072f565b60005b818110156110dd578460e00151818151811061106a5761106a612cf3565b602002602001015163ffffffff166004828154811061108b5761108b612cf3565b9060005260206000200154146110d557600481815481106110ae576110ae612cf3565b9060005260206000200154604051632ab10b0b60e21b815260040161072f91815260200190565b60010161104c565b50505b6111018684600001516bffffffffffffffffffffffff168560e00151611c81565b602083015185546001600160a01b03821673ffffffffffffffffffffffffffffffffffffffff199182161787556001870180549091163317905560009061114790611f02565b805190915061115f9060028801906020840190612995565b50426003870155600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01879055604051632142170760e11b8152336004820152306024820152604481018890527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342842e0e90606401600060405180830381600087803b15801561120957600080fd5b505af115801561121d573d6000803e3d6000fd5b5050505083602001516001600160a01b0316336001600160a01b0316887faa6b005b4958114a0c90492461c24af6525ae0178db7fbf44125ae9217c69ccb6000548560405161126d929190612f57565b60405180910390a450505050505050565b606060048054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020905b8154815260200190600101908083116112b8575b5050505050905090565b6000816001546112e69190612d48565b90506000826002546112f89190612d48565b6001839055600281905590506113307f0000000000000000000000000000000000000000000000000000000000000000333086611f13565b604080518481526020810184905290810182905233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9060600160405180910390a2505050565b6060806060806060600080600080600080600080611394611f9d565b97509750975097509750975097509750606080845167ffffffffffffffff8111156113c1576113c1612cdd565b6040519080825280602002602001820160405280156113ea578160200160208202803683370190505b509a506000891561177d578967ffffffffffffffff81111561140e5761140e612cdd565b604051908082528060200260200182016040528015611437578160200160208202803683370190505b5092508967ffffffffffffffff81111561145357611453612cdd565b60405190808252806020026020018201604052801561147c578160200160208202803683370190505b5091508a8911156116865760008060015b8c811015611579578b8e8b83815181106114a9576114a9612cf3565b60200260200101516114bb9190612f70565b6114c59190612f87565b92506114d18383612d48565b91508a81815181106114e5576114e5612cf3565b602002602001015193508a818151811061150157611501612cf3565b602002602001015186828151811061151b5761151b612cf3565b6020026020010181815250508285828151811061153a5761153a612cf3565b6020026020010181815250508260056000868152602001908152602001600020600401600082825461156c9190612d48565b909155505060010161148d565b508a8d8a60008151811061158f5761158f612cf3565b60200260200101516115a19190612f70565b6115ab9190612f87565b91506115b78282612d48565b9050896000815181106115cc576115cc612cf3565b60200260200101519250896000815181106115e9576115e9612cf3565b60200260200101518560008151811061160457611604612cf3565b602002602001018181525050808d111561162f57611622818e612cca565b61162c9083612d48565b91505b818460008151811061164357611643612cf3565b602002602001018181525050816005600085815260200190815260200160002060040160008282546116759190612d48565b9091555060009d5061177792505050565b60005b8a811015611769578881815181106116a3576116a3612cf3565b602002602001015191508881815181106116bf576116bf612cf3565b60200260200101518482815181106116d9576116d9612cf3565b6020026020010181815250508781815181106116f7576116f7612cf3565b602002602001015183828151811061171157611711612cf3565b60200260200101818152505087818151811061172f5761172f612cf3565b602002602001015160056000848152602001908152602001600020600401600082825461175c9190612d48565b9091555050600101611689565b50611774898c612cca565b9a505b60028b90555b855115611997576000995060005b8651811015611930578681815181106117a6576117a6612cf3565b602002602001015191508581815181106117c2576117c2612cf3565b60200260200101516005600084815260200190815260200160002060020190805190602001906117f3929190612995565b50600085828151811061180857611808612cf3565b602002602001015111156119155784818151811061182857611828612cf3565b602002602001015160056000848152602001908152602001600020600501546118519190612d48565b85828151811061186357611863612cf3565b60200260200101818152505084818151811061188157611881612cf3565b602002602001015160056000848152602001908152602001600020600501819055507f00000000000000000000000000000000000000000000000000000000000000008582815181106118d6576118d6612cf3565b6020026020010151111561191057818d82815181106118f7576118f7612cf3565b60209081029190910101528a61190c81612fa9565b9b50505b611928565b6000828152600560208190526040822001555b60010161178b565b508915611942576119428c858c61239b565b42600355600054611954816001612d48565b60005560405181907f06a98bdd4732811ab3214800ed1ada2dce66a2bce301d250c3ca7d6b461ee6669061198d908f9088908890612fc2565b60405180910390a2505b50939e929d509b50919950969750505050505050565b6000806000806000806119be611f9d565b5050509450945094509450945060005b84811015611a5e57878382815181106119e9576119e9612cf3565b602002602001015103611a565785841115611a35578386838381518110611a1257611a12612cf3565b6020026020010151611a249190612f70565b611a2e9190612f87565b9650611a5e565b818181518110611a4757611a47612cf3565b60200260200101519650611a5e565b6001016119ce565b505050505050919050565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015611ae957602002820191906000526020600020905b815481526020019060010190808311611ad5575b50505050508152602001600382015481526020016004820154815260200160058201548152505090507f00000000000000000000000000000000000000000000000000000000000000008160a001511115611b475760029150611b56565b606081015115611b5657600191505b50919050565b60068181548110610adf57600080fd5b606060068054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020908154815260200190600101908083116112b8575050505050905090565b60007f0000000000000000000000000000000000000000000000000000000000000000600354611bf29190612d48565b905090565b8060016000828254611c099190612cca565b90915550611c3a90507f00000000000000000000000000000000000000000000000000000000000000008383612760565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051611c7591815260200190565b60405180910390a25050565b604051633cebfa4f60e01b81526004810184905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633cebfa4f906024016040805180830381865afa158015611cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0e9190612ff7565b91509150816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611d9757604051630b80380d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161072f565b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff8216811115611dfe57604051632b30b24760e21b81526bffffffffffffffffffffffff831660048201526024810182905260440161072f565b60005b8451811015611ef95760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166375c1f93489888581518110611e4e57611e4e612cf3565b60200260200101516040518363ffffffff1660e01b8152600401611e8292919091825263ffffffff16602082015260400190565b602060405180830381865afa158015611e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec3919061302c565b905082811015611ef057604051632b30b24760e21b8152600481018290526024810184905260440161072f565b50600101611e01565b50505050505050565b6060611f0d826127e3565b92915050565b60006040516323b872dd60e01b6000528460045283602452826044526020600060646000808a5af13d15601f3d1160016000511416171691506000606052806040525080611f965760405163abae3d6d60e01b81526001600160a01b0380871660048301528086166024830152841660448201526064810183905260840161072f565b5050505050565b600080600060608060608060606000600354905060025498507f00000000000000000000000000000000000000000000000000000000000000008142611fe39190612cca565b10158015611ff15750600089115b15612390576006548067ffffffffffffffff81111561201257612012612cdd565b60405190808252806020026020018201604052801561203b578160200160208202803683370190505b5094508067ffffffffffffffff81111561205757612057612cdd565b604051908082528060200260200182016040528015612080578160200160208202803683370190505b5096508067ffffffffffffffff81111561209c5761209c612cdd565b6040519080825280602002602001820160405280156120c5578160200160208202803683370190505b5095508067ffffffffffffffff8111156120e1576120e1612cdd565b60405190808252806020026020018201604052801561211457816020015b60608152602001906001900390816120ff5790505b5093508067ffffffffffffffff81111561213057612130612cdd565b604051908082528060200260200182016040528015612159578160200160208202803683370190505b50925060005b8181101561238d576006818154811061217a5761217a612cf3565b906000526020600020015486828151811061219757612197612cf3565b6020026020010181815250506000600560008884815181106121bb576121bb612cf3565b602090810291909101810151825281019190915260400160002080549091506121ec906001600160a01b0316611f02565b8683815181106121fe576121fe612cf3565b6020908102919091010152600381015484908181111561221c578091505b6122268242612cca565b905060006122a089868151811061223f5761223f612cf3565b60200260200101518560020180548060200260200160405190810160405280929190818152602001828054801561229557602002820191906000526020600020905b815481526020019060010190808311612281575b50505050508461288b565b9050801561235e576122d2827f0000000000000000000000000000000000000000000000000000000000000000612f70565b8b8f815181106122e4576122e4612cf3565b6020026020010181815250508a8e8151811061230257612302612cf3565b60200260200101518d6123159190612d48565b9c5089858151811061232957612329612cf3565b60200260200101518c8f8151811061234357612343612cf3565b60209081029190910101526123578e612fa9565b9d5061237e565b8188868151811061237157612371612cf3565b6020026020010181815250505b5050505080600101905061215f565b50505b509091929394959697565b825160008267ffffffffffffffff8111156123b8576123b8612cdd565b6040519080825280602002602001820160405280156123e1578160200160208202803683370190505b50905060008367ffffffffffffffff8111156123ff576123ff612cdd565b604051908082528060200260200182016040528015612428578160200160208202803683370190505b50905060008467ffffffffffffffff81111561244657612446612cdd565b60405190808252806020026020018201604052801561246f578160200160208202803683370190505b50905060008567ffffffffffffffff81111561248d5761248d612cdd565b6040519080825280602002602001820160405280156124b6578160200160208202803683370190505b50905060008667ffffffffffffffff8111156124d4576124d4612cdd565b6040519080825280602002602001820160405280156124fd578160200160208202803683370190505b50905060008060005b8881101561265d5760008c828151811061252257612522612cf3565b60200260200101511115612655578b818151811061254257612542612cf3565b602002602001015191508188848151811061255f5761255f612cf3565b6020908102919091018101919091526000838152600590915260409020600181015488516001600160a01b03909116908990869081106125a1576125a1612cf3565b6001600160a01b039283166020918202929092010152815488519116908890869081106125d0576125d0612cf3565b60200260200101906001600160a01b031690816001600160a01b0316815250508b828151811061260257612602612cf3565b602002602001015186858151811061261c5761261c612cf3565b6020026020010181815250508185858151811061263b5761263b612cf3565b60209081029190910101528361265081612fa9565b945050505b600101612506565b50885b8015612712578861267081613045565b99506000905084612682600184612cca565b8151811061269257612692612cf3565b6020026020010151905060068a815481106126af576126af612cf3565b9060005260206000200154600682815481106126cd576126cd612cf3565b60009182526020909120015560068054806126ea576126ea612d09565b60019003818190600052602060002001600090559055508061270b90613045565b9050612660565b506000547fd19a3d42ed383465e4058c322d9411aeac76ddb8454d22e139fc99808bd569528888888860405161274b9493929190613096565b60405180910390a25050505050505050505050565b600060405163a9059cbb60e01b6000528360045282602452602060006044600080895af13d15601f3d11600160005114161716915060006060528060405250806127dd5760405163abae3d6d60e01b81526001600160a01b038086166004830152306024830152841660448201526064810183905260840161072f565b50505050565b60408051600180825281830190925260609160208083019080368337019050509050816001600160a01b031663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612843573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612867919061302c565b8160008151811061287a5761287a612cf3565b602002602001018181525050919050565b60006128988484846128a0565b949350505050565b600080821180156128e45750826000815181106128bf576128bf612cf3565b6020026020010151846000815181106128da576128da612cf3565b6020026020010151115b15610bb357600082846000815181106128ff576128ff612cf3565b60200260200101518660008151811061291a5761291a612cf3565b602002602001015161292c9190612cca565b61293e90670de0b6b3a7640000612f70565b6129489190612f87565b7f0000000000000000000000000000000000000000000000000000000000000000111595945050505050565b508054600082559060005260206000209081019061299291906129e0565b50565b8280548282559060005260206000209081019282156129d0579160200282015b828111156129d05782518255916020019190600101906129b5565b506129dc9291506129e0565b5090565b5b808211156129dc57600081556001016129e1565b6001600160a01b038116811461299257600080fd5b600080600080600060808688031215612a2257600080fd5b8535612a2d816129f5565b94506020860135612a3d816129f5565b935060408601359250606086013567ffffffffffffffff80821115612a6157600080fd5b818801915088601f830112612a7557600080fd5b813581811115612a8457600080fd5b896020828501011115612a9657600080fd5b9699959850939650602001949392505050565b600060208284031215612abb57600080fd5b5035919050565b60008151808452602080850194506020840160005b83811015612af357815187529582019590820190600101612ad7565b509495945050505050565b6020815260006001600160a01b0380845116602084015280602085015116604084015250604083015160c06060840152612b3b60e0840182612ac2565b905060608401516080840152608084015160a084015260a084015160c08401528091505092915050565b602081526000610bb36020830184612ac2565b60a081526000612b8b60a0830188612ac2565b6020838203818501528188518084528284019150828160051b850101838b0160005b83811015612bdb57601f19878403018552612bc9838351612ac2565b94860194925090850190600101612bad565b50508681036040880152612bef818b612ac2565b9450505050508281036060840152612c078186612ac2565b90508281036080840152612c1b8185612ac2565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6020810160038310612c5f57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020808352835180602085015260005b81811015612c9357858101830151858201604001528201612c77565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b81810381811115611f0d57611f0d612cb4565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b838152606060208201526000612d386060830185612ac2565b9050826040830152949350505050565b80820180821115611f0d57611f0d612cb4565b604051610100810167ffffffffffffffff81118282101715612d7f57612d7f612cdd565b60405290565b80516bffffffffffffffffffffffff81168114612da157600080fd5b919050565b8051612da1816129f5565b805163ffffffff81168114612da157600080fd5b805160068110612da157600080fd5b600082601f830112612de557600080fd5b8151602067ffffffffffffffff80831115612e0257612e02612cdd565b8260051b604051601f19603f83011681018181108482111715612e2757612e27612cdd565b6040529384526020818701810194908101925087851115612e4757600080fd5b6020870191505b84821015612e6e57612e5f82612db1565b83529183019190830190612e4e565b979650505050505050565b600060208284031215612e8b57600080fd5b815167ffffffffffffffff80821115612ea357600080fd5b908301906101008286031215612eb857600080fd5b612ec0612d5b565b612ec983612d85565b8152612ed760208401612da6565b602082015260408301516040820152612ef260608401612db1565b6060820152612f0360808401612db1565b6080820152612f1460a08401612db1565b60a0820152612f2560c08401612dc5565b60c082015260e083015182811115612f3c57600080fd5b612f4887828601612dd4565b60e08301525095945050505050565b8281526040602082015260006128986040830184612ac2565b8082028115828204841417611f0d57611f0d612cb4565b600082612fa457634e487b7160e01b600052601260045260246000fd5b500490565b600060018201612fbb57612fbb612cb4565b5060010190565b838152606060208201526000612fdb6060830185612ac2565b8281036040840152612fed8185612ac2565b9695505050505050565b6000806040838503121561300a57600080fd5b8251613015816129f5565b915061302360208401612d85565b90509250929050565b60006020828403121561303e57600080fd5b5051919050565b60008161305457613054612cb4565b506000190190565b60008151808452602080850194506020840160005b83811015612af35781516001600160a01b031687529582019590820190600101613071565b6080815260006130a96080830187612ac2565b82810360208401526130bb818761305c565b905082810360408401526130cf818661305c565b90508281036060840152612e6e8185612ac256fea26469706673582212201cbb3243bdf2246a74a754c4b24385dc52b256b192f67778a3b3a76648374a5864736f6c63430008170033",
1271
- "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102415760003560e01c8063a0ed60e011610145578063cbcf252a116100bd578063eb338c961161008c578063f4dce71411610071578063f4dce71414610681578063f86ad2b614610689578063ffa1ad74146106b057600080fd5b8063eb338c9614610666578063f189e85a1461067957600080fd5b8063cbcf252a146105ca578063e1f1176d146105f1578063e77cdcc914610618578063eacdaabc1461063f57600080fd5b8063b69ef8a811610114578063c2c4c5c1116100f9578063c2c4c5c11461057e578063c889921d14610597578063cae2a5f0146105aa57600080fd5b8063b69ef8a814610562578063b6b55f251461056b57600080fd5b8063a0ed60e014610496578063a694fc3a146104bd578063a74466ad146104d0578063b15087601461054d57600080fd5b806352c824f5116101d857806372f702f3116101a7578063809cee2f1161018c578063809cee2f1461044657806382a8ea581461046d578063879d90901461048d57600080fd5b806372f702f31461040c57806378e061361461043357600080fd5b806352c824f51461038457806356e76058146103ab5780635829c5ec146103be578063592cf3fb146103e557600080fd5b8063287140511161021457806328714051146103005780632e17de781461033f5780633e7329971461035457806342cde4e81461035d57600080fd5b806308ae7e541461024657806314b19c5a14610280578063150b7a021461028957806316a75172146102d9575b600080fd5b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61026d60005481565b6102a8610297366004612a0a565b630a85bd0160e11b95945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610277565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b61035261034d366004612aa9565b6106e1565b005b61026d60035481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d6103b9366004612aa9565b610acf565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d610441366004612aa9565b610af0565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61048061047b366004612aa9565b610bba565b6040516102779190612afe565b61026d60025481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103526104cb366004612aa9565b610cb1565b61051a6104de366004612aa9565b6005602081905260009182526040909120805460018201546003830154600484015493909401546001600160a01b039283169492909116929085565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610277565b61055561127e565b6040516102779190612b65565b61026d60015481565b610352610579366004612aa9565b6112d6565b610586611378565b604051610277959493929190612b78565b61026d6105a5366004612aa9565b6119ad565b6105bd6105b8366004612aa9565b611a69565b6040516102779190612c3d565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d610674366004612aa9565b611b5c565b610555611b6c565b61026d611bc2565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6106d4604051806040016040528060058152602001640302e312e360dc1b81525081565b6040516102779190612c65565b600081815260056020526040902060018101546001600160a01b0316331461073857600181015460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b600381015460006107498242612cca565b90507f0000000000000000000000000000000000000000000000000000000000000000811115801561077d57506000600254115b156107cb5760405163ba2bbc6b60e01b815260048101859052602481018290527f0000000000000000000000000000000000000000000000000000000000000000604482015260640161072f565b6000806107d6611378565b945050505091508151600003610837576107ee611b6c565b9150815167ffffffffffffffff81111561080a5761080a612cdd565b604051908082528060200260200182016040528015610833578160200160208202803683370190505b5090505b6000805b8351821015610898578783838151811061085757610857612cf3565b60200260200101510315610898578784838151811061087857610878612cf3565b60200260200101510361088d57506001610898565b81600101915061083b565b600487015460028801805460408051602080840282018101909252828152600093909290918301828280156108ec57602002820191906000526020600020905b8154815260200190600101908083116108d8575b50508c5460008f8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff19908116825560018201805490911690559596506001600160a01b03909116949350915061094890506002830182612974565b506000600382018190556004820181905560059091015583156109d7576006805461097590600190612cca565b8154811061098557610985612cf3565b9060005260206000200154600686815481106109a3576109a3612cf3565b60009182526020909120015560068054806109c0576109c0612d09565b600190038181906000526020600020016000905590555b604051632142170760e11b8152306004820152336024820152604481018c90526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342842e0e90606401600060405180830381600087803b158015610a4557600080fd5b505af1158015610a59573d6000803e3d6000fd5b505050506000831115610a7057610a708184611bf7565b806001600160a01b0316336001600160a01b03168c7f950733f4c0bf951b8e770f3cc619a4288e7b59b1236d59aeaf2c238488e8ae816000548688604051610aba93929190612d1f565b60405180910390a45050505050505050505050565b60048181548110610adf57600080fd5b600091825260209091200154905081565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015610b7057602002820191906000526020600020905b815481526020019060010190808311610b5c575b505050505081526020016003820154815260200160048201548152602001600582015481525050905080608001519150610ba9836119ad565b610bb39083612d48565b9392505050565b610c056040518060c0016040528060006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016000815260200160008152602001600081525090565b600082815260056020908152604091829020825160c08101845281546001600160a01b0390811682526001830154168184015260028201805485518186028101860187528181529295939493860193830182828015610c8357602002820191906000526020600020905b815481526020019060010190808311610c6f575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050919050565b600254600003610cd45760405163afb0be3360e01b815260040160405180910390fd5b6000818152600560205260409020600381015415610d085760405163b4817ce760e01b81526004810183905260240161072f565b6006547f00000000000000000000000000000000000000000000000000000000000000008103610d6d5760405163fd20861560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260240161072f565b60405163ef0e239b60e01b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ef0e239b90602401600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610dfd9190810190612e79565b9050806080015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014610e4c57604051637ad404bf60e11b81526004810185905260240161072f565b7f000000000000000000000000000000000000000000000000000000000000000015801590610e9f575080604001517f000000000000000000000000000000000000000000000000000000000000000014155b15610ec057604051637ad404bf60e11b81526004810185905260240161072f565b60007f0000000000000000000000000000000000000000000000000000000000000000118015610f1a5750806060015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014155b15610f3b57604051637ad404bf60e11b81526004810185905260240161072f565b60048160c001516005811115610f5357610f53612c27565b14610f92578060c001516005811115610f6e57610f6e612c27565b604051633c053f9d60e21b815260048101919091526024810185905260440161072f565b600081602001516001600160a01b0316803b806020016040519081016040528181526000908060200190933c805190602001209050807f00000000000000000000000000000000000000000000000000000000000000001461101757602082015160405162a2307960e51b81526001600160a01b03909116600482015260240161072f565b60045480156110e05760e08301515181811461104957604051637ad404bf60e11b81526004810188905260240161072f565b60005b818110156110dd578460e00151818151811061106a5761106a612cf3565b602002602001015163ffffffff166004828154811061108b5761108b612cf3565b9060005260206000200154146110d557600481815481106110ae576110ae612cf3565b9060005260206000200154604051632ab10b0b60e21b815260040161072f91815260200190565b60010161104c565b50505b6111018684600001516bffffffffffffffffffffffff168560e00151611c81565b602083015185546001600160a01b03821673ffffffffffffffffffffffffffffffffffffffff199182161787556001870180549091163317905560009061114790611f02565b805190915061115f9060028801906020840190612995565b50426003870155600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01879055604051632142170760e11b8152336004820152306024820152604481018890527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342842e0e90606401600060405180830381600087803b15801561120957600080fd5b505af115801561121d573d6000803e3d6000fd5b5050505083602001516001600160a01b0316336001600160a01b0316887faa6b005b4958114a0c90492461c24af6525ae0178db7fbf44125ae9217c69ccb6000548560405161126d929190612f57565b60405180910390a450505050505050565b606060048054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020905b8154815260200190600101908083116112b8575b5050505050905090565b6000816001546112e69190612d48565b90506000826002546112f89190612d48565b6001839055600281905590506113307f0000000000000000000000000000000000000000000000000000000000000000333086611f13565b604080518481526020810184905290810182905233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9060600160405180910390a2505050565b6060806060806060600080600080600080600080611394611f9d565b97509750975097509750975097509750606080845167ffffffffffffffff8111156113c1576113c1612cdd565b6040519080825280602002602001820160405280156113ea578160200160208202803683370190505b509a506000891561177d578967ffffffffffffffff81111561140e5761140e612cdd565b604051908082528060200260200182016040528015611437578160200160208202803683370190505b5092508967ffffffffffffffff81111561145357611453612cdd565b60405190808252806020026020018201604052801561147c578160200160208202803683370190505b5091508a8911156116865760008060015b8c811015611579578b8e8b83815181106114a9576114a9612cf3565b60200260200101516114bb9190612f70565b6114c59190612f87565b92506114d18383612d48565b91508a81815181106114e5576114e5612cf3565b602002602001015193508a818151811061150157611501612cf3565b602002602001015186828151811061151b5761151b612cf3565b6020026020010181815250508285828151811061153a5761153a612cf3565b6020026020010181815250508260056000868152602001908152602001600020600401600082825461156c9190612d48565b909155505060010161148d565b508a8d8a60008151811061158f5761158f612cf3565b60200260200101516115a19190612f70565b6115ab9190612f87565b91506115b78282612d48565b9050896000815181106115cc576115cc612cf3565b60200260200101519250896000815181106115e9576115e9612cf3565b60200260200101518560008151811061160457611604612cf3565b602002602001018181525050808d111561162f57611622818e612cca565b61162c9083612d48565b91505b818460008151811061164357611643612cf3565b602002602001018181525050816005600085815260200190815260200160002060040160008282546116759190612d48565b9091555060009d5061177792505050565b60005b8a811015611769578881815181106116a3576116a3612cf3565b602002602001015191508881815181106116bf576116bf612cf3565b60200260200101518482815181106116d9576116d9612cf3565b6020026020010181815250508781815181106116f7576116f7612cf3565b602002602001015183828151811061171157611711612cf3565b60200260200101818152505087818151811061172f5761172f612cf3565b602002602001015160056000848152602001908152602001600020600401600082825461175c9190612d48565b9091555050600101611689565b50611774898c612cca565b9a505b60028b90555b855115611997576000995060005b8651811015611930578681815181106117a6576117a6612cf3565b602002602001015191508581815181106117c2576117c2612cf3565b60200260200101516005600084815260200190815260200160002060020190805190602001906117f3929190612995565b50600085828151811061180857611808612cf3565b602002602001015111156119155784818151811061182857611828612cf3565b602002602001015160056000848152602001908152602001600020600501546118519190612d48565b85828151811061186357611863612cf3565b60200260200101818152505084818151811061188157611881612cf3565b602002602001015160056000848152602001908152602001600020600501819055507f00000000000000000000000000000000000000000000000000000000000000008582815181106118d6576118d6612cf3565b6020026020010151111561191057818d82815181106118f7576118f7612cf3565b60209081029190910101528a61190c81612fa9565b9b50505b611928565b6000828152600560208190526040822001555b60010161178b565b508915611942576119428c858c61239b565b42600355600054611954816001612d48565b60005560405181907f06a98bdd4732811ab3214800ed1ada2dce66a2bce301d250c3ca7d6b461ee6669061198d908f9088908890612fc2565b60405180910390a2505b50939e929d509b50919950969750505050505050565b6000806000806000806119be611f9d565b5050509450945094509450945060005b84811015611a5e57878382815181106119e9576119e9612cf3565b602002602001015103611a565785841115611a35578386838381518110611a1257611a12612cf3565b6020026020010151611a249190612f70565b611a2e9190612f87565b9650611a5e565b818181518110611a4757611a47612cf3565b60200260200101519650611a5e565b6001016119ce565b505050505050919050565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015611ae957602002820191906000526020600020905b815481526020019060010190808311611ad5575b50505050508152602001600382015481526020016004820154815260200160058201548152505090507f00000000000000000000000000000000000000000000000000000000000000008160a001511115611b475760029150611b56565b606081015115611b5657600191505b50919050565b60068181548110610adf57600080fd5b606060068054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020908154815260200190600101908083116112b8575050505050905090565b60007f0000000000000000000000000000000000000000000000000000000000000000600354611bf29190612d48565b905090565b8060016000828254611c099190612cca565b90915550611c3a90507f00000000000000000000000000000000000000000000000000000000000000008383612760565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051611c7591815260200190565b60405180910390a25050565b604051633cebfa4f60e01b81526004810184905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633cebfa4f906024016040805180830381865afa158015611cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0e9190612ff7565b91509150816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611d9757604051630b80380d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161072f565b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff8216811115611dfe57604051632b30b24760e21b81526bffffffffffffffffffffffff831660048201526024810182905260440161072f565b60005b8451811015611ef95760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166375c1f93489888581518110611e4e57611e4e612cf3565b60200260200101516040518363ffffffff1660e01b8152600401611e8292919091825263ffffffff16602082015260400190565b602060405180830381865afa158015611e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec3919061302c565b905082811015611ef057604051632b30b24760e21b8152600481018290526024810184905260440161072f565b50600101611e01565b50505050505050565b6060611f0d826127e3565b92915050565b60006040516323b872dd60e01b6000528460045283602452826044526020600060646000808a5af13d15601f3d1160016000511416171691506000606052806040525080611f965760405163abae3d6d60e01b81526001600160a01b0380871660048301528086166024830152841660448201526064810183905260840161072f565b5050505050565b600080600060608060608060606000600354905060025498507f00000000000000000000000000000000000000000000000000000000000000008142611fe39190612cca565b10158015611ff15750600089115b15612390576006548067ffffffffffffffff81111561201257612012612cdd565b60405190808252806020026020018201604052801561203b578160200160208202803683370190505b5094508067ffffffffffffffff81111561205757612057612cdd565b604051908082528060200260200182016040528015612080578160200160208202803683370190505b5096508067ffffffffffffffff81111561209c5761209c612cdd565b6040519080825280602002602001820160405280156120c5578160200160208202803683370190505b5095508067ffffffffffffffff8111156120e1576120e1612cdd565b60405190808252806020026020018201604052801561211457816020015b60608152602001906001900390816120ff5790505b5093508067ffffffffffffffff81111561213057612130612cdd565b604051908082528060200260200182016040528015612159578160200160208202803683370190505b50925060005b8181101561238d576006818154811061217a5761217a612cf3565b906000526020600020015486828151811061219757612197612cf3565b6020026020010181815250506000600560008884815181106121bb576121bb612cf3565b602090810291909101810151825281019190915260400160002080549091506121ec906001600160a01b0316611f02565b8683815181106121fe576121fe612cf3565b6020908102919091010152600381015484908181111561221c578091505b6122268242612cca565b905060006122a089868151811061223f5761223f612cf3565b60200260200101518560020180548060200260200160405190810160405280929190818152602001828054801561229557602002820191906000526020600020905b815481526020019060010190808311612281575b50505050508461288b565b9050801561235e576122d2827f0000000000000000000000000000000000000000000000000000000000000000612f70565b8b8f815181106122e4576122e4612cf3565b6020026020010181815250508a8e8151811061230257612302612cf3565b60200260200101518d6123159190612d48565b9c5089858151811061232957612329612cf3565b60200260200101518c8f8151811061234357612343612cf3565b60209081029190910101526123578e612fa9565b9d5061237e565b8188868151811061237157612371612cf3565b6020026020010181815250505b5050505080600101905061215f565b50505b509091929394959697565b825160008267ffffffffffffffff8111156123b8576123b8612cdd565b6040519080825280602002602001820160405280156123e1578160200160208202803683370190505b50905060008367ffffffffffffffff8111156123ff576123ff612cdd565b604051908082528060200260200182016040528015612428578160200160208202803683370190505b50905060008467ffffffffffffffff81111561244657612446612cdd565b60405190808252806020026020018201604052801561246f578160200160208202803683370190505b50905060008567ffffffffffffffff81111561248d5761248d612cdd565b6040519080825280602002602001820160405280156124b6578160200160208202803683370190505b50905060008667ffffffffffffffff8111156124d4576124d4612cdd565b6040519080825280602002602001820160405280156124fd578160200160208202803683370190505b50905060008060005b8881101561265d5760008c828151811061252257612522612cf3565b60200260200101511115612655578b818151811061254257612542612cf3565b602002602001015191508188848151811061255f5761255f612cf3565b6020908102919091018101919091526000838152600590915260409020600181015488516001600160a01b03909116908990869081106125a1576125a1612cf3565b6001600160a01b039283166020918202929092010152815488519116908890869081106125d0576125d0612cf3565b60200260200101906001600160a01b031690816001600160a01b0316815250508b828151811061260257612602612cf3565b602002602001015186858151811061261c5761261c612cf3565b6020026020010181815250508185858151811061263b5761263b612cf3565b60209081029190910101528361265081612fa9565b945050505b600101612506565b50885b8015612712578861267081613045565b99506000905084612682600184612cca565b8151811061269257612692612cf3565b6020026020010151905060068a815481106126af576126af612cf3565b9060005260206000200154600682815481106126cd576126cd612cf3565b60009182526020909120015560068054806126ea576126ea612d09565b60019003818190600052602060002001600090559055508061270b90613045565b9050612660565b506000547fd19a3d42ed383465e4058c322d9411aeac76ddb8454d22e139fc99808bd569528888888860405161274b9493929190613096565b60405180910390a25050505050505050505050565b600060405163a9059cbb60e01b6000528360045282602452602060006044600080895af13d15601f3d11600160005114161716915060006060528060405250806127dd5760405163abae3d6d60e01b81526001600160a01b038086166004830152306024830152841660448201526064810183905260840161072f565b50505050565b60408051600180825281830190925260609160208083019080368337019050509050816001600160a01b031663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612843573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612867919061302c565b8160008151811061287a5761287a612cf3565b602002602001018181525050919050565b60006128988484846128a0565b949350505050565b600080821180156128e45750826000815181106128bf576128bf612cf3565b6020026020010151846000815181106128da576128da612cf3565b6020026020010151115b15610bb357600082846000815181106128ff576128ff612cf3565b60200260200101518660008151811061291a5761291a612cf3565b602002602001015161292c9190612cca565b61293e90670de0b6b3a7640000612f70565b6129489190612f87565b7f0000000000000000000000000000000000000000000000000000000000000000111595945050505050565b508054600082559060005260206000209081019061299291906129e0565b50565b8280548282559060005260206000209081019282156129d0579160200282015b828111156129d05782518255916020019190600101906129b5565b506129dc9291506129e0565b5090565b5b808211156129dc57600081556001016129e1565b6001600160a01b038116811461299257600080fd5b600080600080600060808688031215612a2257600080fd5b8535612a2d816129f5565b94506020860135612a3d816129f5565b935060408601359250606086013567ffffffffffffffff80821115612a6157600080fd5b818801915088601f830112612a7557600080fd5b813581811115612a8457600080fd5b896020828501011115612a9657600080fd5b9699959850939650602001949392505050565b600060208284031215612abb57600080fd5b5035919050565b60008151808452602080850194506020840160005b83811015612af357815187529582019590820190600101612ad7565b509495945050505050565b6020815260006001600160a01b0380845116602084015280602085015116604084015250604083015160c06060840152612b3b60e0840182612ac2565b905060608401516080840152608084015160a084015260a084015160c08401528091505092915050565b602081526000610bb36020830184612ac2565b60a081526000612b8b60a0830188612ac2565b6020838203818501528188518084528284019150828160051b850101838b0160005b83811015612bdb57601f19878403018552612bc9838351612ac2565b94860194925090850190600101612bad565b50508681036040880152612bef818b612ac2565b9450505050508281036060840152612c078186612ac2565b90508281036080840152612c1b8185612ac2565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6020810160038310612c5f57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020808352835180602085015260005b81811015612c9357858101830151858201604001528201612c77565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b81810381811115611f0d57611f0d612cb4565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b838152606060208201526000612d386060830185612ac2565b9050826040830152949350505050565b80820180821115611f0d57611f0d612cb4565b604051610100810167ffffffffffffffff81118282101715612d7f57612d7f612cdd565b60405290565b80516bffffffffffffffffffffffff81168114612da157600080fd5b919050565b8051612da1816129f5565b805163ffffffff81168114612da157600080fd5b805160068110612da157600080fd5b600082601f830112612de557600080fd5b8151602067ffffffffffffffff80831115612e0257612e02612cdd565b8260051b604051601f19603f83011681018181108482111715612e2757612e27612cdd565b6040529384526020818701810194908101925087851115612e4757600080fd5b6020870191505b84821015612e6e57612e5f82612db1565b83529183019190830190612e4e565b979650505050505050565b600060208284031215612e8b57600080fd5b815167ffffffffffffffff80821115612ea357600080fd5b908301906101008286031215612eb857600080fd5b612ec0612d5b565b612ec983612d85565b8152612ed760208401612da6565b602082015260408301516040820152612ef260608401612db1565b6060820152612f0360808401612db1565b6080820152612f1460a08401612db1565b60a0820152612f2560c08401612dc5565b60c082015260e083015182811115612f3c57600080fd5b612f4887828601612dd4565b60e08301525095945050505050565b8281526040602082015260006128986040830184612ac2565b8082028115828204841417611f0d57611f0d612cb4565b600082612fa457634e487b7160e01b600052601260045260246000fd5b500490565b600060018201612fbb57612fbb612cb4565b5060010190565b838152606060208201526000612fdb6060830185612ac2565b8281036040840152612fed8185612ac2565b9695505050505050565b6000806040838503121561300a57600080fd5b8251613015816129f5565b915061302360208401612d85565b90509250929050565b60006020828403121561303e57600080fd5b5051919050565b60008161305457613054612cb4565b506000190190565b60008151808452602080850194506020840160005b83811015612af35781516001600160a01b031687529582019590820190600101613071565b6080815260006130a96080830187612ac2565b82810360208401526130bb818761305c565b905082810360408401526130cf818661305c565b90508281036060840152612e6e8185612ac256fea26469706673582212201cbb3243bdf2246a74a754c4b24385dc52b256b192f67778a3b3a76648374a5864736f6c63430008170033",
1272
- "linkReferences": {},
1273
- "deployedLinkReferences": {}
1274
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
contracts/Vault.json DELETED
@@ -1,1186 +0,0 @@
1
- {
2
- "contractName": "",
3
- "abi": [
4
- {
5
- "inputs": [
6
- {
7
- "internalType": "contract IAuthorizer",
8
- "name": "authorizer",
9
- "type": "address"
10
- },
11
- {
12
- "internalType": "contract IWETH",
13
- "name": "weth",
14
- "type": "address"
15
- },
16
- {
17
- "internalType": "uint256",
18
- "name": "pauseWindowDuration",
19
- "type": "uint256"
20
- },
21
- {
22
- "internalType": "uint256",
23
- "name": "bufferPeriodDuration",
24
- "type": "uint256"
25
- }
26
- ],
27
- "stateMutability": "nonpayable",
28
- "type": "constructor"
29
- },
30
- {
31
- "anonymous": false,
32
- "inputs": [
33
- {
34
- "indexed": true,
35
- "internalType": "contract IAuthorizer",
36
- "name": "newAuthorizer",
37
- "type": "address"
38
- }
39
- ],
40
- "name": "AuthorizerChanged",
41
- "type": "event"
42
- },
43
- {
44
- "anonymous": false,
45
- "inputs": [
46
- {
47
- "indexed": true,
48
- "internalType": "contract IERC20",
49
- "name": "token",
50
- "type": "address"
51
- },
52
- {
53
- "indexed": true,
54
- "internalType": "address",
55
- "name": "sender",
56
- "type": "address"
57
- },
58
- {
59
- "indexed": false,
60
- "internalType": "address",
61
- "name": "recipient",
62
- "type": "address"
63
- },
64
- {
65
- "indexed": false,
66
- "internalType": "uint256",
67
- "name": "amount",
68
- "type": "uint256"
69
- }
70
- ],
71
- "name": "ExternalBalanceTransfer",
72
- "type": "event"
73
- },
74
- {
75
- "anonymous": false,
76
- "inputs": [
77
- {
78
- "indexed": true,
79
- "internalType": "contract IFlashLoanRecipient",
80
- "name": "recipient",
81
- "type": "address"
82
- },
83
- {
84
- "indexed": true,
85
- "internalType": "contract IERC20",
86
- "name": "token",
87
- "type": "address"
88
- },
89
- {
90
- "indexed": false,
91
- "internalType": "uint256",
92
- "name": "amount",
93
- "type": "uint256"
94
- },
95
- {
96
- "indexed": false,
97
- "internalType": "uint256",
98
- "name": "feeAmount",
99
- "type": "uint256"
100
- }
101
- ],
102
- "name": "FlashLoan",
103
- "type": "event"
104
- },
105
- {
106
- "anonymous": false,
107
- "inputs": [
108
- {
109
- "indexed": true,
110
- "internalType": "address",
111
- "name": "user",
112
- "type": "address"
113
- },
114
- {
115
- "indexed": true,
116
- "internalType": "contract IERC20",
117
- "name": "token",
118
- "type": "address"
119
- },
120
- {
121
- "indexed": false,
122
- "internalType": "int256",
123
- "name": "delta",
124
- "type": "int256"
125
- }
126
- ],
127
- "name": "InternalBalanceChanged",
128
- "type": "event"
129
- },
130
- {
131
- "anonymous": false,
132
- "inputs": [
133
- {
134
- "indexed": false,
135
- "internalType": "bool",
136
- "name": "paused",
137
- "type": "bool"
138
- }
139
- ],
140
- "name": "PausedStateChanged",
141
- "type": "event"
142
- },
143
- {
144
- "anonymous": false,
145
- "inputs": [
146
- {
147
- "indexed": true,
148
- "internalType": "bytes32",
149
- "name": "poolId",
150
- "type": "bytes32"
151
- },
152
- {
153
- "indexed": true,
154
- "internalType": "address",
155
- "name": "liquidityProvider",
156
- "type": "address"
157
- },
158
- {
159
- "indexed": false,
160
- "internalType": "contract IERC20[]",
161
- "name": "tokens",
162
- "type": "address[]"
163
- },
164
- {
165
- "indexed": false,
166
- "internalType": "int256[]",
167
- "name": "deltas",
168
- "type": "int256[]"
169
- },
170
- {
171
- "indexed": false,
172
- "internalType": "uint256[]",
173
- "name": "protocolFeeAmounts",
174
- "type": "uint256[]"
175
- }
176
- ],
177
- "name": "PoolBalanceChanged",
178
- "type": "event"
179
- },
180
- {
181
- "anonymous": false,
182
- "inputs": [
183
- {
184
- "indexed": true,
185
- "internalType": "bytes32",
186
- "name": "poolId",
187
- "type": "bytes32"
188
- },
189
- {
190
- "indexed": true,
191
- "internalType": "address",
192
- "name": "assetManager",
193
- "type": "address"
194
- },
195
- {
196
- "indexed": true,
197
- "internalType": "contract IERC20",
198
- "name": "token",
199
- "type": "address"
200
- },
201
- {
202
- "indexed": false,
203
- "internalType": "int256",
204
- "name": "cashDelta",
205
- "type": "int256"
206
- },
207
- {
208
- "indexed": false,
209
- "internalType": "int256",
210
- "name": "managedDelta",
211
- "type": "int256"
212
- }
213
- ],
214
- "name": "PoolBalanceManaged",
215
- "type": "event"
216
- },
217
- {
218
- "anonymous": false,
219
- "inputs": [
220
- {
221
- "indexed": true,
222
- "internalType": "bytes32",
223
- "name": "poolId",
224
- "type": "bytes32"
225
- },
226
- {
227
- "indexed": true,
228
- "internalType": "address",
229
- "name": "poolAddress",
230
- "type": "address"
231
- },
232
- {
233
- "indexed": false,
234
- "internalType": "enum IVault.PoolSpecialization",
235
- "name": "specialization",
236
- "type": "uint8"
237
- }
238
- ],
239
- "name": "PoolRegistered",
240
- "type": "event"
241
- },
242
- {
243
- "anonymous": false,
244
- "inputs": [
245
- {
246
- "indexed": true,
247
- "internalType": "address",
248
- "name": "relayer",
249
- "type": "address"
250
- },
251
- {
252
- "indexed": true,
253
- "internalType": "address",
254
- "name": "sender",
255
- "type": "address"
256
- },
257
- {
258
- "indexed": false,
259
- "internalType": "bool",
260
- "name": "approved",
261
- "type": "bool"
262
- }
263
- ],
264
- "name": "RelayerApprovalChanged",
265
- "type": "event"
266
- },
267
- {
268
- "anonymous": false,
269
- "inputs": [
270
- {
271
- "indexed": true,
272
- "internalType": "bytes32",
273
- "name": "poolId",
274
- "type": "bytes32"
275
- },
276
- {
277
- "indexed": true,
278
- "internalType": "contract IERC20",
279
- "name": "tokenIn",
280
- "type": "address"
281
- },
282
- {
283
- "indexed": true,
284
- "internalType": "contract IERC20",
285
- "name": "tokenOut",
286
- "type": "address"
287
- },
288
- {
289
- "indexed": false,
290
- "internalType": "uint256",
291
- "name": "amountIn",
292
- "type": "uint256"
293
- },
294
- {
295
- "indexed": false,
296
- "internalType": "uint256",
297
- "name": "amountOut",
298
- "type": "uint256"
299
- }
300
- ],
301
- "name": "Swap",
302
- "type": "event"
303
- },
304
- {
305
- "anonymous": false,
306
- "inputs": [
307
- {
308
- "indexed": true,
309
- "internalType": "bytes32",
310
- "name": "poolId",
311
- "type": "bytes32"
312
- },
313
- {
314
- "indexed": false,
315
- "internalType": "contract IERC20[]",
316
- "name": "tokens",
317
- "type": "address[]"
318
- }
319
- ],
320
- "name": "TokensDeregistered",
321
- "type": "event"
322
- },
323
- {
324
- "anonymous": false,
325
- "inputs": [
326
- {
327
- "indexed": true,
328
- "internalType": "bytes32",
329
- "name": "poolId",
330
- "type": "bytes32"
331
- },
332
- {
333
- "indexed": false,
334
- "internalType": "contract IERC20[]",
335
- "name": "tokens",
336
- "type": "address[]"
337
- },
338
- {
339
- "indexed": false,
340
- "internalType": "address[]",
341
- "name": "assetManagers",
342
- "type": "address[]"
343
- }
344
- ],
345
- "name": "TokensRegistered",
346
- "type": "event"
347
- },
348
- {
349
- "inputs": [],
350
- "name": "WETH",
351
- "outputs": [
352
- {
353
- "internalType": "contract IWETH",
354
- "name": "",
355
- "type": "address"
356
- }
357
- ],
358
- "stateMutability": "view",
359
- "type": "function"
360
- },
361
- {
362
- "inputs": [
363
- {
364
- "internalType": "enum IVault.SwapKind",
365
- "name": "kind",
366
- "type": "uint8"
367
- },
368
- {
369
- "components": [
370
- {
371
- "internalType": "bytes32",
372
- "name": "poolId",
373
- "type": "bytes32"
374
- },
375
- {
376
- "internalType": "uint256",
377
- "name": "assetInIndex",
378
- "type": "uint256"
379
- },
380
- {
381
- "internalType": "uint256",
382
- "name": "assetOutIndex",
383
- "type": "uint256"
384
- },
385
- {
386
- "internalType": "uint256",
387
- "name": "amount",
388
- "type": "uint256"
389
- },
390
- {
391
- "internalType": "bytes",
392
- "name": "userData",
393
- "type": "bytes"
394
- }
395
- ],
396
- "internalType": "struct IVault.BatchSwapStep[]",
397
- "name": "swaps",
398
- "type": "tuple[]"
399
- },
400
- {
401
- "internalType": "contract IAsset[]",
402
- "name": "assets",
403
- "type": "address[]"
404
- },
405
- {
406
- "components": [
407
- {
408
- "internalType": "address",
409
- "name": "sender",
410
- "type": "address"
411
- },
412
- {
413
- "internalType": "bool",
414
- "name": "fromInternalBalance",
415
- "type": "bool"
416
- },
417
- {
418
- "internalType": "address payable",
419
- "name": "recipient",
420
- "type": "address"
421
- },
422
- {
423
- "internalType": "bool",
424
- "name": "toInternalBalance",
425
- "type": "bool"
426
- }
427
- ],
428
- "internalType": "struct IVault.FundManagement",
429
- "name": "funds",
430
- "type": "tuple"
431
- },
432
- {
433
- "internalType": "int256[]",
434
- "name": "limits",
435
- "type": "int256[]"
436
- },
437
- {
438
- "internalType": "uint256",
439
- "name": "deadline",
440
- "type": "uint256"
441
- }
442
- ],
443
- "name": "batchSwap",
444
- "outputs": [
445
- {
446
- "internalType": "int256[]",
447
- "name": "assetDeltas",
448
- "type": "int256[]"
449
- }
450
- ],
451
- "stateMutability": "payable",
452
- "type": "function"
453
- },
454
- {
455
- "inputs": [
456
- {
457
- "internalType": "bytes32",
458
- "name": "poolId",
459
- "type": "bytes32"
460
- },
461
- {
462
- "internalType": "contract IERC20[]",
463
- "name": "tokens",
464
- "type": "address[]"
465
- }
466
- ],
467
- "name": "deregisterTokens",
468
- "outputs": [],
469
- "stateMutability": "nonpayable",
470
- "type": "function"
471
- },
472
- {
473
- "inputs": [
474
- {
475
- "internalType": "bytes32",
476
- "name": "poolId",
477
- "type": "bytes32"
478
- },
479
- {
480
- "internalType": "address",
481
- "name": "sender",
482
- "type": "address"
483
- },
484
- {
485
- "internalType": "address payable",
486
- "name": "recipient",
487
- "type": "address"
488
- },
489
- {
490
- "components": [
491
- {
492
- "internalType": "contract IAsset[]",
493
- "name": "assets",
494
- "type": "address[]"
495
- },
496
- {
497
- "internalType": "uint256[]",
498
- "name": "minAmountsOut",
499
- "type": "uint256[]"
500
- },
501
- {
502
- "internalType": "bytes",
503
- "name": "userData",
504
- "type": "bytes"
505
- },
506
- {
507
- "internalType": "bool",
508
- "name": "toInternalBalance",
509
- "type": "bool"
510
- }
511
- ],
512
- "internalType": "struct IVault.ExitPoolRequest",
513
- "name": "request",
514
- "type": "tuple"
515
- }
516
- ],
517
- "name": "exitPool",
518
- "outputs": [],
519
- "stateMutability": "nonpayable",
520
- "type": "function"
521
- },
522
- {
523
- "inputs": [
524
- {
525
- "internalType": "contract IFlashLoanRecipient",
526
- "name": "recipient",
527
- "type": "address"
528
- },
529
- {
530
- "internalType": "contract IERC20[]",
531
- "name": "tokens",
532
- "type": "address[]"
533
- },
534
- {
535
- "internalType": "uint256[]",
536
- "name": "amounts",
537
- "type": "uint256[]"
538
- },
539
- {
540
- "internalType": "bytes",
541
- "name": "userData",
542
- "type": "bytes"
543
- }
544
- ],
545
- "name": "flashLoan",
546
- "outputs": [],
547
- "stateMutability": "nonpayable",
548
- "type": "function"
549
- },
550
- {
551
- "inputs": [
552
- {
553
- "internalType": "bytes4",
554
- "name": "selector",
555
- "type": "bytes4"
556
- }
557
- ],
558
- "name": "getActionId",
559
- "outputs": [
560
- {
561
- "internalType": "bytes32",
562
- "name": "",
563
- "type": "bytes32"
564
- }
565
- ],
566
- "stateMutability": "view",
567
- "type": "function"
568
- },
569
- {
570
- "inputs": [],
571
- "name": "getAuthorizer",
572
- "outputs": [
573
- {
574
- "internalType": "contract IAuthorizer",
575
- "name": "",
576
- "type": "address"
577
- }
578
- ],
579
- "stateMutability": "view",
580
- "type": "function"
581
- },
582
- {
583
- "inputs": [],
584
- "name": "getDomainSeparator",
585
- "outputs": [
586
- {
587
- "internalType": "bytes32",
588
- "name": "",
589
- "type": "bytes32"
590
- }
591
- ],
592
- "stateMutability": "view",
593
- "type": "function"
594
- },
595
- {
596
- "inputs": [
597
- {
598
- "internalType": "address",
599
- "name": "user",
600
- "type": "address"
601
- },
602
- {
603
- "internalType": "contract IERC20[]",
604
- "name": "tokens",
605
- "type": "address[]"
606
- }
607
- ],
608
- "name": "getInternalBalance",
609
- "outputs": [
610
- {
611
- "internalType": "uint256[]",
612
- "name": "balances",
613
- "type": "uint256[]"
614
- }
615
- ],
616
- "stateMutability": "view",
617
- "type": "function"
618
- },
619
- {
620
- "inputs": [
621
- {
622
- "internalType": "address",
623
- "name": "user",
624
- "type": "address"
625
- }
626
- ],
627
- "name": "getNextNonce",
628
- "outputs": [
629
- {
630
- "internalType": "uint256",
631
- "name": "",
632
- "type": "uint256"
633
- }
634
- ],
635
- "stateMutability": "view",
636
- "type": "function"
637
- },
638
- {
639
- "inputs": [],
640
- "name": "getPausedState",
641
- "outputs": [
642
- {
643
- "internalType": "bool",
644
- "name": "paused",
645
- "type": "bool"
646
- },
647
- {
648
- "internalType": "uint256",
649
- "name": "pauseWindowEndTime",
650
- "type": "uint256"
651
- },
652
- {
653
- "internalType": "uint256",
654
- "name": "bufferPeriodEndTime",
655
- "type": "uint256"
656
- }
657
- ],
658
- "stateMutability": "view",
659
- "type": "function"
660
- },
661
- {
662
- "inputs": [
663
- {
664
- "internalType": "bytes32",
665
- "name": "poolId",
666
- "type": "bytes32"
667
- }
668
- ],
669
- "name": "getPool",
670
- "outputs": [
671
- {
672
- "internalType": "address",
673
- "name": "",
674
- "type": "address"
675
- },
676
- {
677
- "internalType": "enum IVault.PoolSpecialization",
678
- "name": "",
679
- "type": "uint8"
680
- }
681
- ],
682
- "stateMutability": "view",
683
- "type": "function"
684
- },
685
- {
686
- "inputs": [
687
- {
688
- "internalType": "bytes32",
689
- "name": "poolId",
690
- "type": "bytes32"
691
- },
692
- {
693
- "internalType": "contract IERC20",
694
- "name": "token",
695
- "type": "address"
696
- }
697
- ],
698
- "name": "getPoolTokenInfo",
699
- "outputs": [
700
- {
701
- "internalType": "uint256",
702
- "name": "cash",
703
- "type": "uint256"
704
- },
705
- {
706
- "internalType": "uint256",
707
- "name": "managed",
708
- "type": "uint256"
709
- },
710
- {
711
- "internalType": "uint256",
712
- "name": "lastChangeBlock",
713
- "type": "uint256"
714
- },
715
- {
716
- "internalType": "address",
717
- "name": "assetManager",
718
- "type": "address"
719
- }
720
- ],
721
- "stateMutability": "view",
722
- "type": "function"
723
- },
724
- {
725
- "inputs": [
726
- {
727
- "internalType": "bytes32",
728
- "name": "poolId",
729
- "type": "bytes32"
730
- }
731
- ],
732
- "name": "getPoolTokens",
733
- "outputs": [
734
- {
735
- "internalType": "contract IERC20[]",
736
- "name": "tokens",
737
- "type": "address[]"
738
- },
739
- {
740
- "internalType": "uint256[]",
741
- "name": "balances",
742
- "type": "uint256[]"
743
- },
744
- {
745
- "internalType": "uint256",
746
- "name": "lastChangeBlock",
747
- "type": "uint256"
748
- }
749
- ],
750
- "stateMutability": "view",
751
- "type": "function"
752
- },
753
- {
754
- "inputs": [],
755
- "name": "getProtocolFeesCollector",
756
- "outputs": [
757
- {
758
- "internalType": "contract ProtocolFeesCollector",
759
- "name": "",
760
- "type": "address"
761
- }
762
- ],
763
- "stateMutability": "view",
764
- "type": "function"
765
- },
766
- {
767
- "inputs": [
768
- {
769
- "internalType": "address",
770
- "name": "user",
771
- "type": "address"
772
- },
773
- {
774
- "internalType": "address",
775
- "name": "relayer",
776
- "type": "address"
777
- }
778
- ],
779
- "name": "hasApprovedRelayer",
780
- "outputs": [
781
- {
782
- "internalType": "bool",
783
- "name": "",
784
- "type": "bool"
785
- }
786
- ],
787
- "stateMutability": "view",
788
- "type": "function"
789
- },
790
- {
791
- "inputs": [
792
- {
793
- "internalType": "bytes32",
794
- "name": "poolId",
795
- "type": "bytes32"
796
- },
797
- {
798
- "internalType": "address",
799
- "name": "sender",
800
- "type": "address"
801
- },
802
- {
803
- "internalType": "address",
804
- "name": "recipient",
805
- "type": "address"
806
- },
807
- {
808
- "components": [
809
- {
810
- "internalType": "contract IAsset[]",
811
- "name": "assets",
812
- "type": "address[]"
813
- },
814
- {
815
- "internalType": "uint256[]",
816
- "name": "maxAmountsIn",
817
- "type": "uint256[]"
818
- },
819
- {
820
- "internalType": "bytes",
821
- "name": "userData",
822
- "type": "bytes"
823
- },
824
- {
825
- "internalType": "bool",
826
- "name": "fromInternalBalance",
827
- "type": "bool"
828
- }
829
- ],
830
- "internalType": "struct IVault.JoinPoolRequest",
831
- "name": "request",
832
- "type": "tuple"
833
- }
834
- ],
835
- "name": "joinPool",
836
- "outputs": [],
837
- "stateMutability": "payable",
838
- "type": "function"
839
- },
840
- {
841
- "inputs": [
842
- {
843
- "components": [
844
- {
845
- "internalType": "enum IVault.PoolBalanceOpKind",
846
- "name": "kind",
847
- "type": "uint8"
848
- },
849
- {
850
- "internalType": "bytes32",
851
- "name": "poolId",
852
- "type": "bytes32"
853
- },
854
- {
855
- "internalType": "contract IERC20",
856
- "name": "token",
857
- "type": "address"
858
- },
859
- {
860
- "internalType": "uint256",
861
- "name": "amount",
862
- "type": "uint256"
863
- }
864
- ],
865
- "internalType": "struct IVault.PoolBalanceOp[]",
866
- "name": "ops",
867
- "type": "tuple[]"
868
- }
869
- ],
870
- "name": "managePoolBalance",
871
- "outputs": [],
872
- "stateMutability": "nonpayable",
873
- "type": "function"
874
- },
875
- {
876
- "inputs": [
877
- {
878
- "components": [
879
- {
880
- "internalType": "enum IVault.UserBalanceOpKind",
881
- "name": "kind",
882
- "type": "uint8"
883
- },
884
- {
885
- "internalType": "contract IAsset",
886
- "name": "asset",
887
- "type": "address"
888
- },
889
- {
890
- "internalType": "uint256",
891
- "name": "amount",
892
- "type": "uint256"
893
- },
894
- {
895
- "internalType": "address",
896
- "name": "sender",
897
- "type": "address"
898
- },
899
- {
900
- "internalType": "address payable",
901
- "name": "recipient",
902
- "type": "address"
903
- }
904
- ],
905
- "internalType": "struct IVault.UserBalanceOp[]",
906
- "name": "ops",
907
- "type": "tuple[]"
908
- }
909
- ],
910
- "name": "manageUserBalance",
911
- "outputs": [],
912
- "stateMutability": "payable",
913
- "type": "function"
914
- },
915
- {
916
- "inputs": [
917
- {
918
- "internalType": "enum IVault.SwapKind",
919
- "name": "kind",
920
- "type": "uint8"
921
- },
922
- {
923
- "components": [
924
- {
925
- "internalType": "bytes32",
926
- "name": "poolId",
927
- "type": "bytes32"
928
- },
929
- {
930
- "internalType": "uint256",
931
- "name": "assetInIndex",
932
- "type": "uint256"
933
- },
934
- {
935
- "internalType": "uint256",
936
- "name": "assetOutIndex",
937
- "type": "uint256"
938
- },
939
- {
940
- "internalType": "uint256",
941
- "name": "amount",
942
- "type": "uint256"
943
- },
944
- {
945
- "internalType": "bytes",
946
- "name": "userData",
947
- "type": "bytes"
948
- }
949
- ],
950
- "internalType": "struct IVault.BatchSwapStep[]",
951
- "name": "swaps",
952
- "type": "tuple[]"
953
- },
954
- {
955
- "internalType": "contract IAsset[]",
956
- "name": "assets",
957
- "type": "address[]"
958
- },
959
- {
960
- "components": [
961
- {
962
- "internalType": "address",
963
- "name": "sender",
964
- "type": "address"
965
- },
966
- {
967
- "internalType": "bool",
968
- "name": "fromInternalBalance",
969
- "type": "bool"
970
- },
971
- {
972
- "internalType": "address payable",
973
- "name": "recipient",
974
- "type": "address"
975
- },
976
- {
977
- "internalType": "bool",
978
- "name": "toInternalBalance",
979
- "type": "bool"
980
- }
981
- ],
982
- "internalType": "struct IVault.FundManagement",
983
- "name": "funds",
984
- "type": "tuple"
985
- }
986
- ],
987
- "name": "queryBatchSwap",
988
- "outputs": [
989
- {
990
- "internalType": "int256[]",
991
- "name": "",
992
- "type": "int256[]"
993
- }
994
- ],
995
- "stateMutability": "nonpayable",
996
- "type": "function"
997
- },
998
- {
999
- "inputs": [
1000
- {
1001
- "internalType": "enum IVault.PoolSpecialization",
1002
- "name": "specialization",
1003
- "type": "uint8"
1004
- }
1005
- ],
1006
- "name": "registerPool",
1007
- "outputs": [
1008
- {
1009
- "internalType": "bytes32",
1010
- "name": "",
1011
- "type": "bytes32"
1012
- }
1013
- ],
1014
- "stateMutability": "nonpayable",
1015
- "type": "function"
1016
- },
1017
- {
1018
- "inputs": [
1019
- {
1020
- "internalType": "bytes32",
1021
- "name": "poolId",
1022
- "type": "bytes32"
1023
- },
1024
- {
1025
- "internalType": "contract IERC20[]",
1026
- "name": "tokens",
1027
- "type": "address[]"
1028
- },
1029
- {
1030
- "internalType": "address[]",
1031
- "name": "assetManagers",
1032
- "type": "address[]"
1033
- }
1034
- ],
1035
- "name": "registerTokens",
1036
- "outputs": [],
1037
- "stateMutability": "nonpayable",
1038
- "type": "function"
1039
- },
1040
- {
1041
- "inputs": [
1042
- {
1043
- "internalType": "contract IAuthorizer",
1044
- "name": "newAuthorizer",
1045
- "type": "address"
1046
- }
1047
- ],
1048
- "name": "setAuthorizer",
1049
- "outputs": [],
1050
- "stateMutability": "nonpayable",
1051
- "type": "function"
1052
- },
1053
- {
1054
- "inputs": [
1055
- {
1056
- "internalType": "bool",
1057
- "name": "paused",
1058
- "type": "bool"
1059
- }
1060
- ],
1061
- "name": "setPaused",
1062
- "outputs": [],
1063
- "stateMutability": "nonpayable",
1064
- "type": "function"
1065
- },
1066
- {
1067
- "inputs": [
1068
- {
1069
- "internalType": "address",
1070
- "name": "sender",
1071
- "type": "address"
1072
- },
1073
- {
1074
- "internalType": "address",
1075
- "name": "relayer",
1076
- "type": "address"
1077
- },
1078
- {
1079
- "internalType": "bool",
1080
- "name": "approved",
1081
- "type": "bool"
1082
- }
1083
- ],
1084
- "name": "setRelayerApproval",
1085
- "outputs": [],
1086
- "stateMutability": "nonpayable",
1087
- "type": "function"
1088
- },
1089
- {
1090
- "inputs": [
1091
- {
1092
- "components": [
1093
- {
1094
- "internalType": "bytes32",
1095
- "name": "poolId",
1096
- "type": "bytes32"
1097
- },
1098
- {
1099
- "internalType": "enum IVault.SwapKind",
1100
- "name": "kind",
1101
- "type": "uint8"
1102
- },
1103
- {
1104
- "internalType": "contract IAsset",
1105
- "name": "assetIn",
1106
- "type": "address"
1107
- },
1108
- {
1109
- "internalType": "contract IAsset",
1110
- "name": "assetOut",
1111
- "type": "address"
1112
- },
1113
- {
1114
- "internalType": "uint256",
1115
- "name": "amount",
1116
- "type": "uint256"
1117
- },
1118
- {
1119
- "internalType": "bytes",
1120
- "name": "userData",
1121
- "type": "bytes"
1122
- }
1123
- ],
1124
- "internalType": "struct IVault.SingleSwap",
1125
- "name": "singleSwap",
1126
- "type": "tuple"
1127
- },
1128
- {
1129
- "components": [
1130
- {
1131
- "internalType": "address",
1132
- "name": "sender",
1133
- "type": "address"
1134
- },
1135
- {
1136
- "internalType": "bool",
1137
- "name": "fromInternalBalance",
1138
- "type": "bool"
1139
- },
1140
- {
1141
- "internalType": "address payable",
1142
- "name": "recipient",
1143
- "type": "address"
1144
- },
1145
- {
1146
- "internalType": "bool",
1147
- "name": "toInternalBalance",
1148
- "type": "bool"
1149
- }
1150
- ],
1151
- "internalType": "struct IVault.FundManagement",
1152
- "name": "funds",
1153
- "type": "tuple"
1154
- },
1155
- {
1156
- "internalType": "uint256",
1157
- "name": "limit",
1158
- "type": "uint256"
1159
- },
1160
- {
1161
- "internalType": "uint256",
1162
- "name": "deadline",
1163
- "type": "uint256"
1164
- }
1165
- ],
1166
- "name": "swap",
1167
- "outputs": [
1168
- {
1169
- "internalType": "uint256",
1170
- "name": "amountCalculated",
1171
- "type": "uint256"
1172
- }
1173
- ],
1174
- "stateMutability": "payable",
1175
- "type": "function"
1176
- },
1177
- {
1178
- "stateMutability": "payable",
1179
- "type": "receive"
1180
- }
1181
- ],
1182
- "bytecode": "",
1183
- "deployedBytecode": "",
1184
- "linkReferences": {},
1185
- "deployedLinkReferences": {}
1186
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
contracts/service_registry_abi.json DELETED
@@ -1 +0,0 @@
1
- [{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_baseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"AgentInstanceRegistered","type":"error"},{"inputs":[{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"AgentInstancesSlotsFilled","type":"error"},{"inputs":[{"internalType":"uint256","name":"agentId","type":"uint256"}],"name":"AgentNotFound","type":"error"},{"inputs":[{"internalType":"uint256","name":"agentId","type":"uint256"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"AgentNotInService","type":"error"},{"inputs":[{"internalType":"uint256","name":"componentId","type":"uint256"}],"name":"ComponentNotFound","type":"error"},{"inputs":[],"name":"HashExists","type":"error"},{"inputs":[{"internalType":"uint256","name":"sent","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"IncorrectAgentBondingValue","type":"error"},{"inputs":[{"internalType":"uint256","name":"sent","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"IncorrectRegistrationDepositValue","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"manager","type":"address"}],"name":"ManagerOnly","type":"error"},{"inputs":[{"internalType":"address","name":"provided","type":"address"},{"internalType":"address","name":"expected","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"OnlyOwnServiceMultisig","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"OperatorHasNoInstances","type":"error"},{"inputs":[{"internalType":"uint256","name":"provided","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"Overflow","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"OwnerOnly","type":"error"},{"inputs":[],"name":"Paused","type":"error"},{"inputs":[],"name":"ReentrancyGuard","type":"error"},{"inputs":[{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"ServiceMustBeInactive","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferFailed","type":"error"},{"inputs":[{"internalType":"address","name":"multisig","type":"address"}],"name":"UnauthorizedMultisig","type":"error"},{"inputs":[{"internalType":"uint256","name":"agentId","type":"uint256"}],"name":"WrongAgentId","type":"error"},{"inputs":[{"internalType":"uint256","name":"numValues1","type":"uint256"},{"internalType":"uint256","name":"numValues2","type":"uint256"}],"name":"WrongArrayLength","type":"error"},{"inputs":[{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"WrongOperator","type":"error"},{"inputs":[{"internalType":"uint256","name":"state","type":"uint256"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"WrongServiceState","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentThreshold","type":"uint256"},{"internalType":"uint256","name":"minThreshold","type":"uint256"},{"internalType":"uint256","name":"maxThreshold","type":"uint256"}],"name":"WrongThreshold","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroValue","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"ActivateRegistration","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"baseURI","type":"string"}],"name":"BaseURIChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"serviceId","type":"uint256"},{"indexed":true,"internalType":"address","name":"multisig","type":"address"}],"name":"CreateMultisigWithAgents","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"serviceId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"CreateService","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"DeployService","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"drainer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Drain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"drainer","type":"address"}],"name":"DrainerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"manager","type":"address"}],"name":"ManagerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"OperatorSlashed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"OperatorUnbond","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"uint256","name":"serviceId","type":"uint256"},{"indexed":true,"internalType":"address","name":"agentInstance","type":"address"},{"indexed":false,"internalType":"uint256","name":"agentId","type":"uint256"}],"name":"RegisterInstance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"TerminateService","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"serviceId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"configHash","type":"bytes32"}],"name":"UpdateService","type":"event"},{"inputs":[],"name":"CID_PREFIX","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"serviceOwner","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"activateRegistration","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newDrainer","type":"address"}],"name":"changeDrainer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newManager","type":"address"}],"name":"changeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"multisig","type":"address"},{"internalType":"bool","name":"permission","type":"bool"}],"name":"changeMultisigPermission","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"changeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"serviceOwner","type":"address"},{"internalType":"bytes32","name":"configHash","type":"bytes32"},{"internalType":"uint32[]","name":"agentIds","type":"uint32[]"},{"components":[{"internalType":"uint32","name":"slots","type":"uint32"},{"internalType":"uint96","name":"bond","type":"uint96"}],"internalType":"struct AgentParams[]","name":"agentParams","type":"tuple[]"},{"internalType":"uint32","name":"threshold","type":"uint32"}],"name":"create","outputs":[{"internalType":"uint256","name":"serviceId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"serviceOwner","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"},{"internalType":"address","name":"multisigImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"deploy","outputs":[{"internalType":"address","name":"multisig","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"drain","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"drainer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"unitId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"getAgentInstances","outputs":[{"internalType":"uint256","name":"numAgentInstances","type":"uint256"},{"internalType":"address[]","name":"agentInstances","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"getAgentParams","outputs":[{"internalType":"uint256","name":"numAgentIds","type":"uint256"},{"components":[{"internalType":"uint32","name":"slots","type":"uint32"},{"internalType":"uint96","name":"bond","type":"uint96"}],"internalType":"struct AgentParams[]","name":"agentParams","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"serviceId","type":"uint256"},{"internalType":"uint256","name":"agentId","type":"uint256"}],"name":"getInstancesForAgentId","outputs":[{"internalType":"uint256","name":"numAgentInstances","type":"uint256"},{"internalType":"address[]","name":"agentInstances","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"getOperatorBalance","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"getPreviousHashes","outputs":[{"internalType":"uint256","name":"numHashes","type":"uint256"},{"internalType":"bytes32[]","name":"configHashes","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"getService","outputs":[{"components":[{"internalType":"uint96","name":"securityDeposit","type":"uint96"},{"internalType":"address","name":"multisig","type":"address"},{"internalType":"bytes32","name":"configHash","type":"bytes32"},{"internalType":"uint32","name":"threshold","type":"uint32"},{"internalType":"uint32","name":"maxNumAgentInstances","type":"uint32"},{"internalType":"uint32","name":"numAgentInstances","type":"uint32"},{"internalType":"enum ServiceRegistryL2.ServiceState","name":"state","type":"uint8"},{"internalType":"uint32[]","name":"agentIds","type":"uint32[]"}],"internalType":"struct ServiceRegistryL2.Service","name":"service","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mapAgentInstanceOperators","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"mapConfigHashes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mapMultisigs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"mapOperatorAndServiceIdAgentInstances","outputs":[{"internalType":"address","name":"instance","type":"address"},{"internalType":"uint32","name":"agentId","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mapOperatorAndServiceIdOperatorBalances","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"mapServiceAndAgentIdAgentInstances","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mapServiceAndAgentIdAgentParams","outputs":[{"internalType":"uint32","name":"slots","type":"uint32"},{"internalType":"uint96","name":"bond","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mapServices","outputs":[{"internalType":"uint96","name":"securityDeposit","type":"uint96"},{"internalType":"address","name":"multisig","type":"address"},{"internalType":"bytes32","name":"configHash","type":"bytes32"},{"internalType":"uint32","name":"threshold","type":"uint32"},{"internalType":"uint32","name":"maxNumAgentInstances","type":"uint32"},{"internalType":"uint32","name":"numAgentInstances","type":"uint32"},{"internalType":"enum ServiceRegistryL2.ServiceState","name":"state","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"},{"internalType":"address[]","name":"agentInstances","type":"address[]"},{"internalType":"uint32[]","name":"agentIds","type":"uint32[]"}],"name":"registerAgents","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"bURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"agentInstances","type":"address[]"},{"internalType":"uint96[]","name":"amounts","type":"uint96[]"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"slash","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"slashedFunds","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"serviceOwner","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"terminate","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"refund","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"unitId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"unitId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"unbond","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"refund","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"serviceOwner","type":"address"},{"internalType":"bytes32","name":"configHash","type":"bytes32"},{"internalType":"uint32[]","name":"agentIds","type":"uint32[]"},{"components":[{"internalType":"uint32","name":"slots","type":"uint32"},{"internalType":"uint96","name":"bond","type":"uint96"}],"internalType":"struct AgentParams[]","name":"agentParams","type":"tuple[]"},{"internalType":"uint32","name":"threshold","type":"uint32"},{"internalType":"uint256","name":"serviceId","type":"uint256"}],"name":"update","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
 
 
daily_transactions_new.csv DELETED
@@ -1,334 +0,0 @@
1
- chain,safe_address,date,transaction_hash,timestamp,from,to,value_eth,agent_address
2
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-09-19,0xb5cdd01edbc80bddf67edea2a88bc71d86372f1cc603c311da4b593e20376048,2024-09-19 00:16:41,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
3
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-09-19,0x3514a3d2a1e0462a11ebf4a64f2dbeb10405052fbb060d5b62b978ea601b1bd6,2024-09-19 00:17:03,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
4
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-09-19,0x98385000a78c7b85800e1551ed64d1ef4b31ce7a4e7dfa49a8d0800a3f143fdb,2024-09-19 00:17:23,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
5
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-09-20,0x583b8737470ba6912c373a03dc2429554f560dd4a5ab98f7449a815c12e7a447,2024-09-20 06:07:35,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
6
- base,0xa13DFc6DdCFF0B5B637e721ee83d6cF7E0676e73,2024-09-19,0x3c9bff22604410db277f50b2a2305ca93bf0b93e91e29ec34f4be15557e4a5bb,2024-09-19 15:48:11,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0xa13dfc6ddcff0b5b637e721ee83d6cf7e0676e73,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
7
- base,0xa13DFc6DdCFF0B5B637e721ee83d6cF7E0676e73,2024-09-19,0xc056887d8d0850dab2414be04894b8137b79f3a1e39185315fc41179564e8880,2024-09-19 15:48:39,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0xa13dfc6ddcff0b5b637e721ee83d6cf7e0676e73,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
8
- base,0xa13DFc6DdCFF0B5B637e721ee83d6cF7E0676e73,2024-09-19,0xdb88168a449551c5d61fab051c683bba16b52a438d0de6d8eab9f724caa1aebb,2024-09-19 18:33:15,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0xa13dfc6ddcff0b5b637e721ee83d6cf7e0676e73,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
9
- ethereum,0xDD58D70646e51eA332aE3Bc2D43CB336A3F50D3C,2024-09-19,0x766bcbe570f81eda83cdedc82574c6f1cfd076d967fcbb0e5aa7e0d530bfa89c,2024-09-19 15:16:11,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0xdd58d70646e51ea332ae3bc2d43cb336a3f50d3c,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
10
- ethereum,0xDD58D70646e51eA332aE3Bc2D43CB336A3F50D3C,2024-09-19,0x06d25b87f3322ac8f7e55f105d1e95a706453b166c36179ea8c595f3375500ec,2024-09-19 15:44:59,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0xdd58d70646e51ea332ae3bc2d43cb336a3f50d3c,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
11
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-26,0x2d77abf9ca4c5430b05b74767158b9d08f5135f985a34a19e4a6221e17959677,2024-09-26 23:26:43,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
12
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-26,0xb143af4766236055e4fb30912eb7c79f171e1a1d9f69936d53bc5bbe7f89108e,2024-09-26 23:27:03,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
13
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-26,0x38af0f7ef29b9b604b18fd68388da25ff04a5230a7d3da96d0e2850e3e5aa380,2024-09-26 23:27:25,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
14
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-26,0xad4bafff9ce4f0eca88928931143d4cda3a750f6e8a2155e3519d10d3f58ab6b,2024-09-26 23:27:47,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
15
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-27,0x6c320f41b7a137430474a785cb0006a189884d75f93e8941d5044b2ace0c6f79,2024-09-27 17:50:57,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
16
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-27,0xe1ca0e0f238a13e94d1b270992584924c87ced3acc666da9f808f4c789a2ae37,2024-09-27 18:16:49,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
17
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-27,0x1a713b1b719b9a64c95d706ef5f339e93d183fa3cfb01ed41f5d7ad3bbbaeee1,2024-09-27 18:17:11,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
18
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-27,0x0cfe8b5333e7bb213629a412e46742bfda3a7206366e4b0a02aa6a9fe1b13602,2024-09-27 18:17:35,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
19
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-27,0xca2b584bc17078eed70a91ad3c371f5b99945a97f1396516968bbcaa57454848,2024-09-27 18:17:57,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
20
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-28,0x4ab554c57c4aec076e3b18cbb57d0d928911ff4b4fb5e6856b5e7e7cd613f783,2024-09-28 17:51:31,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
21
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-28,0xed357b343ca86b7387c53a560568bed89f244f42e765879efb918f26139ed79e,2024-09-28 18:17:21,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
22
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-28,0x7ba1746736b944b47e175f3a87d9766b2e0406204ce228770f89bd5c0c6a1473,2024-09-28 18:17:45,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
23
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-28,0x03c98aef9e44614676d96481d58c3f6a65cc0518dbbe872998107421b73b0c19,2024-09-28 18:18:07,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
24
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-28,0x2a7837f17aafdab94dd4531f131995e53035ddae9a2e841a2175883296d3be89,2024-09-28 18:18:29,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
25
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-29,0x50195e96bf0fffbb03fc107a9dc7c8e6a8e3e56ce66b34ff07c6e9e03e1ff2f9,2024-09-29 17:56:05,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
26
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-29,0x6e8b7cde35dfa4e8685468efc4372a0ddc29dbe6402cdd7aa9558420e99b76d3,2024-09-29 18:21:53,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
27
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-29,0x3dcd18338ae0b8fdee620b5a624403b37acf7c0e9358337f223068ef803f8780,2024-09-29 18:22:17,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
28
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-29,0xd4cde9b125d7f1fb6a3a643d0f1dcecfedafa35a56b082e45496a57df1e630da,2024-09-29 18:22:39,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
29
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-29,0x58afed267747fd871fcde3d259789b11527c813734c5385f024bfd65c0d80477,2024-09-29 18:23:03,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
30
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-30,0x3603d6513b26de8f6e8fa30c068afd9357543559a44b500770eebb39d70a37bb,2024-09-30 17:59:49,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
31
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-30,0xa5829b7d23f43925c76c444d8b3982e7e36a5c772fa1e52a195f170bec7bdeff,2024-09-30 18:25:43,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
32
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-30,0xaac5a58e3c17589b3fc738875f2ca63d4b8a931cd4d83b605c1c63904b3a8c7b,2024-09-30 18:26:07,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
33
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-30,0x23123c823bcc0bd6e7debb6cf898c09f9633b307fa0362a5b695860fcd26556d,2024-09-30 18:26:29,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
34
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-09-30,0x2ef4002702b6c5e822b7f1eb56ef8868b485cd6133ea75e324f52d9d961e7f39,2024-09-30 18:26:51,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
35
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-01,0x07edf2c1d52bd085b483a4d78d68f66f3b960c2f8b00a116c75f356d395014a2,2024-10-01 18:04:13,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
36
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-01,0x002d1e1a828b3a5bf0b9a1aafea84e3b2aa1baa3821f365f56740d7d2ad7a728,2024-10-01 18:30:05,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
37
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-01,0x1c13d5371972b9483d3fec56a30bc3a3037192077d4aa53dea7ca264fec9713e,2024-10-01 18:30:29,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
38
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-01,0x3b27d64ff2953ecf83ad012f6491c6811c53e4a741d6f001418c2341a72a005c,2024-10-01 18:30:53,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
39
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-01,0xab518b126e28e79cadd4787192bddf14982e53f1147596537020e29b263ea06e,2024-10-01 18:31:17,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
40
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-02,0x03bed38602800fe269f10de492385ba526a84ec2cc7f9baa23619bd35da85fd7,2024-10-02 18:08:25,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
41
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-02,0xd22d313ad6e3182c458f622bca14d43bb8b9ca9048d26091314120eb89327ae4,2024-10-02 18:34:21,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
42
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-02,0x675ccf60999d108687723fbad766b4fe9c88fc4124922075f4eb66a419069f00,2024-10-02 18:34:45,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
43
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-02,0xae6738f676a6df8468dd35631a84e236196f31781e10f42b59a5f2e06ec8d621,2024-10-02 18:35:11,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
44
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-02,0x2f52592f281c86e3595310037a111a6aaec3a35e0c291197878f5ceffd060e47,2024-10-02 18:35:33,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
45
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-02,0x4177e1d24e370c07740cb39146afb5bb8d94ea86a7cc7d99a91418063a2e51e1,2024-10-02 22:47:59,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
46
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-02,0x67eef64284209d9ac03f57cdfa8f23ee9ad158ae12d92a3d5d70263c76d50311,2024-10-02 22:48:23,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
47
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-02,0xe1b09e4690cad0315a50f6e651a1e4f7e7636f089fc897b92fdf9de3efb88848,2024-10-02 22:48:47,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
48
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-02,0xd716065247d7d17f2d5df0b0884efb1429b9fd8429390ecb8c368139d73269f8,2024-10-02 22:49:09,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
49
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-03,0xbdd16cc721c952ac2db3dacb6084babeb8a13c17ba1dbb44a642f766ef806c40,2024-10-03 18:09:11,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
50
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-03,0x2296dbb131d0a670822fbd3f682d550aa40fdc039759041ba5a178050b0e6e9c,2024-10-03 18:34:59,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
51
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-03,0x15926312822752070924174de37cda4d3d8f03f2f0970b07ab04bc2e153f8f28,2024-10-03 18:35:23,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
52
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-03,0xa8d6ced16e7154fbcbbafb4959cb3ca2a772c5184280e41818c3e0a77ea99cc9,2024-10-03 18:35:45,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
53
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-03,0xd34ce2ec71e543c0d043ab81500450c7ba15784af08cd162041ab9c861dffcd4,2024-10-03 18:36:09,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
54
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-04,0xa2f5c1d49938c2c522053a6e580950e47f13cbd8969b584f759e7455aeab190e,2024-10-04 18:14:23,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
55
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-04,0x255f06717a24abbf83a3e38458b7f319131f49ea78b407f7cc3b730044d0f903,2024-10-04 18:40:17,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
56
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-04,0x7edc08a131c9c98d38a6ab7f9d8e9f712919ec20cc9d4039b81af0ae3d7b73c7,2024-10-04 18:40:39,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
57
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-04,0xf791d1891ab8c19cd188f36733e7b2283e0d9c03b6eb1fae8ec02cf8ce743ab2,2024-10-04 18:41:01,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
58
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-04,0xb6a6a874ab5990e90df1a82071653b4ae76849945493bfa0c138943bcb4ec27a,2024-10-04 18:41:25,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
59
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-05,0xca9355317dbe951c691cbc00663c285a2f7b2ebe6ba6c97d56323b43d2ca5b4d,2024-10-05 18:16:33,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
60
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-05,0x8bc424a0b63e30bb90eae9f3d8b39331e9eeab3dca931398c55e812daeec67aa,2024-10-05 18:42:27,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
61
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-05,0x67e4281c16ef8943674c5a754bfb9424bedc76cee05cb18689ee6ae00f813c16,2024-10-05 18:42:49,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
62
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-05,0x5727658de3c9c2203db2f902c2ab793acd1743d48c34976f94d69ace7da13c85,2024-10-05 18:43:13,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
63
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-05,0x3d0716682ef361878ec806fcd13312c2bbb3992f6d1579972bcda7f3a071d0c9,2024-10-05 18:43:37,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
64
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-06,0x950db9e6fb2ffef17e18108f78cdee3ea67e50fe1f77bf217ddc2187391878c4,2024-10-06 18:18:17,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
65
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-06,0x082ee7e680fbe729a6d4762f44937472341f0dbbab0246bd2453e7d6789a7a04,2024-10-06 18:44:09,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
66
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-06,0xb48ca890464e5f5a936a2b37356b45d6d899ba35ac2dd786ed32106979bd182b,2024-10-06 18:44:33,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
67
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-06,0x01249bb16afd6e82b29107db57fb010aa1566e952808826609097850f28d6e95,2024-10-06 18:44:57,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
68
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-06,0xb01eeefc632f63e689de5b5b46cdd98f8ef5c363c1c3ae72c7fb34bdfdecc9b0,2024-10-06 18:45:19,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
69
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-07,0x566a02173d6d0d03acfc0c3d460db03793af4b55465e8ab2af17b4db03e1225b,2024-10-07 18:19:49,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
70
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-07,0xb12acc7e1b984e34b35763ae63b82e651b12b984e8e0a4ef6d4962984f1e59c1,2024-10-07 18:45:37,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
71
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-07,0x9be5b67d4cdf13c079aa44674c30554cbe2d6545463e3afc6327822cd4a6499f,2024-10-07 18:46:01,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
72
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-07,0xdc5c6fd66965fa021891c3914a9d3138bfee598902cf82a7327222193accf47c,2024-10-07 18:46:23,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
73
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-10-07,0xc6ec42440f16143e30decf95356285ff2c996a80b7377324e2db27c28922ac6f,2024-10-07 18:46:45,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050e90bea65c9ba6416996bb6fffa8f925885d40
74
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-10-04,0xdf58f14196a0693e1d767996fcec10b487efa8f6758ece46b47af91ecc820249,2024-10-04 19:09:29,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d
75
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-09-26,0x3cffb2e0ad7a1112415619dc7cdf87d4549eaa1eb15f6f349be8ab69aae5cd23,2024-09-26 18:16:59,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
76
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-09-26,0x0da11730c3f7bb0cc1ab62939d76cdbbcadb0cebf1af74319fbb5061816aac43,2024-09-26 18:17:17,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
77
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-09-26,0xa15b9e0cc87e4bb10cdfacc978353396432ff1fe90d6518930e5f0793a8b37a9,2024-09-26 18:17:37,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
78
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-09-26,0xca171f90a61c0894165d9927c4ecd3353a3e042db4b2c795042be91331d6de2f,2024-09-26 18:17:55,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
79
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-09-27,0x34ea9a3d8e63d645df4ea9358f8bf66a90a4c8a3725fdfdc235d1b4287ee9c84,2024-09-27 17:51:19,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
80
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-09-27,0xbebdf9ea646631ff785d04a11b4a1f9f9d34a28d941fa64162a75e11759ceaae,2024-09-27 17:51:37,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
81
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-09-27,0x74ce4551cc81a4d8a6e550aeb20f321d05bc119383e07587f4cb4b50f288ec01,2024-09-27 17:51:59,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
82
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-09-27,0x907910b3d3a536beaa703ed074348883356b9226a00d840787afdc9a77cfe3fc,2024-09-27 17:52:17,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
83
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-04,0x54a5d52d4bae5f2a448b6518f70bc804bb12b7094c906ea1069c0533df0ce8a1,2024-10-04 23:12:35,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
84
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-04,0x356719746d140a01e0958320beae6c7d2fd3c665d3735740aea4b37ed94d8e55,2024-10-04 23:12:53,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
85
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-04,0x858c90cfc4558e5cbd1bc5ba9224d38c227a52238e9a01df145021338cef23fb,2024-10-04 23:13:13,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
86
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-04,0xe410d7236f09f4c4f2e520417c5d392b0c90f8e3c146bf59a150fb7cd2b013b4,2024-10-04 23:13:31,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
87
- optimism,0x5f0C4273Ff97ae91fc8D2fc8621b5E37a741d1b1,2024-10-07,0x64e43a3197333fc6efcd577837649b54e25c47ccbc9d00f91a11d368e25009e9,2024-10-07 11:57:33,0xa0ff35bfbd3c42e3afe29255742c7558498f5544,0x5f0c4273ff97ae91fc8d2fc8621b5e37a741d1b1,0.0,0xa0ff35bfbd3c42e3afe29255742c7558498f5544
88
- optimism,0x5f0C4273Ff97ae91fc8D2fc8621b5E37a741d1b1,2024-10-07,0xc0bdf9c0215249d766034fe8999569c6fedbc3e973386731f68e180c03d9a430,2024-10-07 12:12:29,0xa0ff35bfbd3c42e3afe29255742c7558498f5544,0x5f0c4273ff97ae91fc8d2fc8621b5e37a741d1b1,0.0,0xa0ff35bfbd3c42e3afe29255742c7558498f5544
89
- optimism,0x5f0C4273Ff97ae91fc8D2fc8621b5E37a741d1b1,2024-10-07,0x426ec7fe2dddc83ebc5ae45163841743465ed4f3a3a3fcd5e29d9224fb35fb1b,2024-10-07 12:13:21,0xa0ff35bfbd3c42e3afe29255742c7558498f5544,0x5f0c4273ff97ae91fc8d2fc8621b5e37a741d1b1,0.0,0xa0ff35bfbd3c42e3afe29255742c7558498f5544
90
- base,0xaC55EEb3fdAcfdFae78c62cAA58934900Ad54ED2,2024-09-26,0x1927d44a64dcb7d49a853c7aecae452009100433458a575d207b6fe564bcb254,2024-09-26 17:51:17,0x66749af7e077bfa30aca7c671d56f07e95304722,0xac55eeb3fdacfdfae78c62caa58934900ad54ed2,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
91
- base,0xaC55EEb3fdAcfdFae78c62cAA58934900Ad54ED2,2024-09-26,0x60bad359d0e6a3f07979c8370ba1226f6a5effdfe47c901fbb7e4b1f44c805e5,2024-09-26 18:29:31,0x66749af7e077bfa30aca7c671d56f07e95304722,0xac55eeb3fdacfdfae78c62caa58934900ad54ed2,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
92
- base,0xaC55EEb3fdAcfdFae78c62cAA58934900Ad54ED2,2024-09-29,0x5d3f63be96d60a282a0d5b8216e22101dfc384999a5b5a5de59ade764c59367d,2024-09-29 17:33:13,0x66749af7e077bfa30aca7c671d56f07e95304722,0xac55eeb3fdacfdfae78c62caa58934900ad54ed2,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
93
- base,0xaC55EEb3fdAcfdFae78c62cAA58934900Ad54ED2,2024-09-29,0xcd4986fc3a3406e2ae5a3246a72f04b6b3500f6074c64433582947606a202486,2024-09-29 17:33:43,0x66749af7e077bfa30aca7c671d56f07e95304722,0xac55eeb3fdacfdfae78c62caa58934900ad54ed2,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
94
- ethereum,0xe1EC43B9e4aF80c0b50579AB820f0Ca4304D4DB0,2024-09-26,0x44c17afd9cf22261dc7881c0b72453f532d724d87a6b8a0fc41b5ee524223248,2024-09-26 17:49:59,0x66749af7e077bfa30aca7c671d56f07e95304722,0xe1ec43b9e4af80c0b50579ab820f0ca4304d4db0,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
95
- ethereum,0xe1EC43B9e4aF80c0b50579AB820f0Ca4304D4DB0,2024-09-26,0x4e1b99d3a5457ac8e6598dacd0b163217965cc69fe9dbe97fb7f1829e7879a52,2024-09-26 18:28:59,0x66749af7e077bfa30aca7c671d56f07e95304722,0xe1ec43b9e4af80c0b50579ab820f0ca4304d4db0,0.0,0x66749af7e077bfa30aca7c671d56f07e95304722
96
- ethereum,0xb0830c65499ff2A25D10D895970b152193b13FCf,2024-10-04,0x2d6cd40bc7862c05d8a1cf26b473a58aab79b322d98fecd304b261eda46ada20,2024-10-04 18:56:35,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0xb0830c65499ff2a25d10d895970b152193b13fcf,0.0,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d
97
- ethereum,0x654F17A32fE4ebAEBD6A0669AFD4f7392A7A47BE,2024-10-07,0x7928005ff789c7f3615ab40a8368695be812835ddba4b0645bc4043dd9ec5ae5,2024-10-07 11:45:59,0xa0ff35bfbd3c42e3afe29255742c7558498f5544,0x654f17a32fe4ebaebd6a0669afd4f7392a7a47be,0.0,0xa0ff35bfbd3c42e3afe29255742c7558498f5544
98
- ethereum,0x654F17A32fE4ebAEBD6A0669AFD4f7392A7A47BE,2024-10-07,0xaf3e92969ca37a7999c81c509d33c5b50b2f212574752c22916cde6f7c58c49a,2024-10-07 12:11:11,0xa0ff35bfbd3c42e3afe29255742c7558498f5544,0x654f17a32fe4ebaebd6a0669afd4f7392a7a47be,0.0,0xa0ff35bfbd3c42e3afe29255742c7558498f5544
99
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-08,0xaee13886847dc95d2e608ab7d56f9630dc59122ac807168f9ca952c6163c5a81,2024-10-08 15:32:07,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
100
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-08,0x1d913feaa55fc772cded5a1464e30b1a162d4d81ead9c353498ba272678b71ab,2024-10-08 15:32:27,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
101
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-08,0x9bac7a0e70877600504770e9baab57aca80e605ef154c4023fb58ece09c5cbc3,2024-10-08 15:32:41,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
102
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-08,0x84bde757adfa865b03b5a3aad8c535c80de02e89e679a79408c613ce68f7e53b,2024-10-08 15:32:59,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
103
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-13,0xdc6264296464eec917a29cfa499671e1101b76493199a9d2d708fac9ed7dc2ad,2024-10-13 00:28:39,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
104
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-13,0x1e64654a1ca673846f73da3af87e9b64aa201794c2739687fe19bc61a1856eee,2024-10-13 00:28:57,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
105
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-13,0x621252dc18c34d105930349c91c717b20b15942ea9cf559f3fd873f9ee4e2a6f,2024-10-13 00:29:19,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
106
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-13,0x9f59766b0e38e91500646912786b19e2e09d1c7ad76834468ae9d83a68fc482d,2024-10-13 00:29:39,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
107
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-13,0x3c322ee250f3fe6a003920d58054e73950706a803f93a3f45bdf87c3cdf89d9b,2024-10-13 18:29:23,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
108
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-13,0x44068297bf896955f23d92757957292f066446efb329d3c9771ba220d5556321,2024-10-13 18:55:27,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
109
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-13,0x3f0b301a85002d1c89e912c5fb59004dbcb425eaa30df4582a672db0b4d4c376,2024-10-13 18:55:45,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
110
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-13,0x2aa1b5207df4b04baec42408893544f59c977e34048b445aa7172def84f89c8a,2024-10-13 18:56:03,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
111
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-13,0x304741cf12f71f523ef9d4f9a166f9f123e251c8e486cd73d0f5ca9152587ea8,2024-10-13 18:56:23,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
112
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-14,0xa2c5c1805397e690208aa98456f20e41718077a151a03fbfddea6b1e870a428e,2024-10-14 09:31:55,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
113
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-16,0x8c5fe6db3b2e873853884d5855f4d495aa7f3740edb15ca38dd1991f350efbf2,2024-10-16 19:44:05,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
114
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-16,0x12f7bff8f9124c87bb5f024d3f6a7408541cba2012ab5cf91307f6bbdebc917a,2024-10-16 19:44:25,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
115
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-16,0x890bab71cb998b2ce20bf726a399935234feaae1634fff1379cd6b176eeedfee,2024-10-16 19:44:45,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
116
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-16,0x456d9007e0d58381f0368c41c83f8ae2e8ac98439decfd91ab401436ac97719b,2024-10-16 19:45:05,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
117
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-17,0x58a8b1331e4f65b3a0500931b968867a89c9c09ea51ca6633fc5ad607535aaa3,2024-10-17 18:43:21,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
118
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-17,0x3cefa7ad4c42a59b536f844f2523bf9b9a083de4ec2e6b1e03fc239aa80f2ab9,2024-10-17 19:09:15,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
119
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-17,0x269a707d5e892bd9970261cc7c46c9fc504b18aecf115f5ebdb274959d0b3ebf,2024-10-17 19:09:35,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
120
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-17,0x7ffeabb33e2e802e21ec2a65e994c020d22b29944bc740f924e549deec34ce26,2024-10-17 19:09:55,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
121
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-17,0x14d3ed4f990013913f74ca3eebcc0ae5e4a2ba1092f11292009761977b202d63,2024-10-17 19:10:15,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
122
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-18,0x532448cdfbeff3df4bb62f481eaffa078b2c5adc72b69642cfb69079665ff522,2024-10-18 18:45:19,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
123
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-18,0x713bc3c78922b7f1106daa1e655472b9b026368545fd768c9ea7b92309947334,2024-10-18 19:11:19,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
124
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-18,0x95a42baa217807385097803f3a143fffb20b746e90696c8a46b047e7c7e6e7f3,2024-10-18 19:11:39,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
125
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-18,0x9367d6e66f04fa982057b71015105a71d62e412a8f15893ee94e4c1acc94a6ee,2024-10-18 19:11:59,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
126
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-18,0xa0436d809e9fc7181f96389b233e9205cde9b323f0112b228af72d651a81c9d5,2024-10-18 19:12:19,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
127
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-19,0x4bcd3ce86be93a62fb338feadd3a4ea2446de2d8a200ad4c041b141a19c10201,2024-10-19 18:47:51,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
128
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-19,0x740660a2af7e3109e4790e5d63c2044cceda76f63447b6bd0cca721113dc84f7,2024-10-19 19:13:43,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
129
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-19,0xbdf047bc27897dee5bbf00437cb7e03ae9eac0928fd749341c92c10d437d9dd4,2024-10-19 19:14:01,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
130
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-19,0xf34f26b8357cc5ef4d274a68fb7ab4bfa74c0548a8c534304cdaaf0460b204b4,2024-10-19 19:14:17,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
131
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-19,0x6c6747478eda1d352e6f6c7178dbd75123870574047730e418a4f0a3fb6c1cf4,2024-10-19 19:14:35,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
132
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-20,0xa2879a875d64fead59ca4129aa717104c4b33b2a762187e1e48c7bebb6c0b353,2024-10-20 18:49:09,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
133
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-20,0x423585ea66b5b290b569dd8b84f56b7a9e8d330cb06f3701db163791fcff2714,2024-10-20 19:15:05,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
134
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-20,0x672ec755a343763daa8b687f01e71c1b088815a41192c4aff62d68b801c956c5,2024-10-20 19:15:25,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
135
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-20,0x434e1ee73b31f0a559c24f57c6914346d9a44fa388a75bf130204e75800a61cf,2024-10-20 19:15:47,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
136
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-20,0x68f45e463facb02da1963b43646341a90755c539f767e6ee6adf70513d051c03,2024-10-20 19:16:15,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
137
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-21,0xb89c76c2eb8d73b8998decea57c8e3e77730e0aacbb469b7708973ee4bc27cf8,2024-10-21 18:49:31,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
138
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-21,0x90b00da8ae4eb267161baa3e33a98bbdb23749df77e6b66733c5efaa45b1d178,2024-10-21 19:15:27,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
139
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-21,0xa000f5cb6f82557048c04256b173c17ad077524f3adbec9bf011a246d6a0f2e1,2024-10-21 19:15:45,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
140
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-21,0xc222a959b5246a4fd564d3bc5f282b618e2c16960f671b93bb28ab23f23f7fda,2024-10-21 19:16:05,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
141
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-21,0x47c0ab659de596bc52edc299a957ae2504fc203852a9eb697936b5155aff3e3a,2024-10-21 19:16:23,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
142
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-22,0xf4075fb335e25c08d3ef7761e837624ba584391f5c8278ee871d1bffde785ed2,2024-10-22 18:54:15,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
143
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-22,0x8bbfb98576ebcd9d1ce5d3e94624b60daa0b2b4be4aadeb3f1cf3e33c816fe3d,2024-10-22 18:54:33,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
144
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-22,0x913ff32263bace6c07f713c63bc9328d57cabfac0f39d741ad1f31e7770e0e35,2024-10-22 18:54:53,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
145
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-22,0x8b1d52b325e6fc187124a7176a34d2fdf57761890a4d45f13eef99f6111cf7cd,2024-10-22 18:55:11,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
146
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-23,0x93bcad48afc8a95d24eca58f220753f0534e60ad8b4690d022540834471feaba,2024-10-23 18:54:11,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
147
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-23,0x146f693496b5cf221180b709351b7fbc39c5a428637bc06c87f4a5904ce84821,2024-10-23 19:19:59,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
148
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-23,0x9896ff4ee5456131fc4949f1c4e01acc013751a1763bbf103562caef2515cb1d,2024-10-23 19:20:19,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
149
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-23,0x320182ea16bfb101d94e092338a993ffcfc92e55cc46030e18198e845ba8794c,2024-10-23 19:20:39,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
150
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-23,0x76ba277dfdd9bef45034b33f074da67a8626fab5bb147eb21088a881ecbeef0c,2024-10-23 19:20:59,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
151
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-24,0x264fa35911f00f1a1b513beb2f32d4d5c281cb00493f96894cf981d881d840b1,2024-10-24 18:58:45,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
152
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-24,0xe77ee3efdb94a400fbb9e5413561bc9625f676a7bc599a3cbdf62096bcd012dd,2024-10-24 19:24:37,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
153
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-24,0x518f90668a03279ea9a67e57e1f77300aa9e551267e24e3c74d488ef031dec61,2024-10-24 19:24:57,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
154
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-24,0xe74cf41e7d6809c0833ebd576464f0cb3d909689c050b809aeab68eec748c0e0,2024-10-24 19:25:17,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
155
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-24,0x360ef20f43eb93b89ffa27f5c8d8172d7cef3736fa6760c136f3f6c6069d1f15,2024-10-24 19:25:37,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
156
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-25,0x1ef28e781f3d79a97f68f65ee074f4d5fc2017b5cd873de4c9b8aa14481aceba,2024-10-25 18:59:59,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
157
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-25,0xd236de3085624b6076c806dd047510a045427eaffc2a442fd0f519f9d9634e85,2024-10-25 19:25:49,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
158
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-25,0xee4dabd6cb62b7edcdcab7bd57f6ac5e20d525387a25f16758cc8d1ecd19f73b,2024-10-25 19:26:09,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
159
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-25,0x5b6224dc73111cfd98476df1b0dd985cad877898bbd93b6e5ef08f6f72853c8b,2024-10-25 19:26:29,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
160
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-25,0x05317fd0de5f014271756ba00fb4ee549bda6b04c6990815fdb380cbbbbc6d09,2024-10-25 19:26:47,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
161
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-26,0x217f3af788804ae6e562907d9521f723954a33600f414672653ea27580068465,2024-10-26 19:05:07,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
162
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-26,0xa2b613d431ca658ac1021ff3c23a68a0de4cd0b8a4e66b19b9af3b6150f9d516,2024-10-26 19:30:55,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
163
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-26,0x66c7c50ad857ef0d2a85ef5995c66a03be668354be4cb3d95e45528a21536a38,2024-10-26 19:31:09,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
164
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-26,0xfc2f9428e250fbe061b0654d93d3a11357aded6ab8a77e3909dfa81ef46441ba,2024-10-26 19:31:29,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
165
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-26,0x375a00e2b2a0b054cc05720614d93c507de8e2b5e2172c7a8634e0657ccdc6b8,2024-10-26 19:31:49,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
166
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-27,0xd3cb6bb7d734ffda7fdf1fb5acbf59de43ec0de8029493598ceb66eee64c826e,2024-10-27 19:09:05,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
167
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-27,0x9fb681cfbd404e934da5caa9501ad344f09cbf7392da91e877aa9beaa79f8d5b,2024-10-27 19:34:53,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
168
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-27,0x5531415dba71092cca3d3692f881825c21494b4a805a76fdc2d8cc241ba21671,2024-10-27 19:35:11,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
169
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-27,0x88ebc564c11d0d965d695ccef18b6f74a8f912845cf881b804fe4ac40fca4496,2024-10-27 19:35:31,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
170
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-27,0x0fc54a1c69c596af4e206d8f75785fb20f1a6e2045861f859b7645f5b4f0386e,2024-10-27 19:35:51,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
171
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-28,0xa00031a4011c14d0bbc21708512ef70a5a2a5d375f030382672538a793127589,2024-10-28 19:10:33,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
172
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-28,0x8d02c3c70e6ee4f3b3b87ce24c97c00b0d7e1b6491fde0c57a31a99b27174f99,2024-10-28 19:36:29,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
173
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-28,0xeda6184920bb594ad0449b6fe9762cc3444684df691e722963fefca8f2626fe2,2024-10-28 19:36:55,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
174
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-28,0x95477eafc145e1d5b1f418266041acf086e5ef68d3e9cde3ab04bb3c26d87824,2024-10-28 19:37:15,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
175
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-28,0x2fecdf097c478a3a9c95fe2388690037b4d36deeedc8e43fead5301821216e64,2024-10-28 19:37:35,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
176
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-29,0xe01b84d49c84e01c5715a9f8c4459126758201b57d224a6f82e76e15085a71e4,2024-10-29 19:13:05,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
177
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-29,0xf02f9f552b4034c184b13da263df2fb0d1f2d646df7add4b125a196079b2abd3,2024-10-29 19:38:55,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
178
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-29,0x3938b5bd5b140b0b65d377727634264f1d6bf5406f7541c542151eb5d4bba689,2024-10-29 19:39:15,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
179
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-29,0x9026951710b3a50c1f810aae614d91e36a0cff079a095d5665fe075a9043cc55,2024-10-29 19:39:35,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
180
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-29,0x223eb50fcfe4197559b263fa627e836c3eb34ca5aed52debdc10c1f7cab43c9d,2024-10-29 19:39:53,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
181
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-30,0x8582916cc4cebe710368798b63a258579e191aa8458ef3ab053d6bd94742ca66,2024-10-30 19:15:53,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
182
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-30,0xd0e43873574f9b5d2ebf2e574e8df23b3e28848f38c9d87d05ff4f049e677af4,2024-10-30 19:41:45,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
183
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-30,0x2df7a6b5e288b33fbf5d6d781d303bb38eccd3b524f363ae1af3588c04b0b7aa,2024-10-30 19:42:03,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
184
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-30,0x28c95deb4a724ce96f75db7e571f33f76246c7820c4b6c3c7676b99535abc49a,2024-10-30 19:42:17,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
185
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-30,0x158bb912fb5c9fb2cc0dbe39403ebd89af6c43ce1a4f52967a56aec88d1b75c5,2024-10-30 19:42:37,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
186
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-31,0x040dc97e7862c2c8171404a551e1a384ece5660a57e954eb74854dacf9c61fb4,2024-10-31 19:17:05,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
187
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-31,0x9da0aac3d1fdc020b59a9189477a0da83ed977fffb95621ec44217144cadf551,2024-10-31 19:42:51,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
188
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-31,0x2f33cf3b588fc7c64f35de8fc59037f4d0adf1a0d3eb51d4252a21cc50c8eb7e,2024-10-31 19:43:11,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
189
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-31,0xc31f680881727987cd0acbb1a41cfb4181893e302a8efdca6fe8ea7de0a41099,2024-10-31 19:43:29,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
190
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-10-31,0x85e404a4890a59a6effaecc5264d520c29e390507ac3928ccf2315e3b5fe793e,2024-10-31 19:43:49,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
191
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-01,0x1802f2651936e4546c66de5da6938e44b87264441b7474cd4467550c404eec22,2024-11-01 19:19:17,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
192
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-01,0x7ad26e34cfb57041448e8fe66e13e4b7b4ef455420fb991cc7b80173156c63f3,2024-11-01 19:45:07,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
193
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-01,0x68fb23d59aee63bd0828eeacba23401f9e8f4c3cfe14c4ee68a0770232fd0c6d,2024-11-01 19:45:27,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
194
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-01,0x6782b12f2d402145479c2d924b23f2192cc28785e56be161606081de2fde68bf,2024-11-01 19:45:45,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
195
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-01,0xe07a8e535f1bae4b0a24069cefa0bf27cde63fb62adc6ca60a59b1f497d935a6,2024-11-01 19:46:03,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
196
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-02,0x617248afac580453cc0d28a3f15797f8834e814e07c562c7647418c2717fc3a1,2024-11-02 19:21:25,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
197
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-02,0x85f67b51bca14306a725ea35185273710f3bc67425394c949d96ddd9b58bd3e3,2024-11-02 19:47:19,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
198
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-02,0x5f736fd5a5a858e89a982a294810b0e394d729cf159f69f72a6d4f8bbf819372,2024-11-02 19:47:37,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
199
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-02,0x88d799d9b24ce3b9c2022127b1a9fce4851089fac6b589d35dc1fe636554eb72,2024-11-02 19:47:57,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
200
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-02,0x5318d7a208a8656d937407312e98832708116a215c30b9aa6bcfc02be714e463,2024-11-02 19:48:15,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
201
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-03,0xb4c218e08e15d67bdce233db280b2c39fbb12eaf6868b3f4fc361b60f92dc3cf,2024-11-03 19:23:19,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
202
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-03,0xd2d2cfeb9a5c6cf7a2cdc8598702a45146da4579f800628499e04189ea3de559,2024-11-03 19:49:29,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
203
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-03,0xcd0efd92eefc80a14e8cdfd866fe663625ef810eccd0470399482847551e274f,2024-11-03 19:49:49,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
204
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-03,0x4b776be31cc433cf87cf5b71028711a432a98ad9cef38a9954f9f8c7b30fe0fd,2024-11-03 19:50:09,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
205
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-03,0x403310590961833ed5e0232ccd9e465d0bea968c1ac9ca8eca409c692fa5faba,2024-11-03 19:50:29,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
206
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-04,0x7a53660c46a06ce181c632c18f982bbad090d0c392b14d563c451525120ce91f,2024-11-04 19:27:41,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
207
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-04,0x9f1e5fe60f6582d654d3fc157d7e54ab3c7e90f1a5cb5f9d1bd2fb2da03d7118,2024-11-04 19:53:31,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
208
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-04,0x8b7c93c5f72a7fb1be439f5dcfff758ae7734278c86eb0bb942a30ce6d59d9cc,2024-11-04 19:53:49,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
209
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-04,0xa5d6de28b1f0e6ff99acd54d4d27933b75ef41477e2d3d985fee6d7bad107fb5,2024-11-04 19:54:09,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
210
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-04,0xb27813f63f526a86f3f219c25c2d93a0013fc75b1830647bfec622eeddcf337f,2024-11-04 19:54:27,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
211
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-05,0x6ff2f5c8fdb1ff1cdcc1e2af37c8584f0876fcf2eb08c07913f5b8320f5a98f0,2024-11-05 19:29:29,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
212
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-05,0x31991c9e4c950e833211a6088f1a92fe48beb77aec9ff91d052348982529f0c9,2024-11-05 19:55:23,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
213
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-05,0x6a49f3b11d3b74400e6226377fab2f120e4ae1c612cb543038012449481c9c96,2024-11-05 19:55:41,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
214
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-05,0x74cd714e4161130f3f65722c2d8320119a73b9b4903e35ef4c33262b0c8de825,2024-11-05 19:55:59,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
215
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-05,0xc2dc3ffc66d1c310f93449a456dd3e753940f5468c09daa0788435755a7014bd,2024-11-05 19:56:21,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
216
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-06,0x50bef7a9a824cc2f0bb71f0e18a494d31ddf9940eca724414155cc7337f4fb3a,2024-11-06 19:31:07,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
217
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-06,0xa57c0b6fa67f07d324fa72730e30246915fa2d8ad624c159e3f64b0135707b52,2024-11-06 19:31:25,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
218
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-06,0xfcfadc6d2a48eb5a1ccbe37896c5ad40fab88eb68b54313d2be7270f64cb3606,2024-11-06 19:31:45,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
219
- optimism,0x65F0fDeBCe6E62c195A3Bd5f2447c87991BEbFF1,2024-11-06,0x3818bfd6ec999bf226e75c57b02976bcc96ce3bb0fb1fe7bd8b9c3a4a3b9dd7c,2024-11-06 19:32:05,0x66749af7e077bfa30aca7c671d56f07e95304722,0x65f0fdebce6e62c195a3bd5f2447c87991bebff1,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
220
- optimism,0x5f0C4273Ff97ae91fc8D2fc8621b5E37a741d1b1,2024-10-08,0xc1cdf7fe5e6cf49304dff2c6f0e21c2efe6eaee974397569a5bf6d8a07f25278,2024-10-08 15:43:15,0xa0ff35bfbd3c42e3afe29255742c7558498f5544,0x5f0c4273ff97ae91fc8d2fc8621b5e37a741d1b1,0.0,0xA0fF35Bfbd3C42E3aFE29255742C7558498f5544
221
- optimism,0x5f0C4273Ff97ae91fc8D2fc8621b5E37a741d1b1,2024-10-08,0x4bd5c053da25974ede509aece519ff525c8021498ac001ec733f5f10a8ce2a8d,2024-10-08 15:43:49,0xa0ff35bfbd3c42e3afe29255742c7558498f5544,0x5f0c4273ff97ae91fc8d2fc8621b5e37a741d1b1,0.0,0xA0fF35Bfbd3C42E3aFE29255742C7558498f5544
222
- optimism,0x5f0C4273Ff97ae91fc8D2fc8621b5E37a741d1b1,2024-10-16,0x2f2befe741ea2f67d1866ad2391f4449a25a24b282bb55a2671aff77ca4c0f8c,2024-10-16 17:26:29,0xa0ff35bfbd3c42e3afe29255742c7558498f5544,0x5f0c4273ff97ae91fc8d2fc8621b5e37a741d1b1,0.0,0xA0fF35Bfbd3C42E3aFE29255742C7558498f5544
223
- base,0xaC55EEb3fdAcfdFae78c62cAA58934900Ad54ED2,2024-10-14,0xc0b652ed397ccf290383de61e39564df58c60ff0838e23db7fbb16e39ab92278,2024-10-14 09:31:17,0x66749af7e077bfa30aca7c671d56f07e95304722,0xac55eeb3fdacfdfae78c62caa58934900ad54ed2,0.0,0x66749AF7e077Bfa30aca7c671d56F07E95304722
224
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-07,0x777101ac049d7178f440dd563d278893224bd45855b2f0dac85018b800e4337b,2024-11-07 19:31:01,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
225
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-07,0x1ce9cb93c284ac98cb42308f7433028d96305324f9445defc30070e6c3b95a47,2024-11-07 19:56:59,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
226
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-07,0xf8a4aafdbc7e2bcc0f72ff24d3c3da0ab2edb09dd21716d2e51741e9a7f5350f,2024-11-07 19:57:21,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
227
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-07,0x01dd25efc5796387f21a4f590344878015b1021c03fb809a8b91752056953f37,2024-11-07 19:57:45,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
228
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-07,0x86a213083f6e577c3a8f9a5d1f594bba22353ced0cf73167b8a34bc4153132fd,2024-11-07 19:58:09,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
229
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-08,0x56c0b7952cbdaf6c5ba89f8977afa051974318d8c93f42c350c97e23f3651d59,2024-11-08 19:33:53,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
230
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-08,0xab1c9ad2d6f3376fff1fb2891850b649730e530ae8202c42d0d0154f5fe4b747,2024-11-08 19:34:17,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
231
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-08,0x21ccbd21afcccf5afa8fc866bffc76d51baa5c2798ffa279ef0cbab1c259f59a,2024-11-08 19:34:39,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
232
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-08,0xc52544163c4c5a1ff493644ac036b8e5caedd85fd9f4d84ea49e9c2ab5877256,2024-11-08 19:35:03,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
233
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-09,0xd9cd34a677fb622c1440fe476358d404ebe67ebc6117a8ad0834c7ee5713aaa6,2024-11-09 19:32:05,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
234
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-09,0xd07fa7d843ff1796bec23c9e008161850332dcb58407e0500cc7d59f53474dc1,2024-11-09 19:58:09,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
235
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-09,0xc721084ac89d3a22711acd9633724820dd417a2b16b7958d8aa4077a8788e679,2024-11-09 19:58:33,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
236
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-09,0x2071f7a06240e0c2842b565256c18979b700e4c6680185883a67237366fbfffc,2024-11-09 19:58:55,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
237
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-09,0x22034096371502cce1c45cd5ecf19adb3da4719d22e7fb3d9bb70f6ce1fbf817,2024-11-09 19:59:19,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
238
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-10,0xd2020ffab1ee7b67911af3755cc093dc22c374bc4b2acee2c9a3cef80dfa35de,2024-11-10 19:32:17,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
239
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-10,0xd3216528b367cb9a04872b0796e9eea05169e1dbeabe0dfb4bcca7c5de48e52e,2024-11-10 19:58:17,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
240
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-10,0x205ce434790c2c5d36e53ee197068b116b2a6d8ef15ac551b687494a8c66725d,2024-11-10 19:58:39,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
241
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-10,0x31683592718cbf103abb6d5b6b77a6167c7913474af170a325942e3ef74b8515,2024-11-10 19:59:03,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
242
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-10,0x12c5980a598ffca619769974276eab2cbb6a7097afa99e0e69148c7c8d80c6d3,2024-11-10 19:59:25,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
243
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-11,0xa9b4a40a6d089564307472fb6c420931ec25e22c9fa5375242fc881eb8f9f2c7,2024-11-11 19:33:37,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
244
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-11,0x9fdaf94fd3ecdd6310afa58d90c1f79870c7baff10b0dd7b70145fa692750c6f,2024-11-11 19:59:33,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
245
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-11,0x10dec24ccf339fff6aef309ac04968b8c80d38a6238849610b5251dc4e786fe6,2024-11-11 19:59:57,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
246
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-11,0x0576b6ff2a0bc3ee6a6baab7de7ceeae1e095c28517c1fbb8f04913223b7047c,2024-11-11 20:00:19,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
247
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-11,0x36f176f26e8cd484be0c2ee53b2c71196f5b3a59651ffc99926f657c94579310,2024-11-11 20:00:43,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
248
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-12,0x3944a2a9969310ce2062cd55008aaaca2e19c7224d011b9962981f8b1bab2e49,2024-11-12 19:36:15,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
249
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-12,0x4a7622409194f23b2c6a883845650e699aaa8a3041c95adc35b004522ad58fdb,2024-11-12 20:02:11,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
250
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-12,0x1613786a3bedaa3bb0a9c4e5689c82f70e915879ee03425c4e3132bfa9ff0baf,2024-11-12 20:02:35,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
251
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-12,0x7690b38342c7ce3b2083e5aaa143f07398fcd9f4142c752509c52e52f3cb58ee,2024-11-12 20:02:59,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
252
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-12,0x8396385dced898d0991a3f14db45fe7f238f05bb8ceb44dac8c1bebf68501e73,2024-11-12 20:03:31,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
253
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-13,0xc330e488ee6344ddf38e525dd4d985ca5f29cce4573bb5ad2cd4cdb287d4ee34,2024-11-13 19:38:15,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
254
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-13,0x79fa8a612cff5c3139388df45c803c1a592d2da541827706e8fe66e438d92fca,2024-11-13 20:04:13,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
255
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-13,0xef31d42f1c4f877cc78d84d50a510685a1d715e93439fc3a991a56e62be65e67,2024-11-13 20:04:35,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
256
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-13,0x729d1797f1710774c3595c02adfa04934efd60df3f89164f10d6826f8ab3c954,2024-11-13 20:04:59,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
257
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-13,0x278e630b6c199be3f8f2fe3c73797b27ad79a9d9fb2ff8016ad5e8849fcf166c,2024-11-13 20:05:21,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
258
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-14,0xe331f57282bf964b830fe5e073aecc528d9b48a26ca78c56ca37338e7c700bfb,2024-11-14 19:42:01,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
259
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-14,0x11995578ec6941fa53d18827cfdbb944e9e2f88b589c70fa0a865d702d44c8df,2024-11-14 20:08:07,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
260
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-14,0x7242a09272ab2bc786fad9303b1997c6eddf328f9bbb32b41912aaae3e480d14,2024-11-14 20:08:31,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
261
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-14,0x51ae1bc6849d27792e8cd3dfff6f34cec86fda63e82c506f28487f5d9641d17c,2024-11-14 20:08:55,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
262
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-14,0xff4b107ff5aaa6c29c31eeeff51000a58d935699598431cfcbea71e1936e9351,2024-11-14 20:09:17,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
263
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-15,0x204cb142eabe270acb7a687790153791845cbacbb07e8fd79237e05f456fd7ff,2024-11-15 19:46:41,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
264
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-15,0x7a72b3dac5dddd4543bee32be0efd2ab174b25d0cacc59c977285af514bebf61,2024-11-15 20:12:43,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
265
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-15,0x0c25b21a56666d88af1c8f7eaa263a8a922e9a4aea2bfa40d8b6afe503b7457b,2024-11-15 20:13:07,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
266
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-15,0x2550ae44cba79f2ad31e8feb6e923a0da42baadb9b52b37a6f84d14b5410a26d,2024-11-15 20:13:29,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
267
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-15,0x547ffae6c6b3a7fc2c075cb234dab5ddc28faa128cc82692f60cfba0f4c35baa,2024-11-15 20:13:53,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
268
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-16,0xcddac104ebea92f74253beb1244b5c039be5f348bfa08c91a9abc0347b47eb0d,2024-11-16 19:48:27,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
269
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-16,0x02e88c9c1f924a9c1be8a1e5ff5d5ad8bf779677a2000d405dee07facb38c2e2,2024-11-16 20:14:25,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
270
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-16,0x42f9d2f3ebbb9bad2b46da72fe4e0e6301ece9dfbf55d20a7c11dbe376acfff4,2024-11-16 20:14:47,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
271
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-16,0x4ad796b2bc0531e17b225aa504270b08aa1cac6bf359966c9ee53359102a9c0b,2024-11-16 20:15:11,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
272
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-16,0x6951b25e4610da136965392782d7282699d2c6e25246e8684a42c5a4f2c4724f,2024-11-16 20:15:33,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
273
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-17,0xf1d0b6ee4386cf5480047e8558ae039562b9c6c28bea6e7b7ec38afe2adcef1e,2024-11-17 19:50:11,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
274
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-17,0x960f99b7ee419fcc4843112280b0874622e08f5e248a9ed84e3509a2c82ea647,2024-11-17 20:16:09,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
275
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-17,0x8688f3f153ad1770132a3a5d5f8cd52da712f844933b3ca4f13bb5f7b07eafde,2024-11-17 20:16:31,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
276
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-17,0x27c97e66839e3ef9224a9ef654e7db7c41c1e6c150b3557c385a1f69896e1ca7,2024-11-17 20:16:55,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
277
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-17,0xa6011abde4dbfe78da8d177c67e3b7a6884c837f814dad4fcaa86005520ea86c,2024-11-17 20:17:17,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
278
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-18,0x31db26c6e4b48d276541b9ff1e08d5f14e81481b1d092693a62b84dfe861bd47,2024-11-18 19:52:13,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
279
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-18,0x3f60b62248e059edddcc0c5f7e928b5eb30f42063933562ba710f995c340321a,2024-11-18 20:18:09,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
280
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-18,0xac4bfbfc7b2a78ced844d9d1ae1768c0d762cd439d9bdc7cbc0b034ffc8d4586,2024-11-18 20:18:31,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
281
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-18,0xe07995ae50e683525c7caf75f573744db8330b432d9ac6b5f04cbf78c8de6a57,2024-11-18 20:18:57,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
282
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-18,0x83d1fdcd4e688fbc8621572c79da3ffda205d6846a93344dab272e8320e7ab6b,2024-11-18 20:19:27,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
283
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-19,0x400607f8419e10aa52c380451dc378b4803500a7b7757ad33fb72417b58af531,2024-11-19 19:53:41,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
284
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-19,0xab62b6f5fb23cabb39502daeb68f917e21e71cc881862dbf420b2028f0436d5b,2024-11-19 20:19:39,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
285
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-19,0xed1289ab3a8a3895117de1534edee9581ac32809ac14b4117810bdc75c063c07,2024-11-19 20:20:03,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
286
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-19,0x9d33a422c0617e720946fc6e3d2badcf8f1f36d9d3f310697ddff5fbf54910a5,2024-11-19 20:20:25,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
287
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-19,0x8cd54329d987fcf47a607d0d993e52950feebb3ceaa790cffe9bd3499601968f,2024-11-19 20:20:49,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
288
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-11-07,0xaaae37299329f78ac559ecc15645c370d0a005418c644ee74fc8e168b1315d5a,2024-11-07 04:09:03,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
289
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-11-07,0xb2fe13dc01083c55b85fb19839a10088c8b1f17f6c1785dc478103e70615f5b3,2024-11-07 04:09:33,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
290
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-11-07,0x05961dda08b3e88605517591d5a9f133f611d66d1c80f6ecb229f70c97b9aeb7,2024-11-07 04:10:03,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
291
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-11-07,0x0095018a7d02defd5c9a1f8fda0f4b3294a3a17d9ae97b1885c5ed0431ffbb16,2024-11-07 04:10:31,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
292
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-11-08,0xef508c7a5e05e4e18d783af57139a6522869843bb79c81f42b14c843ff134224,2024-11-08 12:15:43,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
293
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-11-08,0x0437ee97d0339ccdcec63fc82accd7dd8509ed44ab2207d0607272bb211a8d11,2024-11-08 12:16:13,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
294
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-11-08,0x92cf9d5e93b1a57212ad0719a626048eefdd6259fbcd08ca422f38e3baea2986,2024-11-08 12:16:41,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
295
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-11-08,0xfe09b2bd2bc210cef538b7d85b63f6a9910fdf68bd4c4d7c2c9c15b84e56cf4c,2024-11-08 12:17:09,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
296
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-11-08,0x62392be6ff658aa8993f47963cc94c5b4bb0b70ea5c427969812057ea7927828,2024-11-08 19:31:21,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
297
- optimism,0x5f0C4273Ff97ae91fc8D2fc8621b5E37a741d1b1,2024-11-12,0x23837e7d387b26e30b44178bdb0c6c643b8a5d802d916b4342a95305c762bc5a,2024-11-12 14:27:35,0xa0ff35bfbd3c42e3afe29255742c7558498f5544,0x5f0c4273ff97ae91fc8d2fc8621b5e37a741d1b1,0.0,0xA0fF35Bfbd3C42E3aFE29255742C7558498f5544
298
- ethereum,0xb0830c65499ff2A25D10D895970b152193b13FCf,2024-11-07,0x6d73ce5cfe1110def67b1dc776b349dec55b61a7ff1680d30c9fc6a2b6353a64,2024-11-07 13:21:59,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0xb0830c65499ff2a25d10d895970b152193b13fcf,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
299
- mode,0xA37e826fF12Af82e5eAed8c981218B78Cc606bac,2024-11-07,0xcd90dd2e5293269ee22f5fc4913f42e6c7f4e43fc42c90c8b716ad865b377ed7,2024-11-07 14:39:39,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D,0xA37e826fF12Af82e5eAed8c981218B78Cc606bac,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
300
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-15,0xe03a65fabb7468ac633dd5edabbb9609eabcf05be6cf1fc27f9841ed12796445,2024-11-15 18:58:13,0xA40c8a3088F892607AD01a24DBCD755EB720F725,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.00033,0x2302548951Ae698370e3C7943A843861641efB92
301
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-15,0x14588c9945c3d3f6d13fd58d91205a46dda2479a1403bba5b25c96735913310c,2024-11-15 17:56:05,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
302
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-15,0xc3624bc76dd73f83165c9dc483ad58358e8920b843fb7a46a3940f133f7a73f3,2024-11-15 17:55:41,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
303
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-15,0x450ccd2f3b50c6549890a68273176366357edd22b9bb92fb5732c213208fb37d,2024-11-15 17:55:15,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
304
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-15,0xd46245b2666e83243f782eb96876b30ece19c13af9b48497a5278726be12e338,2024-11-15 17:54:51,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
305
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-15,0x35433b80bc04e7de98a3afb506e2c8132a8cf579867be998c9010d02d4c1b78b,2024-11-15 17:28:33,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
306
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-18,0x5e7a0a4093f5463b8777bc1aee302046f3b7cbfe21cbb986ab2e02d6a714e055,2024-11-18 19:32:25,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
307
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-18,0x92defde2b1254a23adc285185324cf2b3ffeac41265dd70f3ef0476b35072c01,2024-11-18 19:32:01,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
308
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-18,0xd3c777e3522b1135bf3c00856ff892a7232745d68e3e3c78684c1e4e4f940354,2024-11-18 19:31:35,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
309
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-18,0xfbb08b7ec61f9c729a5a47dcba3281042ba435cb63b4ef71e729e4214cb8f7c8,2024-11-18 19:25:45,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
310
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-18,0x9842b8f77e8a3e61b9c7142bbea4af63f159f399b81bf77222f7562cce8b87b0,2024-11-18 09:10:05,0xA40c8a3088F892607AD01a24DBCD755EB720F725,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0051,0x2302548951Ae698370e3C7943A843861641efB92
311
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-18,0x2853a70afd78549f97b6d4bbc45952ef6b1d5000847cadb08f508b466aa1a1c9,2024-11-18 08:31:33,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
312
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-19,0x91e86fdb9a5523dd2386e9fa1deeffbb86ac609ac1e5d60795deeddf018409ba,2024-11-19 09:26:05,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
313
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-19,0x9588da03cbd1c6e76e7a90ca7b5ed827552907ca6d537e5cbe26b3b6cb47af45,2024-11-19 09:25:39,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
314
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-19,0xee1a6b8d8b96701221e749c0191d4e3d60cf19c24ac39750a89ba0a1343d25d6,2024-11-19 09:04:49,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
315
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-19,0x6cce2f632f82436fbda196a9fd9e6a14de5ce8c28557f6bb695a5e1c0bd0f40e,2024-11-19 09:04:09,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
316
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-19,0x83523912a0693290f277b265f037ebd5aa953aa550cecfaadbec9013ef624d36,2024-11-19 08:57:57,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
317
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-20,0xcbe5e35f17d1646555c89a95d419f868f7a0682c4540dcaf28311cc4bc583b95,2024-11-20 19:55:53,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
318
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-20,0x348a1064b12184ed4eefca86ae707a3c03f5bb14424d6986f98ec3c71aa71a58,2024-11-20 20:21:55,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
319
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-20,0xf04374541afe9676c6c1be148ad2d361ce343221100d5db91059f3f1f12bf763,2024-11-20 20:22:17,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
320
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-20,0x2878a6586bf53824255d79c4cd45a42b6559f4d11df379c7db99d00da2d0b557,2024-11-20 20:22:41,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
321
- optimism,0x37036d9A0E4aDE3898336a42CC31c71387D48B78,2024-11-20,0xa5d0aa63e6dcc4a7c15df2a2ff27c7852aaa9aaacf41db864cc2bfa01ee7f7d9,2024-11-20 20:23:05,0x050e90bea65c9ba6416996bb6fffa8f925885d40,0x37036d9a0e4ade3898336a42cc31c71387d48b78,0.0,0x050E90BEA65c9Ba6416996bb6fFfa8f925885d40
322
- optimism,0x5f0C4273Ff97ae91fc8D2fc8621b5E37a741d1b1,2024-11-20,0xd880358907e288a44179e4818d853c708df2eed8e6e22f1615ef2745b523c73d,2024-11-20 15:22:37,0xa0ff35bfbd3c42e3afe29255742c7558498f5544,0x5f0c4273ff97ae91fc8d2fc8621b5e37a741d1b1,0.0,0xA0fF35Bfbd3C42E3aFE29255742C7558498f5544
323
- optimism,0x5f0C4273Ff97ae91fc8D2fc8621b5E37a741d1b1,2024-11-20,0x73a4bd3298fe8cff0c8fbc7b2a4ed13c6b65487005f1e4941f62ec76c7d722a8,2024-11-20 15:23:05,0xa0ff35bfbd3c42e3afe29255742c7558498f5544,0x5f0c4273ff97ae91fc8d2fc8621b5e37a741d1b1,0.0,0xA0fF35Bfbd3C42E3aFE29255742C7558498f5544
324
- optimism,0x5f0C4273Ff97ae91fc8D2fc8621b5E37a741d1b1,2024-11-20,0x1c481b97d2f51165d16c3bb9ab9be3150ef3e9e498d62d505790b1696a1d711a,2024-11-20 15:23:39,0xa0ff35bfbd3c42e3afe29255742c7558498f5544,0x5f0c4273ff97ae91fc8d2fc8621b5e37a741d1b1,0.0,0xA0fF35Bfbd3C42E3aFE29255742C7558498f5544
325
- optimism,0x5f0C4273Ff97ae91fc8D2fc8621b5E37a741d1b1,2024-11-20,0x1a22efadf88b6963b3a2cd8673eee706031cb7e7e836c1e6285ffae8d4707cde,2024-11-20 15:24:07,0xa0ff35bfbd3c42e3afe29255742c7558498f5544,0x5f0c4273ff97ae91fc8d2fc8621b5e37a741d1b1,0.0,0xA0fF35Bfbd3C42E3aFE29255742C7558498f5544
326
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-11-20,0xaaae37299329f78ac559ecc15645c370d0a005418c644ee74fc8e168b1315d5a,2024-11-20 04:09:03,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
327
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-11-20,0xb2fe13dc01083c55b85fb19839a10088c8b1f17f6c1785dc478103e70615f5b3,2024-11-20 04:09:33,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
328
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-11-20,0x05961dda08b3e88605517591d5a9f133f611d66d1c80f6ecb229f70c97b9aeb7,2024-11-20 04:10:03,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
329
- optimism,0x5EFC7B394A916aC8090a7D6221F798AbFb9F5510,2024-11-20,0x0095018a7d02defd5c9a1f8fda0f4b3294a3a17d9ae97b1885c5ed0431ffbb16,2024-11-20 04:10:31,0x554d1444b6a38fa2eb18d86f2c10f42be630c89d,0x5efc7b394a916ac8090a7d6221f798abfb9f5510,0.0,0x554D1444b6a38fA2eb18d86f2C10F42BE630c89D
330
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-20,0xcfb768d0d84ad720cde123add806bac3a926b8c1cc00fd06633e45f4eeb5d299,2024-11-20 09:28:43,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
331
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-20,0xed0d98331f87b174b3e71a2e4a366be444735b8146aabaa73deca121b6672c9d,2024-11-20 09:28:11,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
332
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-20,0x007f6d8ee852a151298131b944e0e26f7c64477f91070399c797bbac4ffdc31f,2024-11-20 09:27:45,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
333
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-20,0xe1243862f190fe30e8daaf89d1e9f499a93d2dbbd2bc717fdfa80437597a8e12,2024-11-20 09:27:13,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
334
- mode,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,2024-11-20,0xb654fa5b7e2ae3e05577cfd7b9ad3b6beb1446463dac5f39ed12e8dc74d65380,2024-11-20 09:00:53,0x2302548951Ae698370e3C7943A843861641efB92,0x602afe99D8CF58ba03794d4C7489f6f08702e4e6,0.0,0x2302548951Ae698370e3C7943A843861641efB92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
daily_value_locked.csv DELETED
@@ -1,8 +0,0 @@
1
- chain_name,date,event,topic_0,from,to,token_id,token0,token1,liquidity,amount0,amount1,amount0_usd,amount1_usd
2
- optimism,2024-10-07,Transfer,0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,0x0000000000000000000000000000000000000000,0x5f0c4273ff97ae91fc8d2fc8621b5e37a741d1b1,826974,0x2218a117083f5B482B0bB821d27056Ba9c04b1D3,0xdFA46478F9e5EA86d57387849598dbFB2e964b02,13516644515555081265,8.98929230571145,20.324144854406946,9.97811445933971,10.184307041674192
3
- base,2024-09-19,Transfer,0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,0x0000000000000000000000000000000000000000,0xa13dfc6ddcff0b5b637e721ee83d6cf7e0676e73,963863,0x01CCF4941298a0b5AC4714c0E1799a2dF8387048,0x4200000000000000000000000000000000000006,1210264887099988865,359.58545796548844,0.0040734158306472,9.341785679831974,10.270669941235578
4
- base,2024-09-26,Transfer,0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,0x0000000000000000000000000000000000000000,0xac55eeb3fdacfdfae78c62caa58934900ad54ed2,978001,0x01CCF4941298a0b5AC4714c0E1799a2dF8387048,0x4200000000000000000000000000000000000006,1524286215726092055,469.7981777244338,0.004945631076533,12.205037194519935,12.469864740059744
5
- mode,2024-11-07,Transfer,0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,0x0000000000000000000000000000000000000000,0xac55eeb3fdacfdfae78c62caa58934900ad54ed2,978001,0x01CCF4941298a0b5AC4714c0E1799a2dF8387048,0x4200000000000000000000000000000000000006,1524286215726092055,469.7981777244338,0.004945631076533,18.2495,18.3223
6
- mode,2024-11-19,Transfer,0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef,0x0000000000000000000000000000000000000000,0xac55eeb3fdacfdfae78c62caa58934900ad54ed2,978001,0x01CCF4941298a0b5AC4714c0E1799a2dF8387048,0x4200000000000000000000000000000000000006,1524286215726092055,469.7981777244338,0.004945631076533,16.9373,16.9373
7
- optimism,2024-10-14,Transfer,0xddf252ad1be2c89b66c2b069fc378daa952ba7f163c4a11628f55a4df523b3ef,0x0000000000000000000000000000000000000000,0xac55eeb3fdacfdfae78c62caa58934900ad54ed2,978001,0x01CCF4941298a0b5AC4714c0E1799a2dF8387048,0x4200000000000000000000000000000000000006,1524286215726092055,469.7981777244338,0.004945631076533,12.0644,12.3921
8
- optimism,2024-10-04,Transfer,0xddf272ad1be2c89b69c2b068fc378daa956ba7f163c4a11628f55a4df523b3ef,0x0000000000000000000000000000000000000000,0xac55eeb3fdacfdfae78c62caa58934900ad54ed2,978001,0x01CCF4941298a0b5AC4714c0E1799a2dF8387048,0x4200000000000000000000000000000000000006,1524286215726092055,469.7981777244338,0.004945631076533,14.9849,14.9849
 
 
 
 
 
 
 
 
 
modius_apr_statistics.csv DELETED
@@ -1,3 +0,0 @@
1
- agent_id,agent_name,total_points,apr_points,performance_points,real_apr_points,real_performance_points,avg_apr,avg_performance,max_apr,min_apr,latest_timestamp
2
- 2,gonma-pronfa59,1,0,1,0,1,,-100.0,,,2025-04-04 14:03:55
3
- ALL,All Agents,1,0,1,0,1,,-100.0,,,2025-04-04 14:03:55
 
 
 
 
modius_apr_values.csv DELETED
@@ -1,2 +0,0 @@
1
- apr,timestamp,agent_id,is_dummy,agent_name,metric_type
2
- -100.0,2025-04-04 14:03:55,2,False,gonma-pronfa59,Performance
 
 
 
modius_performance/__init__.py ADDED
File without changes
modius_performance/config/__init__.py ADDED
File without changes
modius_performance/config/constants.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Constants and configuration values for the Modius Agent Performance application.
3
+ """
4
+ from datetime import datetime
5
+ from typing import Dict, Any
6
+
7
+ # API Configuration
8
+ API_BASE_URL = "https://afmdb.autonolas.tech"
9
+
10
+ # Chart Colors
11
+ CHART_COLORS = {
12
+ 'apr': 'red',
13
+ 'adjusted_apr': 'green',
14
+ 'roi': 'blue',
15
+ 'volume': 'purple',
16
+ 'positive_region': 'rgba(230, 243, 255, 0.3)',
17
+ 'negative_region': 'rgba(255, 230, 230, 0.3)',
18
+ 'zero_line': 'black'
19
+ }
20
+
21
+ # Date Ranges
22
+ DATE_RANGES = {
23
+ 'apr_start': datetime(2025, 4, 17),
24
+ 'may_cutoff': datetime(2025, 5, 10),
25
+ 'feb_start': datetime(2025, 2, 1)
26
+ }
27
+
28
+ # Chart Configuration
29
+ CHART_CONFIG = {
30
+ 'height': 600,
31
+ 'template': 'plotly_white',
32
+ 'font_family': 'Arial, sans-serif',
33
+ 'title_size': 22,
34
+ 'axis_font_size': 14,
35
+ 'legend_font_size': 14,
36
+ 'moving_average_window_days': 7,
37
+ 'use_corrected_data': True, # Use corrected CSV data instead of database
38
+ 'corrected_data_file': 'corrected_apr_roi_data.csv',
39
+ 'max_visible_agents': 5,
40
+ 'timestamp_aggregation_method': 'median' # 'mean' or 'median'
41
+ }
42
+
43
+ # Y-axis Ranges
44
+ Y_AXIS_RANGES = {
45
+ 'apr': {'min': -50, 'max': 100},
46
+ 'roi': {'min': -100, 'max': 100},
47
+ 'volume': {'auto': True}
48
+ }
49
+
50
+ # Agent Hash Version Mapping
51
+ AGENT_HASH_VERSIONS = {
52
+ 'tby': 'v0.4.1',
53
+ 'vq': 'v0.4.2'
54
+ }
55
+
56
+ # Logging Configuration
57
+ LOGGING_CONFIG = {
58
+ 'level': 'INFO',
59
+ 'format': '%(asctime)s - %(levelname)s - %(message)s',
60
+ 'file': 'app_debug.log'
61
+ }
62
+
63
+ # File Paths
64
+ FILE_PATHS = {
65
+ 'apr_csv': 'modius_apr_values.csv',
66
+ 'roi_csv': 'modius_roi_values.csv',
67
+ 'volume_csv': 'modius_volume_values.csv',
68
+ 'apr_hash_csv': 'modius_apr_vs_agent_hash.csv',
69
+ 'statistics_csv': 'modius_apr_statistics.csv',
70
+ 'apr_processed_csv': 'modius_apr_processed_values.csv',
71
+ 'roi_processed_csv': 'modius_roi_processed_values.csv',
72
+ 'apr_graph_html': 'modius_apr_combined_graph.html',
73
+ 'apr_graph_png': 'modius_apr_combined_graph.png',
74
+ 'roi_graph_html': 'modius_roi_graph.html',
75
+ 'roi_graph_png': 'modius_roi_graph.png',
76
+ 'volume_graph_html': 'modius_volume_graph.html',
77
+ 'volume_graph_png': 'modius_volume_graph.png',
78
+ 'apr_hash_graph_html': 'modius_apr_vs_agent_hash_graph.html',
79
+ 'apr_hash_graph_png': 'modius_apr_vs_agent_hash_graph.png'
80
+ }
81
+
82
+ # Data Processing Configuration
83
+ DATA_CONFIG = {
84
+ 'agent_type_name': 'Modius',
85
+ 'attribute_name': 'APR',
86
+ 'api_limit': 1000,
87
+ 'exclude_apr_values': [0], # Only exclude zero APR values
88
+ 'excluded_agents': [1, 18, 2, 5, 4], # Include all agents including testing agents for population analysis
89
+ 'max_apr_threshold': 600 # Maximum allowed APR value (remove values above this)
90
+ }
modius_performance/data/__init__.py ADDED
File without changes
modius_performance/data/api_client.py ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ API client for interacting with the Modius Agent Performance API.
3
+ """
4
+ import requests
5
+ import logging
6
+ from typing import List, Dict, Any, Optional
7
+
8
+ from ..config.constants import API_BASE_URL, DATA_CONFIG
9
+ from .models import (
10
+ AgentTypeResponse, AttributeDefinitionResponse,
11
+ AgentsListResponse, AttributeValuesResponse
12
+ )
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class ModiusAPIClient:
18
+ """Client for interacting with the Modius Agent Performance API."""
19
+
20
+ def __init__(self, base_url: str = API_BASE_URL):
21
+ self.base_url = base_url
22
+ self.session = requests.Session()
23
+ # Set default timeout and headers
24
+ self.session.timeout = 30
25
+ self.session.headers.update({
26
+ 'User-Agent': 'Modius-Agent-Performance/1.0'
27
+ })
28
+
29
+ def _make_request(self, endpoint: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
30
+ """Make a request to the API and return the response."""
31
+ url = f"{self.base_url}{endpoint}"
32
+ logger.debug(f"Making API request to: {url}")
33
+
34
+ try:
35
+ response = self.session.get(url, params=params)
36
+ logger.debug(f"Response status: {response.status_code}")
37
+
38
+ if response.status_code == 404:
39
+ logger.warning(f"Resource not found: {url}")
40
+ return {"error": "Not found", "status_code": 404}
41
+
42
+ response.raise_for_status()
43
+ return {"data": response.json(), "status_code": response.status_code}
44
+
45
+ except requests.exceptions.RequestException as e:
46
+ logger.error(f"API request error for {url}: {e}")
47
+ return {"error": str(e), "status_code": getattr(e.response, 'status_code', 500)}
48
+
49
+ def get_agent_type_by_name(self, type_name: str) -> AgentTypeResponse:
50
+ """Get agent type by name."""
51
+ endpoint = f"/api/agent-types/name/{type_name}"
52
+ result = self._make_request(endpoint)
53
+
54
+ if "error" in result:
55
+ return AgentTypeResponse({}, result["status_code"])
56
+
57
+ return AgentTypeResponse(result["data"], result["status_code"])
58
+
59
+ def get_attribute_definition_by_name(self, attr_name: str) -> AttributeDefinitionResponse:
60
+ """Get attribute definition by name."""
61
+ endpoint = f"/api/attributes/name/{attr_name}"
62
+ result = self._make_request(endpoint)
63
+
64
+ if "error" in result:
65
+ return AttributeDefinitionResponse({}, result["status_code"])
66
+
67
+ return AttributeDefinitionResponse(result["data"], result["status_code"])
68
+
69
+ def get_agents_by_type(self, type_id: int) -> AgentsListResponse:
70
+ """Get all agents of a specific type."""
71
+ endpoint = f"/api/agent-types/{type_id}/agents/"
72
+ result = self._make_request(endpoint)
73
+
74
+ if "error" in result:
75
+ return AgentsListResponse([], result["status_code"])
76
+
77
+ return AgentsListResponse(result["data"], result["status_code"])
78
+
79
+ def get_agent_attributes(self, agent_id: int, limit: int = None) -> AttributeValuesResponse:
80
+ """Get attributes for a specific agent."""
81
+ endpoint = f"/api/agents/{agent_id}/attributes/"
82
+ params = {"limit": limit or DATA_CONFIG["api_limit"]}
83
+ result = self._make_request(endpoint, params)
84
+
85
+ if "error" in result:
86
+ return AttributeValuesResponse([], result["status_code"])
87
+
88
+ return AttributeValuesResponse(result["data"], result["status_code"])
89
+
90
+ def get_attribute_values_by_type_and_attr(
91
+ self,
92
+ agents: List[Dict[str, Any]],
93
+ attr_def_id: int
94
+ ) -> List[Dict[str, Any]]:
95
+ """Get all attribute values for a specific attribute definition across all agents."""
96
+ all_attributes = []
97
+ logger.debug(f"Getting attributes for {len(agents)} agents with attr_def_id: {attr_def_id}")
98
+
99
+ for agent in agents:
100
+ agent_id = agent["agent_id"]
101
+
102
+ # Get agent attributes
103
+ response = self.get_agent_attributes(agent_id)
104
+
105
+ if not response.is_success():
106
+ logger.error(f"Failed to get attributes for agent ID {agent_id}")
107
+ continue
108
+
109
+ agent_attrs = response.get_attribute_values()
110
+ logger.debug(f"Agent {agent_id} has {len(agent_attrs)} attributes")
111
+
112
+ # Filter for the specific attribute definition ID
113
+ filtered_attrs = [
114
+ attr for attr in agent_attrs
115
+ if attr.get("attr_def_id") == attr_def_id
116
+ ]
117
+ logger.debug(f"Agent {agent_id} has {len(filtered_attrs)} matching attributes")
118
+
119
+ if filtered_attrs:
120
+ logger.debug(f"Sample attribute for agent {agent_id}: {filtered_attrs[0]}")
121
+
122
+ all_attributes.extend(filtered_attrs)
123
+
124
+ logger.info(f"Total matching attributes found across all agents: {len(all_attributes)}")
125
+ return all_attributes
126
+
127
+ def close(self):
128
+ """Close the session."""
129
+ self.session.close()
130
+
131
+ def __enter__(self):
132
+ return self
133
+
134
+ def __exit__(self, exc_type, exc_val, exc_tb):
135
+ self.close()
136
+
137
+
138
+ # Utility functions for backward compatibility
139
+ def get_agent_name(agent_id: int, agents: List[Dict[str, Any]]) -> str:
140
+ """Get agent name from agent ID."""
141
+ for agent in agents:
142
+ if agent["agent_id"] == agent_id:
143
+ return agent["agent_name"]
144
+ return "Unknown"
145
+
146
+
147
+ # Global client instance (can be replaced with dependency injection later)
148
+ _client_instance = None
149
+
150
+
151
+ def get_api_client() -> ModiusAPIClient:
152
+ """Get the global API client instance."""
153
+ global _client_instance
154
+ if _client_instance is None:
155
+ _client_instance = ModiusAPIClient()
156
+ return _client_instance
157
+
158
+
159
+ def close_api_client():
160
+ """Close the global API client instance."""
161
+ global _client_instance
162
+ if _client_instance is not None:
163
+ _client_instance.close()
164
+ _client_instance = None
modius_performance/data/data_processor.py ADDED
@@ -0,0 +1,765 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Data processing utilities for the Modius Agent Performance application.
3
+ """
4
+ import json
5
+ import pandas as pd
6
+ import logging
7
+ import os
8
+ from datetime import datetime, timedelta
9
+ from typing import List, Dict, Any, Optional, Tuple
10
+
11
+ from ..config.constants import DATA_CONFIG, DATE_RANGES, CHART_CONFIG
12
+ from .models import AgentMetric, AgentStatistics
13
+ from .api_client import get_api_client, get_agent_name
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class DataProcessor:
19
+ """Handles data processing and transformation for agent metrics."""
20
+
21
+ def __init__(self):
22
+ self.api_client = get_api_client()
23
+
24
+ def extract_apr_value(self, attr: Dict[str, Any]) -> Dict[str, Any]:
25
+ """Extract APR value, adjusted APR value, ROI value, volume, and timestamp from JSON value."""
26
+ try:
27
+ agent_id = attr.get("agent_id", "unknown")
28
+ logger.debug(f"Extracting APR value for agent {agent_id}")
29
+
30
+ # The APR value is stored in the json_value field
31
+ if attr["json_value"] is None:
32
+ logger.debug(f"Agent {agent_id}: json_value is None")
33
+ return {
34
+ "apr": None, "adjusted_apr": None, "roi": None,
35
+ "volume": None, "timestamp": None, "agent_id": agent_id,
36
+ "agent_hash": None, "is_dummy": False
37
+ }
38
+
39
+ # If json_value is a string, parse it
40
+ if isinstance(attr["json_value"], str):
41
+ logger.debug(f"Agent {agent_id}: json_value is string, parsing")
42
+ json_data = json.loads(attr["json_value"])
43
+ else:
44
+ json_data = attr["json_value"]
45
+
46
+ apr = json_data.get("apr")
47
+ adjusted_apr = json_data.get("adjusted_apr")
48
+ timestamp = json_data.get("timestamp")
49
+ volume = json_data.get("volume")
50
+
51
+ # ROI extraction from calculation_metrics.f_i_ratio
52
+ roi = None
53
+ if "calculation_metrics" in json_data and json_data["calculation_metrics"] is not None:
54
+ if isinstance(json_data["calculation_metrics"], dict):
55
+ f_i_ratio = json_data["calculation_metrics"].get("f_i_ratio")
56
+ if f_i_ratio is not None:
57
+ roi = f_i_ratio
58
+ logger.debug(f"Agent {agent_id}: ROI extracted from f_i_ratio: {roi}")
59
+ else:
60
+ logger.debug(f"Agent {agent_id}: No f_i_ratio found in calculation_metrics")
61
+ else:
62
+ logger.debug(f"Agent {agent_id}: calculation_metrics is not a dict: {type(json_data['calculation_metrics'])}")
63
+ else:
64
+ logger.debug(f"Agent {agent_id}: No calculation_metrics found")
65
+
66
+ # Try to extract volume from portfolio_snapshot if it's not directly in json_data
67
+ if volume is None and "portfolio_snapshot" in json_data and json_data["portfolio_snapshot"] is not None:
68
+ portfolio = json_data["portfolio_snapshot"].get("portfolio")
69
+ if portfolio and isinstance(portfolio, dict):
70
+ volume = portfolio.get("volume")
71
+
72
+ # Extract agent_hash from json_data or portfolio_snapshot
73
+ agent_hash = json_data.get("agent_hash")
74
+ if agent_hash is None and "portfolio_snapshot" in json_data and json_data["portfolio_snapshot"] is not None:
75
+ portfolio = json_data["portfolio_snapshot"].get("portfolio")
76
+ if portfolio and isinstance(portfolio, dict):
77
+ agent_hash = portfolio.get("agent_hash")
78
+
79
+ logger.debug(f"Agent {agent_id}: Raw values - APR: {apr}, adjusted APR: {adjusted_apr}, ROI: {roi}, volume: {volume}, timestamp: {timestamp}, agent_hash: {agent_hash}")
80
+
81
+ # Convert timestamp to datetime if it exists
82
+ timestamp_dt = None
83
+ if timestamp:
84
+ try:
85
+ timestamp_dt = datetime.fromtimestamp(timestamp)
86
+ except (ValueError, TypeError, OSError) as e:
87
+ logger.warning(f"Invalid timestamp {timestamp} for agent {agent_id}: {e}")
88
+ timestamp_dt = None
89
+
90
+ result = {
91
+ "apr": apr,
92
+ "adjusted_apr": adjusted_apr,
93
+ "roi": roi,
94
+ "volume": volume,
95
+ "timestamp": timestamp_dt,
96
+ "agent_id": agent_id,
97
+ "agent_hash": agent_hash,
98
+ "is_dummy": False
99
+ }
100
+ logger.debug(f"Agent {agent_id}: Extracted result: {result}")
101
+ return result
102
+
103
+ except (json.JSONDecodeError, KeyError, TypeError) as e:
104
+ logger.error(f"Error parsing JSON value: {e} for agent_id: {attr.get('agent_id')}")
105
+ logger.error(f"Problematic json_value: {attr.get('json_value')}")
106
+ return {
107
+ "apr": None, "adjusted_apr": None, "roi": None,
108
+ "volume": None, "timestamp": None, "agent_id": attr.get('agent_id'),
109
+ "agent_hash": None, "is_dummy": False
110
+ }
111
+
112
+ def load_corrected_data_from_csv(self) -> Tuple[pd.DataFrame, pd.DataFrame]:
113
+ """Load corrected APR and ROI data from CSV file."""
114
+ logger.info("==== Loading corrected data from CSV ====")
115
+
116
+ try:
117
+ # Get the CSV file path
118
+ csv_filename = CHART_CONFIG.get('corrected_data_file', 'corrected_apr_roi_data.csv')
119
+ csv_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), csv_filename)
120
+
121
+ if not os.path.exists(csv_path):
122
+ logger.error(f"Corrected data file not found: {csv_path}")
123
+ return pd.DataFrame([]), pd.DataFrame([])
124
+
125
+ # Read the CSV file
126
+ df = pd.read_csv(csv_path)
127
+ logger.info(f"Loaded {len(df)} rows from {csv_path}")
128
+
129
+ # Parse dates and convert to datetime
130
+ df['Date'] = pd.to_datetime(df['Date'], format='%Y-%m-%d')
131
+
132
+ # Create APR DataFrame
133
+ apr_data_list = []
134
+ roi_data_list = []
135
+
136
+ for _, row in df.iterrows():
137
+ timestamp = row['Date']
138
+ apr_value = row['APR']
139
+ roi_value = row['ROI']
140
+ adjusted_apr_value = row['Adjusted_APR'] if 'Adjusted_APR' in df.columns else None
141
+
142
+ # Create APR entry
143
+ apr_entry = {
144
+ 'apr': apr_value,
145
+ 'adjusted_apr': adjusted_apr_value, # Now available in corrected data
146
+ 'roi': None,
147
+ 'volume': None,
148
+ 'timestamp': timestamp,
149
+ 'agent_id': 'corrected_data',
150
+ 'agent_name': 'Corrected Manual Data',
151
+ 'agent_hash': None,
152
+ 'is_dummy': False,
153
+ 'metric_type': 'APR'
154
+ }
155
+ apr_data_list.append(apr_entry)
156
+
157
+ # Create ROI entry
158
+ roi_entry = {
159
+ 'roi': roi_value,
160
+ 'timestamp': timestamp,
161
+ 'agent_id': 'corrected_data',
162
+ 'agent_name': 'Corrected Manual Data',
163
+ 'is_dummy': False,
164
+ 'metric_type': 'ROI'
165
+ }
166
+ roi_data_list.append(roi_entry)
167
+
168
+ # Convert to DataFrames
169
+ apr_df = pd.DataFrame(apr_data_list)
170
+ roi_df = pd.DataFrame(roi_data_list)
171
+
172
+ # Filter data to end at May 29, 2025
173
+ end_date = datetime(2025, 5, 29)
174
+ apr_df = apr_df[apr_df['timestamp'] <= end_date]
175
+ roi_df = roi_df[roi_df['timestamp'] <= end_date]
176
+
177
+ logger.info(f"Created APR DataFrame with {len(apr_df)} rows (filtered to end at May 29, 2025)")
178
+ logger.info(f"Created ROI DataFrame with {len(roi_df)} rows (filtered to end at May 29, 2025)")
179
+
180
+ if not apr_df.empty:
181
+ logger.info(f"APR date range: {apr_df['timestamp'].min()} to {apr_df['timestamp'].max()}")
182
+ logger.info(f"APR statistics: min={apr_df['apr'].min():.2f}, max={apr_df['apr'].max():.2f}, mean={apr_df['apr'].mean():.2f}")
183
+
184
+ if not roi_df.empty:
185
+ logger.info(f"ROI date range: {roi_df['timestamp'].min()} to {roi_df['timestamp'].max()}")
186
+ logger.info(f"ROI statistics: min={roi_df['roi'].min():.2f}, max={roi_df['roi'].max():.2f}, mean={roi_df['roi'].mean():.2f}")
187
+
188
+ return apr_df, roi_df
189
+
190
+ except Exception as e:
191
+ logger.error(f"Error loading corrected data from CSV: {e}")
192
+ logger.exception("Exception traceback:")
193
+ return pd.DataFrame([]), pd.DataFrame([])
194
+
195
+ def fetch_apr_data_from_db(self) -> Tuple[pd.DataFrame, pd.DataFrame]:
196
+ """Fetch APR data from database using the API."""
197
+ # Check if we should use corrected data instead
198
+ if CHART_CONFIG.get('use_corrected_data', False):
199
+ logger.info("Using corrected CSV data instead of database")
200
+ return self.load_corrected_data_from_csv()
201
+
202
+ logger.info("==== Starting APR data fetch ====")
203
+
204
+ try:
205
+ # Step 1: Find the Modius agent type
206
+ logger.info("Finding Modius agent type")
207
+ modius_type_response = self.api_client.get_agent_type_by_name(DATA_CONFIG["agent_type_name"])
208
+
209
+ if not modius_type_response.is_success():
210
+ logger.error("Modius agent type not found, using placeholder data")
211
+ return pd.DataFrame([]), pd.DataFrame([])
212
+
213
+ modius_type = modius_type_response.get_agent_type()
214
+ type_id = modius_type.type_id
215
+ logger.info(f"Found Modius agent type with ID: {type_id}")
216
+
217
+ # Step 2: Find the APR attribute definition
218
+ logger.info("Finding APR attribute definition")
219
+ apr_attr_response = self.api_client.get_attribute_definition_by_name(DATA_CONFIG["attribute_name"])
220
+
221
+ if not apr_attr_response.is_success():
222
+ logger.error("APR attribute definition not found, using placeholder data")
223
+ return pd.DataFrame([]), pd.DataFrame([])
224
+
225
+ apr_attr_def = apr_attr_response.get_attribute_definition()
226
+ attr_def_id = apr_attr_def.attr_def_id
227
+ logger.info(f"Found APR attribute definition with ID: {attr_def_id}")
228
+
229
+ # Step 3: Get all agents of type Modius
230
+ logger.info(f"Getting all agents of type Modius (type_id: {type_id})")
231
+ agents_response = self.api_client.get_agents_by_type(type_id)
232
+
233
+ if not agents_response.is_success():
234
+ logger.error("No agents of type 'Modius' found")
235
+ return pd.DataFrame([]), pd.DataFrame([])
236
+
237
+ modius_agents_info = agents_response.get_agents()
238
+ modius_agents = [
239
+ {
240
+ "agent_id": agent.agent_id,
241
+ "agent_name": agent.agent_name,
242
+ "type_id": agent.type_id
243
+ }
244
+ for agent in modius_agents_info
245
+ ]
246
+
247
+ # Filter out excluded agents
248
+ excluded_agents = DATA_CONFIG.get("excluded_agents", [])
249
+ if excluded_agents:
250
+ original_count = len(modius_agents)
251
+ modius_agents = [agent for agent in modius_agents if agent["agent_id"] not in excluded_agents]
252
+ filtered_count = original_count - len(modius_agents)
253
+ logger.info(f"Filtered out {filtered_count} excluded agents: {excluded_agents}")
254
+
255
+ logger.info(f"Found {len(modius_agents)} Modius agents after filtering")
256
+ logger.debug(f"Modius agents: {[{'agent_id': a['agent_id'], 'agent_name': a['agent_name']} for a in modius_agents]}")
257
+
258
+ # Step 4: Fetch all APR values for Modius agents
259
+ logger.info(f"Fetching APR values for all Modius agents (attr_def_id: {attr_def_id})")
260
+ apr_attributes = self.api_client.get_attribute_values_by_type_and_attr(modius_agents, attr_def_id)
261
+
262
+ if not apr_attributes:
263
+ logger.error("No APR values found for 'Modius' agents")
264
+ return pd.DataFrame([]), pd.DataFrame([])
265
+
266
+ logger.info(f"Found {len(apr_attributes)} APR attributes total")
267
+
268
+ # Step 5: Extract APR and ROI data
269
+ logger.info("Extracting APR and ROI data from attributes")
270
+ apr_data_list = []
271
+ roi_data_list = []
272
+
273
+ for attr in apr_attributes:
274
+ data = self.extract_apr_value(attr)
275
+ if data["timestamp"] is not None:
276
+ # Get agent name
277
+ agent_name = get_agent_name(attr["agent_id"], modius_agents)
278
+ data["agent_name"] = agent_name
279
+ data["is_dummy"] = False
280
+
281
+ # Process APR data
282
+ if data["apr"] is not None:
283
+ # Filter APR values based on exclusion list
284
+ if data["apr"] not in DATA_CONFIG.get("exclude_apr_values", []):
285
+ apr_entry = data.copy()
286
+ apr_entry["metric_type"] = "APR"
287
+ logger.debug(f"Agent {agent_name} ({attr['agent_id']}): APR value: {data['apr']}")
288
+ apr_data_list.append(apr_entry)
289
+ else:
290
+ logger.debug(f"Skipping APR value for agent {agent_name}: {data['apr']} (excluded value)")
291
+
292
+ # Process ROI data
293
+ if data["roi"] is not None:
294
+ # Filter ROI values if needed (similar to APR filtering)
295
+ roi_entry = {
296
+ "roi": data["roi"],
297
+ "timestamp": data["timestamp"],
298
+ "agent_id": data["agent_id"],
299
+ "agent_name": agent_name,
300
+ "is_dummy": False,
301
+ "metric_type": "ROI"
302
+ }
303
+ logger.debug(f"Agent {agent_name} ({attr['agent_id']}): ROI value: {data['roi']}")
304
+ roi_data_list.append(roi_entry)
305
+ else:
306
+ logger.debug(f"Agent {agent_name} ({attr['agent_id']}): No ROI data available")
307
+
308
+ logger.info(f"Extracted {len(apr_data_list)} valid APR data points and {len(roi_data_list)} valid ROI data points")
309
+
310
+ # Convert to DataFrames
311
+ apr_df = pd.DataFrame(apr_data_list) if apr_data_list else pd.DataFrame([])
312
+ roi_df = pd.DataFrame(roi_data_list) if roi_data_list else pd.DataFrame([])
313
+
314
+ # Log the resulting dataframes
315
+ logger.info(f"Created APR DataFrame with {len(apr_df)} rows")
316
+ if not apr_df.empty:
317
+ logger.info(f"APR DataFrame columns: {apr_df.columns.tolist()}")
318
+ logger.info(f"APR statistics: min={apr_df['apr'].min()}, max={apr_df['apr'].max()}, mean={apr_df['apr'].mean()}")
319
+
320
+ logger.info(f"Created ROI DataFrame with {len(roi_df)} rows")
321
+ if not roi_df.empty:
322
+ logger.info(f"ROI DataFrame columns: {roi_df.columns.tolist()}")
323
+ logger.info(f"ROI statistics: min={roi_df['roi'].min()}, max={roi_df['roi'].max()}, mean={roi_df['roi'].mean()}")
324
+
325
+ return apr_df, roi_df
326
+
327
+ except Exception as e:
328
+ logger.error(f"Error fetching APR data: {e}")
329
+ logger.exception("Exception traceback:")
330
+ return pd.DataFrame([]), pd.DataFrame([])
331
+
332
+ def filter_outliers(self, df: pd.DataFrame, column: str, threshold: float = None) -> pd.DataFrame:
333
+ """Filter outliers from a DataFrame based on a threshold."""
334
+ if df.empty or column not in df.columns:
335
+ return df
336
+
337
+ # Use configured outlier threshold
338
+ threshold = threshold or DATA_CONFIG.get("outlier_threshold", 200)
339
+
340
+ # Filter out outliers based on threshold
341
+ outlier_mask = (df[column] > threshold) | (df[column] < -threshold)
342
+ filtered_df = df[~outlier_mask]
343
+
344
+ outliers_removed = len(df) - len(filtered_df)
345
+ if outliers_removed > 0:
346
+ logger.info(f"Filtered {outliers_removed} outliers from {column} column using threshold ±{threshold}")
347
+ else:
348
+ logger.info(f"No outliers found in {column} column using threshold ±{threshold}")
349
+
350
+ return filtered_df
351
+
352
+ def calculate_moving_average(self, df: pd.DataFrame, value_column: str, window_days: int = None) -> pd.DataFrame:
353
+ """Calculate moving average for a DataFrame."""
354
+ if df.empty:
355
+ return df
356
+
357
+ window_days = window_days or CHART_CONFIG["moving_average_window_days"]
358
+ time_window = pd.Timedelta(days=window_days)
359
+ aggregation_method = CHART_CONFIG.get("timestamp_aggregation_method", "mean")
360
+
361
+ # Sort by timestamp
362
+ df_sorted = df.sort_values('timestamp')
363
+
364
+ # Group by timestamp and calculate aggregation (mean or median based on config)
365
+ if aggregation_method == "median":
366
+ aggregated_data = df_sorted.groupby('timestamp')[value_column].median().reset_index()
367
+ logger.info(f"Using median aggregation for timestamp grouping")
368
+ else:
369
+ aggregated_data = df_sorted.groupby('timestamp')[value_column].mean().reset_index()
370
+ logger.info(f"Using mean aggregation for timestamp grouping")
371
+
372
+ aggregated_data = aggregated_data.sort_values('timestamp')
373
+
374
+ # Calculate moving average (still using mean for the moving window)
375
+ aggregated_data['moving_avg'] = None
376
+
377
+ for i, row in aggregated_data.iterrows():
378
+ current_time = row['timestamp']
379
+ window_start = current_time - time_window
380
+
381
+ # Get all data points within the time window
382
+ window_data = df_sorted[
383
+ (df_sorted['timestamp'] >= window_start) &
384
+ (df_sorted['timestamp'] <= current_time)
385
+ ]
386
+
387
+ if not window_data.empty:
388
+ aggregated_data.at[i, 'moving_avg'] = window_data[value_column].mean()
389
+ else:
390
+ aggregated_data.at[i, 'moving_avg'] = row[value_column]
391
+
392
+ logger.info(f"Calculated {window_days}-day moving average with {len(aggregated_data)} points using {aggregation_method} timestamp aggregation")
393
+ return aggregated_data
394
+
395
+ def generate_statistics(self, df: pd.DataFrame) -> pd.DataFrame:
396
+ """Generate statistics from the data."""
397
+ if df.empty:
398
+ return pd.DataFrame()
399
+
400
+ # Get unique agents
401
+ unique_agents = df['agent_id'].unique()
402
+ stats_list = []
403
+
404
+ # Generate per-agent statistics
405
+ for agent_id in unique_agents:
406
+ agent_data = df[df['agent_id'] == agent_id]
407
+ agent_name = agent_data['agent_name'].iloc[0]
408
+
409
+ # APR statistics
410
+ apr_data = agent_data[agent_data['metric_type'] == 'APR']
411
+ real_apr = apr_data[apr_data['is_dummy'] == False]
412
+
413
+ # Check if adjusted_apr exists and has non-null values
414
+ has_adjusted_apr = 'adjusted_apr' in apr_data.columns and apr_data['adjusted_apr'].notna().any()
415
+
416
+ stats = {
417
+ 'agent_id': agent_id,
418
+ 'agent_name': agent_name,
419
+ 'total_points': len(agent_data),
420
+ 'apr_points': len(apr_data),
421
+ 'real_apr_points': len(real_apr),
422
+ 'avg_apr': apr_data['apr'].mean() if not apr_data.empty else None,
423
+ 'max_apr': apr_data['apr'].max() if not apr_data.empty else None,
424
+ 'min_apr': apr_data['apr'].min() if not apr_data.empty else None,
425
+ 'avg_adjusted_apr': apr_data['adjusted_apr'].mean() if has_adjusted_apr else None,
426
+ 'max_adjusted_apr': apr_data['adjusted_apr'].max() if has_adjusted_apr else None,
427
+ 'min_adjusted_apr': apr_data['adjusted_apr'].min() if has_adjusted_apr else None,
428
+ 'latest_timestamp': agent_data['timestamp'].max().strftime('%Y-%m-%d %H:%M:%S') if not agent_data.empty and pd.notna(agent_data['timestamp'].max()) else None
429
+ }
430
+ stats_list.append(stats)
431
+
432
+ # Generate overall statistics
433
+ apr_only = df[df['metric_type'] == 'APR']
434
+ has_adjusted_apr_overall = 'adjusted_apr' in apr_only.columns and apr_only['adjusted_apr'].notna().any()
435
+
436
+ overall_stats = {
437
+ 'agent_id': 'ALL',
438
+ 'agent_name': 'All Agents',
439
+ 'total_points': len(df),
440
+ 'apr_points': len(apr_only),
441
+ 'real_apr_points': len(apr_only[apr_only['is_dummy'] == False]),
442
+ 'avg_apr': apr_only['apr'].mean() if not apr_only.empty else None,
443
+ 'max_apr': apr_only['apr'].max() if not apr_only.empty else None,
444
+ 'min_apr': apr_only['apr'].min() if not apr_only.empty else None,
445
+ 'avg_adjusted_apr': apr_only['adjusted_apr'].mean() if has_adjusted_apr_overall else None,
446
+ 'max_adjusted_apr': apr_only['adjusted_apr'].max() if has_adjusted_apr_overall else None,
447
+ 'min_adjusted_apr': apr_only['adjusted_apr'].min() if has_adjusted_apr_overall else None,
448
+ 'latest_timestamp': df['timestamp'].max().strftime('%Y-%m-%d %H:%M:%S') if not df.empty and pd.notna(df['timestamp'].max()) else None
449
+ }
450
+ stats_list.append(overall_stats)
451
+
452
+ return pd.DataFrame(stats_list)
453
+
454
+ def calculate_daily_volume_changes(self, df: pd.DataFrame) -> pd.DataFrame:
455
+ """Calculate daily volume totals and cumulative volume with 7-day SMA."""
456
+ if df.empty or 'volume' not in df.columns:
457
+ logger.warning("No volume data available for daily calculation")
458
+ return pd.DataFrame()
459
+
460
+ # Filter out excluded agents
461
+ excluded_agents = DATA_CONFIG.get("excluded_agents", [])
462
+ if excluded_agents:
463
+ original_count = len(df)
464
+ df = df[~df['agent_id'].isin(excluded_agents)]
465
+ filtered_count = original_count - len(df)
466
+ logger.info(f"Filtered out {filtered_count} records from excluded agents {excluded_agents} for volume calculation")
467
+
468
+ # Filter for records with volume data
469
+ volume_data = df[df['volume'].notna()].copy()
470
+ if volume_data.empty:
471
+ logger.warning("No valid volume data found")
472
+ return pd.DataFrame()
473
+
474
+ # Ensure volume is float and timestamp is datetime
475
+ volume_data['volume'] = volume_data['volume'].astype(float)
476
+ volume_data = volume_data.sort_values('timestamp')
477
+
478
+ logger.info(f"Processing {len(volume_data)} volume records for daily aggregation")
479
+
480
+ # Group by date (day) and sum volume across all agents
481
+ volume_data['date'] = volume_data['timestamp'].dt.date
482
+ daily_sums = volume_data.groupby('date')['volume'].sum().reset_index()
483
+ daily_sums = daily_sums.sort_values('date')
484
+
485
+ # Convert date back to datetime for easier plotting
486
+ daily_sums['date'] = pd.to_datetime(daily_sums['date'])
487
+
488
+ # Calculate cumulative volume (each day adds to the previous day's total)
489
+ daily_sums['cumulative_volume'] = daily_sums['volume'].cumsum()
490
+
491
+ # Calculate day-over-day percentage changes for the cumulative volume
492
+ daily_sums['prev_cumulative'] = daily_sums['cumulative_volume'].shift(1)
493
+ daily_sums['day_over_day_pct'] = ((daily_sums['cumulative_volume'] / daily_sums['prev_cumulative']) - 1) * 100
494
+
495
+ # Set first day to 0% change
496
+ daily_sums.loc[0, 'day_over_day_pct'] = 0.0
497
+
498
+ # Fill any NaN or infinite values with 0
499
+ daily_sums['day_over_day_pct'] = daily_sums['day_over_day_pct'].replace([float('inf'), float('-inf')], 0.0)
500
+ daily_sums['day_over_day_pct'] = daily_sums['day_over_day_pct'].fillna(0.0)
501
+
502
+ # Calculate 7-day Simple Moving Average (SMA) of percentage changes
503
+ daily_sums['sma_7d'] = daily_sums['day_over_day_pct'].rolling(window=7, min_periods=1).mean()
504
+
505
+ logger.info(f"Calculated daily changes for {len(daily_sums)} days")
506
+ logger.info(f"Daily volume range: {daily_sums['volume'].min():.2f} to {daily_sums['volume'].max():.2f}")
507
+ logger.info(f"Cumulative volume range: {daily_sums['cumulative_volume'].min():.2f} to {daily_sums['cumulative_volume'].max():.2f}")
508
+ logger.info(f"Day-over-day percentage range: {daily_sums['day_over_day_pct'].min():.1f}% to {daily_sums['day_over_day_pct'].max():.1f}%")
509
+ logger.info(f"7-day SMA range: {daily_sums['sma_7d'].min():.1f}% to {daily_sums['sma_7d'].max():.1f}%")
510
+
511
+ return daily_sums[['date', 'volume', 'cumulative_volume', 'day_over_day_pct', 'sma_7d']]
512
+
513
+ def calculate_weekly_volume_changes(self, df: pd.DataFrame) -> pd.DataFrame:
514
+ """Calculate weekly volume averages and week-over-week percentage changes."""
515
+ if df.empty or 'volume' not in df.columns:
516
+ logger.warning("No volume data available for weekly calculation")
517
+ return pd.DataFrame()
518
+
519
+ # Filter out excluded agents
520
+ excluded_agents = DATA_CONFIG.get("excluded_agents", [])
521
+ if excluded_agents:
522
+ original_count = len(df)
523
+ df = df[~df['agent_id'].isin(excluded_agents)]
524
+ filtered_count = original_count - len(df)
525
+ logger.info(f"Filtered out {filtered_count} records from excluded agents {excluded_agents} for weekly volume calculation")
526
+
527
+ # Filter for records with volume data
528
+ volume_data = df[df['volume'].notna()].copy()
529
+ if volume_data.empty:
530
+ logger.warning("No valid volume data found")
531
+ return pd.DataFrame()
532
+
533
+ # Ensure volume is float and timestamp is datetime
534
+ volume_data['volume'] = volume_data['volume'].astype(float)
535
+ volume_data = volume_data.sort_values('timestamp')
536
+
537
+ logger.info(f"Processing {len(volume_data)} volume records for weekly aggregation")
538
+
539
+ # Group by Monday-starting weeks and sum volume
540
+ volume_data['week_start'] = volume_data['timestamp'].dt.to_period('W-MON').dt.start_time
541
+
542
+ # Sum volume for each week across all agents
543
+ weekly_sums = volume_data.groupby('week_start')['volume'].sum().reset_index()
544
+ weekly_sums = weekly_sums.sort_values('week_start')
545
+
546
+ # Calculate weekly averages (sum ÷ 7)
547
+ weekly_sums['weekly_avg_volume'] = weekly_sums['volume'] / 7
548
+
549
+ # Calculate week-over-week percentage changes
550
+ weekly_sums['prev_week_avg'] = weekly_sums['weekly_avg_volume'].shift(1)
551
+ weekly_sums['week_over_week_pct'] = ((weekly_sums['weekly_avg_volume'] / weekly_sums['prev_week_avg']) - 1) * 100
552
+
553
+ # Set first week to 0% change as requested
554
+ weekly_sums.loc[0, 'week_over_week_pct'] = 0.0
555
+
556
+ # Fill any NaN values with 0
557
+ weekly_sums['week_over_week_pct'] = weekly_sums['week_over_week_pct'].fillna(0.0)
558
+
559
+ logger.info(f"Calculated weekly changes for {len(weekly_sums)} weeks")
560
+ logger.info(f"Week-over-week percentage range: {weekly_sums['week_over_week_pct'].min():.1f}% to {weekly_sums['week_over_week_pct'].max():.1f}%")
561
+
562
+ return weekly_sums[['week_start', 'weekly_avg_volume', 'week_over_week_pct']]
563
+
564
+ def aggregate_daily_medians(self, df: pd.DataFrame, value_columns: List[str]) -> pd.DataFrame:
565
+ """
566
+ Aggregate multiple values per day for each agent by taking the median.
567
+ This reduces outliers and provides one clean data point per agent per day.
568
+
569
+ Args:
570
+ df: DataFrame with agent data
571
+ value_columns: List of columns to aggregate (e.g., ['apr', 'adjusted_apr'] or ['roi'])
572
+
573
+ Returns:
574
+ DataFrame with daily median values for each agent
575
+ """
576
+ if df.empty:
577
+ logger.info("No data to aggregate")
578
+ return df
579
+
580
+ # Create a copy to avoid modifying the original
581
+ data = df.copy()
582
+
583
+ # Add date column for grouping
584
+ data['date'] = data['timestamp'].dt.date
585
+
586
+ # Group by agent and date, then calculate median for each value column
587
+ grouping_cols = ['agent_id', 'agent_name', 'date']
588
+
589
+ # Prepare aggregation dictionary
590
+ agg_dict = {}
591
+ for col in value_columns:
592
+ if col in data.columns:
593
+ agg_dict[col] = 'median'
594
+
595
+ # Add other columns that should be preserved (take first value per group)
596
+ preserve_cols = ['metric_type', 'is_dummy', 'agent_hash']
597
+ for col in preserve_cols:
598
+ if col in data.columns:
599
+ agg_dict[col] = 'first'
600
+
601
+ if not agg_dict:
602
+ logger.warning("No valid columns to aggregate")
603
+ return pd.DataFrame()
604
+
605
+ # Perform aggregation
606
+ aggregated = data.groupby(grouping_cols).agg(agg_dict).reset_index()
607
+
608
+ # Convert date back to datetime and set as timestamp
609
+ aggregated['timestamp'] = pd.to_datetime(aggregated['date'])
610
+ aggregated = aggregated.drop('date', axis=1)
611
+
612
+ # Sort by agent and timestamp
613
+ aggregated = aggregated.sort_values(['agent_id', 'timestamp'])
614
+
615
+ # Log aggregation results
616
+ original_count = len(data)
617
+ aggregated_count = len(aggregated)
618
+ reduction_pct = ((original_count - aggregated_count) / original_count * 100) if original_count > 0 else 0
619
+
620
+ logger.info(f"Daily median aggregation completed:")
621
+ logger.info(f" Original data points: {original_count}")
622
+ logger.info(f" Aggregated data points: {aggregated_count}")
623
+ logger.info(f" Data reduction: {reduction_pct:.1f}%")
624
+ logger.info(f" Aggregated columns: {list(agg_dict.keys())}")
625
+
626
+ # Log per-agent statistics
627
+ agent_stats = data.groupby('agent_id').size()
628
+ aggregated_stats = aggregated.groupby('agent_id').size()
629
+
630
+ for agent_id in agent_stats.index:
631
+ original = agent_stats[agent_id]
632
+ final = aggregated_stats.get(agent_id, 0)
633
+ agent_name = data[data['agent_id'] == agent_id]['agent_name'].iloc[0]
634
+ logger.debug(f" Agent {agent_name} ({agent_id}): {original} → {final} points")
635
+
636
+ return aggregated
637
+
638
+ def filter_high_apr_values(self, apr_df: pd.DataFrame, roi_df: pd.DataFrame = None) -> Tuple[pd.DataFrame, pd.DataFrame]:
639
+ """
640
+ Filter out APR values above the threshold and corresponding ROI values.
641
+ Forward fill gaps to maintain continuity in time series.
642
+
643
+ Args:
644
+ apr_df: DataFrame with APR data
645
+ roi_df: DataFrame with ROI data (optional)
646
+
647
+ Returns:
648
+ Tuple of (filtered_apr_df, filtered_roi_df)
649
+ """
650
+ max_apr_threshold = DATA_CONFIG.get("max_apr_threshold", 400)
651
+
652
+ if apr_df.empty:
653
+ logger.info("No APR data to filter")
654
+ return apr_df, roi_df if roi_df is not None else pd.DataFrame()
655
+
656
+ # Create copies to avoid modifying originals
657
+ apr_filtered = apr_df.copy()
658
+ roi_filtered = roi_df.copy() if roi_df is not None and not roi_df.empty else pd.DataFrame()
659
+
660
+ # Identify high APR values (both regular and adjusted APR)
661
+ high_apr_mask = pd.Series(False, index=apr_filtered.index)
662
+
663
+ if 'apr' in apr_filtered.columns:
664
+ high_apr_mask |= (apr_filtered['apr'] > max_apr_threshold)
665
+
666
+ if 'adjusted_apr' in apr_filtered.columns:
667
+ high_apr_mask |= (apr_filtered['adjusted_apr'] > max_apr_threshold)
668
+
669
+ high_apr_count = high_apr_mask.sum()
670
+
671
+ if high_apr_count == 0:
672
+ logger.info(f"No APR values above {max_apr_threshold}% threshold found")
673
+ return apr_filtered, roi_filtered
674
+
675
+ logger.info(f"Found {high_apr_count} APR values above {max_apr_threshold}% threshold")
676
+
677
+ # Get the high APR records for ROI filtering
678
+ high_apr_records = apr_filtered[high_apr_mask][['agent_id', 'timestamp']].copy()
679
+
680
+ # Remove high APR values
681
+ apr_filtered = apr_filtered[~high_apr_mask].copy()
682
+
683
+ # Forward fill APR gaps for each agent
684
+ apr_filled_count = 0
685
+ for agent_id in apr_filtered['agent_id'].unique():
686
+ agent_mask = apr_filtered['agent_id'] == agent_id
687
+ agent_data = apr_filtered[agent_mask].sort_values('timestamp')
688
+
689
+ if len(agent_data) > 0:
690
+ # Forward fill APR values
691
+ if 'apr' in apr_filtered.columns:
692
+ filled_apr = agent_data['apr'].ffill()
693
+ apr_filled_count += (filled_apr != agent_data['apr']).sum()
694
+ apr_filtered.loc[agent_mask, 'apr'] = filled_apr
695
+
696
+ # Forward fill adjusted APR values
697
+ if 'adjusted_apr' in apr_filtered.columns:
698
+ filled_adj_apr = agent_data['adjusted_apr'].ffill()
699
+ apr_filtered.loc[agent_mask, 'adjusted_apr'] = filled_adj_apr
700
+
701
+ logger.info(f"Forward filled {apr_filled_count} APR gaps")
702
+
703
+ # Filter corresponding ROI values if ROI data is provided
704
+ if not roi_filtered.empty and not high_apr_records.empty:
705
+ # Remove ROI values for the same agent-timestamp combinations
706
+ roi_before_count = len(roi_filtered)
707
+
708
+ # Merge to identify which ROI records to remove
709
+ roi_to_remove = roi_filtered.merge(
710
+ high_apr_records,
711
+ on=['agent_id', 'timestamp'],
712
+ how='inner'
713
+ )
714
+
715
+ roi_removed_count = len(roi_to_remove)
716
+
717
+ if roi_removed_count > 0:
718
+ # Remove the matching ROI records
719
+ roi_filtered = roi_filtered.merge(
720
+ high_apr_records,
721
+ on=['agent_id', 'timestamp'],
722
+ how='left',
723
+ indicator=True
724
+ )
725
+ roi_filtered = roi_filtered[roi_filtered['_merge'] == 'left_only'].drop('_merge', axis=1)
726
+
727
+ # Forward fill ROI gaps for each agent
728
+ roi_filled_count = 0
729
+ for agent_id in roi_filtered['agent_id'].unique():
730
+ agent_mask = roi_filtered['agent_id'] == agent_id
731
+ agent_data = roi_filtered[agent_mask].sort_values('timestamp')
732
+
733
+ if len(agent_data) > 0 and 'roi' in roi_filtered.columns:
734
+ filled_roi = agent_data['roi'].ffill()
735
+ roi_filled_count += (filled_roi != agent_data['roi']).sum()
736
+ roi_filtered.loc[agent_mask, 'roi'] = filled_roi
737
+
738
+ logger.info(f"Removed {roi_removed_count} corresponding ROI values")
739
+ logger.info(f"Forward filled {roi_filled_count} ROI gaps")
740
+ else:
741
+ logger.info("No corresponding ROI values to remove")
742
+
743
+ # Log final statistics
744
+ logger.info(f"High APR filtering completed:")
745
+ logger.info(f" APR threshold: {max_apr_threshold}%")
746
+ logger.info(f" APR values removed: {high_apr_count}")
747
+ logger.info(f" Final APR data points: {len(apr_filtered)}")
748
+ if not roi_filtered.empty:
749
+ logger.info(f" Final ROI data points: {len(roi_filtered)}")
750
+
751
+ return apr_filtered, roi_filtered
752
+
753
+ def save_to_csv(self, df: pd.DataFrame, filename: str) -> Optional[str]:
754
+ """Save DataFrame to CSV file."""
755
+ if df.empty:
756
+ logger.error(f"No data to save to {filename}")
757
+ return None
758
+
759
+ try:
760
+ df.to_csv(filename, index=False)
761
+ logger.info(f"Data saved to {filename}")
762
+ return filename
763
+ except Exception as e:
764
+ logger.error(f"Error saving data to {filename}: {e}")
765
+ return None
modius_performance/data/models.py ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Data models for the Modius Agent Performance application.
3
+ """
4
+ from dataclasses import dataclass
5
+ from datetime import datetime
6
+ from typing import Optional, List, Dict, Any
7
+
8
+
9
+ @dataclass
10
+ class AgentMetric:
11
+ """Represents a single agent performance metric."""
12
+ agent_id: int
13
+ agent_name: str
14
+ timestamp: datetime
15
+ metric_type: str
16
+ apr: Optional[float] = None
17
+ adjusted_apr: Optional[float] = None
18
+ roi: Optional[float] = None
19
+ volume: Optional[float] = None
20
+ agent_hash: Optional[str] = None
21
+ is_dummy: bool = False
22
+
23
+
24
+ @dataclass
25
+ class AgentInfo:
26
+ """Represents basic agent information."""
27
+ agent_id: int
28
+ agent_name: str
29
+ type_id: int
30
+
31
+
32
+ @dataclass
33
+ class AgentType:
34
+ """Represents an agent type."""
35
+ type_id: int
36
+ type_name: str
37
+
38
+
39
+ @dataclass
40
+ class AttributeDefinition:
41
+ """Represents an attribute definition."""
42
+ attr_def_id: int
43
+ attr_name: str
44
+
45
+
46
+ @dataclass
47
+ class AgentStatistics:
48
+ """Represents statistical data for an agent."""
49
+ agent_id: int
50
+ agent_name: str
51
+ total_points: int
52
+ apr_points: int
53
+ performance_points: int
54
+ real_apr_points: int
55
+ real_performance_points: int
56
+ avg_apr: Optional[float] = None
57
+ avg_performance: Optional[float] = None
58
+ max_apr: Optional[float] = None
59
+ min_apr: Optional[float] = None
60
+ avg_adjusted_apr: Optional[float] = None
61
+ max_adjusted_apr: Optional[float] = None
62
+ min_adjusted_apr: Optional[float] = None
63
+ latest_timestamp: Optional[str] = None
64
+
65
+
66
+ @dataclass
67
+ class ChartData:
68
+ """Represents data for chart visualization."""
69
+ x_values: List[datetime]
70
+ y_values: List[float]
71
+ agent_name: str
72
+ metric_type: str
73
+ color: str
74
+ visible: bool = True
75
+
76
+
77
+ @dataclass
78
+ class MovingAverageData:
79
+ """Represents moving average data."""
80
+ timestamp: datetime
81
+ value: float
82
+ moving_avg: Optional[float] = None
83
+ adjusted_moving_avg: Optional[float] = None
84
+
85
+
86
+ class APIResponse:
87
+ """Base class for API responses."""
88
+
89
+ def __init__(self, data: Dict[str, Any], status_code: int = 200):
90
+ self.data = data
91
+ self.status_code = status_code
92
+ self.success = status_code == 200
93
+
94
+ def is_success(self) -> bool:
95
+ return self.success
96
+
97
+ def get_data(self) -> Dict[str, Any]:
98
+ return self.data if self.success else {}
99
+
100
+
101
+ class AgentTypeResponse(APIResponse):
102
+ """Response for agent type API calls."""
103
+
104
+ def get_agent_type(self) -> Optional[AgentType]:
105
+ if self.success and self.data:
106
+ return AgentType(
107
+ type_id=self.data.get('type_id'),
108
+ type_name=self.data.get('type_name')
109
+ )
110
+ return None
111
+
112
+
113
+ class AttributeDefinitionResponse(APIResponse):
114
+ """Response for attribute definition API calls."""
115
+
116
+ def get_attribute_definition(self) -> Optional[AttributeDefinition]:
117
+ if self.success and self.data:
118
+ return AttributeDefinition(
119
+ attr_def_id=self.data.get('attr_def_id'),
120
+ attr_name=self.data.get('attr_name')
121
+ )
122
+ return None
123
+
124
+
125
+ class AgentsListResponse(APIResponse):
126
+ """Response for agents list API calls."""
127
+
128
+ def get_agents(self) -> List[AgentInfo]:
129
+ if self.success and isinstance(self.data, list):
130
+ return [
131
+ AgentInfo(
132
+ agent_id=agent.get('agent_id'),
133
+ agent_name=agent.get('agent_name'),
134
+ type_id=agent.get('type_id')
135
+ )
136
+ for agent in self.data
137
+ if agent.get('agent_id') and agent.get('agent_name')
138
+ ]
139
+ return []
140
+
141
+
142
+ class AttributeValuesResponse(APIResponse):
143
+ """Response for attribute values API calls."""
144
+
145
+ def get_attribute_values(self) -> List[Dict[str, Any]]:
146
+ if self.success and isinstance(self.data, list):
147
+ return self.data
148
+ return []
modius_performance/ui/__init__.py ADDED
File without changes
modius_performance/ui/dashboard.py ADDED
@@ -0,0 +1,470 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Main dashboard UI for the Modius Agent Performance application.
3
+ """
4
+ import gradio as gr
5
+ import plotly.graph_objects as go
6
+ import logging
7
+ from typing import Tuple, Optional
8
+
9
+ from ..data.data_processor import DataProcessor
10
+ from ..visualization.apr_charts import generate_apr_visualizations, generate_apr_vs_agent_hash_visualizations
11
+ from ..visualization.roi_charts import generate_roi_visualizations
12
+ from ..visualization.volume_charts import generate_volume_visualizations
13
+ from ..utils.logging_config import get_logger
14
+
15
+ logger = get_logger(__name__)
16
+
17
+
18
+ class ModiusDashboard:
19
+ """Main dashboard class for the Modius Agent Performance application."""
20
+
21
+ def __init__(self):
22
+ self.data_processor = DataProcessor()
23
+ self.global_df = None
24
+ self.global_roi_df = None
25
+ self.global_volume_df = None
26
+
27
+ def create_dashboard(self) -> gr.Blocks:
28
+ """Create the main dashboard interface."""
29
+ with gr.Blocks() as demo:
30
+ gr.Markdown("# Average Modius Agent Performance")
31
+
32
+ # Create tabs for different metrics
33
+ with gr.Tabs():
34
+ # APR Metrics tab
35
+ with gr.Tab("APR Metrics"):
36
+ apr_tab = self._create_apr_tab()
37
+
38
+ # ROI Metrics tab
39
+ with gr.Tab("ROI Metrics"):
40
+ roi_tab = self._create_roi_tab()
41
+
42
+ # Volume Metrics tab - COMMENTED OUT
43
+ # with gr.Tab("Volume Metrics"):
44
+ # volume_tab = self._create_volume_tab()
45
+
46
+ # Performance Graph tab - COMMENTED OUT
47
+ # with gr.Tab("Performance Graph"):
48
+ # performance_tab = self._create_performance_tab()
49
+
50
+ # Add custom CSS for responsive design
51
+ self._add_custom_css()
52
+
53
+ return demo
54
+
55
+ def _create_apr_tab(self) -> gr.Column:
56
+ """Create the APR metrics tab."""
57
+ with gr.Column() as apr_tab:
58
+ refresh_apr_btn = gr.Button("Refresh APR Data")
59
+
60
+ with gr.Column():
61
+ combined_apr_graph = gr.Plot(label="APR for All Agents", elem_id="responsive_apr_plot")
62
+
63
+ # Toggle controls
64
+ with gr.Row(visible=True):
65
+ gr.Markdown("##### Toggle Graph Lines", elem_id="apr_toggle_title")
66
+
67
+ with gr.Row():
68
+ with gr.Column():
69
+ with gr.Row(elem_id="apr_toggle_container"):
70
+ with gr.Column(scale=1, min_width=150):
71
+ apr_toggle = gr.Checkbox(label="APR Average (7-Day MA)", value=True, elem_id="apr_toggle")
72
+
73
+ with gr.Column(scale=1, min_width=150):
74
+ adjusted_apr_toggle = gr.Checkbox(label="ETH Adjusted APR Average (7-Day MA)", value=True, elem_id="adjusted_apr_toggle")
75
+
76
+ apr_status_text = gr.Textbox(label="Status", value="Ready", interactive=False)
77
+
78
+ # Set up event handlers
79
+ self._setup_apr_events(refresh_apr_btn, combined_apr_graph, apr_toggle, adjusted_apr_toggle, apr_status_text)
80
+
81
+ # Initialize with placeholder
82
+ apr_placeholder_fig = self._create_placeholder_chart("Click 'Refresh APR Data' to load APR graph")
83
+ combined_apr_graph.value = apr_placeholder_fig
84
+
85
+ return apr_tab
86
+
87
+ def _create_roi_tab(self) -> gr.Column:
88
+ """Create the ROI metrics tab."""
89
+ with gr.Column() as roi_tab:
90
+ refresh_roi_btn = gr.Button("Refresh ROI Data")
91
+
92
+ with gr.Column():
93
+ combined_roi_graph = gr.Plot(label="ROI for All Agents", elem_id="responsive_roi_plot")
94
+
95
+ # Toggle controls
96
+ with gr.Row(visible=True):
97
+ gr.Markdown("##### Toggle Graph Lines", elem_id="roi_toggle_title")
98
+
99
+ with gr.Row():
100
+ with gr.Column():
101
+ with gr.Row(elem_id="roi_toggle_container"):
102
+ with gr.Column(scale=1, min_width=150):
103
+ roi_toggle = gr.Checkbox(label="ROI Average (7-Day MA)", value=True, elem_id="roi_toggle")
104
+
105
+ roi_status_text = gr.Textbox(label="Status", value="Ready", interactive=False)
106
+
107
+ # Set up event handlers
108
+ self._setup_roi_events(refresh_roi_btn, combined_roi_graph, roi_toggle, roi_status_text)
109
+
110
+ # Initialize with placeholder
111
+ roi_placeholder_fig = self._create_placeholder_chart("Click 'Refresh ROI Data' to load ROI graph")
112
+ combined_roi_graph.value = roi_placeholder_fig
113
+
114
+ return roi_tab
115
+
116
+ def _create_volume_tab(self) -> gr.Column:
117
+ """Create the Volume metrics tab."""
118
+ with gr.Column() as volume_tab:
119
+ refresh_volume_btn = gr.Button("Refresh Volume Data")
120
+
121
+ with gr.Column():
122
+ combined_volume_graph = gr.Plot(label="Daily Volume Change (%) with 7-Day SMA", elem_id="responsive_volume_plot")
123
+
124
+ # Toggle controls
125
+ with gr.Row(visible=True):
126
+ gr.Markdown("##### Toggle Chart Display", elem_id="volume_toggle_title")
127
+
128
+ with gr.Row():
129
+ with gr.Column():
130
+ with gr.Row(elem_id="volume_toggle_container"):
131
+ with gr.Column(scale=1, min_width=150):
132
+ volume_bars_toggle = gr.Checkbox(label="Daily Volume Bars", value=True, elem_id="volume_bars_toggle")
133
+
134
+ with gr.Column(scale=1, min_width=150):
135
+ volume_sma_toggle = gr.Checkbox(label="7-Day SMA Line", value=True, elem_id="volume_sma_toggle")
136
+
137
+ volume_status_text = gr.Textbox(label="Status", value="Ready", interactive=False)
138
+
139
+ # Set up event handlers
140
+ self._setup_volume_events(refresh_volume_btn, combined_volume_graph, volume_bars_toggle, volume_sma_toggle, volume_status_text)
141
+
142
+ # Initialize with placeholder
143
+ volume_placeholder_fig = self._create_placeholder_chart("Click 'Refresh Volume Data' to load Volume graph")
144
+ combined_volume_graph.value = volume_placeholder_fig
145
+
146
+ return volume_tab
147
+
148
+ def _create_performance_tab(self) -> gr.Column:
149
+ """Create the Performance Graph tab."""
150
+ with gr.Column() as performance_tab:
151
+ refresh_apr_hash_btn = gr.Button("Refresh APR vs Agent Hash Data")
152
+
153
+ with gr.Column():
154
+ apr_vs_agent_hash_graph = gr.Plot(label="APR vs Agent Hash", elem_id="responsive_apr_hash_plot")
155
+
156
+ apr_hash_status_text = gr.Textbox(label="Status", value="Ready", interactive=False)
157
+
158
+ # Set up event handlers
159
+ self._setup_performance_events(refresh_apr_hash_btn, apr_vs_agent_hash_graph, apr_hash_status_text)
160
+
161
+ # Initialize with placeholder
162
+ apr_hash_placeholder_fig = self._create_placeholder_chart("Click 'Refresh APR vs Agent Hash Data' to load APR vs Agent Hash graph")
163
+ apr_vs_agent_hash_graph.value = apr_hash_placeholder_fig
164
+
165
+ return performance_tab
166
+
167
+ def _setup_apr_events(self, refresh_btn, graph, apr_toggle, adjusted_apr_toggle, status_text):
168
+ """Set up event handlers for APR tab."""
169
+
170
+ def update_apr_graph(show_apr_ma=True, show_adjusted_apr_ma=True):
171
+ try:
172
+ combined_fig, _ = generate_apr_visualizations(self.data_processor)
173
+
174
+ # Update visibility of traces based on toggle values
175
+ for trace in combined_fig.data:
176
+ if 'Average APR (7d window)' in trace.name and 'Adjusted' not in trace.name:
177
+ trace.visible = show_apr_ma
178
+ elif 'Average ETH Adjusted APR (7d window)' in trace.name:
179
+ trace.visible = show_adjusted_apr_ma
180
+
181
+ return combined_fig
182
+ except Exception as e:
183
+ logger.exception("Error generating APR visualization")
184
+ return self._create_error_chart(f"Error: {str(e)}")
185
+
186
+ def refresh_apr_data():
187
+ try:
188
+ logger.info("Manually refreshing APR data...")
189
+ self.global_df, self.global_roi_df = self.data_processor.fetch_apr_data_from_db()
190
+
191
+ if self.global_df is None or len(self.global_df) == 0:
192
+ logger.error("Failed to fetch APR data")
193
+ return graph.value, "Error: Failed to fetch APR data. Check the logs for details."
194
+
195
+ logger.info("Generating new APR visualization...")
196
+ new_graph = update_apr_graph(apr_toggle.value, adjusted_apr_toggle.value)
197
+ return new_graph, "APR data refreshed successfully"
198
+ except Exception as e:
199
+ logger.error(f"Error refreshing APR data: {e}")
200
+ return graph.value, f"Error: {str(e)}"
201
+
202
+ # Set up event handlers
203
+ refresh_btn.click(
204
+ fn=refresh_apr_data,
205
+ inputs=[],
206
+ outputs=[graph, status_text]
207
+ )
208
+
209
+ apr_toggle.change(
210
+ fn=update_apr_graph,
211
+ inputs=[apr_toggle, adjusted_apr_toggle],
212
+ outputs=[graph]
213
+ )
214
+
215
+ adjusted_apr_toggle.change(
216
+ fn=update_apr_graph,
217
+ inputs=[apr_toggle, adjusted_apr_toggle],
218
+ outputs=[graph]
219
+ )
220
+
221
+ def _setup_roi_events(self, refresh_btn, graph, roi_toggle, status_text):
222
+ """Set up event handlers for ROI tab."""
223
+
224
+ def update_roi_graph(show_roi_ma=True):
225
+ try:
226
+ combined_fig, _ = generate_roi_visualizations(self.data_processor)
227
+
228
+ # Update visibility of traces based on toggle values
229
+ for trace in combined_fig.data:
230
+ if trace.name == 'Average ROI (3d window)':
231
+ trace.visible = show_roi_ma
232
+
233
+ return combined_fig
234
+ except Exception as e:
235
+ logger.exception("Error generating ROI visualization")
236
+ return self._create_error_chart(f"Error: {str(e)}")
237
+
238
+ def refresh_roi_data():
239
+ try:
240
+ logger.info("Manually refreshing ROI data...")
241
+ self.global_df, self.global_roi_df = self.data_processor.fetch_apr_data_from_db()
242
+
243
+ if self.global_roi_df is None or len(self.global_roi_df) == 0:
244
+ logger.error("Failed to fetch ROI data")
245
+ return graph.value, "Error: Failed to fetch ROI data. Check the logs for details."
246
+
247
+ logger.info("Generating new ROI visualization...")
248
+ new_graph = update_roi_graph(roi_toggle.value)
249
+ return new_graph, "ROI data refreshed successfully"
250
+ except Exception as e:
251
+ logger.error(f"Error refreshing ROI data: {e}")
252
+ return graph.value, f"Error: {str(e)}"
253
+
254
+ # Set up event handlers
255
+ refresh_btn.click(
256
+ fn=refresh_roi_data,
257
+ inputs=[],
258
+ outputs=[graph, status_text]
259
+ )
260
+
261
+ roi_toggle.change(
262
+ fn=update_roi_graph,
263
+ inputs=[roi_toggle],
264
+ outputs=[graph]
265
+ )
266
+
267
+ def _setup_volume_events(self, refresh_btn, graph, volume_bars_toggle, volume_sma_toggle, status_text):
268
+ """Set up event handlers for Volume tab."""
269
+
270
+ def update_volume_graph(show_bars=True, show_sma=True):
271
+ try:
272
+ combined_fig, _ = generate_volume_visualizations(self.data_processor)
273
+
274
+ # Update visibility of traces based on toggle values
275
+ for trace in combined_fig.data:
276
+ if trace.name == 'Daily Volume Change':
277
+ trace.visible = show_bars
278
+ elif trace.name == '7-Day SMA':
279
+ trace.visible = show_sma
280
+
281
+ return combined_fig
282
+ except Exception as e:
283
+ logger.exception("Error generating Volume visualization")
284
+ return self._create_error_chart(f"Error: {str(e)}")
285
+
286
+ def refresh_volume_data():
287
+ try:
288
+ logger.info("Manually refreshing volume data...")
289
+ self.global_df, _ = self.data_processor.fetch_apr_data_from_db()
290
+
291
+ if self.global_df is None or len(self.global_df) == 0:
292
+ logger.error("Failed to fetch volume data")
293
+ return graph.value, "Error: Failed to fetch volume data. Check the logs for details."
294
+
295
+ logger.info("Generating new volume visualization...")
296
+ new_graph = update_volume_graph(volume_bars_toggle.value, volume_sma_toggle.value)
297
+ return new_graph, "Volume data refreshed successfully"
298
+ except Exception as e:
299
+ logger.error(f"Error refreshing volume data: {e}")
300
+ return graph.value, f"Error: {str(e)}"
301
+
302
+ # Set up event handlers
303
+ refresh_btn.click(
304
+ fn=refresh_volume_data,
305
+ inputs=[],
306
+ outputs=[graph, status_text]
307
+ )
308
+
309
+ volume_bars_toggle.change(
310
+ fn=update_volume_graph,
311
+ inputs=[volume_bars_toggle, volume_sma_toggle],
312
+ outputs=[graph]
313
+ )
314
+
315
+ volume_sma_toggle.change(
316
+ fn=update_volume_graph,
317
+ inputs=[volume_bars_toggle, volume_sma_toggle],
318
+ outputs=[graph]
319
+ )
320
+
321
+ def _setup_performance_events(self, refresh_btn, graph, status_text):
322
+ """Set up event handlers for Performance tab."""
323
+
324
+ def update_apr_vs_agent_hash_graph():
325
+ try:
326
+ if self.global_df is None or self.global_df.empty:
327
+ return self._create_error_chart("No data available. Please refresh APR data first.")
328
+
329
+ fig, _ = generate_apr_vs_agent_hash_visualizations(self.global_df)
330
+ return fig
331
+ except Exception as e:
332
+ logger.exception("Error generating APR vs Agent Hash visualization")
333
+ return self._create_error_chart(f"Error: {str(e)}")
334
+
335
+ def refresh_apr_vs_agent_hash_data():
336
+ try:
337
+ logger.info("Manually refreshing APR vs Agent Hash data...")
338
+ if self.global_df is None or self.global_df.empty:
339
+ self.global_df, _ = self.data_processor.fetch_apr_data_from_db()
340
+
341
+ if self.global_df is None or len(self.global_df) == 0:
342
+ logger.error("Failed to fetch APR data for APR vs Agent Hash visualization")
343
+ return graph.value, "Error: Failed to fetch APR data. Check the logs for details."
344
+
345
+ if 'agent_hash' not in self.global_df.columns:
346
+ logger.error("agent_hash column not found in DataFrame")
347
+ return graph.value, "Error: agent_hash column not found in data. Check the logs for details."
348
+
349
+ logger.info("Generating new APR vs Agent Hash visualization...")
350
+ new_graph = update_apr_vs_agent_hash_graph()
351
+ return new_graph, "APR vs Agent Hash data refreshed successfully"
352
+ except Exception as e:
353
+ logger.error(f"Error refreshing APR vs Agent Hash data: {e}")
354
+ return graph.value, f"Error: {str(e)}"
355
+
356
+ # Set up event handlers
357
+ refresh_btn.click(
358
+ fn=refresh_apr_vs_agent_hash_data,
359
+ inputs=[],
360
+ outputs=[graph, status_text]
361
+ )
362
+
363
+ def _create_placeholder_chart(self, message: str) -> go.Figure:
364
+ """Create a placeholder chart with a message."""
365
+ fig = go.Figure()
366
+ fig.add_annotation(
367
+ text=message,
368
+ x=0.5, y=0.5,
369
+ showarrow=False,
370
+ font=dict(size=15)
371
+ )
372
+ return fig
373
+
374
+ def _create_error_chart(self, message: str) -> go.Figure:
375
+ """Create an error chart with a message."""
376
+ fig = go.Figure()
377
+ fig.add_annotation(
378
+ text=message,
379
+ x=0.5, y=0.5,
380
+ showarrow=False,
381
+ font=dict(size=15, color="red")
382
+ )
383
+ return fig
384
+
385
+ def _add_custom_css(self):
386
+ """Add custom CSS for responsive design."""
387
+ gr.HTML("""
388
+ <style>
389
+ /* Make plots responsive */
390
+ #responsive_apr_plot, #responsive_roi_plot, #responsive_volume_plot, #responsive_apr_hash_plot {
391
+ width: 100% !important;
392
+ max-width: 100% !important;
393
+ }
394
+ #responsive_apr_plot > div, #responsive_roi_plot > div, #responsive_volume_plot > div, #responsive_apr_hash_plot > div {
395
+ width: 100% !important;
396
+ height: auto !important;
397
+ min-height: 500px !important;
398
+ }
399
+
400
+ /* Toggle checkbox styling */
401
+ #apr_toggle .gr-checkbox {
402
+ accent-color: #e74c3c !important;
403
+ }
404
+
405
+ #adjusted_apr_toggle .gr-checkbox {
406
+ accent-color: #2ecc71 !important;
407
+ }
408
+
409
+ #roi_toggle .gr-checkbox {
410
+ accent-color: #3498db !important;
411
+ }
412
+
413
+ #volume_toggle .gr-checkbox {
414
+ accent-color: #9b59b6 !important;
415
+ }
416
+
417
+ /* Make the toggle section more compact */
418
+ #apr_toggle_title, #roi_toggle_title, #volume_toggle_title {
419
+ margin-bottom: 0;
420
+ margin-top: 10px;
421
+ }
422
+
423
+ #apr_toggle_container, #roi_toggle_container, #volume_toggle_container {
424
+ margin-top: 5px;
425
+ }
426
+
427
+ /* Style the checkbox labels */
428
+ .gr-form.gr-box {
429
+ border: none !important;
430
+ background: transparent !important;
431
+ }
432
+
433
+ /* Make checkboxes and labels appear on the same line */
434
+ .gr-checkbox-container {
435
+ display: flex !important;
436
+ align-items: center !important;
437
+ }
438
+
439
+ /* Add colored indicators */
440
+ #apr_toggle .gr-checkbox-label::before {
441
+ content: "●";
442
+ color: #e74c3c;
443
+ margin-right: 5px;
444
+ }
445
+
446
+ #adjusted_apr_toggle .gr-checkbox-label::before {
447
+ content: "●";
448
+ color: #2ecc71;
449
+ margin-right: 5px;
450
+ }
451
+
452
+ #roi_toggle .gr-checkbox-label::before {
453
+ content: "●";
454
+ color: #3498db;
455
+ margin-right: 5px;
456
+ }
457
+
458
+ #volume_toggle .gr-checkbox-label::before {
459
+ content: "●";
460
+ color: #9b59b6;
461
+ margin-right: 5px;
462
+ }
463
+ </style>
464
+ """)
465
+
466
+
467
+ def create_dashboard() -> gr.Blocks:
468
+ """Create and return the dashboard."""
469
+ dashboard = ModiusDashboard()
470
+ return dashboard.create_dashboard()
modius_performance/utils/__init__.py ADDED
File without changes
modius_performance/utils/logging_config.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Logging configuration for the Modius Agent Performance application.
3
+ """
4
+ import logging
5
+ import logging.handlers
6
+ from typing import Optional
7
+
8
+ from ..config.constants import LOGGING_CONFIG
9
+
10
+
11
+ def setup_logging(level: Optional[str] = None, log_file: Optional[str] = None) -> None:
12
+ """Set up logging configuration."""
13
+ log_level = level or LOGGING_CONFIG['level']
14
+ log_file = log_file or LOGGING_CONFIG['file']
15
+ log_format = LOGGING_CONFIG['format']
16
+
17
+ # Convert string level to logging constant
18
+ if isinstance(log_level, str):
19
+ log_level = getattr(logging, log_level.upper())
20
+
21
+ # Create logger
22
+ logger = logging.getLogger()
23
+ logger.setLevel(log_level)
24
+
25
+ # Clear existing handlers
26
+ logger.handlers.clear()
27
+
28
+ # Create formatter
29
+ formatter = logging.Formatter(log_format)
30
+
31
+ # Console handler
32
+ console_handler = logging.StreamHandler()
33
+ console_handler.setLevel(log_level)
34
+ console_handler.setFormatter(formatter)
35
+ logger.addHandler(console_handler)
36
+
37
+ # File handler with rotation
38
+ if log_file:
39
+ file_handler = logging.handlers.RotatingFileHandler(
40
+ log_file,
41
+ maxBytes=10*1024*1024, # 10MB
42
+ backupCount=5
43
+ )
44
+ file_handler.setLevel(log_level)
45
+ file_handler.setFormatter(formatter)
46
+ logger.addHandler(file_handler)
47
+
48
+ # Reduce third-party library logging
49
+ logging.getLogger("urllib3").setLevel(logging.WARNING)
50
+ logging.getLogger("httpx").setLevel(logging.WARNING)
51
+ logging.getLogger("matplotlib").setLevel(logging.WARNING)
52
+ logging.getLogger("requests").setLevel(logging.WARNING)
53
+
54
+ # Log startup information
55
+ logger.info("============= APPLICATION STARTING =============")
56
+ logger.info(f"Logging level set to: {logging.getLevelName(log_level)}")
57
+ if log_file:
58
+ logger.info(f"Logging to file: {log_file}")
59
+
60
+
61
+ def get_logger(name: str) -> logging.Logger:
62
+ """Get a logger instance."""
63
+ return logging.getLogger(name)
modius_performance/visualization/__init__.py ADDED
File without changes
modius_performance/visualization/apr_charts.py ADDED
@@ -0,0 +1,395 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ APR chart implementations.
3
+ """
4
+ import plotly.graph_objects as go
5
+ import pandas as pd
6
+ import logging
7
+ from datetime import datetime
8
+ from typing import Dict, Any, Optional, Tuple
9
+
10
+ from ..config.constants import DATE_RANGES, Y_AXIS_RANGES, FILE_PATHS
11
+ from .base_chart import BaseChart
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class APRChart(BaseChart):
17
+ """Chart for APR visualizations."""
18
+
19
+ def create_chart(self, df: pd.DataFrame, **kwargs) -> go.Figure:
20
+ """Create APR time series chart."""
21
+ if df.empty:
22
+ return self._create_empty_chart("No APR data available")
23
+
24
+ # Filter for APR data only
25
+ apr_data = df[df['metric_type'] == 'APR'].copy()
26
+ if apr_data.empty:
27
+ return self._create_empty_chart("No APR data available")
28
+
29
+ # Apply daily median aggregation to reduce outliers
30
+ apr_data = self.data_processor.aggregate_daily_medians(apr_data, ['apr', 'adjusted_apr'])
31
+ if apr_data.empty:
32
+ return self._create_empty_chart("No APR data available after aggregation")
33
+
34
+ # Apply high APR filtering (400% threshold) with forward filling
35
+ apr_data, _ = self.data_processor.filter_high_apr_values(apr_data)
36
+ if apr_data.empty:
37
+ return self._create_empty_chart("No APR data available after high APR filtering")
38
+
39
+ # Save processed APR data for verification (after all processing steps)
40
+ processed_csv_path = self.data_processor.save_to_csv(apr_data, FILE_PATHS['apr_processed_csv'])
41
+ if processed_csv_path:
42
+ logger.info(f"Saved processed APR data to {processed_csv_path} for verification")
43
+ logger.info(f"Processed APR data contains {len(apr_data)} rows after agent exclusion, zero filtering, daily median aggregation, and high APR filtering")
44
+
45
+ # Filter outliers (disabled but keeping for compatibility)
46
+ apr_data = self._filter_outliers(apr_data, 'apr')
47
+
48
+ # Get time range
49
+ min_time = apr_data['timestamp'].min()
50
+ max_time = apr_data['timestamp'].max()
51
+ x_start_date = DATE_RANGES['apr_start']
52
+
53
+ # Create figure
54
+ fig = self._create_base_figure()
55
+
56
+ # Add background shapes
57
+ y_range = Y_AXIS_RANGES['apr']
58
+ self._add_background_shapes(fig, min_time, max_time, y_range['min'], y_range['max'])
59
+ self._add_zero_line(fig, min_time, max_time)
60
+
61
+ # Calculate moving averages
62
+ avg_apr_data = self._calculate_moving_average(apr_data, 'apr')
63
+
64
+ # Add individual agent data points
65
+ unique_agents = apr_data['agent_name'].unique()
66
+ color_map = self._get_color_map(unique_agents)
67
+ self._add_agent_data_points(fig, apr_data, 'apr', color_map)
68
+
69
+ # Add APR moving average line
70
+ self._add_moving_average_line(
71
+ fig, avg_apr_data, 'apr',
72
+ 'Average APR (7d window)',
73
+ self.colors['apr'],
74
+ width=3
75
+ )
76
+
77
+ # Add adjusted APR moving average if available
78
+ if 'adjusted_apr' in apr_data.columns and apr_data['adjusted_apr'].notna().any():
79
+ # Calculate adjusted APR moving average
80
+ adjusted_avg_data = self._calculate_moving_average(apr_data, 'adjusted_apr')
81
+
82
+ # Handle missing values with forward fill (fix the column name)
83
+ import warnings
84
+ with warnings.catch_warnings():
85
+ warnings.simplefilter("ignore", FutureWarning)
86
+ # Fix: Use the correct column name 'moving_avg' not 'adjusted_moving_avg'
87
+ adjusted_avg_data['moving_avg'] = adjusted_avg_data['moving_avg'].ffill()
88
+
89
+ self._add_moving_average_line(
90
+ fig, adjusted_avg_data, 'adjusted_apr',
91
+ 'Average ETH Adjusted APR (7d window)',
92
+ self.colors['adjusted_apr'],
93
+ width=3
94
+ )
95
+
96
+ # Update layout and axes
97
+ self._update_layout(
98
+ fig,
99
+ title="Modius Agents",
100
+ y_axis_title=None, # Remove single y-axis title to use region-specific labels
101
+ y_range=[y_range['min'], y_range['max']]
102
+ )
103
+
104
+ # Find last valid date for x-axis range
105
+ last_valid_date = avg_apr_data['timestamp'].max() if not avg_apr_data.empty else max_time
106
+
107
+ self._update_axes(
108
+ fig,
109
+ x_range=[x_start_date, last_valid_date],
110
+ y_range=[y_range['min'], y_range['max']]
111
+ )
112
+
113
+ # Add region-specific annotations for positive and negative areas
114
+ self._add_region_annotations(fig, y_range)
115
+
116
+ # Save chart
117
+ self._save_chart(
118
+ fig,
119
+ FILE_PATHS['apr_graph_html'],
120
+ FILE_PATHS['apr_graph_png']
121
+ )
122
+
123
+ return fig
124
+
125
+ def _add_region_annotations(self, fig: go.Figure, y_range: Dict[str, float]) -> None:
126
+ """Add annotations for positive and negative regions."""
127
+ # Annotation for negative region
128
+ fig.add_annotation(
129
+ x=-0.08,
130
+ y=-25,
131
+ xref="paper",
132
+ yref="y",
133
+ text="Percent drawdown [%]",
134
+ showarrow=False,
135
+ font=dict(
136
+ size=16,
137
+ family=self.config['font_family'],
138
+ color="black",
139
+ weight="bold"
140
+ ),
141
+ textangle=-90,
142
+ align="center"
143
+ )
144
+
145
+ # Annotation for positive region
146
+ fig.add_annotation(
147
+ x=-0.08,
148
+ y=50,
149
+ xref="paper",
150
+ yref="y",
151
+ text="Agent APR [%]",
152
+ showarrow=False,
153
+ font=dict(
154
+ size=16,
155
+ family=self.config['font_family'],
156
+ color="black",
157
+ weight="bold"
158
+ ),
159
+ textangle=-90,
160
+ align="center"
161
+ )
162
+
163
+
164
+ class APRHashChart(BaseChart):
165
+ """Chart for APR vs Agent Hash visualizations."""
166
+
167
+ def create_chart(self, df: pd.DataFrame, **kwargs) -> go.Figure:
168
+ """Create APR vs agent hash bar chart."""
169
+ if df.empty:
170
+ return self._create_empty_chart("No agent hash data available")
171
+
172
+ # Data is already filtered and processed by the calling function
173
+ # Just filter for data with agent hash
174
+ apr_data = df[df['agent_hash'].notna()].copy()
175
+ if apr_data.empty:
176
+ return self._create_empty_chart("No valid APR data with agent_hash found")
177
+
178
+ logger.info(f"APR Hash Chart: Using {len(apr_data)} processed data points")
179
+
180
+ # Create figure
181
+ fig = self._create_base_figure()
182
+
183
+ # Get unique hashes and create version mapping
184
+ unique_hashes = apr_data['agent_hash'].unique()
185
+ version_map = self._create_version_map(unique_hashes)
186
+
187
+ # Sort hashes by version
188
+ sorted_hashes = sorted(unique_hashes, key=lambda h: "1" if h.endswith("tby") else "2" if h.endswith("vq") else h)
189
+
190
+ # Add zero line for bar chart
191
+ self._add_zero_line(fig, -0.5, len(version_map) - 0.5)
192
+
193
+ # Version colors
194
+ version_colors = {
195
+ "v0.4.1": "rgba(31, 119, 180, 0.7)",
196
+ "v0.4.2": "rgba(44, 160, 44, 0.7)",
197
+ }
198
+ default_color = "rgba(214, 39, 40, 0.7)"
199
+
200
+ # Aggregate data by version for bar chart
201
+ version_data = {}
202
+ version_stats = {}
203
+
204
+ # Aggregate data by version
205
+ for agent_hash in sorted_hashes:
206
+ hash_data = apr_data[apr_data['agent_hash'] == agent_hash]
207
+ version = version_map[agent_hash]
208
+
209
+ # Calculate statistics
210
+ apr_values = hash_data['apr'].tolist()
211
+
212
+ # Store statistics for version comparison
213
+ if version not in version_stats:
214
+ version_stats[version] = {'apr_values': [], 'count': 0, 'hashes': []}
215
+
216
+ version_stats[version]['apr_values'].extend(apr_values)
217
+ version_stats[version]['count'] += len(apr_values)
218
+ version_stats[version]['hashes'].append(agent_hash)
219
+
220
+ # Create bar chart data
221
+ versions = list(version_stats.keys())
222
+ medians = []
223
+ colors = []
224
+ hover_texts = []
225
+
226
+ for version in versions:
227
+ # Calculate median APR for this version
228
+ all_values = version_stats[version]['apr_values']
229
+ median_apr = pd.Series(all_values).median()
230
+ medians.append(median_apr)
231
+
232
+ # Choose color
233
+ color = version_colors.get(version, default_color)
234
+ colors.append(color)
235
+
236
+ # Create hover text
237
+ count = version_stats[version]['count']
238
+ mean_apr = pd.Series(all_values).mean()
239
+ min_apr = pd.Series(all_values).min()
240
+ max_apr = pd.Series(all_values).max()
241
+
242
+ hover_text = (
243
+ f"Version: {version}<br>"
244
+ f"Median APR: {median_apr:.2f}%<br>"
245
+ f"Mean APR: {mean_apr:.2f}%<br>"
246
+ f"Min APR: {min_apr:.2f}%<br>"
247
+ f"Max APR: {max_apr:.2f}%<br>"
248
+ f"Data points: {count}"
249
+ )
250
+ hover_texts.append(hover_text)
251
+
252
+ # Add bar chart
253
+ fig.add_trace(
254
+ go.Bar(
255
+ x=versions,
256
+ y=medians,
257
+ marker=dict(
258
+ color=colors,
259
+ line=dict(width=1, color='black')
260
+ ),
261
+ hoverinfo='text',
262
+ hovertext=hover_texts,
263
+ showlegend=False,
264
+ name="Median APR"
265
+ )
266
+ )
267
+
268
+ # Add median value annotations on top of bars
269
+ for i, (version, median_apr) in enumerate(zip(versions, medians)):
270
+ fig.add_annotation(
271
+ x=version,
272
+ y=median_apr + (max(medians) * 0.05), # 5% above the bar
273
+ text=f"{median_apr:.1f}%",
274
+ showarrow=False,
275
+ font=dict(
276
+ family=self.config['font_family'],
277
+ size=14,
278
+ color="black",
279
+ weight="bold"
280
+ )
281
+ )
282
+
283
+ # Add version comparison annotation
284
+ self._add_version_comparison(fig, version_stats, len(versions))
285
+
286
+ # Update layout
287
+ self._update_layout(
288
+ fig,
289
+ title="Performance Graph",
290
+ height=900
291
+ )
292
+
293
+ # Update axes
294
+ self._update_axes(fig, y_auto=True)
295
+
296
+ # Update x-axis for bar chart
297
+ fig.update_xaxes(
298
+ tickangle=-45
299
+ )
300
+
301
+ # Save chart
302
+ self._save_chart(
303
+ fig,
304
+ FILE_PATHS['apr_hash_graph_html'],
305
+ FILE_PATHS['apr_hash_graph_png']
306
+ )
307
+
308
+ return fig
309
+
310
+ def _create_version_map(self, hashes: list) -> Dict[str, str]:
311
+ """Create version mapping for agent hashes."""
312
+ version_map = {}
313
+ for hash_val in hashes:
314
+ if hash_val.endswith("tby"):
315
+ version_map[hash_val] = "v0.4.1"
316
+ elif hash_val.endswith("vq"):
317
+ version_map[hash_val] = "v0.4.2"
318
+ else:
319
+ version_map[hash_val] = f"Hash: {hash_val[-6:]}"
320
+ return version_map
321
+
322
+ def _add_version_comparison(self, fig: go.Figure, version_stats: Dict, num_hashes: int) -> None:
323
+ """Add version comparison annotation."""
324
+ if "v0.4.1" in version_stats and "v0.4.2" in version_stats:
325
+ v041_values = version_stats["v0.4.1"]["apr_values"]
326
+ v042_values = version_stats["v0.4.2"]["apr_values"]
327
+
328
+ v041_median = pd.Series(v041_values).median()
329
+ v042_median = pd.Series(v042_values).median()
330
+
331
+ improvement = v042_median - v041_median
332
+ change_text = "improvement" if improvement > 0 else "decrease"
333
+
334
+ fig.add_annotation(
335
+ x=(num_hashes - 1) / 2,
336
+ y=90,
337
+ text=f"<b>Version Comparison:</b> {abs(improvement):.2f}% {change_text} from v0.4.1 to v0.4.2",
338
+ showarrow=False,
339
+ font=dict(
340
+ family=self.config['font_family'],
341
+ size=16,
342
+ color="black",
343
+ weight="bold"
344
+ ),
345
+ bgcolor="rgba(255, 255, 255, 0.9)",
346
+ bordercolor="black",
347
+ borderwidth=2,
348
+ borderpad=6,
349
+ opacity=0.9
350
+ )
351
+
352
+
353
+ def generate_apr_visualizations(data_processor=None) -> Tuple[go.Figure, Optional[str]]:
354
+ """Generate APR visualizations."""
355
+ from ..data.data_processor import DataProcessor
356
+
357
+ if data_processor is None:
358
+ data_processor = DataProcessor()
359
+
360
+ # Fetch data
361
+ apr_df, _ = data_processor.fetch_apr_data_from_db()
362
+
363
+ # Create chart
364
+ apr_chart = APRChart(data_processor)
365
+ fig, csv_path = apr_chart.generate_visualization(
366
+ apr_df,
367
+ csv_filename=FILE_PATHS['apr_csv']
368
+ )
369
+
370
+ return fig, csv_path
371
+
372
+
373
+ def generate_apr_vs_agent_hash_visualizations(df: pd.DataFrame) -> Tuple[go.Figure, Optional[str]]:
374
+ """Generate APR vs agent hash visualizations."""
375
+ from ..data.data_processor import DataProcessor
376
+
377
+ data_processor = DataProcessor()
378
+
379
+ # Use the same processed data as the APR time series chart
380
+ # First apply the same filtering pipeline to get consistent data
381
+ apr_data = df[df['metric_type'] == 'APR'].copy()
382
+ if not apr_data.empty:
383
+ # Apply daily median aggregation
384
+ apr_data = data_processor.aggregate_daily_medians(apr_data, ['apr', 'adjusted_apr'])
385
+ # Apply high APR filtering
386
+ apr_data, _ = data_processor.filter_high_apr_values(apr_data)
387
+
388
+ # Create chart using the processed data
389
+ apr_hash_chart = APRHashChart(data_processor)
390
+ fig, csv_path = apr_hash_chart.generate_visualization(
391
+ apr_data,
392
+ csv_filename=FILE_PATHS['apr_hash_csv']
393
+ )
394
+
395
+ return fig, csv_path
modius_performance/visualization/base_chart.py ADDED
@@ -0,0 +1,365 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Base chart class for creating visualizations.
3
+ """
4
+ import plotly.graph_objects as go
5
+ import plotly.express as px
6
+ import pandas as pd
7
+ import logging
8
+ from datetime import datetime
9
+ from typing import List, Dict, Any, Optional, Tuple
10
+ from abc import ABC, abstractmethod
11
+
12
+ from ..config.constants import CHART_CONFIG, CHART_COLORS, Y_AXIS_RANGES, FILE_PATHS
13
+ from ..data.data_processor import DataProcessor
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class BaseChart(ABC):
19
+ """Base class for all chart visualizations."""
20
+
21
+ def __init__(self, data_processor: DataProcessor = None):
22
+ self.data_processor = data_processor or DataProcessor()
23
+ self.config = CHART_CONFIG
24
+ self.colors = CHART_COLORS
25
+ self.y_ranges = Y_AXIS_RANGES
26
+ self.file_paths = FILE_PATHS
27
+
28
+ @abstractmethod
29
+ def create_chart(self, df: pd.DataFrame, **kwargs) -> go.Figure:
30
+ """Create the chart visualization."""
31
+ pass
32
+
33
+ def _create_base_figure(self) -> go.Figure:
34
+ """Create a base figure with common settings."""
35
+ return go.Figure()
36
+
37
+ def _add_background_shapes(self, fig: go.Figure, min_time: datetime, max_time: datetime,
38
+ y_min: float, y_max: float) -> None:
39
+ """Add background shapes for positive and negative regions."""
40
+ # Add shape for positive region (above zero)
41
+ fig.add_shape(
42
+ type="rect",
43
+ fillcolor=self.colors['positive_region'],
44
+ line=dict(width=0),
45
+ y0=0, y1=y_max,
46
+ x0=min_time, x1=max_time,
47
+ layer="below"
48
+ )
49
+
50
+ # Add shape for negative region (below zero)
51
+ fig.add_shape(
52
+ type="rect",
53
+ fillcolor=self.colors['negative_region'],
54
+ line=dict(width=0),
55
+ y0=y_min, y1=0,
56
+ x0=min_time, x1=max_time,
57
+ layer="below"
58
+ )
59
+
60
+ def _add_zero_line(self, fig: go.Figure, min_time: datetime, max_time: datetime) -> None:
61
+ """Add a zero line to the chart."""
62
+ fig.add_shape(
63
+ type="line",
64
+ line=dict(dash="solid", width=1.5, color=self.colors['zero_line']),
65
+ y0=0, y1=0,
66
+ x0=min_time, x1=max_time
67
+ )
68
+
69
+ def _update_layout(self, fig: go.Figure, title: str, y_axis_title: str = None,
70
+ height: int = None, y_range: List[float] = None) -> None:
71
+ """Update the figure layout with common settings."""
72
+ fig.update_layout(
73
+ title=dict(
74
+ text=title,
75
+ font=dict(
76
+ family=self.config['font_family'],
77
+ size=self.config['title_size'],
78
+ color="black",
79
+ weight="bold"
80
+ )
81
+ ),
82
+ xaxis_title=None,
83
+ yaxis_title=None,
84
+ template=self.config['template'],
85
+ height=height or self.config['height'],
86
+ autosize=True,
87
+ legend=dict(
88
+ orientation="h",
89
+ yanchor="bottom",
90
+ y=1.02,
91
+ xanchor="right",
92
+ x=1,
93
+ groupclick="toggleitem",
94
+ font=dict(
95
+ family=self.config['font_family'],
96
+ size=self.config['legend_font_size'],
97
+ color="black",
98
+ weight="bold"
99
+ )
100
+ ),
101
+ margin=dict(r=30, l=120, t=40, b=50),
102
+ hovermode="closest"
103
+ )
104
+
105
+ # Add y-axis annotation if provided
106
+ if y_axis_title:
107
+ fig.add_annotation(
108
+ x=-0.08,
109
+ y=0 if y_range is None else (y_range[0] + y_range[1]) / 2,
110
+ xref="paper",
111
+ yref="y",
112
+ text=y_axis_title,
113
+ showarrow=False,
114
+ font=dict(
115
+ size=16,
116
+ family=self.config['font_family'],
117
+ color="black",
118
+ weight="bold"
119
+ ),
120
+ textangle=-90,
121
+ align="center"
122
+ )
123
+
124
+ def _update_axes(self, fig: go.Figure, x_range: List[datetime] = None,
125
+ y_range: List[float] = None, y_auto: bool = False) -> None:
126
+ """Update the axes with common settings."""
127
+ # Update y-axis
128
+ y_axis_config = {
129
+ 'showgrid': True,
130
+ 'gridwidth': 1,
131
+ 'gridcolor': 'rgba(0,0,0,0.1)',
132
+ 'tickformat': ".2f",
133
+ 'tickfont': dict(
134
+ size=self.config['axis_font_size'],
135
+ family=self.config['font_family'],
136
+ color="black",
137
+ weight="bold"
138
+ ),
139
+ 'title': None
140
+ }
141
+
142
+ if y_auto:
143
+ y_axis_config['autorange'] = True
144
+ elif y_range:
145
+ y_axis_config['autorange'] = False
146
+ y_axis_config['range'] = y_range
147
+
148
+ fig.update_yaxes(**y_axis_config)
149
+
150
+ # Update x-axis
151
+ x_axis_config = {
152
+ 'showgrid': True,
153
+ 'gridwidth': 1,
154
+ 'gridcolor': 'rgba(0,0,0,0.1)',
155
+ 'tickformat': "%b %d",
156
+ 'tickangle': -30,
157
+ 'tickfont': dict(
158
+ size=self.config['axis_font_size'],
159
+ family=self.config['font_family'],
160
+ color="black",
161
+ weight="bold"
162
+ ),
163
+ 'title': None
164
+ }
165
+
166
+ if x_range:
167
+ x_axis_config['autorange'] = False
168
+ x_axis_config['range'] = x_range
169
+
170
+ fig.update_xaxes(**x_axis_config)
171
+
172
+ def _add_agent_data_points(self, fig: go.Figure, df: pd.DataFrame, value_column: str,
173
+ color_map: Dict[str, str], max_visible: int = None) -> None:
174
+ """Add individual agent data points to the chart."""
175
+ if df.empty:
176
+ return
177
+
178
+ unique_agents = df['agent_name'].unique()
179
+ max_visible = max_visible or self.config['max_visible_agents']
180
+
181
+ # Calculate agent activity to determine which to show by default
182
+ agent_counts = df['agent_name'].value_counts()
183
+ top_agents = agent_counts.nlargest(min(max_visible, len(agent_counts))).index.tolist()
184
+
185
+ logger.info(f"Showing {len(top_agents)} agents by default out of {len(unique_agents)} total agents")
186
+
187
+ for agent_name in unique_agents:
188
+ agent_data = df[df['agent_name'] == agent_name]
189
+
190
+ x_values = agent_data['timestamp'].tolist()
191
+ y_values = agent_data[value_column].tolist()
192
+
193
+ # Determine visibility
194
+ is_visible = False # Hide all agent data points by default
195
+
196
+ fig.add_trace(
197
+ go.Scatter(
198
+ x=x_values,
199
+ y=y_values,
200
+ mode='markers',
201
+ marker=dict(
202
+ color=color_map.get(agent_name, 'gray'),
203
+ symbol='circle',
204
+ size=10,
205
+ line=dict(width=1, color='black')
206
+ ),
207
+ name=f'Agent: {agent_name} ({value_column.upper()})',
208
+ hovertemplate=f'Time: %{{x}}<br>{value_column.upper()}: %{{y:.2f}}<br>Agent: {agent_name}<extra></extra>',
209
+ visible=is_visible
210
+ )
211
+ )
212
+ logger.info(f"Added {value_column} data points for agent {agent_name} with {len(x_values)} points (visible: {is_visible})")
213
+
214
+ def _add_moving_average_line(self, fig: go.Figure, avg_data: pd.DataFrame,
215
+ value_column: str, line_name: str, color: str,
216
+ width: int = 2, hover_data: List[str] = None) -> None:
217
+ """Add a moving average line to the chart."""
218
+ if avg_data.empty or 'moving_avg' not in avg_data.columns:
219
+ return
220
+
221
+ # Filter out NaT values before processing - be more aggressive
222
+ clean_data = avg_data.copy()
223
+
224
+ # Remove rows with NaT timestamps more comprehensively
225
+ clean_data = clean_data.dropna(subset=['timestamp'])
226
+ clean_data = clean_data[clean_data['timestamp'].notna()]
227
+ clean_data = clean_data[~clean_data['timestamp'].isnull()]
228
+
229
+ # Additional check for pandas NaT specifically
230
+ if hasattr(pd, 'NaT'):
231
+ clean_data = clean_data[clean_data['timestamp'] != pd.NaT]
232
+
233
+ # Also filter out NaN moving averages
234
+ clean_data = clean_data.dropna(subset=['moving_avg'])
235
+ clean_data = clean_data[clean_data['moving_avg'].notna()]
236
+
237
+ if clean_data.empty:
238
+ logger.warning("No valid timestamps found for " + str(line_name))
239
+ return
240
+
241
+ x_values = clean_data['timestamp'].tolist()
242
+ y_values = clean_data['moving_avg'].tolist()
243
+
244
+ # Create hover text without any f-strings to avoid strftime issues
245
+ if hover_data:
246
+ hover_text = hover_data
247
+ else:
248
+ hover_text = []
249
+ for _, row in clean_data.iterrows():
250
+ try:
251
+ # Convert timestamp to string safely
252
+ ts = row['timestamp']
253
+
254
+ # More comprehensive NaT checking
255
+ if pd.isna(ts) or pd.isnull(ts) or (hasattr(pd, 'NaT') and ts is pd.NaT):
256
+ time_str = "Invalid Date"
257
+ elif hasattr(ts, 'strftime'):
258
+ try:
259
+ time_str = ts.strftime('%Y-%m-%d %H:%M:%S')
260
+ except (ValueError, TypeError):
261
+ time_str = str(ts)
262
+ else:
263
+ time_str = str(ts)
264
+
265
+ # Build hover text using string concatenation only
266
+ hover_line = "Time: " + time_str + "<br>"
267
+
268
+ # Safely format moving average value
269
+ try:
270
+ avg_val = row['moving_avg']
271
+ if pd.isna(avg_val) or pd.isnull(avg_val):
272
+ avg_str = "N/A"
273
+ else:
274
+ avg_str = "{:.2f}".format(float(avg_val))
275
+ except (ValueError, TypeError):
276
+ avg_str = "N/A"
277
+
278
+ hover_line += "Avg " + value_column.upper() + " (7d window): " + avg_str
279
+ hover_text.append(hover_line)
280
+
281
+ except Exception as e:
282
+ logger.warning("Error formatting timestamp for hover text: " + str(e))
283
+ # Fallback hover text
284
+ hover_line = "Time: Invalid Date<br>"
285
+ hover_line += "Avg " + value_column.upper() + " (3d window): N/A"
286
+ hover_text.append(hover_line)
287
+
288
+ fig.add_trace(
289
+ go.Scatter(
290
+ x=x_values,
291
+ y=y_values,
292
+ mode='lines',
293
+ line=dict(color=color, width=width, shape='spline', smoothing=1.3),
294
+ name=line_name,
295
+ hovertext=hover_text,
296
+ hoverinfo='text',
297
+ visible=True
298
+ )
299
+ )
300
+ logger.info("Added moving average line '" + str(line_name) + "' with " + str(len(x_values)) + " points")
301
+
302
+ def _filter_outliers(self, df: pd.DataFrame, column: str) -> pd.DataFrame:
303
+ """Filter outliers from the data - DISABLED: Return data unchanged."""
304
+ # Outlier filtering disabled - return original data
305
+ logger.info(f"Outlier filtering disabled for {column} column - returning all data")
306
+ return df
307
+
308
+ def _calculate_moving_average(self, df: pd.DataFrame, value_column: str) -> pd.DataFrame:
309
+ """Calculate moving average for the data."""
310
+ return self.data_processor.calculate_moving_average(df, value_column)
311
+
312
+ def _save_chart(self, fig: go.Figure, html_filename: str, png_filename: str = None) -> None:
313
+ """Save the chart to HTML and optionally PNG."""
314
+ try:
315
+ fig.write_html(html_filename, include_plotlyjs='cdn', full_html=False)
316
+ logger.info(f"Chart saved to {html_filename}")
317
+
318
+ if png_filename:
319
+ try:
320
+ fig.write_image(png_filename)
321
+ logger.info(f"Chart also saved to {png_filename}")
322
+ except Exception as e:
323
+ logger.error(f"Error saving PNG image: {e}")
324
+ logger.info(f"Chart saved to {html_filename} only")
325
+ except Exception as e:
326
+ logger.error(f"Error saving chart: {e}")
327
+
328
+ def generate_visualization(self, df: pd.DataFrame, **kwargs) -> Tuple[go.Figure, Optional[str]]:
329
+ """Generate the complete visualization including chart and CSV export."""
330
+ if df.empty:
331
+ logger.info("No data available for visualization.")
332
+ fig = self._create_empty_chart("No data available")
333
+ return fig, None
334
+
335
+ # Create the chart
336
+ fig = self.create_chart(df, **kwargs)
337
+
338
+ # Save to CSV
339
+ csv_filename = kwargs.get('csv_filename')
340
+ if csv_filename:
341
+ csv_path = self.data_processor.save_to_csv(df, csv_filename)
342
+ else:
343
+ csv_path = None
344
+
345
+ return fig, csv_path
346
+
347
+ def _create_empty_chart(self, message: str) -> go.Figure:
348
+ """Create an empty chart with a message."""
349
+ fig = go.Figure()
350
+ fig.add_annotation(
351
+ x=0.5, y=0.5,
352
+ text=message,
353
+ font=dict(size=20),
354
+ showarrow=False
355
+ )
356
+ fig.update_layout(
357
+ xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
358
+ yaxis=dict(showgrid=False, zeroline=False, showticklabels=False)
359
+ )
360
+ return fig
361
+
362
+ def _get_color_map(self, agents: List[str]) -> Dict[str, str]:
363
+ """Generate a color map for agents."""
364
+ colors = px.colors.qualitative.Plotly[:len(agents)]
365
+ return {agent: colors[i % len(colors)] for i, agent in enumerate(agents)}
modius_performance/visualization/roi_charts.py ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ ROI chart implementations.
3
+ """
4
+ import plotly.graph_objects as go
5
+ import pandas as pd
6
+ import logging
7
+ from datetime import datetime
8
+ from typing import Dict, Any, Optional, Tuple
9
+
10
+ from ..config.constants import DATE_RANGES, Y_AXIS_RANGES, FILE_PATHS
11
+ from .base_chart import BaseChart
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class ROIChart(BaseChart):
17
+ """Chart for ROI visualizations."""
18
+
19
+ def create_chart(self, df: pd.DataFrame, **kwargs) -> go.Figure:
20
+ """Create ROI time series chart."""
21
+ if df.empty:
22
+ return self._create_empty_chart("No ROI data available")
23
+
24
+ # Filter for ROI data only
25
+ roi_data = df[df['metric_type'] == 'ROI'].copy()
26
+ if roi_data.empty:
27
+ return self._create_empty_chart("No ROI data available")
28
+
29
+ # ROI data is already in percentage format from corrected CSV
30
+ # No conversion needed
31
+
32
+ # Apply daily median aggregation to reduce outliers
33
+ roi_data = self.data_processor.aggregate_daily_medians(roi_data, ['roi'])
34
+ if roi_data.empty:
35
+ return self._create_empty_chart("No ROI data available after aggregation")
36
+
37
+ # Apply high APR filtering to ROI data (need to get APR data first to determine what to filter)
38
+ # Fetch APR data to determine which agent-timestamp combinations to filter
39
+ apr_df, _ = self.data_processor.fetch_apr_data_from_db()
40
+ if not apr_df.empty:
41
+ # Apply same processing to APR data to get the filtering reference
42
+ apr_processed = apr_df[apr_df['metric_type'] == 'APR'].copy()
43
+ apr_processed = self.data_processor.aggregate_daily_medians(apr_processed, ['apr', 'adjusted_apr'])
44
+
45
+ # Apply high APR filtering to both datasets
46
+ _, roi_data = self.data_processor.filter_high_apr_values(apr_processed, roi_data)
47
+
48
+ if roi_data.empty:
49
+ return self._create_empty_chart("No ROI data available after high APR filtering")
50
+
51
+ # Save processed ROI data for verification (after all processing steps)
52
+ processed_csv_path = self.data_processor.save_to_csv(roi_data, FILE_PATHS['roi_processed_csv'])
53
+ if processed_csv_path:
54
+ logger.info(f"Saved processed ROI data to {processed_csv_path} for verification")
55
+ logger.info(f"Processed ROI data contains {len(roi_data)} rows after agent exclusion, daily median aggregation, and high APR filtering")
56
+
57
+ # Filter outliers (disabled but keeping for compatibility)
58
+ roi_data = self._filter_outliers(roi_data, 'roi')
59
+
60
+ # Get time range
61
+ min_time = roi_data['timestamp'].min()
62
+ max_time = roi_data['timestamp'].max()
63
+ x_start_date = min_time # Use actual start date for ROI
64
+
65
+ # Calculate average runtime for title
66
+ fixed_start_date = DATE_RANGES['feb_start']
67
+ agent_runtimes = {}
68
+ for agent_id in roi_data['agent_id'].unique():
69
+ agent_data = roi_data[roi_data['agent_id'] == agent_id]
70
+ agent_name = agent_data['agent_name'].iloc[0]
71
+ last_report = agent_data['timestamp'].max()
72
+ runtime_days = (last_report - fixed_start_date).total_seconds() / (24 * 3600)
73
+ agent_runtimes[agent_id] = {
74
+ 'agent_name': agent_name,
75
+ 'last_report': last_report,
76
+ 'runtime_days': runtime_days
77
+ }
78
+
79
+ avg_runtime = sum(data['runtime_days'] for data in agent_runtimes.values()) / len(agent_runtimes) if agent_runtimes else 0
80
+
81
+ # Create figure
82
+ fig = self._create_base_figure()
83
+
84
+ # Add background shapes
85
+ y_range = Y_AXIS_RANGES['roi']
86
+ self._add_background_shapes(fig, min_time, max_time, y_range['min'], y_range['max'])
87
+ self._add_zero_line(fig, min_time, max_time)
88
+
89
+ # Calculate moving averages
90
+ avg_roi_data = self._calculate_moving_average(roi_data, 'roi')
91
+
92
+ # Add individual agent data points
93
+ unique_agents = roi_data['agent_name'].unique()
94
+ color_map = self._get_color_map(unique_agents)
95
+ self._add_agent_data_points(fig, roi_data, 'roi', color_map)
96
+
97
+ # Add ROI moving average line
98
+ self._add_moving_average_line(
99
+ fig, avg_roi_data, 'roi',
100
+ 'Average ROI (3d window)',
101
+ self.colors['roi'],
102
+ width=2
103
+ )
104
+
105
+ # Update layout and axes
106
+ title = f"Modius Agents ROI (over avg. {avg_runtime:.1f} days runtime)"
107
+ self._update_layout(
108
+ fig,
109
+ title=title,
110
+ y_axis_title="ROI [%]",
111
+ y_range=[y_range['min'], y_range['max']]
112
+ )
113
+
114
+ # Find last valid date for x-axis range
115
+ last_valid_date = avg_roi_data['timestamp'].max() if not avg_roi_data.empty else max_time
116
+
117
+ self._update_axes(
118
+ fig,
119
+ x_range=[x_start_date, last_valid_date],
120
+ y_range=[y_range['min'], y_range['max']]
121
+ )
122
+
123
+ # Save chart
124
+ self._save_chart(
125
+ fig,
126
+ FILE_PATHS['roi_graph_html'],
127
+ FILE_PATHS['roi_graph_png']
128
+ )
129
+
130
+ return fig
131
+
132
+
133
+ def generate_roi_visualizations(data_processor=None) -> Tuple[go.Figure, Optional[str]]:
134
+ """Generate ROI visualizations."""
135
+ from ..data.data_processor import DataProcessor
136
+
137
+ if data_processor is None:
138
+ data_processor = DataProcessor()
139
+
140
+ # Fetch data
141
+ _, roi_df = data_processor.fetch_apr_data_from_db()
142
+
143
+ # Create chart
144
+ roi_chart = ROIChart(data_processor)
145
+ fig, csv_path = roi_chart.generate_visualization(
146
+ roi_df,
147
+ csv_filename=FILE_PATHS['roi_csv']
148
+ )
149
+
150
+ return fig, csv_path
modius_performance/visualization/volume_charts.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Volume chart implementations.
3
+ """
4
+ import plotly.graph_objects as go
5
+ import pandas as pd
6
+ import logging
7
+ from datetime import datetime
8
+ from typing import Dict, Any, Optional, Tuple
9
+
10
+ from ..config.constants import Y_AXIS_RANGES, FILE_PATHS
11
+ from .base_chart import BaseChart
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class VolumeChart(BaseChart):
17
+ """Chart for Volume visualizations."""
18
+
19
+ def create_chart(self, df: pd.DataFrame, **kwargs) -> go.Figure:
20
+ """Create Cumulative Volume bar chart."""
21
+ if df.empty:
22
+ return self._create_empty_chart("No volume data available")
23
+
24
+ # Calculate daily volume changes using the new method
25
+ daily_data = self.data_processor.calculate_daily_volume_changes(df)
26
+ if daily_data.empty:
27
+ return self._create_empty_chart("No daily volume data available")
28
+
29
+ # Create figure
30
+ fig = self._create_base_figure()
31
+
32
+ # Get time range
33
+ min_time = daily_data['date'].min()
34
+ max_time = daily_data['date'].max()
35
+
36
+ # Determine bar colors based on daily volume (all bars will be blue for cumulative volume)
37
+ bar_colors = ['blue'] * len(daily_data)
38
+
39
+ # Create custom hover text for bars
40
+ bar_hover_text = []
41
+ for _, row in daily_data.iterrows():
42
+ date_str = row['date'].strftime('%Y-%m-%d')
43
+ bar_hover_text.append(
44
+ f"Date: {date_str}<br>"
45
+ f"Daily Volume: {row['volume']:.2f}<br>"
46
+ f"Cumulative Volume: {row['cumulative_volume']:.2f}<br>"
47
+ f"Day-over-Day Change: {row['day_over_day_pct']:.1f}%<br>"
48
+ f"7-Day SMA: {row['sma_7d']:.1f}%"
49
+ )
50
+
51
+ # Add cumulative volume bar chart
52
+ fig.add_trace(
53
+ go.Bar(
54
+ x=daily_data['date'],
55
+ y=daily_data['cumulative_volume'],
56
+ marker=dict(
57
+ color=bar_colors,
58
+ line=dict(width=1, color='black'),
59
+ opacity=0.7
60
+ ),
61
+ name='Daily Volume Change',
62
+ hovertext=bar_hover_text,
63
+ hoverinfo='text',
64
+ customdata=daily_data[['volume', 'day_over_day_pct']].values
65
+ )
66
+ )
67
+
68
+ # Add 7-Day SMA line
69
+ fig.add_trace(
70
+ go.Scatter(
71
+ x=daily_data['date'],
72
+ y=daily_data['sma_7d'],
73
+ mode='lines',
74
+ line=dict(color='red', width=3),
75
+ name='7-Day SMA',
76
+ hovertemplate='Date: %{x}<br>7-Day SMA: %{y:.1f}%<extra></extra>',
77
+ yaxis='y2'
78
+ )
79
+ )
80
+
81
+ # Update layout and axes
82
+ self._update_layout(
83
+ fig,
84
+ title="Daily Volume Change (%) with 7-Day SMA",
85
+ y_axis_title="Cumulative Volume"
86
+ )
87
+
88
+ # Update axes
89
+ self._update_axes(
90
+ fig,
91
+ x_range=[min_time, max_time],
92
+ y_auto=True
93
+ )
94
+
95
+ # Update primary y-axis to show volume format
96
+ fig.update_yaxes(tickformat=".2f")
97
+
98
+ # Add secondary y-axis for SMA
99
+ fig.update_layout(
100
+ yaxis2=dict(
101
+ title="Percentage Change (%)",
102
+ overlaying='y',
103
+ side='right',
104
+ tickformat=".1f"
105
+ )
106
+ )
107
+
108
+ # Save chart
109
+ self._save_chart(
110
+ fig,
111
+ FILE_PATHS['volume_graph_html'],
112
+ FILE_PATHS['volume_graph_png']
113
+ )
114
+
115
+ return fig
116
+
117
+
118
+ def generate_volume_visualizations(data_processor=None) -> Tuple[go.Figure, Optional[str]]:
119
+ """Generate Volume visualizations."""
120
+ from ..data.data_processor import DataProcessor
121
+
122
+ if data_processor is None:
123
+ data_processor = DataProcessor()
124
+
125
+ # Fetch data
126
+ apr_df, _ = data_processor.fetch_apr_data_from_db()
127
+
128
+ # Filter for records with volume data
129
+ volume_df = apr_df[apr_df['volume'].notna()].copy()
130
+
131
+ # Create chart
132
+ volume_chart = VolumeChart(data_processor)
133
+ fig, csv_path = volume_chart.generate_visualization(
134
+ volume_df,
135
+ csv_filename=FILE_PATHS['volume_csv']
136
+ )
137
+
138
+ return fig, csv_path
requirements.txt DELETED
@@ -1,8 +0,0 @@
1
- web3
2
- gradio
3
- plotly
4
- pandas
5
- requests
6
- python-dotenv
7
- kaleido
8
- matplotlib