# Treasury can be fully emptied via surplus auctions due to missing treasury coin uniqueness check

Missing uniqueness check on treasury_coins in surplus_auction_start lets attacker double-count spent coins, bypassing treasury maximum and auctioning off the entire treasury at a discount.

- Payout: Contest reward
- Severity: critical
- Program: Circuit Puzzles
- Credited: muellerberndt
- Disclosed: 2025-08-21
- Write-up quality: 8/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_circuit_puzzles.pdf#3.1.1
- Library page: https://bugbountylibrary.com/r/cantina%3Acircuit_puzzles%3A3.1.1
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:cantina sev:critical technique:incomplete-fix technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Chia smart-contract surplus auction operation (surplus_auction_start)
**Root cause:** assert-treasury-coins-withdrawal sums amounts from a caller-supplied treasury_coins list without verifying coin uniqueness; on Chia a coin and its output can be spent in the same bundle, so the same value is counted multiple times.
**Steps:**
1. Attacker holds one treasury coin T-1 with 1,000 BYC; STATUTE_TREASURY_MAXIMUM = 1,500.
2. Call `surplus_auction_start` with treasury_coins listing T-1 and its ephemeral output coins.
3. Spend T-1 with withdraw_amount=10, then spend its output with withdraw_amount=10 in the same spend bundle.
4. new_treasury_coins_amount = 990 + 980 = 1,970 > 1,500, so the auction is permitted despite only 980 BYC remaining.
5. Chain further spends to inflate the counted total arbitrarily and start auctions repeatedly until the treasury is nearly empty.
**How found:** Reviewer compared surplus_auction_start against the recharge auction, which does verify treasury coin uniqueness, and noticed the missing check combined with Chia's same-bundle coin-and-output spend semantics enabling double counting.
**Exploitation:** Attacker constructs a chain of spends of the same treasury coin and its ephemeral outputs within one spend bundle, passing all coin IDs to surplus_auction_start. The inflated sum passes the treasury-maximum check, allowing a surplus auction to be started at will. CRT holders (including the attacker) buy the auctioned BYC at a discount, extracting value while draining the treasury.
**Escalation:** Repeat the auction across multiple rounds to sell off all but a small residual of BYC, breaking treasury operations, saver interest payments, and bad-debt settlement.
**Insight:** On UTXO-style chains like Chia, any accounting that sums caller-supplied coin lists must enforce uniqueness (e.g. by LAUNCHER_ID) because a coin and its ephemeral output can both be spent in one bundle; compare sibling operations for the missing check.
