Problem
A tracked account can still own a Uniswap v4 position NFT and have its mint correctly decoded, yet the position does not appear in blockchain balances. This can affect other EVM tokens discovered through historical decoding; it is not specific to Uniswap v4.
How to reproduce
- Track an account that currently owns a position NFT.
- Save a balance snapshot newer than the NFT's mint transaction.
- Decode the historical mint transaction for the first time.
- Refresh blockchain balances without manually re-detecting tokens.
Observed: The decoded incoming NFT event exists, but the position is absent from the account's detected-token cache and balance response. Explicit token re-detection followed by a fresh balance query makes it appear.
Expected: A still-owned position discovered during decoding should appear on the first subsequent fresh balance query. A position transferred away must not be reported as owned.
Cause
After decoding, EVMTransactionDecoder._decode_transaction_hashes() calls maybe_detect_new_tokens(). That function selects candidate events using the latest saved balance-snapshot time:
WHERE ms.value IS NULL AND timestamp >= ?
The event timestamp is when the transaction happened on-chain, not when rotki decoded it. A historical mint decoded after a newer snapshot is therefore excluded from automatic discovery. The normal balance query reads the saved detected-token list and cannot find the omitted NFT itself.
The existing Uniswap v3/v4 balance test runs explicit token detection before querying balances, so it does not cover this sequence.
Constraints for a fix
- Distinguish newly discovered information from recent on-chain activity; do not use the on-chain timestamp as a decoding watermark.
- Remain incremental and idempotent during a full re-decode, which may return thousands of events.
- Deduplicate work by chain, account, and token; bound ownership RPC batches.
- Verify current ownership of each ERC-721 ID before caching it. An old incoming event—or a positive collection-level balance—does not prove ownership of that particular NFT.
- Preserve ignored-asset and disabled-chain behavior. Failed checks must remain retryable without replacing a valid cache with incomplete results.
Regression coverage
Add a backend test with a historical mint decoded after a newer snapshot. Without an explicit token-detection call, the first fresh balance query should include the still-owned NFT. Add a distinct check that a transferred NFT is not cached when the account owns another NFT from the same collection. Preserve coverage for periodic detection and explicit re-detection.
Separate UI issue
The action labelled "Re-detect tokens and refresh balances" currently re-detects tokens but then reads cached balances rather than making a fresh balance query. That compounds the symptom but does not cause the backend discovery failure described here; track it separately.
Problem
A tracked account can still own a Uniswap v4 position NFT and have its mint correctly decoded, yet the position does not appear in blockchain balances. This can affect other EVM tokens discovered through historical decoding; it is not specific to Uniswap v4.
How to reproduce
Observed: The decoded incoming NFT event exists, but the position is absent from the account's detected-token cache and balance response. Explicit token re-detection followed by a fresh balance query makes it appear.
Expected: A still-owned position discovered during decoding should appear on the first subsequent fresh balance query. A position transferred away must not be reported as owned.
Cause
After decoding,
EVMTransactionDecoder._decode_transaction_hashes()callsmaybe_detect_new_tokens(). That function selects candidate events using the latest saved balance-snapshot time:The event timestamp is when the transaction happened on-chain, not when rotki decoded it. A historical mint decoded after a newer snapshot is therefore excluded from automatic discovery. The normal balance query reads the saved detected-token list and cannot find the omitted NFT itself.
The existing Uniswap v3/v4 balance test runs explicit token detection before querying balances, so it does not cover this sequence.
Constraints for a fix
Regression coverage
Add a backend test with a historical mint decoded after a newer snapshot. Without an explicit token-detection call, the first fresh balance query should include the still-owned NFT. Add a distinct check that a transferred NFT is not cached when the account owns another NFT from the same collection. Preserve coverage for periodic detection and explicit re-detection.
Separate UI issue
The action labelled "Re-detect tokens and refresh balances" currently re-detects tokens but then reads cached balances rather than making a fresh balance query. That compounds the symptom but does not cause the backend discovery failure described here; track it separately.