Skip to content

fix: validate_bitassets: count unique BitAsset outputs from the outputs - #54

Open
giaki3003 wants to merge 2 commits into
LayerTwo-Labs:masterfrom
giaki3003:fix/w3-20260611-0220-bitassets-amm-burn-validat-bitassets-state-validate-bitassets-gates-the-amm
Open

giaki3003 wants to merge 2 commits into
LayerTwo-Labs:masterfrom
giaki3003:fix/w3-20260611-0220-bitassets-amm-burn-validat-bitassets-state-validate-bitassets-gates-the-amm

Conversation

@giaki3003

Copy link
Copy Markdown
Contributor

What's wrong

In State::validate_bitassets (lib/state/mod.rs), n_unique_bitasset_outputs is filled from tx.unique_spent_bitassets() — that is, from the spent inputs. An AMM burn spends LP tokens and a Dutch auction collect spends an auction receipt, so neither has BitAsset inputs and the count is 0, while the AMM-burn branch requires at least 2 and the collect branch at least 1. Both are therefore always rejected, with Error::Amm(InvalidBurn) and dutch_auction::Collect::Invalid: LP positions cannot be redeemed and finished auctions cannot be collected. validate_filled_transaction runs this on mempool acceptance and on block connection alike. For AMM mint/swap the two counts are the same value, so those comparisons are vacuous.

The fix

Adds FilledTransaction::n_unique_bitasset_outputs(), which counts unique BitAssets in filled_outputs(), and uses it here; regular txs never read the value, so it isn't computed for them. AMM burns and Dutch auction collects are also exempted from the "no BitAsset inputs implies no BitAsset outputs" rule, since they pay out BitAssets held by the pool/auction — those amounts are still checked against pool and auction state when the tx is applied.

Tests

Adds validate_bitassets_accepts_amm_burn, validate_bitassets_accepts_amm_mint, and validate_bitassets_accepts_dutch_auction_collect.

Finding report (access-controlled): https://giaki3003.tech/#/findings/20260611-0220-bitassets-amm-burn-validator-counts-spent-bitassets-not-outputs-rejects-normal-burn


Part of a short series for this repo (fix 2 of 4); builds on #53, so it reads best merged after that one. Happy to rebase or split if you'd prefer them independent.

giaki3003 and others added 2 commits July 29, 2026 11:01
Bug: w3-20260630-1952-kimiclaw-confirm-openclaw- (primary)
Finding: findings/20260630-1952-kimiclaw-confirm-openclaw-plain-bitassets-dutch-auction-dust-bid-drain.md
Severity: R4-T1

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit b3baea9)
…ty check on a mis-assigned n_unique_bitasset_outputs variable (filled from spent BitAsset INPUTS via unique_spent_bitassets() instead of the computed-but-unused bitasset_outputs() count), so a normal LP-redemption burn is deterministically rejected by block validation with Error::Amm(InvalidBurn)

Bug: w3-20260611-0220-bitassets-amm-burn-validat (primary)
Finding: findings/20260611-0220-bitassets-amm-burn-validator-counts-spent-bitassets-not-outputs-rejects-normal-burn.md
Severity: R4-T2

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit caeb6d5)
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.

1 participant