# NFT sellers can farm SOL by intentionally closing their ATAs

Tensor's buy_spl auto-initializes seller and broker ATAs, letting sellers close them post-sale and repeatedly harvest buyer-paid rent.

- Payout: Contest reward
- Severity: medium
- Program: Tensor
- Credited: krikolkk
- Disclosed: 2025-01-31
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_tensor_nov2024.pdf#3.2.9
- Library page: https://bugbountylibrary.com/r/cantina%3Atensor_nov2024%3A3.2.9
- Tags: domain:web3 impact:funds-loss kind:contest platform:cantina sev:medium tech:solana technique:source-review vuln:business-logic

**Target:** Solana buy_spl instruction (SPL NFT marketplace)
**Root cause:** buy_spl initializes missing seller and maker-broker ATAs and charges rent to the buyer, but nothing prevents the seller from closing those ATAs after each sale and re-triggering initialization on the next sale.
**Steps:**
1. Seller sets up master account A1, NFT/listing owner A2, maker broker A3.
2. Buyer calls `buy_spl`; A2 and A3 ATAs are initialized and buyer pays rent (~0.00203928 SOL each).
3. Seller closes A2/A3 ATAs, sweeping tokens plus rent to A1's master ATA.
4. Repeat on next sale: ATAs reinitialized, buyer pays rent again.
**How found:** Code review of the buy_spl Accounts struct noticed conditional ATA initialization (buy_spl.rs#L73-L79, #L110-L116) with rent paid by the buyer, and reasoned that sellers control ATA lifecycle and can close/reopen them.
**Exploitation:** Seller scripts repeated listing/sale cycles; each sale forces the buyer to fund rent for freshly initialized seller/broker ATAs, which the seller then closes and pockets (~0.004 SOL per sale).
**Insight:** On Solana programs, any account the instruction auto-creates with payer=buyer is a rent-extraction surface if the counterparty controls that account's lifecycle; check who can close accounts the buyer funds.
