Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some issues, some solutions, and general thoughts #13

Closed
mikhailkups opened this issue Mar 14, 2022 · 4 comments
Closed

Some issues, some solutions, and general thoughts #13

mikhailkups opened this issue Mar 14, 2022 · 4 comments

Comments

@mikhailkups
Copy link

So far this year I've spent about 250 hours researching everything crypto tax related and running through various software packages (both commercial and open-source), and it was a nightmare. However, I learned a lot that I would like to share, and I would be interested in supporting this project and helping it grow. Since this is a going to be a really long post, the moral of the story is that here are a bunch of comments and suggestions; let me know how I can help contribute. I'm not a python expert, but I do a lot of work with Excel VBA and can probably write pseudo code fairly well.

First off, thank you so much for this software, as it was the only thing that was able to process all of my data with enough functionality to get it done CORRECTLY and then provide the right output (US tax forms). I ended up having around 103,000 crypto disposals between 14 wallets, exchanges, and services, crossing 7 blockchains, so doing these calculations manually was completely out of the question. However, while this software worked, I had to use several workarounds that I think can and should be integrated into the code, which I'll describe in a bit. First, I have thoughts about implementation, since I think there are two distinct pieces of the puzzle that need to work in tandem.

As mentioned above, this software is focused on primitive IN/OUT transactions, which is totally fine and works well for the tax calculation side of things. The downside to doing it this way is that huge challenge of accurately getting data into this form so that the code can do its job. This challenge is partially because it's a semi-manual process at best, but also because it requires extensive knowledge of the crypto world AND comprehensive tax knowledge. Both of these are difficult because the information on them is still lacking. As such, I think the biggest thing that this project needs is a data pre-processor/converter that prepares the data CORRECTLY for the tax calculation. I see that DaLI has been created, but it still seems pretty sparse and under-documented. I’ll discuss my thoughts on DaLI at the end of this. The primitive code, as it stands, also needs some tweaking to be able to more intelligently handle complex transactions. Here are things that need to be addressed:

FEES

  1. The current code needs to be modified to handle DeFi situations, but most of this comes down to fees. Regarding "fee only" transactions, you guys have already come up with the two obvious solutions (100% Sell with $0 in proceeds vs. 0% Sell with 100% Fees). The problem is that the current software can't handle either of these. It doesn't allow you to put zero as the amount sold, nor does it allow you to put zero for the coin price. Was this done as a data integrity check only, or are these numbers (amount sold and coin price) used later in the denominator of an equation, which might lead to a "divide by zero" error? One solution could be to create a different type of transaction, such as "FEE" or "COST" (mentioned above), which allows either the sell amount or the coin price to be zero. This way the data can still be validated by checking that the right numbers exist in the right place, but also ensures that these numbers aren't used later in calculations that would cause an error. By the way, the current workaround I used here is listing the coin price of "fee only" transactions as 1e-10, which is messy, but it works.

  2. IN, OUT, and INTRA transactions all need to be able to handle fees differently. In general, the most correct way to handle fees is to include them in the transaction by either adding them to the cost basis or removing them from the proceeds. This helps reduce the number of extra "disposals" by limiting the number of "fee only" transactions. This should be handled on two fronts. First, the current code should be modified such that "BUY" fees are in whatever currency is being traded, not simply in fiat. This brings up another issue with fiat currency fees that I'll address shortly. Anyway, the "BUY" fee currency should match that of the asset being bought. It comes up often that transaction fees are paid in the bought currency. The other piece that goes along with this is that the data pre-processor needs to keep the fee for each transaction with either the BUY or SELL half if the fee asset matches the BUY or SELL asset. For INTRA trades, the current code is fine, since adjusting the AMOUNT SENT and AMOUNT RECEIVED numbers sets the fee. This also needs to be part of the data pre-processor, though, since generally, the amount moved between accounts needs to be the same number in order to identify matching transactions. In other words, say you have 1 BTC in you account in the Cash App, and you send it all to Coinbase, which has a transaction fee of .005 BTC. In the ledger, this would look like a 0.995 BTC withdrawal from Cash, a 0.995 BTC Deposit to Coinbase, and a 0.005 BTC fee on the Cash App account. This is necessary so that internal movements of funds can be identified based on their date, asset, and amount. However, this can be converted to an INTRA transaction of 1 BTC send, 0.995 BTC received, if that's the smartest way to handle this in the future version of your software.

