def _maybe_update_events_legacy_contrats( decoded_events: List[HistoryBaseEntry], sender: ChecksumEthAddress, source_token: Asset, destination_token: Asset, spent_amount: FVal, return_amount: FVal, ) -> None: """ Use the information from a trade transaction to modify the HistoryEvents from receive/send to trade if the conditions are correct. """ in_event = out_event = None for event in decoded_events: if event.event_type == HistoryEventType.SPEND and event.location_label == sender and event.asset == source_token and event.balance.amount == spent_amount: # noqa: E501 event.event_type = HistoryEventType.TRADE event.event_subtype = HistoryEventSubType.SPEND event.counterparty = CPT_KYBER event.notes = f'Swap {event.balance.amount} {event.asset.symbol} in kyber' out_event = event elif event.event_type == HistoryEventType.RECEIVE and event.location_label == sender and event.balance.amount == return_amount and destination_token == event.asset: # noqa: E501 event.event_type = HistoryEventType.TRADE event.event_subtype = HistoryEventSubType.RECEIVE event.counterparty = CPT_KYBER event.notes = f'Receive {event.balance.amount} {event.asset.symbol} from kyber swap' # noqa: E501 in_event = event maybe_reshuffle_events(out_event=out_event, in_event=in_event)
def _decode_redeem( self, tx_log: EthereumTxReceiptLog, decoded_events: List[HistoryBaseEntry], compound_token: EthereumToken, ) -> Tuple[Optional[HistoryBaseEntry], Optional[ActionItem]]: redeemer = hex_or_bytes_to_address(tx_log.data[0:32]) if not self.base.is_tracked(redeemer): return None, None redeem_amount_raw = hex_or_bytes_to_int(tx_log.data[32:64]) redeem_tokens_raw = hex_or_bytes_to_int(tx_log.data[64:96]) underlying_token = symbol_to_asset_or_token(compound_token.symbol[1:]) redeem_amount = asset_normalized_value(redeem_amount_raw, underlying_token) redeem_tokens = token_normalized_value(redeem_tokens_raw, compound_token) out_event = in_event = None for event in decoded_events: # Find the transfer event which should have come before the redeeming if event.event_type == HistoryEventType.RECEIVE and event.asset == underlying_token and event.balance.amount == redeem_amount: # noqa: E501 event.event_type = HistoryEventType.WITHDRAWAL event.event_subtype = HistoryEventSubType.REMOVE_ASSET event.counterparty = CPT_COMPOUND event.notes = f'Withdraw {redeem_amount} {underlying_token.symbol} from compound' in_event = event if event.event_type == HistoryEventType.SPEND and event.asset == compound_token and event.balance.amount == redeem_tokens: # noqa: E501 event.event_type = HistoryEventType.SPEND event.event_subtype = HistoryEventSubType.RETURN_WRAPPED event.counterparty = CPT_COMPOUND event.notes = f'Return {redeem_tokens} {compound_token.symbol} to compound' out_event = event maybe_reshuffle_events(out_event=out_event, in_event=in_event, events_list=decoded_events) return None, None
def _decode_swapped( # pylint: disable=no-self-use self, tx_log: EthereumTxReceiptLog, transaction: EthereumTransaction, # pylint: disable=unused-argument decoded_events: List[HistoryBaseEntry], # pylint: disable=unused-argument all_logs: List[EthereumTxReceiptLog], # pylint: disable=unused-argument ) -> Tuple[Optional[HistoryBaseEntry], Optional[ActionItem]]: sender = hex_or_bytes_to_address(tx_log.topics[1]) source_token_address = hex_or_bytes_to_address(tx_log.topics[2]) destination_token_address = hex_or_bytes_to_address(tx_log.topics[3]) source_token = ethaddress_to_asset(source_token_address) if source_token is None: return None, None destination_token = ethaddress_to_asset(destination_token_address) if destination_token is None: return None, None receiver = hex_or_bytes_to_address(tx_log.data[0:32]) spent_amount_raw = hex_or_bytes_to_int(tx_log.data[64:96]) return_amount_raw = hex_or_bytes_to_int(tx_log.data[96:128]) spent_amount = asset_normalized_value(amount=spent_amount_raw, asset=source_token) return_amount = asset_normalized_value(amount=return_amount_raw, asset=destination_token) out_event = in_event = None for event in decoded_events: # Now find the sending and receiving events if event.event_type == HistoryEventType.SPEND and event.location_label == sender and spent_amount == event.balance.amount and source_token == event.asset: # noqa: E501 event.event_type = HistoryEventType.TRADE event.event_subtype = HistoryEventSubType.SPEND event.counterparty = CPT_ONEINCH_V2 event.notes = f'Swap {spent_amount} {source_token.symbol} in {CPT_ONEINCH_V2}' # noqa: E501 out_event = event elif event.event_type == HistoryEventType.RECEIVE and event.location_label == sender and receiver == event.location_label and return_amount == event.balance.amount and destination_token == event.asset: # noqa: E501 event.event_type = HistoryEventType.TRADE event.event_subtype = HistoryEventSubType.RECEIVE event.counterparty = CPT_ONEINCH_V2 event.notes = f'Receive {return_amount} {destination_token.symbol} from {CPT_ONEINCH_V2} swap' # noqa: E501 # use this index as the event may be an ETH transfer and appear at the start event.sequence_index = tx_log.log_index in_event = event maybe_reshuffle_events(out_event=out_event, in_event=in_event, events_list=decoded_events) return None, None
def _decode_history( self, tx_log: EthereumTxReceiptLog, transaction: EthereumTransaction, # pylint: disable=unused-argument decoded_events: List[HistoryBaseEntry], # pylint: disable=unused-argument all_logs: List[EthereumTxReceiptLog], # pylint: disable=unused-argument ) -> Tuple[Optional[HistoryBaseEntry], Optional[ActionItem]]: sender = hex_or_bytes_to_address(tx_log.topics[1]) if not self.base.is_tracked(sender): return None, None from_token_address = hex_or_bytes_to_address(tx_log.data[0:32]) to_token_address = hex_or_bytes_to_address(tx_log.data[32:64]) from_asset = ethaddress_to_asset(from_token_address) to_asset = ethaddress_to_asset(to_token_address) if None in (from_asset, to_asset): return None, None from_raw = hex_or_bytes_to_int(tx_log.data[64:96]) from_amount = asset_normalized_value(from_raw, from_asset) # type: ignore to_raw = hex_or_bytes_to_int(tx_log.data[96:128]) to_amount = asset_normalized_value(to_raw, to_asset) # type: ignore out_event = in_event = None for event in decoded_events: if event.event_type == HistoryEventType.SPEND and event.location_label == sender and from_amount == event.balance.amount and from_asset == event.asset: # noqa: E501 # find the send event event.event_type = HistoryEventType.TRADE event.event_subtype = HistoryEventSubType.SPEND event.counterparty = CPT_ONEINCH_V1 event.notes = f'Swap {from_amount} {from_asset.symbol} in {CPT_ONEINCH_V1} from {event.location_label}' # noqa: E501 out_event = event elif event.event_type == HistoryEventType.RECEIVE and event.location_label == sender and to_amount == event.balance.amount and to_asset == event.asset: # noqa: E501 # find the receive event event.event_type = HistoryEventType.TRADE event.event_subtype = HistoryEventSubType.RECEIVE event.counterparty = CPT_ONEINCH_V1 event.notes = f'Receive {to_amount} {to_asset.symbol} from {CPT_ONEINCH_V1} swap in {event.location_label}' # noqa: E501 # use this index as the event may be an ETH transfer and appear at the start event.sequence_index = tx_log.log_index in_event = event maybe_reshuffle_events(out_event=out_event, in_event=in_event, events_list=decoded_events) return None, None
def _decode_redeem_underlying_event( # pylint: disable=no-self-use self, tx_log: EthereumTxReceiptLog, transaction: EthereumTransaction, # pylint: disable=unused-argument decoded_events: List[HistoryBaseEntry], # pylint: disable=unused-argument all_logs: List[EthereumTxReceiptLog], # pylint: disable=unused-argument action_items: List[ActionItem], # pylint: disable=unused-argument ) -> Tuple[Optional[HistoryBaseEntry], Optional[ActionItem]]: reserve_address = hex_or_bytes_to_address(tx_log.topics[1]) reserve_asset = ethaddress_to_asset(reserve_address) if reserve_asset is None: return None, None user_address = hex_or_bytes_to_address(tx_log.topics[2]) raw_amount = hex_or_bytes_to_int(tx_log.data[0:32]) amount = asset_normalized_value(raw_amount, reserve_asset) atoken = asset_to_atoken(asset=reserve_asset, version=1) if atoken is None: return None, None receive_event = return_event = None for event in decoded_events: if event.event_type == HistoryEventType.RECEIVE and event.location_label == user_address and amount == event.balance.amount and reserve_asset == event.asset: # noqa: E501 event.event_type = HistoryEventType.WITHDRAWAL event.event_subtype = HistoryEventSubType.REMOVE_ASSET event.counterparty = CPT_AAVE_V1 event.notes = f'Withdraw {amount} {reserve_asset.symbol} from aave-v1' receive_event = event elif event.event_type == HistoryEventType.SPEND and event.location_label == user_address and amount == event.balance.amount and atoken == event.asset: # noqa: E501 # find the redeem aToken transfer event.event_type = HistoryEventType.SPEND event.event_subtype = HistoryEventSubType.RETURN_WRAPPED event.counterparty = CPT_AAVE_V1 event.notes = f'Return {amount} {atoken.symbol} to aave-v1' return_event = event elif event.event_type == HistoryEventType.RECEIVE and event.location_label == user_address and event.counterparty == ZERO_ADDRESS and event.asset == atoken: # noqa: E501 event.event_subtype = HistoryEventSubType.REWARD event.counterparty = CPT_AAVE_V1 event.notes = f'Gain {event.balance.amount} {atoken.symbol} from aave-v1 as interest' # noqa: E501 maybe_reshuffle_events(out_event=return_event, in_event=receive_event, events_list=decoded_events) # noqa: E501 return None, None
def _maybe_decode_swap( # pylint: disable=no-self-use self, token: Optional[EthereumToken], # pylint: disable=unused-argument tx_log: EthereumTxReceiptLog, transaction: EthereumTransaction, # pylint: disable=unused-argument decoded_events: List[HistoryBaseEntry], action_items: List[ActionItem], # pylint: disable=unused-argument ) -> None: """Search for both events. Since the order is not guaranteed try reshuffle in both cases""" out_event = in_event = None if tx_log.topics[0] == TOKEN_PURCHASE: buyer = hex_or_bytes_to_address(tx_log.topics[1]) # search for a send to buyer from a tracked address for event in decoded_events: if event.event_type == HistoryEventType.SPEND and event.counterparty == buyer: event.event_type = HistoryEventType.TRADE event.event_subtype = HistoryEventSubType.SPEND event.counterparty = CPT_UNISWAP_V1 event.notes = f'Swap {event.balance.amount} {event.asset.symbol} in uniswap-v1 from {event.location_label}' # noqa: E501 out_event = event elif event.event_type == HistoryEventType.TRADE and event.event_subtype == HistoryEventSubType.RECEIVE and event.counterparty == CPT_UNISWAP_V1: # noqa: :E501 in_event = event elif tx_log.topics[0] == ETH_PURCHASE: buyer = hex_or_bytes_to_address(tx_log.topics[1]) # search for a receive to buyer for event in decoded_events: if event.event_type == HistoryEventType.RECEIVE and event.location_label == buyer: event.event_type = HistoryEventType.TRADE event.event_subtype = HistoryEventSubType.RECEIVE event.counterparty = CPT_UNISWAP_V1 event.notes = f'Receive {event.balance.amount} {event.asset.symbol} from uniswap-v1 swap in {event.location_label}' # noqa: E501 in_event = event elif event.event_type == HistoryEventType.TRADE and event.event_subtype == HistoryEventSubType.SPEND and event.counterparty == CPT_UNISWAP_V1: # noqa: :E501 out_event = event maybe_reshuffle_events(out_event=out_event, in_event=in_event)