Skip to main content

How Koinly handles transfers between your own wallets

Written by Robin Singh

Transferring crypto assets between exchanges and wallets you own is usually not taxable. Once you added all your data, Koinly will try to find & match transfers them automatically. Having them correctly identified can significantly lower your calculated taxable gains.

What is a transfer in Koinly

Koinly uses a double-ledger notation, meaning that every action you take will have two separate records associated with it. For transfers in Koinly, this means specifically:

  • One withdrawal (negative) from wallet A

  • One deposit (positive) to wallet B

If the two transactions pass Koinly's auto-matching rules, they will be merged together into a non-taxable transfer (with no change to the cost basis or acquisition date of the transferred asset).

Example of a transfer in Koinly

Let's say you have 2 wallets: Coinbase and MetaMask.

  • You send out 1 ETH from Coinbase.

  • A few minutes later, you receive 1 ETH into your MetaMask wallet.

Here you would initially have 2 separate transactions - a withdrawal of 1 ETH from Coinbase and a deposit of 1 ETH to MetaMask:

image.png

But Koinly can see that you are just moving coins from one wallet into another so it automatically merges them into a single transfer transaction. The difference between the sending and receiving amount would be added as a transfer fee. The merged transaction will look like this:

image.png

Oftentimes you won't even notice the two separate transactions, as Koinly almost instantly merges them during its calculations.

Auto-matching rules

Koinly will automatically merge a deposit and a withdrawal into a transfer if the following rules are met:

  1. 👯‍♀️ Likeness check
    The deposit and withdrawal are for the same asset/currency

  2. ⏱️ Interval check
    Both transactions should be within 12 hours of each other

  3. 🗓️ Chronology check
    The withdrawal happens before the deposit

  4. ⚖️ Amount check
    The deposited amount is equal to or smaller than the withdrawn amount

  5. 🧮 Difference check
    The deposit is not significantly smaller than the withdrawal - the maximum difference between the deposit and the withdrawal is 20%.
    Koinly will merge 0.10 BTC >> 0.08 BTC, but will not merge 0.15 ETH >> 0.05 ETH

  6. #️⃣ Hash check
    Transactions have the same transaction hash, or one of the transactions doesn't have a hash at all, or none of them do

Can Koinly match bridging transactions?

The short answer is - it depends. If you bridge your asset from one blockchain to another, the asset you receive might be a slightly different token than the one you've sent.

🍎 ➡️ 🍎 Bridges if the token is the same

e.g. Sending ETH on Ethereum and receiving ETH on Polygon

  • Bridging is no different than transferring assets between wallets

  • Koinly will merge them automatically (assuming all other checks passed)

🍎 ➡️ 🍏 Bridges if the token is different

e.g. Sending BTC on Bitcoin and receiving wBTC on Ethereum

  • Koinly will not merge it automatically as the transactions fail the likeness check

  • In such cases, if all the other checks are passed, you can still merge them manually

  • Such bridges will appear as an Exchange, not a transfer, and gains will be calculated as if the asset was sold (ie. you sold BTC for wBTC)

How can I create a Transfer manually?

Before making any manual changes, first ensure your data is accurate. Most issues with transfer matching come from incomplete or incorrect data:

  • Deposits and withdrawals files not imported from an exchange

  • CSV files imported in the wrong timezone

  • Inaccurate API data

  • Wrong currency imported on one of the legs of the transfers

  • Exchange data is rounded (amounts) or inaccurate (timestamps after x confirmations)

  • etc.

See:

If your transaction history still needs manual amendments after importing, fixing a transfer depends on the scenario - see three possible situations below.

☝️ Adding incorrect data may skew your gains

Before making any manual changes, make sure that the data is really missing, not just slightly incorrect. If you edit a withdrawal into a transfer while the deposit was already there (e.g. with the wrong timestamp) you are effectively corrupting (duplicating) your data

⬆️ *️⃣ One of the transactions is missing

The transfer could not be automatically merged, because there is only a deposit to one of your wallets, without the corresponding withdrawal from the other wallet (or the opposite - you have a withdrawal, but not a matching deposit)

Solution: Mark as transfer

  1. Click the transaction type (as if you were going to apply a tag) and select "Mark as transfer".

  2. Follow the steps in the popup, selecting "Own Wallet"

  3. Click "Create manually"

  4. Confirm date, wallet of the other side of the transfer and the amount

  5. Once everything looks correct, click the "Save" button

The video below shows the steps when the withdrawal is imported and deposit is missing, though the opposite situation would be handled similarly:

*️⃣ *️⃣ Both the deposit and the withdrawal are missing

The imported data was incomplete and didn't contain any information about this particular transfer.

Solution: Add the transfer manually

Missing transaction needs to be added manually.

  1. Click the "Add" button on the Transactions page

  2. Choose either the deposit or withdrawal

  3. On the edit popup, change the type to "Transfer"

  4. Fill all the necessary information (currency, sending and receiving wallet, amounts, etc.)

Note that:

  • One of the currency fields will be greyed out as it's linked to the other field (for a transfer, sending and receiving currency has to be the same)

  • Transfer fee is computed automatically as the difference between the amount sent and received

⬆️ ⬇️ The deposit and withdrawal are present but weren't merged

This happens if the transactions failed on one of our checks described above. This issue is usually caused by wrong data import (eg. wrong timezone selected) and should be fixed at source (by reimporting your data, this time correctly).

But if it's a single instance, then you can just fix this one transfer manually.

Most common reasons why Koinly didn't merge a transfer:

  • Inaccurate timestamps: deposit happens before the withdrawal

  • Inaccurate amounts: deposit is larger than the withdrawal

Solution: Edit inaccurate transaction and merge

Edit either the deposit or withdrawal and modify it so that the transactions pass all the matching rules. Depending on what's wrong, you may need to edit the timestamp (so the deposit happens after the withdrawal) or the amount (so the deposit is smaller/equal to withdrawal).

After that, merge them manually.

Why is there a profit/loss on a transfer to my own wallet?

Koinly may show a gain/loss on a transfer if:

  • One leg of the transfer is missing

    • Either because not all data was imported yet, or some data is missing

  • The transactions are not merged into a transfer

    • Because one of the checks failed: likeness, chronology, interval, etc.

  • The profit is on the disposal of the transfer fee only

    • This is expected if you have "Treat transfer fees as disposals" set to ON

For details and possible fixes, see:

Did this answer your question?