September 7, 2026
Closing a Case on a Single Exchange Deposit Address: What to Assemble Before You Send the Request
A deposit address points to an account only inside a time window. Here is the bundle to assemble before the request goes out.
By onescope
5 min read
Most stolen-funds traces end at the same wall. The money moves through a handful of hops, lands on an address that belongs to a centralized exchange, and the chain stops answering questions. What happens after that lives in someone else's database. The only way in is a request a compliance analyst can act on without calling you back.
The part that gets underestimated is how much of that request is built before it is sent. I keep a composite case set for training work: twelve exchange requests, with details merged and anonymized from public reporting and hypothetical reconstruction. Treat the counts as illustrative rather than measured. Seven of the twelve came back with nothing usable, and all seven had the same shape. An address, an amount, and a sentence asking who owns it. The five that produced account records each carried a bounded time window plus the exact transaction hashes that fell inside it.
The difference comes from what a deposit address is on the exchange side.
Why an address on its own comes back empty
A deposit address is a routing label. A user asks the exchange for an address on a given chain, the exchange hands one out of a pool it controls, and it writes a row: address, account, time. Funds arriving there get credited to that account. Some minutes or hours later an automated sweep moves the balance into the exchange's hot wallet, where it mixes with every other customer's deposit.
Two things follow, and both change how the request should read.
The mapping is a record the exchange keeps, not a property of the address itself. Deposit addresses get rotated. Some venues issue a fresh address per deposit, some keep one address per user per chain for years, and some recycle addresses after an account closes. You cannot tell which policy applies by looking at the chain. An address queried with no date attached can legitimately match more than one account, and the analyst reading your request will not guess which one you meant.
The sweep transaction is evidence you already hold. It is public, it sits on-chain, and it happens at the same moment their internal ledger credits a customer. Name that transaction and you have pointed at a row in a database whose schema you have never seen.
The bundle, item by item
Fix the window with two transactions
The lower edge is the transaction that credits the deposit address from your last traced hop. The upper edge is the sweep into the hot wallet. Give both as UTC timestamps and block heights. Exchanges run their logs on UTC, and a converted timestamp becomes something to argue about later. If the sweep has not happened yet, say so and leave the upper edge open at the block height you last checked.
A worked shape from the composite set, with values changed: the victim's individually controlled wallet address (EOA) sends 41.6 ETH out at 09:12 UTC. Two pass-through addresses forward it inside four minutes each. At 09:24 UTC, 41.58 ETH lands on the deposit address, and at 10:07 UTC the full balance sweeps into the venue's hot wallet. The window in the request read 09:24 to 10:07 UTC with block heights on both ends, and the 0.02 ETH difference was explained as gas across the two hops. The reply named an account opened three months earlier, its verification tier, and two withdrawal destinations that followed the credit.
List hashes, one row at a time
A narrative of the flow is hard to check. Rows are easy: hash, from, to, asset, amount, block time. Include the hops before the deposit even though the exchange cannot see them. It lets the analyst reconcile against the amount they credited, and it shows a person walked the path. Amounts rarely match end to end. Bridge fees, gas, and split transfers change the number between the victim's wallet and the deposit, so state the discrepancy and its cause instead of waiting to be asked about it.
Say what each address does, and why
Group the addresses by role: the victim wallet, the pass-through hops, the deposit address. Attach the observation behind each label. A hop that receives once, forwards its entire balance within two minutes, and never receives again reads as a pass-through. An address that collects from many unrelated victims and sweeps on a fixed schedule is more likely a service, and treating it as an operator wallet points the whole request in the wrong direction. Label confidence honestly. "Probable" is a usable word in a request, and a certainty that turns out wrong costs you the next one.
Bring one off-chain artifact
Compliance teams are deciding whether yours is a live case or a fishing trip. A drainer kit's deployment repository, the registration record of the phishing domain that fed the victim wallet, a contact handle reused across a commit message and a Telegram channel: any one of these does more for that judgment than another page of hops. It also hands them a second identifier to search on, which occasionally matters more than the address itself.
Ask in their units
Name the record types you want. Account open date, verification tier, the internal credit that matches your sweep, login IP addresses bounded by your window, and the withdrawal destinations that followed the credit. A request for all information related to an address gets triaged behind the specific ones. State the authority in the first two lines as well, whether that is a law enforcement request, a mutual legal assistance treaty (MLAT) route, a civil subpoena, or a voluntary victim-side ask. A voluntary request written in subpoena language goes to legal and stops there.
Where this does not work
The deposit address may belong to a business rather than a person. Payment processors, over-the-counter desks, and nested exchanges that hold accounts at larger venues all look like ordinary deposits from the chain side. The answer that comes back names another company, and the work restarts one layer down.
Batched sweeps break the clean version of this. Some venues sweep dozens of deposit addresses in a single transaction, so the sweep no longer isolates your deposit. Lean on the credit side instead: arrival timestamp and exact amount, with a request to match on those two fields.
Retention limits end it outright. If the deposit falls outside the venue's record-keeping window, a perfect bundle still returns nothing. Build the bundle early anyway. Explorer labels drift, attribution sets get revised, and the graph you can reconstruct eight months from now is thinner than the one in front of you today.
Assembling it in one view
Most of the time in this task goes to transcription rather than analysis. Hashes come out of an explorer, timestamps out of a second tab, the GitHub artifact out of a third, and then everything is re-checked to confirm it all refers to the same window. OneScope holds on-chain flows, GitHub signals, and threat feeds in a single graph, so the deposit address, its sweep, and the off-chain artifacts sit as connected nodes that export together instead of three sets of notes reconciled by hand.
Before you hit send
- Both edges of the window in UTC, with block heights on each.
- One row per transfer, hashes included, covering the hops you walked yourself.
- A role for every address, with the observation that produced it.
- The amount discrepancy explained before anyone asks about it.
- At least one off-chain artifact tied to the same case.
- The authority you are asking under, stated in the opening lines.
When the bundle holds together, the request stops being a question about an address and becomes a lookup someone can run in a few minutes.
We publish case teardowns like this one. Follow to keep them in your feed.
This is the kind of trace we built OneScope for.
See how a deposit address, its sweep, and the off-chain artifacts connect in one graph.