forked from EvergreenCrypto/docker-finance
- Fixes broken import of any tx that contains non-alpha character(s) in its currency (digits, etc.) * Currencies may now contain any character(s) supported by hledger
216 lines
10 KiB
Plaintext
216 lines
10 KiB
Plaintext
# docker-finance | modern accounting for the power-user
|
|
#
|
|
# 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
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
fields date,blockchain,account_name,subaccount_name,subaccount_address,type,direction,tx_index,tx_hash,token_name,token_id,contract_address,symbol,block_hash,block_number,method_id,from_address,to_address,amount_,fees
|
|
|
|
date-format %Y-%m-%d %H:%M:%S
|
|
|
|
description %date +0000
|
|
|
|
account1 assets:%account_name:%subaccount_name:%blockchain:%symbol
|
|
amount %amount_ "%symbol"
|
|
|
|
comment blockchain:%blockchain, type:%type, block:%block_number, blockid:%block_hash, index:%tx_index, method:%method_id, subaccount_address:%subaccount_address, from_address:%from_address, to_address:%to_address, txid:%tx_hash, direction:%direction
|
|
|
|
# Txs marked as 'internal'
|
|
if %type ^internal$
|
|
comment blockchain:%blockchain, type:%type, block:%block_number, subaccount_address:%subaccount_address, from_address:%from_address, to_address:%to_address, txid:%tx_hash, direction:%direction
|
|
|
|
# Txs with contract addresses
|
|
if %contract_address [a-z]
|
|
comment blockchain:%blockchain, type:%type, block:%block_number, blockid:%block_hash, index:%tx_index, subaccount_address:%subaccount_address, contract_address:%contract_address, from_address:%from_address, to_address:%to_address, txid:%tx_hash, direction:%direction
|
|
|
|
if %token_id [0-9]
|
|
comment blockchain:%blockchain, type:%type, block:%block_number, blockid:%block_hash, index:%tx_index, subaccount_address:%subaccount_address, contract_address:%contract_address, from_address:%from_address, to_address:%to_address, tokenid:%token_id, txid:%tx_hash, direction:%direction
|
|
|
|
# Subtract when sending OUT
|
|
if %direction ^OUT$
|
|
amount -%amount_ "%symbol"
|
|
|
|
# Default transfers as equity accounts
|
|
if %direction ^IN$
|
|
account2 equity:%account_name:%subaccount_name:%blockchain:withdrawal:%symbol
|
|
|
|
if %direction ^OUT$
|
|
account2 equity:%account_name:%subaccount_name:%blockchain:deposit:%symbol
|
|
|
|
# Network fees
|
|
# - To get accurate balance, take all fees from "normal" because fees are also
|
|
# included in ERC-20's.
|
|
# - For certain sends, polygonscan *will* include the ERC-20 tx amount in a
|
|
# 'normal' tx along with the fees. For whatever reason, "sending matic" can,
|
|
# at times, send to the contract address for certain end-user addresses. So,
|
|
# reports will produce a double-spend unless this is corrected here.
|
|
if %direction ^OUT$
|
|
& %blockchain (^ethereum$|^polygon$|^arbitrum$|^base$|^optimism$)
|
|
& %type ^normal$
|
|
& %fees [1-9]
|
|
account3 assets:%account_name:%subaccount_name:%blockchain:%symbol
|
|
amount3 -%fees %symbol
|
|
account4 expenses:%account_name:%subaccount_name:%blockchain:fees:%symbol
|
|
amount4 %fees %symbol
|
|
comment blockchain:%blockchain, type:%type, block:%block_number, blockid:%block_hash, index:%tx_index, method:%method_id, subaccount_address:%subaccount_address, from_address:%from_address, to_address:%to_address, txid:%tx_hash, direction:%direction, taxed_as:SPEND
|
|
comment3 %date +0000,SPEND,%account_name:%subaccount_name:%blockchain,%symbol,%fees,USD,,FEE
|
|
# NOTE: docker-finance *WANTS* a MATCH trade to overwrite comment3 because that will *include* this fee in the tx
|
|
|
|
# Remove 0 value txs (or else journal is cluttered). These should appear for FEE spends only
|
|
if %direction ^OUT$
|
|
& %blockchain (^ethereum$|^polygon$|^arbitrum$|^base$|^optimism$)
|
|
& %amount_ ^[^1-9]*$
|
|
account1
|
|
account2
|
|
|
|
# ---------------------------------------------------------------------------- #
|
|
# Polygon #
|
|
# ---------------------------------------------------------------------------- #
|
|
|
|
# Polygon/MATIC remove dups (only fees in journal entry instead of fees + assets)
|
|
if %to_address ^0x0000000000000000000000000000000000001010$
|
|
& %direction ^OUT$
|
|
& %blockchain ^polygon$
|
|
& %type ^normal$
|
|
account1
|
|
account2
|
|
|
|
# MATIC Plasma bridge contract
|
|
|
|
if %to_address ^0x401f6c983ea34274ec46f84d70b31c151321188b$
|
|
& %blockchain (^ethereum$|^polygon$)
|
|
& %amount_ [1-9]
|
|
account2 assets:%account_name:%subaccount_name:polygon:MATIC
|
|
|
|
# ---------------------------------------------------------------------------- #
|
|
# Wrapped Ethereum (WETH) contract #
|
|
# ---------------------------------------------------------------------------- #
|
|
|
|
# NOTE: No ERC-20 txs here for WETH... all "normal" or "internal"
|
|
|
|
# TODO: on all supported chains
|
|
|
|
# BUY
|
|
if %to_address ^0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2$
|
|
& %blockchain ^ethereum$
|
|
& %type (^normal$|^internal$)
|
|
& %amount_ [1-9]
|
|
account1 assets:%account_name:%subaccount_name:%blockchain:WETH
|
|
amount %amount_ WETH @@ %amount_ %symbol
|
|
account2 assets:%account_name:%subaccount_name:%blockchain:%symbol
|
|
comment blockchain:%blockchain, type:%type, block:%block_number, blockid:%block_hash, index:%tx_index, method:%method_id, subaccount_address:%subaccount_address, from_address:%from_address, to_address:%to_address, txid:%tx_hash, direction:%direction, taxed_as:RAW_TRADE
|
|
comment3 %date +0000,BUY,%account_name:%subaccount_name:%blockchain,WETH,%amount_,%symbol,%amount_,%symbol,%fees
|
|
# NOTE: must use comment3 to overwrite FEE SPEND
|
|
|
|
# BUY (remove unused tags)
|
|
if %to_address ^0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2$
|
|
& %blockchain ^ethereum$
|
|
& %type ^internal$
|
|
& %amount_ [1-9]
|
|
comment blockchain:%blockchain, type:%type, block:%block_number, subaccount_address:%subaccount_address, from_address:%from_address, to_address:%to_address, txid:%tx_hash, direction:%direction, taxed_as:RAW_TRADE
|
|
|
|
# SELL
|
|
if %from_address ^0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2$
|
|
& %blockchain ^ethereum$
|
|
& %type (^normal$|^internal$)
|
|
& %amount_ [1-9]
|
|
account1 assets:%account_name:%subaccount_name:%blockchain:%symbol
|
|
amount %amount_ %symbol @@ %amount_ WETH
|
|
account2 assets:%account_name:%subaccount_name:%blockchain:WETH
|
|
comment blockchain:%blockchain, type:%type, block:%block_number, blockid:%block_hash, index:%tx_index, method:%method_id, subaccount_address:%subaccount_address, contract_address:%contract_address, from_address:%from_address, to_address:%to_address, txid:%tx_hash, direction:%direction, taxed_as:PARTIAL_TRADE
|
|
comment2 %tx_hash,%date +0000,SELL,%account_name:%subaccount_name:%blockchain,WETH,%amount_,%symbol,%amount_
|
|
# NOTE: trailing FeeCurrency and Fee columns left empty for PARTIAL_TRADE (see FEE below)
|
|
|
|
# SELL (remove unused tags)
|
|
if %from_address ^0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2$
|
|
& %blockchain ^ethereum$
|
|
& %type ^internal$
|
|
& %amount_ [1-9]
|
|
comment blockchain:%blockchain, type:%type, block:%block_number, subaccount_address:%subaccount_address, from_address:%from_address, to_address:%to_address, txid:%tx_hash, direction:%direction, taxed_as:PARTIAL_TRADE
|
|
|
|
# FEE
|
|
if %to_address ^0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2$
|
|
& %blockchain ^ethereum$
|
|
& %type ^normal$
|
|
& %amount_ ^[^1-9]*$
|
|
& %fees [1-9]
|
|
comment blockchain:%blockchain, type:%type, block:%block_number, blockid:%block_hash, index:%tx_index, method:%method_id, subaccount_address:%subaccount_address, from_address:%from_address, to_address:%to_address, txid:%tx_hash, direction:%direction, taxed_as:PARTIAL_TRADE
|
|
comment2
|
|
comment3 %tx_hash,%date +0000,SPEND,%account_name:%subaccount_name:%blockchain,%symbol,%fees,USD,,FEE
|
|
# NOTE:
|
|
# - lib_taxes *MUST* extract only the %symbol and %fees column and append to
|
|
# the previous SELL PARTIAL_TRADE. Rationale for keeping a full comment 3:
|
|
# all functions might not be caught below, so at least the tx will be caught
|
|
# as a SPEND (which it should be)
|
|
# - In custom rules, use comment2 for SPENDs that aren't FEE
|
|
|
|
# Non-wrap/unwrap functions will not have corresponding wrap, so no PARTIAL_TRADE
|
|
# TODO: expand functions as needed
|
|
if %to_address ^0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2$
|
|
& %method_id (^0x095ea7b3$|^0xa9059cbb$)
|
|
& %blockchain ^ethereum$
|
|
& %type ^normal$
|
|
& %amount_ ^[^1-9]*$
|
|
& %fees [1-9]
|
|
comment blockchain:%blockchain, type:%type, block:%block_number, blockid:%block_hash, index:%tx_index, method:%method_id, subaccount_address:%subaccount_address, from_address:%from_address, to_address:%to_address, txid:%tx_hash, direction:%direction, taxed_as:SPEND
|
|
comment2
|
|
comment3 %date +0000,SPEND,%account_name:%subaccount_name:%blockchain,%symbol,%fees,USD,,FEE
|
|
|
|
# ---------------------------------------------------------------------------- #
|
|
# Swapping #
|
|
# ---------------------------------------------------------------------------- #
|
|
|
|
# TODO: on all supported chains
|
|
|
|
include ./rules.d/swap.d/1inch.rules
|
|
include ./rules.d/swap.d/airswap.rules
|
|
include ./rules.d/swap.d/metamask.rules
|
|
include ./rules.d/swap.d/uniswap.rules
|
|
|
|
# ---------------------------------------------------------------------------- #
|
|
# Lending #
|
|
# ---------------------------------------------------------------------------- #
|
|
|
|
# TODO: on all supported chains
|
|
|
|
include ./rules.d/lending.d/aave.rules
|
|
include ./rules.d/lending.d/compound.rules
|
|
|
|
# ---------------------------------------------------------------------------- #
|
|
# Staking #
|
|
# ---------------------------------------------------------------------------- #
|
|
|
|
# TODO: on all supported chains
|
|
|
|
include ./rules.d/staking.d/lido.rules
|
|
include ./rules.d/staking.d/rocket-pool.rules
|
|
|
|
# ---------------------------------------------------------------------------- #
|
|
# Spam / Scamdrops #
|
|
# ---------------------------------------------------------------------------- #
|
|
|
|
include ./rules.d/spam.d/arbitrum.rules
|
|
include ./rules.d/spam.d/base.rules
|
|
include ./rules.d/spam.d/ethereum.rules
|
|
include ./rules.d/spam.d/optimism.rules
|
|
include ./rules.d/spam.d/polygon.rules
|
|
|
|
# If an ERC-{721,1155} token has no name and ID of 0, assume it's spam
|
|
if %type (^erc-721$|^erc-1155$)
|
|
& %token_name ^[^a-z1-9]*$
|
|
& %token_id 0
|
|
skip
|
|
|
|
# vim: sw=2 sts=2 si ai et
|