def find_double_fees(withdrawals, fees, blacklist=None): assert len(withdrawals) and len(fees), "no events loaded" print(f"processing {len(withdrawals)=} and {len(fees)=}") overlap = {log["transactionHash"] for log in withdrawals } & {log["transactionHash"] for log in fees} print(f"{len(overlap)=}") withdrawals = decode_logs( [log for log in withdrawals if log["transactionHash"] in overlap]) fees = decode_logs( [log for log in fees if log["transactionHash"] in overlap]) tx_to_refund = { event.transaction_hash: tuple(event.values())[2] for event in fees } refunds = Counter() for item in withdrawals: tx = item.transaction_hash is_contract = bool(web3.eth.get_code(tuple(item.values())[0])) user = chain.get_transaction(tx).sender if is_contract else tuple( item.values())[0] if blacklist and user in blacklist: continue refunds[user] += tx_to_refund[item.transaction_hash] return dict(refunds.most_common())
def populate_erc20_transfers(row): tx = chain.get_transaction(row['tx_hash']) tx.wait(1) if 'Transfer' not in tx.events: return [] return [ { 'date': row['date'], 'from': ens_reverser(t['from'] if 'from' in t else t['src']), 'to': ens_reverser(t['to'] if 'to' in t else t['dst']), 'amount': Decimal(t['value'] if 'value' in t else t['wad']) / decimals(t.address), 'currency': token_name(t.address), 'tx_hash': row['tx_hash'], } for t in tx.events['Transfer'] ]
def populate_erc20_transfers(row): tx = chain.get_transaction(row['tx_hash']) tx.wait(1) if 'Transfer' not in tx.events: return [] dst = ['to', '_to', 'dst', 'receiver'] src = ['from', '_from', 'src', 'sender'] wad = ['value', '_value', 'wad', 'amount'] return [{ 'date': row['date'], 'from': ens_reverser(next(t[k] for k in src if k in t)), 'to': ens_reverser(next(t[k] for k in dst if k in t)), 'amount': Decimal(next(t[k] for k in wad if k in t)) / decimals(t.address), 'currency': token_name(t.address), 'tx_hash': row['tx_hash'], } for t in tx.events['Transfer']]
def print_tx_info(tx, call_trace=False): tx = chain.get_transaction(tx) # sometimes logs don't parse # TODO: brownie should probably handle this for us if tx.events and tx.logs and len(tx.events) != len(tx.logs): for log in tx.logs: try: load_contract(log.address) except Exception as e: logger.warning(f"Unable to load contract @ {log.address}: {e}") tx = network.transaction.TransactionReceipt(tx.id) print() tx.info() if call_trace: print() tx.call_trace() if tx.status == 0: # revert! print() tx.traceback() print() print("Sometimes useful, but often slow: tx.trace") print() print("[ctrl+d] to check another transaction") print() extra_locals = COMMON_HELPERS extra_locals.update({"tx": tx}) debug_shell(extra_locals)