Exemple #1
0
def test_kyber_legacy_old_contract(database, ethereum_manager,
                                   eth_transactions):
    """Data for trade taken from
    https://etherscan.io/tx/0xe9cc9f27ef2a09fe23abc886a0a0f7ae19d9e2eb73663e1e41e07a3e0c011b87
    """
    msg_aggregator = MessagesAggregator()
    tx_hex = '0xe9cc9f27ef2a09fe23abc886a0a0f7ae19d9e2eb73663e1e41e07a3e0c011b87'
    evmhash = deserialize_evm_tx_hash(tx_hex)
    transaction = EthereumTransaction(
        tx_hash=evmhash,
        timestamp=1591043988,
        block_number=10182160,
        from_address='0x6d379cb5BA04c09293b21Bf314E7aba3FfEAaF5b',
        to_address='0x818E6FECD516Ecc3849DAf6845e3EC868087B755',
        value=0,
        gas=600000,
        gas_price=22990000000,
        gas_used=527612,
        input_data=hexstring_to_bytes(
            '0xcb3c28c7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000002aea540000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000006d379cb5ba04c09293b21bf314e7aba3ffeaaf5b8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e5f611df3b9ac000000000000000000000000f1aa99c69715f423086008eb9d06dc1e35cc504d'
        ),  # noqa: E501
        nonce=1,
    )
    receipt = EthereumTxReceipt(
        tx_hash=evmhash,
        contract_address=None,
        status=True,
        type=0,
        logs=[
            EthereumTxReceiptLog(
                log_index=87,
                data=hexstring_to_bytes(
                    '0x0000000000000000000000000000000000000000000000000000000002aea540'
                ),  # noqa: E501
                address=string_to_ethereum_address(
                    '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
                removed=False,
                topics=[
                    hexstring_to_bytes(
                        '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
                    ),  # noqa: E501
                    hexstring_to_bytes(
                        '0x0000000000000000000000006d379cb5ba04c09293b21bf314e7aba3ffeaaf5b'
                    ),  # noqa: E501
                    hexstring_to_bytes(
                        '0x00000000000000000000000065bf64ff5f51272f729bdcd7acfb00677ced86cd'
                    ),  # noqa: E501
                ],
            ),
            EthereumTxReceiptLog(
                log_index=93,
                data=hexstring_to_bytes(
                    '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000000000000000000000000000000000000002aea540000000000000000000000000000000000000000000000000029a80338e28df730000000000000000000000006d379cb5ba04c09293b21bf314e7aba3ffeaaf5b000000000000000000000000000000000000000000000000029a80338e28df730000000000000000000000001670dfb52806de7789d5cf7d5c005cf7083f9a5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000'
                ),  # noqa: E501
                address=string_to_ethereum_address(
                    '0x65bF64Ff5f51272f729BDcD7AcFB00677ced86Cd'),
                removed=False,
                topics=[
                    hexstring_to_bytes(
                        '0xd30ca399cb43507ecec6a629a35cf45eb98cda550c27696dcb0d8c4a3873ce6c'
                    ),  # noqa: E501
                    hexstring_to_bytes(
                        '0x0000000000000000000000006d379cb5ba04c09293b21bf314e7aba3ffeaaf5b'
                    ),  # noqa: E501
                ],
            ),
        ],
    )
    internal_tx = EthereumInternalTransaction(
        parent_tx_hash=evmhash,
        trace_id=27,
        timestamp=Timestamp(1591043988),
        block_number=10182160,
        from_address='0x65bF64Ff5f51272f729BDcD7AcFB00677ced86Cd',
        to_address='0x6d379cb5BA04c09293b21Bf314E7aba3FfEAaF5b',
        value=187603293406027635,
    )
    dbethtx = DBEthTx(database)
    dbethtx.add_ethereum_transactions([transaction], relevant_address=None)
    dbethtx.add_ethereum_internal_transactions(
        [internal_tx],
        relevant_address='0x6d379cb5BA04c09293b21Bf314E7aba3FfEAaF5b'
    )  # noqa: E501
    decoder = EVMTransactionDecoder(
        database=database,
        ethereum_manager=ethereum_manager,
        eth_transactions=eth_transactions,
        msg_aggregator=msg_aggregator,
    )
    events = decoder.decode_transaction(transaction=transaction,
                                        tx_receipt=receipt)

    assert len(events) == 3
    expected_events = [
        HistoryBaseEntry(
            event_identifier=
            '0xe9cc9f27ef2a09fe23abc886a0a0f7ae19d9e2eb73663e1e41e07a3e0c011b87',
            sequence_index=0,
            timestamp=1591043988000,
            location=Location.BLOCKCHAIN,
            event_type=HistoryEventType.SPEND,
            event_subtype=HistoryEventSubType.FEE,
            asset=A_ETH,
            balance=Balance(
                amount=FVal(0.01212979988),
                usd_value=FVal(0),
            ),
            location_label='0x6d379cb5BA04c09293b21Bf314E7aba3FfEAaF5b',
            notes=
            'Burned 0.01212979988 ETH in gas from 0x6d379cb5BA04c09293b21Bf314E7aba3FfEAaF5b',  # noqa: E501
            counterparty=CPT_GAS,
        ),
        HistoryBaseEntry(
            event_identifier=
            '0xe9cc9f27ef2a09fe23abc886a0a0f7ae19d9e2eb73663e1e41e07a3e0c011b87',
            sequence_index=1,
            timestamp=1591043988000,
            location=Location.BLOCKCHAIN,
            event_type=HistoryEventType.TRADE,
            event_subtype=HistoryEventSubType.SPEND,
            asset=A_USDC,
            balance=Balance(amount=FVal(45), usd_value=FVal(0)),
            location_label='0x6d379cb5BA04c09293b21Bf314E7aba3FfEAaF5b',
            notes='Swap 45 USDC in kyber',
            counterparty='kyber legacy',
        ),
        HistoryBaseEntry(
            event_identifier=
            '0xe9cc9f27ef2a09fe23abc886a0a0f7ae19d9e2eb73663e1e41e07a3e0c011b87',
            sequence_index=89,
            timestamp=1591043988000,
            location=Location.BLOCKCHAIN,
            event_type=HistoryEventType.TRADE,
            event_subtype=HistoryEventSubType.RECEIVE,
            asset=A_ETH,
            balance=Balance(
                amount=FVal('0.187603293406027635'),
                usd_value=FVal(0),
            ),
            location_label='0x6d379cb5BA04c09293b21Bf314E7aba3FfEAaF5b',
            notes='Receive 0.187603293406027635 ETH from kyber swap',
            counterparty='kyber legacy',
        )
    ]
    assert events == expected_events
Exemple #2
0
def test_liquity_trove_remove_eth(database, ethereum_manager, eth_transactions):
    """Data for deposit taken from
    https://etherscan.io/tx/0x6be5312c21855c3cc324b5b6ce9f9f65dbd488e270e84ac5e6fb96c74d83fe4e
    Deposit 2.1 ether and borrow 4752 LUSD
    """
    msg_aggregator = MessagesAggregator()
    tx_hex = '0x6be5312c21855c3cc324b5b6ce9f9f65dbd488e270e84ac5e6fb96c74d83fe4e'
    user_address = '0x648E180e246741363639B1496762763dd25649db'
    evmhash = deserialize_evm_tx_hash(tx_hex)
    transaction = EthereumTransaction(
        tx_hash=evmhash,
        timestamp=1646375440,
        block_number=14318825,
        from_address=user_address,
        to_address='0x24179cd81c9e782a4096035f7ec97fb8b783e007',
        value=0,
        gas=171249,
        gas_price=22990000000,
        gas_used=171249,
        input_data=hexstring_to_bytes('0xc6a6cf2000000000000000000000000000000000000000000000000000238811c2e89e1b000000000000000000000000000000000000000000000001bc16d674ec80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cb926f497763ea5cf993912a442431e6a91d5a64000000000000000000000000c68d61757a9894f34871c0ae733ac034d9abf807'),  # noqa: E501
        nonce=507,
    )
    receipt = EthereumTxReceipt(
        tx_hash=evmhash,
        contract_address=None,
        status=True,
        type=0,
        logs=[
            EthereumTxReceiptLog(
                log_index=204,
                data=hexstring_to_bytes('0x000000000000000000000000000000000000000000038f9ba4f4e8bb875c546b0000000000000000000000000000000000000000000000aed129e69968ff40000000000000000000000000000000000000000000000000aed129e69968ff40000000000000000000000000000000000000000000000000000000000000000002'),  # noqa: E501
                address=string_to_ethereum_address('0x24179CD81c9e782A4096035f7eC97fB8B783e007'),
                removed=False,
                topics=[
                    hexstring_to_bytes('0xc3770d654ed33aeea6bf11ac8ef05d02a6a04ed4686dd2f624d853bbec43cc8b'),  # noqa: E501
                    hexstring_to_bytes('0x000000000000000000000000648e180e246741363639b1496762763dd25649db'),  # noqa: E501
                ],
            ), EthereumTxReceiptLog(
                log_index=293,
                data=hexstring_to_bytes('0x0000000000000000000000000000000000000000000000000000000000000000'),  # noqa: E501
                address=string_to_ethereum_address('0x5f98805A4E8be255a32880FDeC7F6728C6568bA0'),
                removed=False,
                topics=[
                    hexstring_to_bytes('0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'),  # noqa: E501
                    hexstring_to_bytes('0x000000000000000000000000648e180e246741363639b1496762763dd25649db'),  # noqa: E501
                    hexstring_to_bytes('0x0000000000000000000000000000000000000000000000000000000000000000'),  # noqa: E501
                ],
            ), EthereumTxReceiptLog(
                log_index=208,
                data=hexstring_to_bytes('0x000000000000000000000000000000000000000000004e927b246c443a2daac9'),  # noqa: E501
                address=string_to_ethereum_address('0xDf9Eb223bAFBE5c5271415C75aeCD68C21fE3D7F'),
                removed=False,
                topics=[
                    hexstring_to_bytes('0xca232b5abb988c540b959ff6c3bfae3e97fff964fd098c508f9613c0a6bf1a80'),  # noqa: E501
                ],
            ),
        ],
    )
    internal_tx = EthereumInternalTransaction(
        parent_tx_hash=evmhash,
        trace_id=19,
        timestamp=Timestamp(1646375440),
        block_number=10182160,
        from_address='0xDf9Eb223bAFBE5c5271415C75aeCD68C21fE3D7F',
        to_address=user_address,
        value=FVal(32) * EXP18,
    )

    dbethtx = DBEthTx(database)
    dbethtx.add_ethereum_transactions([transaction], relevant_address=None)
    dbethtx.add_ethereum_internal_transactions([internal_tx], relevant_address=user_address)  # noqa: E501
    decoder = EVMTransactionDecoder(
        database=database,
        ethereum_manager=ethereum_manager,
        eth_transactions=eth_transactions,
        msg_aggregator=msg_aggregator,
    )
    events = decoder.decode_transaction(transaction=transaction, tx_receipt=receipt)
    assert len(events) == 3
    expected_events = [
        HistoryBaseEntry(
            event_identifier=tx_hex,
            sequence_index=0,
            timestamp=1646375440000,
            location=Location.BLOCKCHAIN,
            event_type=HistoryEventType.SPEND,
            event_subtype=HistoryEventSubType.FEE,
            asset=A_ETH,
            balance=Balance(
                amount=FVal(0.00393701451),
                usd_value=ZERO,
            ),
            location_label=user_address,
            notes=f'Burned 0.00393701451 ETH in gas from {user_address}',
            counterparty=CPT_GAS,
        ), HistoryBaseEntry(
            event_identifier=tx_hex,
            sequence_index=1,
            timestamp=1646375440000,
            location=Location.BLOCKCHAIN,
            event_type=HistoryEventType.WITHDRAWAL,
            event_subtype=HistoryEventSubType.REMOVE_ASSET,
            asset=A_ETH,
            balance=Balance(amount=FVal('32'), usd_value=ZERO),
            location_label=user_address,
            notes='Withdraw 32 ETH collateral from liquity',
            counterparty='liquity',
        ), HistoryBaseEntry(
            event_identifier=tx_hex,
            sequence_index=295,
            timestamp=1646375440000,
            location=Location.BLOCKCHAIN,
            event_type=HistoryEventType.SPEND,
            event_subtype=HistoryEventSubType.PAYBACK_DEBT,
            asset=A_LUSD,
            balance=Balance(amount=FVal('0'), usd_value=ZERO),
            location_label=user_address,
            notes='Return 0 LUSD to liquity',
            counterparty='liquity',
        )]
    assert events == expected_events
Exemple #3
0
def test_curve_remove_liquidity_with_internal(database, ethereum_manager, eth_transactions):
    """Data for deposit taken from
    https://etherscan.io/tx/0x30bb99f3e34fb1fbcf009320af7e290caf18b04b207319e15aa8ffbf645f4ad9
    This tests uses the steth pool to verify that withdrawals are correctly decoded when an
    internal transaction is made for eth transfers
    """
    msg_aggregator = MessagesAggregator()
    tx_hex = '0x30bb99f3e34fb1fbcf009320af7e290caf18b04b207319e15aa8ffbf645f4ad9'
    location_label = '0xa8005630caE7b7d2AFADD38FD3B3040d13cbE2BC'
    evmhash = deserialize_evm_tx_hash(tx_hex)
    transaction = EthereumTransaction(
        tx_hash=evmhash,
        timestamp=1650276061,
        block_number=14647221,
        from_address=location_label,
        to_address='0xF178C0b5Bb7e7aBF4e12A4838C7b7c5bA2C623c0',
        value=0,
        gas=171249,
        gas_price=22990000000,
        gas_used=171249,
        input_data=hexstring_to_bytes('0x1a4d01d20000000000000000000000000000000000000000000000a8815561fefbe56aa300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a8d15fc942541fea7f'),  # noqa: E501
        nonce=5,
    )
    receipt = EthereumTxReceipt(
        tx_hash=evmhash,
        contract_address=None,
        status=True,
        type=0,
        logs=[
            EthereumTxReceiptLog(
                log_index=191,
                data=hexstring_to_bytes('0x0000000000000000000000000000000000000000000000000dc335d474901e08'),  # noqa: E501
                address=string_to_ethereum_address('0x06325440D014e39736583c165C2963BA99fAf14E'),
                removed=False,
                topics=[
                    hexstring_to_bytes('0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'),  # noqa: E501
                    hexstring_to_bytes('0x000000000000000000000000a8005630cae7b7d2afadd38fd3b3040d13cbe2bc'),  # noqa: E501
                    hexstring_to_bytes('0x0000000000000000000000000000000000000000000000000000000000000000'),  # noqa: E501
                ],
            ), EthereumTxReceiptLog(
                log_index=192,
                data=hexstring_to_bytes('0x0000000000000000000000000000000000000000000000000dc335d474901e080000000000000000000000000000000000000000000000000e48d018621788fa'),  # noqa: E501
                address=string_to_ethereum_address('0xDC24316b9AE028F1497c275EB9192a3Ea0f67022'),
                removed=False,
                topics=[
                    hexstring_to_bytes('0x9e96dd3b997a2a257eec4df9bb6eaf626e206df5f543bd963682d143300be310'),  # noqa: E501
                    hexstring_to_bytes('0x000000000000000000000000a8005630cae7b7d2afadd38fd3b3040d13cbe2bc'),  # noqa: E501
                ],
            ),
        ],
    )
    internal_tx = EthereumInternalTransaction(
        parent_tx_hash=evmhash,
        trace_id=27,
        timestamp=Timestamp(1591043988),
        block_number=14647221,
        from_address='0xDC24316b9AE028F1497c275EB9192a3Ea0f67022',
        to_address='0xa8005630caE7b7d2AFADD38FD3B3040d13cbE2BC',
        value=FVal('1.02930131799766041') * EXP18,
    )
    dbethtx = DBEthTx(database)
    dbethtx.add_ethereum_transactions([transaction], relevant_address=None)
    dbethtx.add_ethereum_internal_transactions([internal_tx], relevant_address=location_label)  # noqa: E501
    decoder = EVMTransactionDecoder(
        database=database,
        ethereum_manager=ethereum_manager,
        eth_transactions=eth_transactions,
        msg_aggregator=msg_aggregator,
    )
    events = decoder.decode_transaction(transaction=transaction, tx_receipt=receipt)
    expected_events = [
        HistoryBaseEntry(
            event_identifier=tx_hex,
            sequence_index=0,
            timestamp=1650276061000,
            location=Location.BLOCKCHAIN,
            event_type=HistoryEventType.SPEND,
            event_subtype=HistoryEventSubType.FEE,
            asset=A_ETH,
            balance=Balance(
                amount=FVal(0.00393701451),
                usd_value=ZERO,
            ),
            location_label=location_label,
            notes='Burned 0.00393701451 ETH in gas from 0xa8005630caE7b7d2AFADD38FD3B3040d13cbE2BC',  # noqa: E501
            counterparty=CPT_GAS,
        ), HistoryBaseEntry(
            event_identifier=tx_hex,
            sequence_index=1,
            timestamp=1650276061000,
            location=Location.BLOCKCHAIN,
            event_type=HistoryEventType.WITHDRAWAL,
            event_subtype=HistoryEventSubType.REMOVE_ASSET,
            asset=A_ETH,
            balance=Balance(amount=FVal('1.02930131799766041'), usd_value=ZERO),
            location_label=location_label,
            notes='Remove 1.02930131799766041 ETH from the curve pool',
            counterparty=CPT_CURVE,
        ), HistoryBaseEntry(
            event_identifier=tx_hex,
            sequence_index=193,
            timestamp=1650276061000,
            location=Location.BLOCKCHAIN,
            event_type=HistoryEventType.SPEND,
            event_subtype=HistoryEventSubType.RETURN_WRAPPED,
            asset=EthereumToken('0x06325440D014e39736583c165C2963BA99fAf14E'),
            balance=Balance(amount=FVal('0.991695529556581896'), usd_value=ZERO),
            location_label=location_label,
            notes='Return 0.991695529556581896 steCRV',
            counterparty=CPT_CURVE,
        )]
    assert expected_events == events
    def _get_internal_transactions_for_ranges(
        self,
        address: ChecksumEthAddress,
        start_ts: Timestamp,
        end_ts: Timestamp,
    ) -> None:
        """Queries etherscan for all internal transactions of address in the given ranges.

        If any internal transactions are found, they are added in the DB
        """
        location_string = f'{RANGE_PREFIX_ETHINTERNALTX}_{address}'
        ranges = DBQueryRanges(self.database)
        ranges_to_query = ranges.get_location_query_ranges(
            location_string=location_string,
            start_ts=start_ts,
            end_ts=end_ts,
        )
        dbethtx = DBEthTx(self.database)
        new_internal_txs = []
        for query_start_ts, query_end_ts in ranges_to_query:
            log.debug(
                f'Querying Internal Transactions for {address} -> {query_start_ts} - {query_end_ts}'
            )  # noqa: E501
            try:
                for new_internal_txs in self.ethereum.etherscan.get_transactions(
                        account=address,
                        from_ts=query_start_ts,
                        to_ts=query_end_ts,
                        action='txlistinternal',
                ):
                    if len(new_internal_txs) != 0:
                        for internal_tx in new_internal_txs:
                            # make sure all internal transaction parent transactions are in the DB
                            gevent.sleep(0)
                            result = dbethtx.get_ethereum_transactions(
                                ETHTransactionsFilterQuery.make(
                                    tx_hash=internal_tx.parent_tx_hash
                                ),  # noqa: E501
                                has_premium=True,  # ignore limiting here
                            )
                            if len(
                                    result
                            ) == 0:  # parent transaction is not in the DB. Get it
                                transaction = self.ethereum.get_transaction_by_hash(
                                    internal_tx.parent_tx_hash)  # noqa: E501
                                gevent.sleep(0)
                                dbethtx.add_ethereum_transactions(
                                    ethereum_transactions=[transaction],
                                    relevant_address=address,
                                )
                                timestamp = transaction.timestamp
                            else:
                                timestamp = result[0].timestamp

                            dbethtx.add_ethereum_internal_transactions(
                                transactions=[internal_tx],
                                relevant_address=address,
                            )
                            log.debug(
                                f'Internal Transactions for {address} -> update range {query_start_ts} - {timestamp}'
                            )  # noqa: E501
                            ranges.update_used_query_range(  # update last queried time for address
                                location_string=location_string,
                                queried_ranges=[(query_start_ts, timestamp)],
                            )
                            self.msg_aggregator.add_message(
                                message_type=WSMessageType.
                                ETHEREUM_TRANSACTION_STATUS,
                                data={
                                    'address':
                                    address,
                                    'period': [query_start_ts, timestamp],
                                    'status':
                                    str(TransactionStatusStep.
                                        QUERYING_INTERNAL_TRANSACTIONS
                                        ),  # noqa: E501
                                },
                            )

            except RemoteError as e:
                self.ethereum.msg_aggregator.add_error(
                    f'Got error "{str(e)}" while querying internal ethereum transactions '
                    f'from Etherscan. Transactions not added to the DB '
                    f'address: {address} '
                    f'from_ts: {query_start_ts} '
                    f'to_ts: {query_end_ts} ', )
                return

        log.debug(
            f'Internal Transactions for address {address} done. Update range {start_ts} - {end_ts}'
        )  # noqa: E501
        ranges.update_used_query_range(  # entire range is now considered queried
            location_string=location_string,
            queried_ranges=[(start_ts, end_ts)],
        )