I'll take a moment to pause here with a sidenote on fiat currency fees. Am I correct in assuming that this software was developed to ignore USD as its own "crypto asset" for calculations? I realize that by including a USD tab to be processed by the software that it creates gains/losses on USD, which is a bit weird, but letting the software calculate stuff on USD is useful, since it provides a better picture of what's happening in your USD holdings. Including USD would probably be necessary, however, if the BUY fee asset is changed from USD to whatever the bought currency is. However, this could be managed by just logging USD fees in their own tab and modifying the cost basis/proceeds/expenses of transactions after the fact. Regardless, I bring this up because I included USD in my calculations and I got an error because the software didn't recognize that my excel tab for USD was not the same USD as the FIAT FEE column. So when I listed USD fees for transactions, these dollars weren't removed from my USD holdings. This is another reason why the BUY fees should be set as whatever the BUY asset is.

  1. All fees that aren’t included with either the BUY or SELL half of the transaction need their own transaction, which is already discussed in the conversation about how to list “fee only” transactions. The challenge here is that it would be great if the fiat value of these fees could be added to the cost basis or removed from the proceeds of whatever transaction they came from. On the other hand, the software still needs “fee only” transaction capability because “fee only” transactions actually exist when trading in DeFi. For example, if you go to swap BTC to ETH using 1inch.io on Binance Smart Chain, you must first approve the assets being traded. These are smart contracts that you sign, which tells 1inch.io that you have checked the coin addresses and confirm that you are trading the correct coins. Such a transaction, often called a contract approval, generates a fee (gas fee), but does not buy, sell, or trade any coins. For taxes, it’s a bit unclear how these should be categorized, but I would think they should be expenses, similar to fees incurred when moving assets between accounts. In fact, any fee that cannot be tied to the cost basis/proceeds of a transaction should probably be categorized as an expense.

LIQUIDITY MINING
Interacting with smart contracts can be a tricky business. There are so many ways that these can complicate things, and it probably makes sense to add functionality for them as situations arise, but again, this should be part of the data pre-processor. One example of a very common situation is with liquidity mining. The concept is that you add liquidity to an exchange by adding two assets together, which can be used by people to buy and sell those assets. In return for offering these coins to be traded, you usually get some of the proceeds (trading fees) incurred by the person using the exchange. The way these transactions work is the following. You want to add BUSD/USDC liquidity to PancakeSwap. To do this, you add 1000 BUSD 1000 USDC, and in exchange, you get 2000 Cake-LP tokens as a receipt for the coins you’ve added to the liquidity pool. This transaction has 4 assets involved, in 3 parts. First, you had a withdrawal for 1000 BUSD and a withdrawal for 1000 USDC. Next, you received (a deposit) for 2000 Cake-LP. Lastly, you paid gas in the blockchain’s native token, say 0.001 BNB. In my opinion, the best way to handle this transaction is to split it. So the first transaction would be trading 1000 BUSD for 1000 Cake-LP with a transaction fee of 0.0005 BNB. The second would be trading 1000 USDC for 1000 Cake-LP with a transaction fee of 0.0005 BNB. Also note that the opposite of this situation happens when liquidity is removed from the liquidity pool.

STAKING
First, I think it’s dumb that the IRS, or whoever, decided that rewards from staking assets should be classified as “Staking”. This makes things very confusing for people who are also using “Staking” and “Unstaking” to describe doing those actions. Aside from this stupidity, the actions of staking and unstaking need to be handled appropriately. The current reigning theory in staking assets is that this act is non-taxable, because you still own the assets that you are staking, even though they’re being held by someone else. As such, you could probably exclude the movement of funds into and out of staking pools, except there are a couple problems with this. First, excluding these movements means that the transaction fees (expenses) from these movements wouldn’t be captured. Second, there are some instances where the staking pool charges a fee to add your coins. For example, there are staking pools on brand new “sh**coin” exchanges that charge 4% of your staked assets upon depositing, since the APR offered is incredibly high. In these cases, the coin price always drops like a rock, and you’re lucky to recoup the fees, but it can be done for a decent profit. In either case mentioned here, it’s important to be able to log and account for the fees incurred. The best way I’ve found to do this is to create a separate virtual wallet that stores all of my staked coins. By doing this, you can show your activity of staking and unstaking coins where the only taxable part of the transaction is the fee (which is what we want).

DATA PRE-PROCESSING
As mentioned throughout this post, the need for data pre-processing is huge here. I think this is one of the things that DaLI is supposed to be doing, but it seems to be more focused on parsing data files from common exchanges rather than cleaning, organizing, and preparing an ODS file that can be used for RP2. I suggest that the nearest-term project should be on creating a converter that takes a .csv file (or whatever) and turns it into an input file for RP2. The input data format for this should be predetermined (names of columns, categories, general conventions, etc), and information contained within it should dictate how the data gets transformed into the RP2 input file. As an example, say you label a transaction (a row in the data file) as “FEE”. The converter would then know that this line needs to be processed to make it a fee-only transaction for RP2. Similarly, if a set of 3 lines (all with the same transaction hash) are labeled “ADD LIQUIDITY”, then the converter will know to split the transaction, distribute the LP token and fee to each half, and then process these into IN/OUT lines for RP2.
Once the converter is made and is functional, then time should be spent on parsing and importing common data files from exchanges and wallets (DaLI). Note that these tools should extract data from the downloaded exchange files, for example, and put it into the converter file structure with proper labels and such, so that the converter will be useful for all data. The problem with DaLI currently is that each plugin must be managed separately, but the rules for converting the information to an RP2 input should be centralized. Please consider building a converter first, then using DaLI plugins to populate the input file for the converter. This is because a universal converter will be extremely useful right away, whereas DaLI is only useful for whichever plugins are written and written correctly. Plus, changes to how they convert data for RP2 would have to be managed in each of them individually instead of letting the converter do the hard work.

