# Malicious user can burn any Silo NFT preventing the deployer from receiving fees

SiloFactory.burn lacks owner/approval check, letting anyone burn a deployer's Silo NFT and block their fee withdrawal.

- Payout: Contest reward
- Severity: high
- Program: Silo
- Credited: Jonatas Martins
- Disclosed: 2025-03-19
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_silo.pdf#3.1.1
- Library page: https://bugbountylibrary.com/r/cantina%3Asilo%3A3.1.1
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:cantina sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic vuln:fee-bypass

**Target:** SiloFactory ERC721 burn function
**Root cause:** SiloFactory.burn calls ERC721._burn without verifying caller is owner or approved; _burn is internal and performs no authorization.
**Steps:**
1. Deploy a Silo via `siloFactory.createSilo(...)`; deployer owns NFT tokenId 2
2. As unrelated address, call `siloFactory.burn(2)`
3. Observe burn succeeds; `siloFactory.ownerOf(2)` reverts with `ERC721NonexistentToken(2)`
4. Deployer can no longer be resolved as fee recipient in `getFeeReceivers()`, blocking `Silo.withdrawFees()`
**How found:** Code review of SiloFactory.burn noticed it delegates to ERC721._burn, whose NatSpec explicitly states it does not check sender authorization; traced NFT ownership into getFeeReceivers to establish impact.
**Exploitation:** Any unprivileged account calls burn(tokenId) on the deployer's Silo NFT; since fee recipients derive from NFT ownership, the deployer is permanently unable to withdraw accrued fees.
**Insight:** When a contract exposes a public wrapper around OpenZeppelin internal `_burn`/`_update`, check for a missing `_isAuthorized`/owner check — internal ERC721 helpers intentionally skip authorization.
