The reconciliation report came back off by a few cents on one loan repayment. Not a number anyone pages you about.
A borrower repayment had to be split across every investor in that deal, pro-rata by their share. Each share got computed, rounded to two decimals, written to that investor's balance. The sum of the parts did not equal the money that had actually arrived. Nobody owned the remainder, so it never entered the ledger at all.
A few cents per repayment. Across every multi-investor deal, every repayment cycle. Individually invisible, and that is the problem: the number is too small to trigger an alert and too systematic to stay small.
In lending, "minor rounding discrepancy" and "we cannot fully account for client funds" are the same sentence once a compliance reviewer reads it. The engineering severity and the regulatory severity of that bug are not in the same universe.
What I changed, and still do everywhere money gets divided:
Splits are computed in integer minor units. No decimals, no floats anywhere in that path.
The remainder is allocated deterministically: largest fractional part first, ties broken by a stable ordering. The same input gives you the same split, which is also what makes it reproducible during an audit.
And the invariant that the parts sum exactly to the amount received is asserted inside the same transaction that writes them. If it fails, nothing is written and the payment drops to manual review. A payment stuck in review is a phone call. A payment silently short is a reconciliation archaeology project six months later.
The lesson I carry into every payout system since: whenever money is divided, the leftover minor unit is a first-class entity that needs an owner. If no line of your code decides where it goes, your rounding function decided for you, and it decided to make it disappear.
I write these up in longer form on my blog: https://polycratia.com/c/56c07f0c
If you split funds across multiple parties, something in there already owns the leftover minor unit: probably worth finding out whether that is you or your rounding function...