fix: stop importing unscreened third-party UTXOs into the ckBTC minter reserve#10535
Draft
gregorydemay wants to merge 2 commits into
Draft
fix: stop importing unscreened third-party UTXOs into the ckBTC minter reserve#10535gregorydemay wants to merge 2 commits into
gregorydemay wants to merge 2 commits into
Conversation
Add a failing test showing that a UTXO sent to the minter's main Bitcoin address by a third party enters available_utxos during withdrawal finalization, bypassing the deposit screening that normal deposits undergo. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restrict the UTXOs imported into available_utxos during withdrawal finalization to those matching a change output of a transaction the minter itself submitted. UTXOs sent to the minter's main address by a third party are now dropped instead of entering the spendable reserve, since they never went through deposit screening (minimum amount, check fee, and Bitcoin checker). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens the ckBTC minter’s withdrawal-finalization path so that UTXOs at the publicly-derivable main minter address are only imported into the spendable reserve if they correspond to a known change output from a minter-submitted (or stuck) transaction, preventing unscreened third-party deposits from entering available_utxos and affecting accounting.
Changes:
- Added a regression test covering third-party UTXOs at the main address being incorrectly imported during finalization.
- Introduced filtering to retain only change-output UTXOs from the minter’s submitted/stuck transactions before calling
state::audit::add_utxos.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
rs/bitcoin/ckbtc/minter/src/tests.rs |
Adds a unit test ensuring third-party UTXOs at the main address are not imported during finalization. |
rs/bitcoin/ckbtc/minter/src/lib.rs |
Filters finalization-imported UTXOs to only those matching known change outputs of submitted/stuck transactions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
The ckBTC minter screens normal deposits (minimum amount, check fee, and the Bitcoin checker / KYT) before any UTXO enters the spendable reserve. The withdrawal finalization path did not: it fetched every UTXO at the minter's main Bitcoin address and imported all of them into
available_utxos, filtering only on whether a UTXO was already known.Because the minter's main address is publicly derivable, anyone could send BTC directly to it. Those unscreened UTXOs entered the reserve and became eligible to be co-spent in minter-signed withdrawal transactions, and they inflated the minter's internal
tokens_mintedcounter without any corresponding mint.This restricts finalization to import only UTXOs that match a change output of a transaction the minter itself submitted. Any other UTXO at the main address is dropped rather than absorbed into the reserve.
Changes
available_utxosduring finalization.Notes
The two commits are ordered failing-test-first, then fix. The heavy integration target
//rs/bitcoin/ckbtc/minter:ckbtc_minter_testscould not be built in the authoring environment (missingautoconffor jemalloc); the minter unit tests and replay-event tests all pass.🤖 Generated with Claude Code