示例#1
0
def allowances():
    # pylint: disable = W
    "Show the amount of each asset that you could sell tax-free"

    buchfink_db = BuchfinkDB()

    num_matched_accounts = 0
    all_trades = []

    for account in buchfink_db.get_all_accounts():
        num_matched_accounts += 1
        all_trades.extend(buchfink_db.get_local_trades_for_account(account.name))

    logger.info('Collected %d trades from %d exchange account(s)',
            len(all_trades), num_matched_accounts)

    accountant = buchfink_db.get_accountant()
    currency = buchfink_db.get_main_currency()
    currency_in_usd = FVal(buchfink_db.inquirer.find_usd_price(currency))

    accountant.process_history(epoch_start_ts, epoch_end_ts, all_trades, [], [], [], [], [])
    total_usd = FVal(0)
    table = []

    raise NotImplementedError()
    """
示例#2
0
def quote(asset: Tuple[str], amount: float, base_asset_: Optional[str], timestamp: Optional[str]):
    buchfink_db = BuchfinkDB()
    buchfink_db.perform_assets_updates()
    base_asset = buchfink_db.get_asset_by_symbol(base_asset_) \
            if base_asset_ \
            else buchfink_db.get_main_currency()
    base_in_usd = FVal(buchfink_db.inquirer.find_usd_price(base_asset))
    a_usd = buchfink_db.get_asset_by_symbol('USD')

    ds_timestamp = deserialize_timestamp(timestamp) if timestamp else None
    historian = PriceHistorian()

    for symbol in asset:
        asset_ = buchfink_db.get_asset_by_symbol(symbol)
        if ds_timestamp:
            asset_usd = historian.query_historical_price(
                    from_asset=asset_,
                    to_asset=a_usd,
                    timestamp=ds_timestamp
            )
        else:
            asset_usd = FVal(buchfink_db.inquirer.find_usd_price(asset_))
        click.echo('{} {} = {} {}'.format(
                click.style(f'{amount}', fg='white'),
                click.style(asset_.symbol, fg='green'),
                click.style(f'{FVal(amount) * asset_usd / base_in_usd}', fg='white'),
                click.style(base_asset.symbol, fg='green')
        ))
示例#3
0
def serialize_ledger_action(action: LedgerAction):
    ser_action = action.serialize()
    ser_action['timestamp'] = serialize_timestamp(action.timestamp)

    if action.action_type == LedgerActionType.AIRDROP:
        ser_action['airdrop'] = serialize_amount(FVal(action.amount), action.asset)
        del ser_action['asset']
        del ser_action['amount']
        del ser_action['action_type']

    elif action.action_type == LedgerActionType.INCOME:
        ser_action['income'] = serialize_amount(FVal(action.amount), action.asset)
        del ser_action['asset']
        del ser_action['amount']
        del ser_action['action_type']

    elif action.action_type == LedgerActionType.GIFT:
        ser_action['gift'] = serialize_amount(FVal(action.amount), action.asset)
        del ser_action['asset']
        del ser_action['amount']
        del ser_action['action_type']

    elif action.action_type == LedgerActionType.LOSS:
        ser_action['loss'] = serialize_amount(FVal(action.amount), action.asset)
        del ser_action['asset']
        del ser_action['amount']
        del ser_action['action_type']

    elif action.action_type == LedgerActionType.EXPENSE:
        ser_action['expense'] = serialize_amount(FVal(action.amount), action.asset)
        del ser_action['asset']
        del ser_action['amount']
        del ser_action['action_type']

    if not ser_action['identifier']:
        del ser_action['identifier']

    if not ser_action['location']:
        del ser_action['location']

    if not ser_action['notes']:
        del ser_action['notes']

    if not ser_action['link']:
        del ser_action['link']

    if not ser_action['rate']:
        del ser_action['rate']

    if not ser_action['rate_asset']:
        del ser_action['rate_asset']

    return ser_action
def deserialize_trade(trade_dict) -> Trade:
    if 'pair' in trade_dict:
        return Trade(trade_dict['timestamp'], trade_dict.get('location', ''),
                     trade_dict['pair'],
                     deserialize_tradetype(trade_dict['trade_type']),
                     deserialize_fval(trade_dict['amount']),
                     deserialize_fval(trade_dict['rate']),
                     deserialize_fval(trade_dict['fee']),
                     deserialize_asset(trade_dict['fee_currency']),
                     trade_dict['link'])
    else:
        if 'buy' in trade_dict:
            trade_type = TradeType.BUY
            amount, base_asset = deserialize_amount(trade_dict['buy'])
        elif 'sell' in trade_dict:
            trade_type = TradeType.SELL
            amount, base_asset = deserialize_amount(trade_dict['sell'])
        else:
            raise ValueError('Invalid trade: ' + str(trade_dict))

        quote_amount, quote_asset = deserialize_amount(trade_dict['for'])

        if 'fee' in trade_dict:
            fee, fee_currency = deserialize_amount(trade_dict['fee'])
        else:
            fee, fee_currency = FVal('0'), quote_asset

        return Trade(
            dateutil.parser.isoparse(trade_dict['timestamp']).timestamp(),
            trade_dict.get('location', ''),
            '{0}_{1}'.format(base_asset.symbol, quote_asset.symbol),
            trade_type, amount, quote_amount / amount, fee, fee_currency,
            trade_dict.get('link', ''))
示例#5
0
def test_ethereum_balances():
    start_ts = datetime.fromisoformat('2015-01-01').timestamp()
    end_ts = datetime.fromisoformat('2019-01-01').timestamp()

    buchfink_db = BuchfinkDB(
        os.path.join(os.path.dirname(__file__), 'scenarios', 'ethereum'))
    whale = buchfink_db.get_all_accounts()[0]
    sheet = buchfink_db.query_balances(whale)
    assert sheet.assets['ETH'].amount == FVal('147699.424503407102942053')
示例#6
0
def balances(keyword):
    "Show balances across all accounts"

    buchfink_db = BuchfinkDB()
    balances_sum = {}
    usd_value_sum = {}

    for account in buchfink_db.get_all_accounts():
        if keyword is not None and keyword not in account['name']:
            continue

        if 'exchange' in account:
            exchange = buchfink_db.get_exchange(account['name'])

            api_key_is_valid, error = exchange.validate_api_key()

            if not api_key_is_valid:
                logger.critical(
                    'Skipping exchange %s because API key is not valid (%s)',
                    account['name'], error)
                continue

            balances, error = exchange.query_balances()

            if not error:
                logger.info('Fetched balances for %d assets from %s',
                            len(balances.keys()), account['name'])
                for asset, balance in balances.items():
                    amount = balance['amount']
                    balances_sum[asset] = balances_sum.get(asset,
                                                           FVal(0)) + amount
                    if 'usd_value' in balance:
                        usd_value_sum[asset] = usd_value_sum.get(
                            asset, FVal(0)) + balance['usd_value']

        elif 'ethereum' in account:
            manager = buchfink_db.get_chain_manager(account)
            manager.query_balances()

            for eth_balance in manager.balances.eth.values():
                for asset, balance in eth_balance.asset_balances.items():
                    amount = balance.amount
                    balances_sum[asset] = balances_sum.get(asset,
                                                           FVal(0)) + amount
                    usd_value_sum[asset] = usd_value_sum.get(
                        asset, FVal(0)) + balance.usd_value

        elif 'bitcoin' in account:
            manager = buchfink_db.get_chain_manager(account)
            manager.query_balances()
            asset = Asset('BTC')

            for balance in manager.balances.btc.values():
                amount = balance.amount
                balances_sum[asset] = balances_sum.get(asset, FVal(0)) + amount
                usd_value_sum[asset] = usd_value_sum.get(
                    asset, FVal(0)) + balance.usd_value

        elif 'file' in account:

            account = yaml.load(open(account['file'], 'r'),
                                Loader=yaml.SafeLoader)
            if 'balances' in account:
                for balance in account['balances']:
                    amount = FVal(balance['amount'])
                    asset = Asset(balance['asset'])
                    usd_value = amount * buchfink_db.inquirer.find_usd_price(
                        asset)
                    balances_sum[asset] = balances_sum.get(asset,
                                                           FVal(0)) + amount
                    usd_value_sum[asset] = usd_value_sum.get(
                        asset, FVal(0)) + usd_value

    currency = buchfink_db.get_main_currency()
    currency_in_usd = buchfink_db.inquirer.find_usd_price(currency)

    table = []
    assets = [
        obj[0] for obj in sorted(
            usd_value_sum.items(), key=itemgetter(1), reverse=True)
    ]
    balance_in_currency_sum = 0

    for asset in assets:
        balance = balances_sum[asset]
        balance_in_currency = usd_value_sum.get(asset,
                                                FVal(0)) / currency_in_usd
        balance_in_currency_sum += balance_in_currency
        table.append([
            asset, balance, asset.symbol,
            round(float(balance_in_currency), 2)
        ])
    table.append(
        ['Total', None, None,
         round(float(balance_in_currency_sum), 2)])
    print(
        tabulate(table,
                 headers=[
                     'Asset', 'Amount', 'Symbol',
                     'Fiat Value (%s)' % currency.symbol
                 ]))
示例#7
0
def deserialize_fval(val: str) -> FVal:
    return FVal(val)
示例#8
0
def deserialize_amount(amount: str) -> Tuple[FVal, Optional[Asset]]:
    elems = amount.split(' ')
    amount = FVal(elems[0])
    asset = deserialize_asset(elems[1]) if len(elems) > 1 else None
    return amount, asset
示例#9
0
def deserialize_balance(balance: Dict[str, Any], buchfink_db) -> Tuple[Balance, Asset]:
    amount = FVal(balance['amount'])
    asset = buchfink_db.get_asset_by_symbol(balance['asset'])
    usd_value = amount * FVal(buchfink_db.inquirer.find_usd_price(asset))
    return Balance(amount, usd_value), asset
示例#10
0
def balances(keyword, minimum_balance, fetch, total, external):
    "Show balances across all accounts"

    buchfink_db = BuchfinkDB()
    assets_sum = {}
    assets_usd_sum = {}
    liabilities_sum = {}
    liabilities_usd_sum = {}

    if external:
        accounts = [account_from_string(ext, buchfink_db) for ext in external]
    else:
        accounts = buchfink_db.get_all_accounts()

    for account in accounts:
        if keyword is not None and keyword not in account.name:
            continue

        if fetch:
            buchfink_db.perform_assets_updates()
            buchfink_db.fetch_balances(account)

        sheet = buchfink_db.get_balances(account)

        for asset, balance in sheet.assets.items():
            amount = balance.amount
            assets_sum[asset] = assets_sum.get(asset, FVal(0)) + amount
            assets_usd_sum[asset] = assets_usd_sum.get(asset, FVal(0)) + balance.usd_value

        for liability, balance in sheet.liabilities.items():
            amount = balance.amount
            liabilities_sum[liability] = liabilities_sum.get(liability, FVal(0)) + amount
            liabilities_usd_sum[liability] = liabilities_usd_sum.get(liability, FVal(0)) \
                    + balance.usd_value

    currency = buchfink_db.get_main_currency()
    currency_in_usd = FVal(buchfink_db.inquirer.find_usd_price(currency))

    table = []
    assets = [obj[0] for obj in sorted(assets_usd_sum.items(), key=itemgetter(1), reverse=True)]
    balance_in_currency_sum = 0
    small_balances_sum = 0

    for asset in assets:
        balance = assets_sum[asset]
        balance_in_currency = FVal(assets_usd_sum.get(asset, 0)) / currency_in_usd
        if balance > ZERO:
            if balance_in_currency > FVal(minimum_balance):
                table.append([
                    asset.name,
                    balance,
                    asset.symbol,
                    round(float(balance_in_currency), 2)
                ])
            else:
                small_balances_sum += balance_in_currency
            balance_in_currency_sum += balance_in_currency

    if total:
        print(f'Total assets: {round(float(balance_in_currency_sum), 2)} {currency.symbol}')

    else:
        if small_balances_sum > 0:
            table.append(['Others', None, None, round(float(small_balances_sum), 2)])

        table.append(['Total', None, None, round(float(balance_in_currency_sum), 2)])
        print(tabulate(table, headers=[
            'Asset',
            'Amount',
            'Symbol',
            'Fiat Value (%s)' % currency.symbol
        ]))

    if liabilities_sum:
        table = []
        balance_in_currency_sum = 0
        assets = [
                obj[0]
                for obj
                in sorted(liabilities_usd_sum.items(), key=itemgetter(1), reverse=True)
        ]
        for asset in assets:
            balance = liabilities_sum[asset]
            balance_in_currency = liabilities_usd_sum.get(asset, FVal(0)) / currency_in_usd
            if balance > ZERO and balance_in_currency >= FVal(minimum_balance):
                balance_in_currency_sum += balance_in_currency
                table.append([
                    asset.name,
                    balance,
                    asset.symbol,
                    round(float(balance_in_currency), 2)
                ])
        table.append(['Total', None, None, round(float(balance_in_currency_sum), 2)])

        if total:
            print(
                f'Total liabilities: '
                f'{round(float(balance_in_currency_sum), 2)} {currency.symbol}'
            )

        else:
            print()
            print(tabulate(table, headers=[
                'Liability',
                'Amount',
                'Symbol',
                'Fiat Value (%s)' % currency.symbol
            ]))
def dummy_trade():
    return Trade(
        datetime(2020, 1, 3, tzinfo=timezone.utc).timestamp(), 'coinbase',
        'BTC_EUR', TradeType.BUY, FVal('0.52'), FVal('7200.0'), FVal('0.5'),
        Asset('EUR'), 'LINK-123')
示例#12
0
def classify_tx(account: Account, tx_hash: str, txn: EthereumTransaction, receipt: dict) \
        -> List[LedgerAction]:
    actions = []  # type: List[LedgerAction]

    tx_time = serialize_timestamp(txn.timestamp)

    if txn.from_address != account.address:
        return actions

    for event in receipt['logs']:
        if event['topics'][0] == CLAIMED and event[
                'address'] == ADDR_UNISWAP_AIRDROP.lower():
            amount = hexstr_to_int(event['data'][130:])
            actions += [
                LedgerAction(
                    identifier=None,
                    location='',
                    action_type=LedgerActionType.AIRDROP,
                    amount=FVal(amount) / FVal(1e18),
                    rate=None,
                    rate_asset=None,
                    timestamp=txn.timestamp,
                    asset=symbol_to_asset_or_token(
                        '_ceth_0x1f9840a85d5af5bf1d1762f925bdaddc4201f984'),
                    notes='',
                    link=tx_hash)
            ]

        elif event['topics'][0] == CLAIMED and event[
                'address'] == ADDR_MIRROR_AIRDROP.lower():
            amount = hexstr_to_int(event['data'][130:])
            actions += [
                LedgerAction(
                    identifier=None,
                    location='',
                    action_type=LedgerActionType.AIRDROP,
                    amount=FVal(amount) / FVal(1e18),
                    rate=None,
                    rate_asset=None,
                    timestamp=txn.timestamp,
                    asset=symbol_to_asset_or_token(
                        '_ceth_0x09a3ecafa817268f77be1283176b946c4ff2e608'),
                    notes='',
                    link=tx_hash)
            ]

        elif event['topics'][0] == CLAIMED and event[
                'address'] == ADDR_POOL_AIRDROP.lower():
            amount = hexstr_to_int(event['data'][130:])
            actions += [
                LedgerAction(
                    identifier=None,
                    location='',
                    action_type=LedgerActionType.AIRDROP,
                    amount=FVal(amount) / FVal(1e18),
                    rate=None,
                    rate_asset=None,
                    timestamp=txn.timestamp,
                    asset=symbol_to_asset_or_token(
                        '_ceth_0x0cec1a9154ff802e7934fc916ed7ca50bde6844e'),
                    notes='PoolTogether airdrop',
                    link=tx_hash)
            ]

        elif event['topics'][0] == CLAIMED and event[
                'address'] == ADDR_IMX_AIRDROP.lower():
            amount = hexstr_to_int(event['data'][130:])
            actions += [
                LedgerAction(
                    identifier=None,
                    location='',
                    action_type=LedgerActionType.AIRDROP,
                    amount=FVal(amount) / FVal(1e18),
                    rate=None,
                    rate_asset=None,
                    timestamp=txn.timestamp,
                    asset=symbol_to_asset_or_token(
                        '_ceth_0x7b35ce522cb72e4077baeb96cb923a5529764a00'),
                    notes='IMX airdrop',
                    link=tx_hash)
            ]

        elif event['topics'][0] == CLAIMED:
            logger.warning('Unknown Claimed event for tx %s at %s', tx_hash,
                           tx_time)

        if event['topics'][0] == CLAIMED_3 and event[
                'address'] == ADDR_BADGER_TREE.lower():
            if hexstr_to_int(event['topics'][2]) == hexstr_to_int(ADDR_BADGER):
                amount = hexstr_to_int(event['data'][2:66])
                token = symbol_to_asset_or_token(
                    '_ceth_0x3472a5a71965499acd81997a54bba8d852c6e53d')
                actions += [
                    LedgerAction(identifier=None,
                                 location='',
                                 action_type=LedgerActionType.INCOME,
                                 amount=FVal(amount) / FVal(1e18),
                                 rate=None,
                                 rate_asset=None,
                                 timestamp=txn.timestamp,
                                 asset=token,
                                 notes='Badger rewards for staking',
                                 link=tx_hash)
                ]

        elif event['topics'][0] == CLAIMED_3:
            logger.warning('Unknown Claimed event for tx %s at %s', tx_hash,
                           tx_time)

        if event['topics'][0] == CLAIMED_2 and event[
                'address'] == ADDR_XTOKEN_AIRDROP.lower():
            amount = hexstr_to_int(event['data'])
            actions += [
                LedgerAction(
                    identifier=None,
                    location='',
                    action_type=LedgerActionType.AIRDROP,
                    amount=FVal(amount) / FVal(1e18),
                    rate=None,
                    rate_asset=None,
                    timestamp=txn.timestamp,
                    asset=symbol_to_asset_or_token(
                        '_ceth_0x7f3edcdd180dbe4819bd98fee8929b5cedb3adeb'),
                    notes='xToken airdrop',
                    link=tx_hash)
            ]

        elif event['topics'][0] == CLAIMED_2 and event[
                'address'] == ADDR_BALANCER_REWARDS.lower():
            amount = hexstr_to_int(event['data'][66:])
            actions += [
                LedgerAction(identifier=None,
                             location='',
                             action_type=LedgerActionType.INCOME,
                             amount=FVal(amount) / FVal(1e18),
                             rate=None,
                             rate_asset=None,
                             timestamp=txn.timestamp,
                             asset=symbol_to_asset_or_token('BAL'),
                             notes='Balancer rewards for providing liquidity',
                             link=tx_hash)
            ]

        elif event['topics'][0] == CLAIMED_2 and event[
                'address'] == ADDR_ROOK_REWARDS.lower():
            amount = hexstr_to_int(event['data'][2:])
            actions += [
                LedgerAction(identifier=None,
                             location='',
                             action_type=LedgerActionType.INCOME,
                             amount=FVal(amount) / FVal(1e18),
                             rate=None,
                             rate_asset=None,
                             timestamp=txn.timestamp,
                             asset=symbol_to_asset_or_token('ROOK'),
                             notes='Rook rewards for providing liquidity',
                             link=tx_hash)
            ]

        elif event['topics'][0] == CLAIMED_2:
            logger.warning('Unknown Claimed event for tx: %s', tx_hash)

        if event['topics'][0] == CLAIMED_4 and event[
                'address'] == ADDR_GITCOIN_AIRDROP.lower():
            amount = hexstr_to_int(event['data'][2:][128:192])
            actions += [
                LedgerAction(
                    identifier=None,
                    location='',
                    action_type=LedgerActionType.INCOME,
                    amount=FVal(amount) / FVal(1e18),
                    rate=None,
                    rate_asset=None,
                    timestamp=txn.timestamp,
                    asset=symbol_to_asset_or_token(
                        '_ceth_0xDe30da39c46104798bB5aA3fe8B9e0e1F348163F'),
                    notes='Gitcoin retroactive airdrop',
                    link=tx_hash)
            ]

        elif event['topics'][0] == CLAIMED_4:
            logger.warning('Unknown Claimed event for tx: %s', tx_hash)

        if event['topics'][0] == REWARD_PAID and event[
                'address'] in ADDR_PIEDAO_INCENTIVES:
            amount = hexstr_to_int(event['data'][2:])
            actions += [
                LedgerAction(identifier=None,
                             location='',
                             action_type=LedgerActionType.INCOME,
                             amount=FVal(amount) / FVal(1e18),
                             rate=None,
                             rate_asset=None,
                             timestamp=txn.timestamp,
                             asset=symbol_to_asset_or_token('DOUGH'),
                             notes='rewards for providing liquidity',
                             link=tx_hash)
            ]

        elif event['topics'][0] == REWARD_PAID and event[
                'address'] == ADDR_INDEX_REWARDS.lower():
            amount = hexstr_to_int(event['data'][2:])
            actions += [
                LedgerAction(identifier=None,
                             location='',
                             action_type=LedgerActionType.INCOME,
                             amount=FVal(amount) / FVal(1e18),
                             rate=None,
                             rate_asset=None,
                             timestamp=txn.timestamp,
                             asset=symbol_to_asset_or_token('INDEX'),
                             notes='rewards for providing liquidity',
                             link=tx_hash)
            ]

        elif event['topics'][0] == REWARD_PAID and event[
                'address'] == ADDR_YFI_GOVERNANCE.lower():
            amount = hexstr_to_int(event['data'][2:])
            actions += [
                LedgerAction(
                    identifier=None,
                    location='',
                    action_type=LedgerActionType.INCOME,
                    amount=FVal(amount) / FVal(1e18),
                    rate=None,
                    rate_asset=None,
                    timestamp=txn.timestamp,
                    asset=symbol_to_asset_or_token('yDAI+yUSDC+yUSDT+yTUSD'),
                    notes='rewards from yearn governance',
                    link=tx_hash)
            ]

        elif event['topics'][0] == REWARD_PAID and event[
                'address'] in ADDR_CREAM_REWARDS:
            amount = hexstr_to_int(event['data'][2:])
            actions += [
                LedgerAction(identifier=None,
                             location='',
                             action_type=LedgerActionType.INCOME,
                             amount=FVal(amount) / FVal(1e18),
                             rate=None,
                             rate_asset=None,
                             timestamp=txn.timestamp,
                             asset=symbol_to_asset_or_token('CREAM'),
                             notes='rewards from cream incentives',
                             link=tx_hash)
            ]

        elif event['topics'][0] == REWARD_PAID and event[
                'address'] == ADDR_MIR_REWARDS.lower():
            amount = hexstr_to_int(event['data'][2:])
            actions += [
                LedgerAction(
                    identifier=None,
                    location='',
                    action_type=LedgerActionType.INCOME,
                    amount=FVal(amount) / FVal(1e18),
                    rate=None,
                    rate_asset=None,
                    timestamp=txn.timestamp,
                    asset=symbol_to_asset_or_token(
                        '_ceth_0x09a3ecafa817268f77be1283176b946c4ff2e608'),
                    notes='rewards for staking MIR LP',
                    link=tx_hash)
            ]

        elif event['topics'][0] == REWARD_PAID:
            logger.warning('Unknown RewardPaid event for tx %s at %s', tx_hash,
                           tx_time)

        if event['topics'][0] == MINTED and event[
                'address'] == ADDR_SWERVE_MINTER.lower():
            if hexstr_to_int(event['topics'][1]) == hexstr_to_int(
                    account.address):
                amount = hexstr_to_int(event['data'][66:])
                actions += [
                    LedgerAction(identifier=None,
                                 location='',
                                 action_type=LedgerActionType.INCOME,
                                 amount=FVal(amount) / FVal(1e18),
                                 rate=None,
                                 rate_asset=None,
                                 timestamp=txn.timestamp,
                                 asset=symbol_to_asset_or_token('SWRV'),
                                 notes='Swerve rewards for pooling liquidity',
                                 link=tx_hash)
                ]

        elif event['topics'][0] == MINTED:
            logger.warning('Unknown Minted event for tx %s at %s', tx_hash,
                           tx_time)

        if event['topics'][0] == PURCHASE and event[
                'address'] == ADDR_FEI_GENESIS_GROUP.lower():
            if hexstr_to_int(event['topics'][1]) == hexstr_to_int(
                    account.address):
                amount = hexstr_to_int(event['data'])
                actions += [
                    LedgerAction(identifier=None,
                                 location='',
                                 action_type=LedgerActionType.EXPENSE,
                                 amount=FVal(amount) / FVal(1e18),
                                 rate=None,
                                 rate_asset=None,
                                 timestamp=txn.timestamp,
                                 asset=symbol_to_asset_or_token('ETH'),
                                 notes='Fei Genesis Commit',
                                 link=tx_hash)
                ]

        elif event['topics'][0] == PURCHASE:
            logger.warning('Unknown Purchase event for tx %s at %s', tx_hash,
                           tx_time)

        if event['topics'][0] == TRANSFER and event[
                'address'] == ADDR_DODO.lower():
            if hexstr_to_int(event['topics'][1]) == hexstr_to_int(ADDR_DODO_REWARDS) and \
                    hexstr_to_int(event['topics'][2]) == hexstr_to_int(account.address):
                amount = hexstr_to_int(event['data'])
                actions += [
                    LedgerAction(identifier=None,
                                 location='',
                                 action_type=LedgerActionType.INCOME,
                                 amount=FVal(amount) / FVal(1e18),
                                 rate=None,
                                 rate_asset=None,
                                 timestamp=txn.timestamp,
                                 asset=symbol_to_asset_or_token('DODO'),
                                 notes='Claim DODO rewards',
                                 link=tx_hash)
                ]

        elif event['topics'][0] == TRANSFER and event[
                'address'] == ADDR_SUSHI.lower():
            if hexstr_to_int(event['topics'][1]) == hexstr_to_int(ADDR_SUSHI_REWARDS) and \
                    hexstr_to_int(event['topics'][2]) == hexstr_to_int(account.address):
                amount = hexstr_to_int(event['data'])
                actions += [
                    LedgerAction(identifier=None,
                                 location='',
                                 action_type=LedgerActionType.INCOME,
                                 amount=FVal(amount) / FVal(1e18),
                                 rate=None,
                                 rate_asset=None,
                                 timestamp=txn.timestamp,
                                 asset=symbol_to_asset_or_token('SUSHI'),
                                 notes='Claim SUSHI rewards for staking LP',
                                 link=tx_hash)
                ]

        elif event['topics'][0] == TRANSFER and event[
                'address'] == ADDR_TORN.lower():
            if hexstr_to_int(event['topics'][1]) == hexstr_to_int(ADDR_TORN_VTORN) and \
                    hexstr_to_int(event['topics'][2]) == hexstr_to_int(account.address):
                amount = hexstr_to_int(event['data'])
                actions += [
                    LedgerAction(
                        identifier=None,
                        location='',
                        action_type=LedgerActionType.AIRDROP,
                        amount=FVal(amount) / FVal(1e18),
                        rate=None,
                        rate_asset=None,
                        timestamp=txn.timestamp,
                        asset=symbol_to_asset_or_token(
                            '_ceth_0x77777FeDdddFfC19Ff86DB637967013e6C6A116C'
                        ),
                        notes='TORN airdrop',
                        link=tx_hash)
                ]

        elif event['topics'][0] == STAKEEND and event[
                'address'] == ADDR_HEX.lower():
            if hexstr_to_int(event['topics'][1]) == hexstr_to_int(
                    account.address):
                payout = hexstr_to_int(event['data'][2:][:18])
                actions += [
                    LedgerAction(identifier=None,
                                 location='',
                                 action_type=LedgerActionType.INCOME,
                                 amount=FVal(payout) / FVal(1e8),
                                 rate=None,
                                 rate_asset=None,
                                 timestamp=txn.timestamp,
                                 asset=symbol_to_asset_or_token('_ceth_' +
                                                                ADDR_HEX),
                                 notes='HEX Payout for staking',
                                 link=tx_hash)
                ]

        if event['topics'][0] == HUNT and event[
                'address'] == ADDR_BLACKPOOL_AIRDROP.lower():
            if hexstr_to_int(event['topics'][1]) == hexstr_to_int(
                    account.address):
                amount = hexstr_to_int(event['data'][2:][64:128])
                actions += [
                    LedgerAction(
                        identifier=None,
                        location='',
                        action_type=LedgerActionType.AIRDROP,
                        amount=FVal(amount) / FVal(1e18),
                        rate=None,
                        rate_asset=None,
                        timestamp=txn.timestamp,
                        asset=symbol_to_asset_or_token(
                            '_ceth_0x0eC9F76202a7061eB9b3a7D6B59D36215A7e37da'
                        ),
                        notes='Blackpool airdrop',
                        link=tx_hash)
                ]
    return actions