OUTPUT REPORTS
Another thing that would be useful, since the IRS wants this info, is a script that exports summary statements within the crypto tax report. Information should include:

  1. Summary of Capital Gains with number of disposals, total proceeds from sales, total acquisition costs, total realized gains, total realized losses, net capital gains

  2. Capital Gains Report showing realized gains, realized losses, and net gain/loss grouped by cryptocurrency

  3. Year end holdings with the following information for each coin: quantity, cost basis for that amount, net value at year end (12/31), average cost per coin, and unrealized gains/losses

  4. Income summary showing how much income was received from each type (airdrop, staking, interest, wages, etc.)

  5. Expense summary whosing the total expenses incurred by category (transfer fees, contract approvals, etc.)

  6. The settings and assumptions used by this software. For example, that transfers between accounts are not taxes, but the fees for moving them are included in the expense report and are based on fair market value at the time of the transaction. That gains/losses from crypto-to-crypto trades are included in the capital gains report. Etc...

ADDITIONAL THOUGHTS
The one thing this project is missing is the ability to automatically find and download historical coin prices to be added to the data. This feature would be killer, but the challenge seems to be finding a free crypto price API and interacting with it. Let me know if you want to see what I’ve accomplished on this front.

@eprbell
Copy link
Owner

eprbell commented Mar 15, 2022

Thanks for the long thread and for taking the time to share your experience with RP2 and your research on the topic of crypto taxes! It will take me a few days to respond properly because I'm out of town right now, but I wanted to share my appreciation for the detailed feedback!

@eprbell
Copy link
Owner

eprbell commented Jun 25, 2022

I'm glad this question reappeared: it looked like your account was not accessible for a long time, and this question disappeared for me so I couldn't follow up. However today I noticed it reappeared in the issue page. Most of the things you mentioned have been fixed in the last few months. I'll respond in more detail in the next few days.

@eprbell
Copy link
Owner

eprbell commented Jun 26, 2022

Let me reiterate that I really appreciated your detailed message. Even though it disappeared when your account became non-accessible, I managed to keep a copy of it, which helped inspire some of the development. So thanks for taking the time to provide such good feedback!

Here is my reply:

  • Fee-only transactions are now fully supported.
  • How to represent In/Out/Intra fees: the missing deduction problem has been fixed (see issue Deducting sell fees in proceeds #6) and also read the FAQ on fees and how to represent them in RP2. DaLI doesn't use amounts to match transactions, it uses the unique id field: see the "Transaction Resolution" section in https://github.com/eprbell/dali-rp2/blob/main/docs/configuration_file.md#manual-section-csv (more technical details on this in the developer documentation of the transaction resolver)
  • Liquidity mining/Staking: see various DeFI FAQs under "Tax Scenarios"
  • Data pre-processing. DaLI is actually quite powerful:
    • it reads data from multiple CSV or REST sources,
    • it joins and normalizes all this data,
    • it matches partial transactions into complete ones (e.g. two ends of a transfer),
    • it fills in missing data if needed (e.g. spot price),
    • it generates inputs for RP2 (ODS and config).
      It does all this by means of a programmable plugin architecture: anybody can contribute new input format or pair converter plugins. The "converter that takes a .csv file and turns it into an input file" is already there: see the Manual Plugin. The conversion of special crypto events like coin conversion or DeFI transactions can be handled in the exchange-specific input plugin, which knows all the details of what can be done on that specific exchange and how to best translate it into RP2 primitives.
  • Output reports. I think much of what you suggest is already available in the Summary tab of the full_report output: you can sort the table in different ways to group the specific data you're interested in (by date, crypto, transaction type, etc.). Whatever else is missing could be added in the form of an RP2 output plugin.
  • Historical coin price download. This is already there as a DaLI feature: see pair converter plugins.

@eprbell
Copy link
Owner

eprbell commented Jul 28, 2022

Closing the issue. I invite you to check the latest version of RP2 and DaLI, which incorporate a lot of your feedback. Feel free to open a new issue if you have more feedback.

@eprbell eprbell closed this as completed Jul 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants