What it flags
Two patterns:TransactionEnvelope.Fee()orFeeBumpFee()in a function that never readsFeeCharged. The envelope fee is the bid, not the charge.TransactionEnvelope.SourceAccount()in fee logic (the function’s name or body mentions fees) that never checks for a fee-bump (IsFeeBump,FeeBumpAccount,FeeAccount…). On a fee-bump,SourceAccount()is the inner source, who didn’t pay.
Why it matters
On the fee-bump fixture, reading fees from the envelope gives the wrong account and the wrong amount: 46,341 stroops charged toGDMV…COIW, when the ledger charged 40,354 to GA2J…HVAW. The naive replay indexer makes exactly this mistake.
Fix
Why it’s limited to fee logic
SourceAccount() is often right. An operation without its own source runs as the inner transaction’s source, fee-bump or not, so using it as the fallback is correct. The first version of this rule flagged every call and produced two false positives in wallet-backend, both correct fallbacks. Restricting it to fee logic removed them without losing the real pattern.