Skip to content

fix(support): match compliance search address case-insensitively#3824

Open
TaprootFreak wants to merge 2 commits into
developfrom
fix/compliance-search-address-case-insensitive
Open

fix(support): match compliance search address case-insensitively#3824
TaprootFreak wants to merge 2 commits into
developfrom
fix/compliance-search-address-case-insensitive

Conversation

@TaprootFreak

@TaprootFreak TaprootFreak commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

Problem

The compliance database search returns "No user or bankTx found" when an EVM address is entered in a different letter case than it is stored. Addresses are persisted in EIP-55 checksummed form, so a non-checksummed (e.g. all-lowercase) address — as commonly copied from block explorers — is never found.

Root cause

The address branch of SupportService.getUniqueUserDataByKey looked addresses up with exact, case-sensitive = comparisons (WHERE user.address = :param, WHERE deposit.address = :param). On Postgres these are case-sensitive, so a lowercase input does not match the stored checksummed value and the search falls through to the not-found error. This affected both lookups in that branch:

  • the user (login) address, and
  • the Sell/Swap deposit address fallback.

Fix

Case-insensitive matching for the compliance search address branch only, via dedicated methods:

  • UserService.getUserByAddressIgnoreCase(address)
  • SellService.getSellByDepositAddressIgnoreCase(address)
  • SwapService.getSwapByDepositAddressIgnoreCase(address)

Each uses LOWER(<col>) = LOWER(:address) and loads the exact same relations as the previous lookup, so downstream behaviour is unchanged apart from being case-insensitive.

The shared getUserByKey, getUserByAddress, getSellByKey and getSwapByKey stay untouched, so authentication, KYC, history and every other caller keep their existing exact-match behaviour.

Tests

  • Unit tests assert the case-insensitive WHERE clause for each of the three new methods.

Scope

Read-only admin search only — no change to authentication or any address-write path.

@TaprootFreak TaprootFreak marked this pull request as ready for review June 5, 2026 06:55
@TaprootFreak TaprootFreak requested a review from davidleomay as a code owner June 5, 2026 06:55

@davidleomay davidleomay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidleomay davidleomay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three dedicated IgnoreCase methods could be avoided entirely. MSSQL used a case-insensitive collation, so address lookups always matched regardless of case — this bug only appeared after the Postgres migration. Making getByKey use ILIKE for the address column would restore pre-Postgres behaviour rather than introduce a new one, and avoids duplicating the query logic three times. Something like replacing = :param with ILIKE :param in getUserByKey, getSellByKey, and getSwapByKey when the key is an address field. The three new dedicated methods could then be dropped.


if (Config.formats.address.test(key)) {
const user = await this.userService.getUserByKey('address', key, true);
const user = await this.userService.getUserByAddressIgnoreCase(key);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MSSQL used a case-insensitive collation, so address lookups worked regardless of case before the Postgres migration — this is a regression, not a new requirement. Instead of three dedicated IgnoreCase methods, consider using ILIKE :param in place of = :param in getUserByKey, getSellByKey, and getSwapByKey. That restores pre-Postgres behaviour across the board and avoids duplicating the query logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants