From 2b3b09dafa9697124d7113652250e4eb00533fc8 Mon Sep 17 00:00:00 2001 From: Aaron Fiore Date: Sun, 29 Dec 2024 20:02:10 -0800 Subject: [PATCH] container: lib_taxes: add support for IRS Rev. Proc. 2024-28 - Creates per-wallet / per-account compliance for IRS Rev. Proc. 2024-28 * Obfuscated keymap now creates a unique indentifier per-wallet / per-account where all trades, spends and income are now clearly tied to their respective wallets / accounts. - Removes support for anonymized ("universal pool") reports. --- .../src/finance/lib/internal/lib_taxes.bash | 76 +++++++------------ 1 file changed, 26 insertions(+), 50 deletions(-) diff --git a/container/src/finance/lib/internal/lib_taxes.bash b/container/src/finance/lib/internal/lib_taxes.bash index 80adfc3..c20aa13 100644 --- a/container/src/finance/lib/internal/lib_taxes.bash +++ b/container/src/finance/lib/internal/lib_taxes.bash @@ -2,7 +2,7 @@ # docker-finance | modern accounting for the power-user # -# Copyright (C) 2021-2024 Aaron Fiore (Founder, Evergreen Crypto LLC) +# Copyright (C) 2021-2025 Aaron Fiore (Founder, Evergreen Crypto LLC) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -1067,24 +1067,12 @@ function lib_taxes::__taxes_write() lib_taxes::__reports_obfs lib_utils::catch $? - # - # Anonymized - # - - lib_utils::print_custom " \e[32m├─\e[34m\e[1;3m ${_arg_tag} (anonymized)\e[0m\n" - - local _ext_anon="report_anon.csv" - local _out_file="${_base_path}-${_ext_anon}" - - lib_taxes::__reports_anon - lib_utils::catch $? - # # Verify reports # lib_utils::print_custom " \e[32m│\e[0m\n" - lib_utils::print_custom " \e[32m│\e[0m\t\e[37;2m ... Verifying $_arg_tag (full/obfuscated/anonymized) ...\e[0m\n" + lib_utils::print_custom " \e[32m│\e[0m\t\e[37;2m ... Verifying $_arg_tag (full/obfuscated) ...\e[0m\n" lib_utils::print_custom " \e[32m│\e[0m\n" local _full @@ -1093,12 +1081,9 @@ function lib_taxes::__taxes_write() local _obfs _obfs="$(wc -l ${_base_path}-${_ext_obfs})" - local _anon - _anon="$(wc -l ${_base_path}-${_ext_anon})" - # TODO: more involved verification - if [[ "${_full% *}" != "${_obfs% *}" && "${_obfs% *}" != "${_anon% *}" ]]; then + if [[ "${_full% *}" != "${_obfs% *}" ]]; then lib_utils::die_fatal "Report verification: line count mistmatch" fi fi @@ -1187,6 +1172,8 @@ function lib_taxes::__reports_patch() # # - Coinbase Pro was sunsetted in late 2022 + # TODO: for 2025+, subaccount will be included before comma + # (must add appropriate regex if patch must ever be applied to 2025+) local _coinbase_string="(coinbase,|coinbase-pro,)" grep -E "$_coinbase_string" "$_spends" &>/dev/null @@ -1282,11 +1269,25 @@ function lib_taxes::__reports_obfs_gen() local _count _count=$(echo "$_raw_column" | wc -l) + local _sha="sha256sum" + lib_utils::deps_check "$_sha" + local _obfs_column - _obfs_column="$(shuf --random-source='/dev/urandom' -i 1-"${_count}" \ - | while read _line; do - [ "$_line" -lt 10 ] && _num="0${_line}" || _num="${_line}" - echo "$_num" + _obfs_column="$(echo "$_raw_column" \ + | while read _account; do + # + # OBFS column key is a truncated SHA digest of complete profile along with complete account. + # + # NOTE: + # + # - static delimiter is used to avoid potential inconsistencies + # (if ever given a custom delimiter) + # + # - complete profile is included as a means to provide a 'reasonable' salt + # (since default account names and memos can be used across profiles or subprofiles) + # + echo -n "${global_parent_profile}/${global_child_profile}/${_account}" | "$_sha" | head -c${2:-10} + echo done)" readarray -t _raw <<<"$_raw_column" @@ -1309,18 +1310,14 @@ function lib_taxes::__reports_obfs_gen() for(i = 1; i <= count; i++) { - # HACK: makes the data (most likely the Memo) sed friendly, - # if it has delimiter in string. - sub(/:/, "_", r[i]) - - print tax_year "_" args_tag "-" column "_" o[i] OFS r[i] + print o[i] OFS r[i] } }' FS=, OFS=, \ | ( sed -u 1q sort ) \ - | sed 's:, :,:g' >"$_keymap_file" + | sed 's|, |,|g' >"$_keymap_file" # Generate a temp file of the given raw column local _tmp_file="${_tmp_dir}/${_styled_column}" @@ -1329,7 +1326,7 @@ function lib_taxes::__reports_obfs_gen() # Obfuscate given raw column with keymap data tail -n +2 "$_keymap_file" \ | while read _line; do - sed -i "s:${_line#*,}:${_line%,*}:g" "$_tmp_file" + sed -i "s|${_line#*,}|${_line%,*}|g" "$_tmp_file" done done @@ -1339,25 +1336,4 @@ function lib_taxes::__reports_obfs_gen() | xsv select "$_all_columns" -o "$_out_file" } -# -# Reports (anonymized) -# - -function lib_taxes::__reports_anon() -{ - case "$_arg_tag" in - trade | trades) - xsv select "Date,Action,Symbol,Volume,Currency,Total,FeeCurrency,Fee" \ - "$_in_file" -o "$_out_file" - ;; - income | spend | spends) - xsv select "Date,Action,Symbol,Volume,Currency,Total" \ - "$_in_file" -o "$_out_file" - ;; - *) - lib_utils::die_fatal "Unsupported type" - ;; - esac -} - # vim: sw=2 sts=2 si ai et