Files
docker-finance/container/src/hledger-flow/accounts/blockchain-explorers/ethereum-based/ethereum-based-shared.rules
Aaron Fiore 418ed80a8c container: hledger-flow: ethereum-based: support non-alpha chars (currency)
- 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
2025-08-04 15:27:33 -07:00

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