Crypto Tax Reporting: FIFO, LIFO, and Specific Identification

Crypto taxes are notoriously complex, and lot tracking is where most people mess up. Let me share what I’ve learned tracking Bitcoin and Ethereum in Beancount.

Cost Basis Methods

The IRS allows several methods for determining which coins you sold:

  1. FIFO (First In, First Out): Sell oldest coins first
  2. LIFO (Last In, First Out): Sell newest coins first
  3. Specific Identification: Choose exactly which lot to sell

Why Lot Selection Matters

If you bought BTC at:

  • Jan 2024: 1 BTC at USD 40,000
  • Nov 2024: 1 BTC at USD 70,000

And sell 1 BTC at USD 65,000:

  • FIFO: Gain = USD 25,000 (sold the USD 40K coin)
  • Specific ID: Loss = USD 5,000 (sold the USD 70K coin)

That’s a USD 30,000 tax difference!

Beancount Implementation

; Purchases with lot tracking
2024-01-15 * "Buy BTC"
  Assets:Crypto:BTC  1 BTC {40000.00 USD, 2024-01-15}
  Assets:Bank:Checking  -40,000.00 USD

2024-11-10 * "Buy BTC"
  Assets:Crypto:BTC  1 BTC {70000.00 USD, 2024-11-10}
  Assets:Bank:Checking  -70,000.00 USD

; Sell with specific identification
2026-02-01 * "Sell BTC - specific lot"
  Assets:Crypto:BTC  -1 BTC {70000.00 USD, 2024-11-10}  ; Specify exact lot
  Assets:Bank:Checking  65,000.00 USD
  Income:CapitalGains:Crypto:ShortTerm  5,000.00 USD

Questions

  1. Anyone automate lot selection for tax optimization?
  2. How do you handle exchange fees in cost basis?
  3. What’s your approach for tracking across multiple exchanges?

On exchange fees—you MUST add them to cost basis. The IRS is clear on this.

Fee Treatment

When buying:

2024-01-15 * "Buy BTC on Coinbase"
  Assets:Crypto:BTC  0.99 BTC {40404.04 USD, 2024-01-15}
  ; You paid 40,000 but got 0.99 BTC due to fee
  ; Cost basis = 40,000 / 0.99 = 40,404.04 per BTC
  Assets:Bank:Checking  -40,000.00 USD

Wait, actually I prefer tracking fees explicitly:

2024-01-15 * "Buy BTC on Coinbase"
  Assets:Crypto:BTC  1 BTC {39,600.00 USD, 2024-01-15}
  Expenses:Fees:Crypto:Trading  400.00 USD
  Assets:Bank:Checking  -40,000.00 USD

The difference:

  • Method 1: Fee baked into basis (cleaner for gains calculation)
  • Method 2: Fee separate (better expense tracking, same tax result)

When Selling

Fees at sale reduce your proceeds:

2026-02-01 * "Sell BTC"
  Assets:Crypto:BTC  -1 BTC {39,600.00 USD, 2024-01-15}
  Assets:Bank:Checking  64,700.00 USD  ; 65K minus 300 fee
  Expenses:Fees:Crypto:Trading  300.00 USD
  Income:CapitalGains:Crypto:LongTerm  -25,100.00 USD  
  ; Gain = 64,700 - 39,600 = 25,100

For tracking across multiple exchanges, I use sub-accounts per exchange but a single commodity.

My Structure

Assets:Crypto:Coinbase:BTC
Assets:Crypto:Kraken:BTC
Assets:Crypto:ColdStorage:BTC

All use the same BTC commodity, so queries can aggregate:

SELECT sum(units(position)), sum(cost(position))
WHERE currency = 'BTC'

The Transfer Problem

Moving between exchanges is NOT a taxable event, but you need to track it:

2026-01-15 * "Transfer BTC to cold storage"
  Assets:Crypto:Coinbase:BTC  -1 BTC {39,600.00 USD, 2024-01-15}
  Assets:Crypto:ColdStorage:BTC  1 BTC {39,600.00 USD, 2024-01-15}

Critical: Preserve the original lot information! The cost basis follows the coin.

Network Fees on Transfers

Gas fees for transfers are tricky. They’re not deductible (since transfer isn’t a sale), but they might affect basis:

2026-01-15 * "Transfer BTC - with network fee"
  Assets:Crypto:Coinbase:BTC  -1 BTC {39,600.00 USD, 2024-01-15}
  Assets:Crypto:ColdStorage:BTC  0.9998 BTC {39,607.92 USD, 2024-01-15}
  ; Basis increases slightly to account for transfer fee
  Expenses:Fees:Crypto:Network  8.00 USD

One more thing on specific identification—documentation requirements!

IRS Requirements for Specific ID

To use specific identification, the IRS requires you to:

  1. Specify which exact units you’re selling at the time of sale
  2. Receive confirmation from the exchange/wallet
  3. Keep adequate records

How to Document in Beancount

I use metadata to create an audit trail:

2026-02-01 * "Sell BTC - specific lot"
  Assets:Crypto:Coinbase:BTC  -1 BTC {70000.00 USD, 2024-11-10}
  Assets:Bank:Checking  65,000.00 USD
  Income:CapitalGains:Crypto:ShortTerm  5,000.00 USD
  lot-selection-method: "Specific Identification"
  lot-selected: "2024-11-10 purchase at 70000"
  selection-reason: "Harvesting short-term loss"
  confirmation: "Coinbase trade ID XYZ123"

Consistency Warning

Once you start using specific identification for a coin, the IRS expects consistency. Don’t switch between FIFO and specific ID arbitrarily—have a documented policy.

I personally use specific ID for everything because Beancount’s lot tracking makes it easy, and it gives me maximum tax flexibility.