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.
This commit is contained in:
2024-12-29 20:02:10 -08:00
parent 499c171d73
commit 2b3b09dafa

View File

@@ -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