From 726267d1c91e8fef09d1674ad5a3b595391295e0 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 7 Apr 2026 16:55:39 +0000 Subject: [PATCH] Add tax accounting guide, event types reference and accounting rules --- .vitepress/config.mts | 3 + index.md | 6 +- usage-guides/accounting-rules.md | 183 ++++++++++++++++ usage-guides/customization.md | 3 + usage-guides/event-types.md | 352 ++++++++++++++++++++++++++++++ usage-guides/historical-events.md | 3 + usage-guides/index.md | 3 + usage-guides/pnl.md | 3 + usage-guides/tax-accounting.md | 90 ++++++++ 9 files changed, 645 insertions(+), 1 deletion(-) create mode 100644 usage-guides/accounting-rules.md create mode 100644 usage-guides/event-types.md create mode 100644 usage-guides/tax-accounting.md diff --git a/.vitepress/config.mts b/.vitepress/config.mts index 8be4064..d76e9e1 100644 --- a/.vitepress/config.mts +++ b/.vitepress/config.mts @@ -58,12 +58,15 @@ export default defineConfig({ text: 'Usage Guides', items: [ { text: 'Introduction', link: '/usage-guides/' }, + { text: 'Tax Accounting Guide', link: '/usage-guides/tax-accounting' }, { text: 'Tracking Accounts & Balances', link: '/usage-guides/accounts-and-balances' }, { text: 'Historical Events', link: '/usage-guides/historical-events' }, + { text: 'Event Types & Subtypes', link: '/usage-guides/event-types' }, { text: 'On-Chain Transactions', link: '/usage-guides/onchain' }, { text: 'Staking', link: '/usage-guides/staking' }, { text: 'Statistics', link: '/usage-guides/statistic' }, { text: 'Profit/Loss Report', link: '/usage-guides/pnl' }, + { text: 'Accounting Rule Options', link: '/usage-guides/accounting-rules' }, { text: 'Tag Management', link: '/usage-guides/tag-management' }, { text: 'Assets Management', link: '/usage-guides/assets' }, { text: 'Add Missing Prices', link: '/usage-guides/custom-price' }, diff --git a/index.md b/index.md index 5ad394d..20891c3 100644 --- a/index.md +++ b/index.md @@ -12,4 +12,8 @@ THE SERVICE IS NOT INTENDED FOR CONTINUOUS MONITORING OF TRANSACTION DATA OR FOR # Where to start? -If this is the first time looking at rotki you will probably want to visit the [Installation Guide](/requirement-and-installation/). Once you have successfully managed to install rotki you can proceed to the [Usage Guide](/usage-guides/). If you wish to contribute to rotki please check the [Contribution Guide](/contribution-guides/). +If this is the first time looking at rotki you will probably want to visit the [Installation Guide](/requirement-and-installation/). Once you have successfully managed to install rotki you can proceed to the [Usage Guide](/usage-guides/). + +**Looking to do your crypto taxes?** Check the [Tax Accounting Guide](/usage-guides/tax-accounting) for a step-by-step walkthrough from setup to generating your PnL report. + +If you wish to contribute to rotki please check the [Contribution Guide](/contribution-guides/). diff --git a/usage-guides/accounting-rules.md b/usage-guides/accounting-rules.md new file mode 100644 index 0000000..ed15903 --- /dev/null +++ b/usage-guides/accounting-rules.md @@ -0,0 +1,183 @@ +# Accounting Rule Options Explained + +This page explains every accounting setting in rotki in detail. These settings control how your transactions are processed when generating a [Profit/Loss Report](/usage-guides/pnl). You can configure them under **Settings → Accounting Settings** ([screenshot guide](/usage-guides/customization#accounting-settings)). + +> [!IMPORTANT] +> rotki's default settings are based on German tax rules. Check with your tax advisor about what's required in your country and adjust accordingly. + +## Cost basis method + +The cost basis method determines which acquisition is matched to a sale when calculating profit or loss. + +| Method | Full Name | How it works | Best for | +| -------- | --------------------- | ----------------------------------------------- | -------------------------------------------------------------- | +| **FIFO** | First In, First Out | The oldest acquisition is matched first | Most common default; required in many jurisdictions | +| **LIFO** | Last In, First Out | The most recent acquisition is matched first | Jurisdictions that allow it; can defer gains in rising markets | +| **HIFO** | Highest In, First Out | The highest-priced acquisition is matched first | Minimizing taxable gains (where allowed) | +| **ACB** | Average Cost Basis | Uses the weighted average price of all holdings | Required in some jurisdictions (e.g., Canada, UK for shares) | + +**Example (FIFO)**: You bought 1 ETH at $1,000, then another 1 ETH at $2,000. You sell 1 ETH at $3,000. Under FIFO, the sale is matched to the $1,000 purchase, so your taxable gain is $2,000. + +**Example (HIFO)**: Same scenario — the sale is matched to the $2,000 purchase, so your taxable gain is only $1,000. + +## Crypto to crypto trades + +**Setting**: `True` (default) or `False` + +Controls whether swapping one cryptocurrency for another is treated as a taxable event. + +**When `True`**: Each crypto-to-crypto swap generates "virtual trades" through your profit currency. For example, swapping 1 ETH → 2000 USDC when ETH is worth €3,000 and you originally bought ETH at €1,000 creates: + +- Virtual sell: Sell 1 ETH for €3,000 → PnL = €3,000 - €1,000 = **€2,000 gain** +- Virtual buy: Buy 2000 USDC for €3,000 → PnL = €0 (acquisition, not taxable yet) + +**When `False`**: No profit/loss is calculated on the swap. The cost basis of the received asset inherits from what was given up. + +**Most users should**: Leave this as `True`. Most tax jurisdictions treat crypto-to-crypto swaps as taxable dispositions. + +## Crypto spending + +This is part of the "Crypto to Crypto Trades" setting and controls whether spending crypto (on fees, purchases, etc.) triggers a cost basis PnL calculation. + +**When `True`**: When you spend crypto, rotki calculates both the loss from spending and any profit/loss from price changes since you acquired the asset. + +**Example**: You bought 1 ETH at €50. You later spend it on gas when ETH is worth €100. + +- Loss from spending: -€100 +- Gain from price increase: €100 - €50 = €50 +- **Net PnL: -€50** + +**When `False`**: Only the spending loss is counted. Net PnL: -€100. + +## EVM gas costs + +**Setting**: `True` (default) or `False` + +Whether gas fees for on-chain transactions should be counted as a loss (expense) in PnL calculations. + +**When `True`**: Gas costs reduce your PnL as an expense. + +**When `False`**: Gas costs are ignored in PnL calculations. + +## Tax-free period + +**Setting**: Number of days, or disabled + +If your country exempts crypto assets held for longer than a certain period from capital gains tax (e.g., Germany: 1 year = 365 days), enter the number of days here. + +**How it works**: When you sell an asset that you've held longer than the tax-free period, the gain is moved to the `pnl_free` column instead of `pnl_taxable` in the PnL report. + +## Calculate past cost basis + +**Setting**: `True` (default) or `False` + +Whether rotki should look at all of your historical transactions (even before the report period) to determine the cost basis of assets sold during the report period. + +**When `True`**: If you bought ETH in 2020 and sell it in 2024, rotki uses the 2020 purchase price as the cost basis — even if your report period is only 2024. + +**When `False`**: Only events within the report period are considered for cost basis. This means older acquisitions are ignored, which can result in "no documented acquisition found" warnings. + +**Most users should**: Leave this as `True`. Turning it off means rotki can't trace the original purchase price for assets you've held for a long time. + +## Omit ETH staking events + +**Setting**: `True` or `False` (default) + +Controls when ETH staking rewards become taxable. + +**When `True`**: Staking rewards are only considered taxable after the Ethereum merge and withdrawals are enabled (September 2022+). Earlier rewards are omitted from PnL. + +**When `False`**: All staking rewards are taxable at the time they are received, including pre-merge rewards. + +## Include fees in cost basis + +**Setting**: `True` (default) or `False` + +Whether trading fees are added to the cost basis of the asset you're buying. + +**Example**: You buy 1 ETH for €1,000 and pay a €10 fee. + +**When `True`**: The cost basis of that ETH is €1,010. The fee is incorporated into the cost basis and will reduce your taxable gain when you eventually sell. + +**When `False`**: The cost basis is €1,000. The €10 fee appears as a separate spend event. + +## Understanding accounting rule properties + +When you create or edit an [accounting rule](/usage-guides/customization#add-edit-accounting-rules), or when you look at the default rules in rotki's codebase, each rule has several properties that control how events are processed: + +### Taxable + +Whether the event is subject to tax. If `False`, the event is recorded but doesn't contribute to taxable PnL. + +### Count entire amount as spend + +For spending events, whether the full amount should be counted as an expense (negative PnL). + +**Example**: You spend 0.01 ETH (worth €30) on gas. + +- If `True`: The full €30 is counted as a loss. +- If `False`: The amount is not counted as a direct loss (but cost basis PnL may still apply). + +### Count cost basis PnL + +Whether to calculate the profit or loss between the asset's current value and its original acquisition price. + +This is the setting the user named "Count cost basis PnL" in the UI. It determines whether, in addition to counting the event as a spend/acquisition, rotki also computes the capital gain or loss since you originally acquired the asset. + +**Example**: You bought 1 ETH at €1,000. You later spend it when ETH is worth €3,000. + +- If `True`: rotki records a €2,000 capital gain (€3,000 - €1,000) in addition to the €3,000 spend. +- If `False`: Only the spending amount is recorded; the difference from the acquisition price is ignored. + +**When you'd set this to `False`**: For events where the "spend" is not a real disposal — for example, depositing into a protocol. You're moving your asset, not selling it, so there's no capital gain to realize. + +### Accounting treatment: Swap + +When multiple events are processed together (e.g., a trade that has both a spend and a receive event), the **Swap** treatment tells rotki to treat them as a single exchange. + +In a swap: + +1. The spend side disposes of the asset (potentially triggering a capital gain/loss) +2. The receive side acquires a new asset at the current market value + +This is the default treatment for trades and DEX swaps. Without swap treatment, each side of a trade would be processed independently, which would produce incorrect PnL. + +**Example**: You swap 1 ETH (bought at €1,000) for 3,000 USDC when ETH is worth €3,000. + +- Spend side: Dispose of 1 ETH → capital gain of €2,000 +- Receive side: Acquire 3,000 USDC at cost basis of €3,000 + +### Accounting treatment: Basis Transfer + +**Basis Transfer** is used when you move assets between forms without realizing a gain or loss. The cost basis of the original asset is transferred to the new asset. + +This is used for events like token migrations (SAI → DAI), protocol deposits where you receive a receipt token, and similar non-taxable conversions. + +**Example**: You migrate 1,000 SAI (cost basis €900) to 1,000 DAI. + +- With Basis Transfer: The 1,000 DAI inherits the €900 cost basis. No taxable event. +- Without Basis Transfer: The SAI disposal would trigger a gain/loss calculation, and DAI would be acquired at current market price. + +**When it's used**: Token migrations, wrapping/unwrapping (ETH ↔ WETH), receipt tokens from lending protocols, and other conversions where economic value doesn't change. + +## Custom accounting rules + +You can create custom rules that override the defaults for specific combinations of: + +- Event type +- Event subtype +- Counterparty (protocol identifier) + +See [Add/Edit accounting rules](/usage-guides/customization#add-edit-accounting-rules) for how to create them in the UI. + +### Limitations + +- **Counterparty must be a known protocol**: You can only create rules for counterparties that rotki recognizes (e.g., "uniswap-v3", "aave", "makerdao_dsr"). Custom smart contract addresses cannot currently be used as counterparties for accounting rules. Support for custom counterparties is tracked in [rotki/rotki#9803](https://github.com/rotki/rotki/issues/9803). +- **Rules are global**: A rule applies to all events matching the type/subtype/counterparty combination. For per-event overrides, use [special accounting rules for specific events](/usage-guides/customization#special-accounting-rules-for-specific-events). + +## CSV export settings + +These settings control the format of exported PnL reports: + +- **Export Formulas**: Whether to export cell formulas (for spreadsheet calculations) or just the computed values. +- **Have Summary**: Whether to include a summary section at the end of the CSV with totals and the rotki version/settings used. diff --git a/usage-guides/customization.md b/usage-guides/customization.md index c966405..f31d9dd 100644 --- a/usage-guides/customization.md +++ b/usage-guides/customization.md @@ -150,6 +150,9 @@ There are two options to reset the assets database: ## Accounting Settings +> [!TIP] +> For a detailed explanation of what each accounting option does (with worked examples), see [Accounting Rule Options Explained](/usage-guides/accounting-rules). + ![Customizing the accounting rules](/images/sc_accounting_custom_rule.png) In the accounting menu, you can customize application settings related to accounting calculations. These settings will affect the PnL report calculations. diff --git a/usage-guides/event-types.md b/usage-guides/event-types.md new file mode 100644 index 0000000..d95eaca --- /dev/null +++ b/usage-guides/event-types.md @@ -0,0 +1,352 @@ +# Event Types and Subtypes Reference + +This page provides a complete reference for all event types and subtypes in rotki. Understanding these categories is essential for reviewing your transaction history and ensuring your PnL reports are accurate. + +## How event types work + +Every transaction in rotki is categorized with two fields: + +- **Event Type**: The broad category of what happened (e.g., Trade, Deposit, Spend) +- **Event Subtype**: The specific action within that category (e.g., Fee, Reward, Airdrop) + +Together, these determine how rotki treats the event in accounting — whether it's taxable, whether it counts as an acquisition or a spend, and how it affects your cost basis. + +Not every combination of type and subtype is valid. The table in [all valid type/subtype combinations](#all-valid-type-subtype-combinations) below lists every combination that rotki recognizes. + +## Event Types + +### Trade + +A trade is an exchange of one asset for another. In rotki, trades are represented as a pair of events with consecutive `sequence_index` values: + +- First event: `Trade` type with `Spend` subtype (what you gave up) +- Second event: `Trade` type with `Receive` subtype (what you got) + +**Example**: Swapping 1 ETH for 2000 USDC on Uniswap. + +**Default tax treatment**: Taxable (Swap accounting treatment). The spend side triggers a cost basis calculation. The receive side is an acquisition at the current market value. + +**When to use**: Any swap, trade, or exchange of one asset for another — whether on a CEX, a DEX, or OTC. + +| Subtype | UI Category | Direction | Example | +| --------- | ----------- | --------- | -------------------------- | +| `Spend` | swap | Out | Sending 1 ETH in a swap | +| `Receive` | swap | In | Getting 2000 USDC in swap | +| `None` | info | Neutral | Informational trade event | +| `Fee` | fee | Out | Trading fee on an exchange | + +### Multi-Trade + +Similar to Trade but used when a single transaction involves multiple assets being swapped (e.g., aggregator routes through multiple pools). + +| Subtype | UI Category | Direction | Example | +| --------- | ----------- | --------- | --------------------------------- | +| `Spend` | swap | Out | Outgoing side of a multi-hop swap | +| `Receive` | swap | In | Incoming side of a multi-hop swap | +| `Fee` | fee | Out | Fee on a multi-asset swap | + +### Deposit + +Moving assets into an exchange, wallet, or protocol. + +| Subtype | UI Category | Direction | Example | +| --------------------- | ---------------- | --------- | -------------------------------------- | +| `Deposit Asset` | account deposit | Neutral | Depositing ETH to Kraken | +| `Deposit For Wrapped` | deposit | Out | Depositing DAI to receive cDAI | +| `Deposit To Protocol` | protocol deposit | Neutral | Depositing into Aave lending pool | +| `Bridge` | bridge | Out | Sending ETH to the Arbitrum bridge | +| `Place Order` | deposit | Out | Placing a limit order (e.g., CoW Swap) | +| `Fee` | fee | Out | Fee on a deposit | + +### Withdrawal + +Moving assets out of an exchange, wallet, or protocol. + +| Subtype | UI Category | Direction | Example | +| ------------------------ | ------------------- | --------- | -------------------------------------- | +| `Remove Asset` | account withdraw | Neutral | Withdrawing BTC from Binance | +| `Redeem Wrapped` | withdraw | In | Redeeming cDAI back to DAI | +| `Withdraw From Protocol` | protocol withdrawal | Neutral | Withdrawing from Aave lending pool | +| `Bridge` | bridge | In | Receiving ETH from the Optimism bridge | +| `Cancel Order` | cancel order | In | Cancelling a CoW Swap order | +| `Refund` | refund | In | Getting refunded from a failed order | +| `Generate Debt` | borrow | In | Borrowing from a lending protocol | +| `Fee` | fee | Out | Fee on a withdrawal | + +### Spend + +A plain expenditure — you spent crypto and received nothing (or something non-crypto) in return. + +| Subtype | UI Category | Direction | Example | Notes | +| ---------------- | ----------- | --------- | -------------------------------------- | ---------------------------------- | +| `None` | send | Out | Paying for a service with BTC | Taxable (loss) | +| `Fee` | fee | Out | Paying gas fees on Ethereum | Depends on "EVM Gas Costs" setting | +| `Return Wrapped` | return | Out | Returning aDAI to Aave to get DAI back | Not taxable (protocol interaction) | +| `Payback Debt` | repay | Out | Repaying a loan on Aave | | +| `Donate` | donate | Out | Donating crypto to a cause | | +| `Payment` | pay | Out | Making a payment | | +| `Clawback` | clawback | Out | Assets clawed back by protocol | | +| `Burn` | burn | Out | Burning tokens | | + +### Receive + +You received assets — this is an acquisition event. + +| Subtype | UI Category | Direction | Example | Notes | +| ----------------- | ------------------ | --------- | -------------------------------------------- | --------------------------- | +| `None` | receive | In | Receiving a payment in crypto | Taxable (income) | +| `Reward` | claim reward | In | Receiving CRV rewards from Curve | Taxable (income) | +| `Airdrop` | airdrop | In | Receiving a governance token airdrop | Taxable (income) | +| `Receive Wrapped` | receive | In | Getting aDAI after depositing DAI to Aave | Not taxable (receipt token) | +| `Return Wrapped` | receive | In | Getting back wrapped tokens | | +| `Generate Debt` | borrow | In | Borrowing assets from a lending protocol | | +| `Donate` | receive donation | In | Receiving a donation | | +| `Liquidate` | liquidation reward | In | Receiving assets from liquidating a position | | +| `Payment` | receive payment | In | Receiving a payment | | +| `Grant` | receive grant | In | Receiving a grant (e.g., Gitcoin) | | +| `Interest` | receive interest | In | Receiving interest from a lending protocol | | +| `Cashback` | cashback | In | Receiving cashback rewards | | +| `Refund` | refund | In | Getting a refund | | +| `Spam` | spam | In | Spam/phishing tokens sent to your address | Ignored in accounting | + +### Transfer + +Moving assets between your own accounts. Not taxable. + +| Subtype | UI Category | Direction | Example | +| -------- | ----------- | --------- | ------------------------------------- | +| `None` | transfer | Neutral | Moving ETH from one wallet to another | +| `Donate` | donate | Out | Donating via a transfer | +| `Fee` | fee | Out | Fee on a transfer | + +**When to use**: If rotki categorized a self-transfer as a spend or trade, change it to `Transfer` with subtype `None` to avoid it being counted as taxable. + +### Staking + +Events related to staking assets. + +| Subtype | UI Category | Direction | Example | Notes | +| --------------------- | -------------- | --------- | ---------------------------------------- | -------------------------------------------- | +| `Deposit Asset` | stake | Out | Staking ETH in the Eth2 deposit contract | | +| `Deposit For Wrapped` | stake | Out | Staking and receiving a receipt token | | +| `Remove Asset` | unstake | In | Unstaking and getting assets back | | +| `Redeem Wrapped` | unstake | In | Redeeming staked receipt tokens | | +| `Reward` | staking reward | In | ETH2 consensus layer rewards | Depends on "Omit ETH Staking Events" setting | +| `Block Production` | new block | In | ETH block production reward | | +| `MEV Reward` | mev | In | MEV reward from block building | | +| `Fee` | fee | Out | Fee related to staking | | + +### Migration (Migrate) + +Moving assets from one version of a protocol to another, where you don't gain or lose value. + +| Subtype | UI Category | Direction | Example | +| --------- | ----------- | --------- | ------------------------------------ | +| `Spend` | migrate | Out | Sending SAI in a SAI→DAI migration | +| `Receive` | migrate | In | Receiving DAI in a SAI→DAI migration | + +**When to use**: Protocol upgrades or token migrations where the economic value doesn't change. Both events should have type `Migrate`, with the outgoing side as `Spend` and the incoming side as `Receive`. + +### Loss + +Events where you lost assets involuntarily. + +| Subtype | UI Category | Direction | Example | +| -------------------------- | ------------------------ | --------- | ----------------------------------- | +| `None` | loss | Out | General loss of assets | +| `Liquidate` | liquidation loss | Out | Getting liquidated on a loan | +| `Hack` | hack | Out | Losing assets in a protocol exploit | +| `Liquidity Provision Loss` | liquidity provision loss | Out | Impermanent loss realized on exit | + +### Informational + +Events that contain useful information but have no financial impact. + +| Subtype | UI Category | Direction | Example | +| ------------------ | ------------- | --------- | ------------------------------------- | +| `None` | informational | Neutral | General informational event | +| `Governance` | governance | Neutral | Casting a governance vote | +| `Deposit Asset` | informational | Neutral | Informational deposit event | +| `Remove Asset` | withdraw | In | Informational withdrawal event | +| `Place Order` | place order | Neutral | Order placement notification | +| `Create` | new project | Neutral | Creating a Maker vault or Gnosis Safe | +| `Update` | update | Neutral | Updating a protocol position | +| `Apply` | apply | Neutral | Applying for something on-chain | +| `Approve` | approval | Neutral | Token approval (spending allowance) | +| `Attest` | attest | Neutral | On-chain attestation (e.g., EAS) | +| `MEV Reward` | mev | In | MEV reward info | +| `Block Production` | new block | In | Block production info | +| `Consolidate` | combine | Neutral | Consolidating positions | +| `Delegate` | delegate | Neutral | Delegating voting power | +| `Message` | message | Neutral | On-chain message | + +### Renew + +Renewal of a subscription or recurring service payment. + +| Subtype | UI Category | Direction | Example | +| ------- | ----------- | --------- | -------------------------------- | +| `None` | renew | Out | Paying for an ENS domain renewal | + +### Deploy + +Deploying a smart contract. + +| Subtype | UI Category | Direction | Example | +| ------- | ----------------- | --------- | --------------------------- | +| `None` | deploy | Neutral | Deploying a smart contract | +| `Spend` | deploy with spend | Out | Deploying with an ETH spend | +| `NFT` | mint nft | In | Deploying/minting an NFT | + +### Mint + +Minting tokens or NFTs. + +| Subtype | UI Category | Direction | Example | +| ------- | ----------- | --------- | -------------- | +| `NFT` | mint nft | In | Minting an NFT | +| `Fee` | fee | Out | Minting fee | + +### Burn + +Burning tokens or NFTs. + +| Subtype | UI Category | Direction | Example | +| ------- | ----------- | --------- | -------------- | +| `NFT` | burn | Out | Burning an NFT | + +### Fail + +A failed transaction (you still pay gas). + +| Subtype | UI Category | Direction | Example | +| ------- | ----------- | --------- | --------------------------------- | +| `Fee` | failed | Out | Gas fee from a failed transaction | + +### Adjustment + +Forced adjustments by a system like a centralized exchange (e.g., exchange delisting a token and converting it). + +| Subtype | UI Category | Direction | Example | +| --------- | ----------- | --------- | ------------------------------------ | +| `Spend` | send | Out | Asset removed by exchange adjustment | +| `Receive` | receive | In | Asset received from adjustment | + +### Margin + +Margin trading events. + +| Subtype | UI Category | Direction | Example | +| -------- | ----------- | --------- | ------------------------ | +| `Profit` | profit | In | Profit from margin trade | +| `Loss` | loss | Out | Loss from margin trade | +| `Fee` | fee | Out | Margin trading fee | + +### Transaction to Self + +A transaction where you sent assets to yourself (same address). + +| Subtype | UI Category | Direction | Example | +| ------- | ---------------- | --------- | ------------------------------- | +| `None` | self transaction | Neutral | Sending ETH to your own address | + +### Exchange Adjustment + +Adjustments made by exchanges to your balance. + +| Subtype | UI Category | Direction | Example | +| --------- | ----------- | --------- | ----------------------------- | +| `Spend` | send | Out | Exchange debits your balance | +| `Receive` | receive | In | Exchange credits your balance | + +### Exchange Transfer + +Transfers associated with exchange deposits/withdrawals that have both an on-chain and exchange side. + +| Subtype | UI Category | Direction | Example | +| --------- | ---------------- | --------- | --------------------------------------- | +| `Spend` | account withdraw | Neutral | On-chain side of an exchange withdrawal | +| `Receive` | account deposit | Neutral | On-chain side of an exchange deposit | +| `Fee` | fee | Out | Fee on the transfer | + +## All valid type/subtype combinations + +The following table lists every valid combination of event type and subtype recognized by rotki. Combinations not listed here are not valid. + +| Event Type | Valid Subtypes | +| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Trade | Spend, Receive, None, Fee | +| Multi-Trade | Spend, Receive, Fee | +| Deposit | Deposit Asset, Deposit For Wrapped, Deposit To Protocol, Bridge, Place Order, Fee | +| Withdrawal | Remove Asset, Redeem Wrapped, Withdraw From Protocol, Bridge, Cancel Order, Refund, Generate Debt, Fee | +| Spend | None, Fee, Return Wrapped, Payback Debt, Donate, Payment, Clawback, Burn | +| Receive | None, Reward, Airdrop, Receive Wrapped, Return Wrapped, Generate Debt, Donate, Liquidate, Payment, Grant, Interest, Cashback, Refund, Spam | +| Transfer | None, Donate, Fee | +| Staking | Deposit Asset, Deposit For Wrapped, Remove Asset, Redeem Wrapped, Reward, Block Production, MEV Reward, Fee | +| Migrate | Spend, Receive | +| Loss | None, Liquidate, Hack, Liquidity Provision Loss | +| Informational | None, Governance, Deposit Asset, Remove Asset, Place Order, Create, Update, Apply, Approve, Attest, MEV Reward, Block Production, Consolidate, Delegate, Message | +| Renew | None | +| Deploy | None, Spend, NFT | +| Mint | NFT, Fee | +| Burn | NFT | +| Fail | Fee | +| Adjustment | Spend, Receive | +| Margin | Profit, Loss, Fee | +| Transaction to Self | None | +| Exchange Adjustment | Spend, Receive | +| Exchange Transfer | Spend, Receive, Fee | + +## Quick reference: common customizations + +| Situation | Event Type | Event Subtype | +| ---------------------------------------- | --------------- | -------------------------- | +| Swap / trade on DEX or CEX | `Trade` | `Spend` + `Receive` (pair) | +| Moving assets to an exchange | `Deposit` | `Deposit Asset` | +| Moving assets from an exchange | `Withdrawal` | `Remove Asset` | +| Depositing into DeFi (get receipt token) | `Deposit` | `Deposit For Wrapped` | +| Depositing into DeFi (no receipt token) | `Deposit` | `Deposit To Protocol` | +| Withdrawing from DeFi (return receipt) | `Withdrawal` | `Redeem Wrapped` | +| Withdrawing from DeFi (no receipt) | `Withdrawal` | `Withdraw From Protocol` | +| Receiving wrapped/receipt tokens | `Receive` | `Receive Wrapped` | +| Returning wrapped/receipt tokens | `Spend` | `Return Wrapped` | +| Sending assets across a bridge | `Deposit` | `Bridge` | +| Receiving assets from a bridge | `Withdrawal` | `Bridge` | +| Transfer between own wallets | `Transfer` | `None` | +| Paying gas fees | `Spend` | `Fee` | +| Receiving staking rewards | `Staking` | `Reward` | +| Claiming DeFi rewards | `Receive` | `Reward` | +| Receiving an airdrop | `Receive` | `Airdrop` | +| Paying for a service | `Spend` | `None` | +| Getting paid in crypto | `Receive` | `None` | +| Borrowing from a protocol | `Withdrawal` | `Generate Debt` | +| Repaying a loan | `Spend` | `Payback Debt` | +| Token migration (old→new) | `Migrate` | `Spend` + `Receive` (pair) | +| ENS renewal, subscription | `Renew` | `None` | +| Token approval, governance vote | `Informational` | `Approve` / `Governance` | +| Lost in hack / exploit | `Loss` | `Hack` | +| Liquidation (your position) | `Loss` | `Liquidate` | +| Failed transaction (gas only) | `Fail` | `Fee` | + +## Entry types + +In addition to event type/subtype, rotki distinguishes between different **entry types** based on the source of the event: + +| Entry Type | Description | +| ------------------------ | --------------------------------------------------------------------------------------------- | +| **History Event** | Generic events from any source (exchanges, manual input, CSV import) | +| **EVM Event** | Decoded on-chain events from EVM chains (Ethereum, Optimism, Polygon, Arbitrum, Base, Gnosis) | +| **EVM Swap Event** | A specialized EVM event for swaps, supporting multiple spend/receive assets | +| **ETH Withdrawal Event** | ETH consensus layer withdrawal | +| **ETH Block Event** | ETH block production reward | +| **ETH Deposit Event** | ETH2 staking deposit | +| **Asset Movement Event** | Exchange deposit or withdrawal | +| **Swap Event** | A trade/swap from non-EVM sources | + +The entry type determines which fields are available when editing an event. For example, EVM events have a `Counterparty` field (the protocol or address you interacted with), while generic history events do not. + +## Editing events + +If an event is miscategorized, you can edit it directly from the History Events page. See the [common customization guide](/usage-guides/historical-events#common-customization) for step-by-step instructions and examples. + +Changes you make to event types/subtypes directly affect how they are processed in the PnL report. diff --git a/usage-guides/historical-events.md b/usage-guides/historical-events.md index eb00080..dda7b30 100644 --- a/usage-guides/historical-events.md +++ b/usage-guides/historical-events.md @@ -1,5 +1,8 @@ # History events +> [!TIP] +> **Trying to understand event types?** See the [Event Types & Subtypes Reference](/usage-guides/event-types) for a complete guide to what each event category means, with examples and default tax treatments. + rotki is capable of pulling and decoding a bunch of different events, ranging from EVM chain transactions to exchanges events and more. When you visit the `History Events` section the process to obtain all the information will start. You will be able to check the status in an informative breakdown per blockchain address. Free users are limited to a number of latest events. ## Supported events diff --git a/usage-guides/index.md b/usage-guides/index.md index a315ae2..f02cede 100644 --- a/usage-guides/index.md +++ b/usage-guides/index.md @@ -2,6 +2,9 @@ This guide explains how to use the rotki application. +> [!TIP] +> **Using rotki for tax reporting?** Jump to the [Tax Accounting Guide](/usage-guides/tax-accounting) for a focused walkthrough of connecting your data, reviewing transactions, and generating your PnL report. + ## First Time Sign-Up When you start rotki, you'll see a sign-in/signup prompt. rotki is a local app, so your account only exists on your local system. Your account on [rotki.com](https://rotki.com/) is only for managing premium subscription payments. diff --git a/usage-guides/pnl.md b/usage-guides/pnl.md index af52c7a..8bbb3c5 100644 --- a/usage-guides/pnl.md +++ b/usage-guides/pnl.md @@ -1,5 +1,8 @@ # Creating a profit/loss report +> [!TIP] +> **New to rotki?** If you're looking for a step-by-step guide to doing your crypto taxes, start with the [Tax Accounting Guide](/usage-guides/tax-accounting) which walks you through the entire workflow. This page covers the PnL report feature in detail. + rotki helps you track your cryptocurrency profits and losses (PnL) by analyzing your trading history and other transactions. Here's what you need to know about how these reports work: ## Key Features diff --git a/usage-guides/tax-accounting.md b/usage-guides/tax-accounting.md new file mode 100644 index 0000000..93f8b2b --- /dev/null +++ b/usage-guides/tax-accounting.md @@ -0,0 +1,90 @@ +# Using rotki for Tax Accounting + +This guide walks you through using rotki to calculate your cryptocurrency taxes. If you just installed rotki and want to generate a tax report, this is the page for you. + +> [!NOTE] +> rotki does not provide tax or legal advice. Always consult a qualified tax advisor for your specific situation. rotki helps you organize your data and generate reports that you can share with your advisor. + +## Overview + +The two most important sections of rotki for tax accounting are: + +1. **[History Events](/usage-guides/historical-events)** — where you review, correct, and customize all of your transactions +2. **[Profit/Loss Report](/usage-guides/pnl)** — where you generate the actual PnL (profit and loss) report for a given time period + +Everything else in rotki (adding accounts, importing data, configuring settings) feeds into these two sections. + +## Step-by-step tax workflow + +### 1. Connect your data sources + +Before you can generate a tax report, rotki needs to know about your transactions. + +- **Exchanges**: Add API keys for your centralized exchanges under [API Keys](/usage-guides/api-keys). rotki will automatically pull your trade history, deposits, and withdrawals. +- **Blockchain accounts**: Add your EVM, Bitcoin, or Solana addresses under [Accounts & Balances](/usage-guides/accounts-and-balances). rotki will pull and decode on-chain transactions automatically. +- **CSV imports**: For exchanges that don't support API integration (or that no longer exist, like FTX), you can [import CSV files](/usage-guides/import-csv) with your trade history. + +### 2. Configure your accounting settings + +Go to **Settings → Accounting Settings** ([detailed reference](/usage-guides/customization#accounting-settings)) and configure: + +- **Cost basis method**: FIFO, LIFO, HIFO, or ACB — check which method your tax jurisdiction requires. See [accounting rule options explained](/usage-guides/accounting-rules) for details. +- **Crypto to crypto trades**: Whether swapping one crypto for another is a taxable event (it is in most jurisdictions). +- **Tax-free period**: If your country allows tax-free treatment after a holding period (e.g., Germany's 1-year rule), set it here. +- **Profit currency**: The fiat currency your taxes are denominated in (e.g., EUR, USD, GBP). Change this via the currency icon in the top-right menu. + +### 3. Review your history events + +Go to **History Events** in the left sidebar. This is where all your transactions live. rotki automatically decodes most on-chain transactions, but you should review them for accuracy: + +- **Check for missing events**: If you moved assets through unsupported protocols or peer-to-peer, you may need to [add events manually](/usage-guides/historical-events#add--edit-events). +- **Fix incorrectly categorized events**: rotki may not always correctly identify what a transaction represents. See the [event types and subtypes reference](/usage-guides/event-types) to understand each category, and the [common customization guide](/usage-guides/historical-events#common-customization) for how to re-categorize events. +- **Check for missing accounting rules**: Events with a warning icon won't be processed correctly. Either edit the event or add a [missing accounting rule](/usage-guides/historical-events#missing-accounting-rule). +- **Match asset movements**: If you have exchange deposits/withdrawals that aren't linked to on-chain transactions, use the [asset movement matching](/usage-guides/historical-events#unmatched-asset-movements) feature. + +### 4. Add missing prices + +Some assets or time periods may not have price data available from rotki's oracles. Go to **Add Missing Prices** ([guide](/usage-guides/custom-price)) to manually specify prices for assets that rotki can't find automatically. + +### 5. Generate your PnL report + +1. Click **Profit and Loss Report** in the left sidebar +2. Select the time period (e.g., the tax year) +3. Click **Generate** + +The report shows: + +- A summary of total profit/loss and how much is taxable +- A detailed table of every event that contributed to the calculation +- The cost basis for each sell event (where the sold assets were originally acquired) + +### 6. Export and review + +- Click **Export CSV** to download the report for use in Google Sheets or LibreOffice +- Share the export with your tax advisor for review +- See the [PnL report guide](/usage-guides/pnl#results-of-the-pnl-report) for column definitions + +## Common issues and how to fix them + +| Problem | Likely cause | Solution | +| --------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | +| "No documented acquisition found" | rotki doesn't know when/where you originally bought an asset | [Add a manual trade](/usage-guides/historical-events#add--edit-events) or acquisition event | +| Event counted as taxable when it shouldn't be | Wrong event type/subtype | [Edit the event](/usage-guides/historical-events#common-customization) to the correct type | +| Missing price for an asset | Oracle doesn't have data for that asset/timestamp | [Add missing price manually](/usage-guides/custom-price) | +| PnL numbers seem wrong | Accounting settings may not match your jurisdiction | Review [accounting settings](/usage-guides/customization#accounting-settings) and [accounting rule options](/usage-guides/accounting-rules) | +| Report generation gets stuck | Often caused by exchange API rate limits | Check [troubleshooting](/usage-guides/pnl#pnl-report-generation-gets-stuck) | + +## What rotki currently does NOT support + +Understanding what's not available saves you time: + +- **Custom cost basis overrides**: You cannot set an arbitrary cost basis for assets you already hold (e.g., market price on a specific date when moving tax jurisdictions). The workaround is to add a manual trade that represents the acquisition at the desired price. This is tracked in [rotki/rotki#9816](https://github.com/rotki/rotki/issues/9816). +- **Custom counterparty definitions in accounting rules**: Accounting rules can be set per counterparty, but only for counterparties that rotki already recognizes (protocol identifiers like "uniswap", "aave", etc.). You cannot define your own custom smart contract as a counterparty for accounting rule purposes. This is tracked in [rotki/rotki#9803](https://github.com/rotki/rotki/issues/9803). + +## Further reading + +- [Event types and subtypes reference](/usage-guides/event-types) — what each event category means +- [Accounting rule options explained](/usage-guides/accounting-rules) — detailed explanation of every accounting setting +- [Profit/Loss Report guide](/usage-guides/pnl) — full report documentation +- [History Events guide](/usage-guides/historical-events) — managing and customizing your transaction history +- [Import CSV](/usage-guides/import-csv) — importing data from unsupported exchanges