Bid Beasts

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

Unrestricted burn() Allows Anyone to Destroy Arbitrary NFTs

Root + Impact

Description

  • The BidBeasts contract implements an ERC721 with custom mint and burn functions.

  • Burning is completely unrestricted. Any user can call burn(tokenId) and it will call OpenZeppelin’s _burn, which destroys the NFT without checking if the caller is the token’s owner or an approved operator.

  • This means any user can permanently destroy NFTs owned by other users.

function mint(address to) public onlyOwner returns (uint256) {
uint256 _tokenId = CurrenTokenID;
_safeMint(to, _tokenId);
emit BidBeastsMinted(to, _tokenId);
CurrenTokenID++;
return _tokenId;
}
function burn(uint256 _tokenId) public { //@audit-issue unrestricted burn function
_burn(_tokenId);
emit BidBeastsBurn(msg.sender, _tokenId);
}

Risk

Likelihood: High

  • The function is public and callable by anyone.

No access control or ownership checks are enforced.

Impact: High

  • All NFTs can be permanently destroyed by any attacker.

Results in irreversible loss of user funds/assets.

  • Breaks trust in the NFT collection and the marketplace built on it.

Proof of Concept

Bob successfully burns Alice’s NFT without approval, proving unrestricted burn() is exploitable.

function test_unrestrictedBurn_allowsAttackerToDestroyOthersNFT() public {
// Step 1: Owner mints NFT to Alice
vm.prank(OWNER);
uint256 tokenId = nft.mint(BIDDER_1);
assertEq(nft.ownerOf(tokenId), BIDDER_1);
// Step 2: Malicious Bob calls burn() on Alice's token
vm.prank(BIDDER_2);
nft.burn(tokenId);
// Step 3: Verify token no longer exists
vm.expectRevert(); // works for both string and custom error
nft.ownerOf(tokenId);
}

Recommended Mitigation

Restrict burn to only the token owner or approved operator by using the _isApprovedOrOwner modifier.

- function burn(uint256 _tokenId) public {
- _burn(_tokenId);
- emit BidBeastsBurn(msg.sender, _tokenId);
- }
+ function burn(uint256 _tokenId) public {
+ require(
+ _isApprovedOrOwner(msg.sender, _tokenId),
+ "Caller is not owner nor approved"
+ );
+ _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!