NFT protocol vulnerabilities in disclosed bug bounty reports
Minting, marketplace settlement and royalty enforcement — where signature handling and callback hooks do most of the damage.
- Reports indexed
- 64
- Total paid
- $60k
- Critical
- 0
- Largest payout
- $60k
NFT findings concentrate in three places: mint mechanics, marketplace order settlement, and the callback hooks the token standards mandate. Mint bugs are usually supply or allowlist accounting. Marketplace bugs are usually signature scope — an order that can be filled twice, cancelled ineffectively, or matched against a different asset than intended.
The `onERC721Received` and `onERC1155Received` hooks reintroduce reentrancy into contracts that would otherwise be safe, which is why so many NFT reports cross-reference the reentrancy category.
Randomness for reveals and trait assignment is the fourth recurring surface, and on-chain sources of it remain predictable in ways the write-ups spell out clearly.
What reviewers look for
- Allowlist and supply accounting under concurrent mints
- Marketplace orders fillable more than once or after cancellation
- Receiver hooks re-entering mint or settlement logic
- Predictable on-chain randomness for reveals or traits
- Royalty enforcement bypassable through an alternate transfer path
Curated highlights
The largest disclosed payouts in this group, with our own summary of each. Every report links back to the original disclosure.
NFT marketplace signature does not bind to token id allowing order swap
An NFT marketplace implemented an off-chain EIP-712 order signing mechanism that failed to include the token ID within the signed struct hash. Because the token ID was accepted directly from unverified calldata during order execution, malicious actors could swap order parameters to fulfill trades using unintended token IDs from the same collection. This allowed attackers to acquire high-value collection items using floor-priced signatures or trade arbitrary assets under invalid terms.
Putty: An attacker can create a short put option order on an NFT that does not support ERC721 (like cryptopunk), and the user can fulfill the order, but cannot exercise the option
The Putty protocol incorrectly assumes that all NFT assets used as underlying collateral in options contracts support the full ERC-721 standard. By using a safeTransferFrom implementation that requires the onERC721Received callback, the protocol unintentionally renders certain legacy NFTs, like CryptoPunks, unexercisable. Attackers can exploit this by offering options on these incompatible assets, collecting premiums from users who are then unable to exercise their options or receive the underlying asset.
Putty: Create a short call order with non empty floor makes the option impossible to exercise and withdraw
The Putty options protocol suffered from a critical logic error where short call orders could be created with non-empty floor token arrays. This invalid state prevented takers from exercising their options and makers from withdrawing their deposited collateral after expiration, effectively bricking the funds involved in the order. Furthermore, this flaw could be exploited to grief other users by creating orders that conflict with the assets used in active, legitimate positions, leading to a permanent loss of access to those assets.
Putty: Overlap Between `ERC721.transferFrom()` and `ERC20.transferFrom()` Allows `order.erc20Assets` or `order.baseAsset` To Be ERC721 Rather Than ERC20
Putty protocol is vulnerable to a token standard confusion issue where ERC721 tokens can be submitted in place of ERC20 assets. Because both standards share similar transferFrom function signatures, the protocol successfully pulls the NFT into its custody. However, due to the incompatibility between ERC20-based withdrawal logic and the ERC721 standard, these tokens become permanently locked within the contract, resulting in a total loss of funds for the depositor.
Putty: Zero strike call options can be systemically used to steal premium from the taker
The Putty protocol was vulnerable to a permanent denial-of-service (DOS) condition when users attempted to exercise zero-strike call options involving specific non-standard ERC20 tokens. If a token reverted on zero-value transfers, the protocol's unconditional transfer attempt made it impossible for takers to exercise their options, allowing malicious makers to collect premiums without risk. This vulnerability allowed makers to systematically exploit unsuspecting takers by creating orders that appeared valid but were functionally impossible to exercise.
Putty: Putty position tokens may be minted to non ERC721 receivers
The Putty protocol incorrectly uses an unsafe minting function when generating ERC721 position tokens for users and makers. This omission fails to verify that the receiving contract can properly handle ERC721 tokens, leading to a risk where positions are sent to non-ERC721-compliant receivers. Consequently, if a smart contract recipient lacks the necessary logic to interact with or transfer these tokens, the assets remain permanently trapped, unable to be exercised or withdrawn.
All reports in this group
- Superposition: Unrevoked approvals allow NFT recovery by previous ownerLogic error$0
- Superposition: `bytes data` param is not passed to ERC721 recipient as expected by EIP-721Logic error$0
- Superposition: `update_emergency_council_7_D_0_C_1_C_58()` updates nft manager instead of emergency councilLogic error$0
- Phi: Signature replay in `signatureClaim` results in unauthorized claiming of rewardsAccess control$0
- Phi: Contract `PhiNFT1155` can't be pausedReentrancy$0
- Phi: Incorrect fee handling prevents protocol from updating feesAccess control$0
- Phi: Unrestricted changes to token settings allow artists to alter critical featuresLogic error$0
- Phi: Forced `endTime` extension in `updateArtSettings()` allows attacker to mint more tokensAccess control$0
- Phi: Lack of data validation when users are claiming their art allows malicious user to bypass signature/merkle hash to provide unapproved `ref_`, `artId_` and `imageURI`Logic error$0
- Phi: Signature replay in `createArt` allows to impersonate artist and steal royaltiesReentrancy$0
- BendDAO: `YieldEthStakingLido` lacks a limit on the max stake amount, which may result in the unstake exceeding `MAX_STETH_WITHDRAWAL_AMOUNT`, resulting in the token not being retrievedGovernance attack$0
- BendDAO: Unhandled request invalidation by the owner of Etherfi will lead to stuck debtLogic error$0
- Munchables: in `farmPlots()` an underflow in edge case leading to freeze of funds (NFT)Integer overflow/underflow$0
- Munchables: Miscalculation in `_farmPlots` function could lead to a user unable to unstake all NFTsInteger overflow/underflow$0
- Olas: Blocklisted or paused state in staking token can prevent service owner from unstakingReentrancy$0
- Olas: Staked service will be irrecoverable by owner if not an ERC721 receiverReentrancy$0
- Munchables: When `LockManager.lockOnBehalf` is called from `MigrationManager`, the user's `reminder` will be set to 0, resulting in fewer received `MunchableNFTs`Logic error$0
- Revert Lend: Users's tokens stuck in `AutoCompound` after Vault is deactivatedReentrancy$0
- AI Arena: Since you can reroll with a different fighterType than the NFT you own, you can reroll bypassing maxRerollsAllowed and reroll attributes based on a different fighterTypeLogic error$0
- AI Arena: Can mint NFT with the desired attributes by reverting transactionOracle manipulation$0
- AI Arena: Players have complete freedom to customize the fighter NFT when calling `redeemMintPass` and can redeem fighters of types Dendroid and with rare attributesLogic error$0
- AI Arena: Fighter created by `mintFromMergingPool` can have arbitrary weight and elementLogic error$0
- AI Arena: Fighters cannot be minted after the initial generation due to uninitialized `numElements` mappingLogic error$0
- AI Arena: Constraints of `dailyAllowanceReplenishTime` and `allowanceRemaining` during `mint()` can be bypassed by using alias accounts & `safeTransferFrom()`Logic error$0
- AI Arena: `FighterFarm::reRoll` won't work for nft id greater than 255 due to input limited to uint8Logic error$0
- AI Arena: Player can mint more fighter NFTs during claim of rewards by leveraging reentrancy on the `claimRewards() function`Reentrancy$0
- AI Arena: Non-transferable `GameItems` can be transferred with `GameItems::safeBatchTransferFrom(...)`Logic error$0
- reNFT: Incorrect `gnosis_safe_disable_module_offset` constant leads to removing the rental safe's `module` without verificationAccess control$0
- reNFT: Blacklisted extensions can't be disabled for rental safesLogic error$0
- reNFT: All orders can be hijacked to lock rental assets forever by tipping a malicious ERC20Front-running / MEV$0
- reNFT: `RentPayload`'s signature can be replayedLogic error$0
- Collective: Since art pieces' size is not limited, attacker may block AuctionHouse from creating and settling auctionsLogic error$0
- Collective: Malicious delegatees can block delegators from redelegating and from sending their NFTsInteger overflow/underflow$0
- Collective: The quorumVotes can be bypassedReentrancy$0
- Collective: `VerbsToken.tokenURI()` is vulnerable to JSON injection attacksLogic error$0
- Collective: Violation of ERC-721 Standard in VerbsToken:tokenURI ImplementationLogic error$0
- Collective: Bidder can use donations to get VerbsToken from auction that already endedGovernance attack$0
- Collective: Anyone can pause AuctionHouse in `_createAuction`Reentrancy$0
- Collective: `ArtPiece.totalVotesSupply` and `ArtPiece.quorumVotes` are incorrectly calculated due to inclusion of the inaccessible voting powers of the NFT that is being auctioned at the moment when an art piece is createdGovernance attack$0
- PartyDAO: `PartyGovernanceNFT` advertises but does not honor the ERC-4906 standardGovernance attack$0
- PartyDAO: `PartyGovernance.sol#accept` - `passThresholdBps` isn't cached for each proposal which can lead to problems if changed through another proposalGovernance attack$0
- PartyDAO: The 51% majority can hijack the party's precious tokens through an arbitrary call proposal if the `AddPartyCardsAuthority` contract is added as an authority in the party.Flash loan attack$0
- PartyDAO: Single host can unfairly skip veto period for proposal that does not have full host supportGovernance attack$0
- PartyDAO: `PartyGovernanceNFT#rageQuit()` can lead to token loss for users when dealing with zero-balance ERC20 during a `rageQuit()`Governance attack$0
- NextGen: Auction payout goes to `AuctionDemo` contract owner, not the token ownerLogic error$0
- NextGen: Adversary can block `claimAuction()` due to push-strategy to transfer assets to multiple biddersLogic error$0
- NextGen: Vulnerability in `burnToMint` function allows double use of NFTReentrancy$0
- NextGen: On a Linear or Exponential Descending Sale Model, a user that mints on the last `block.timestamp` mints at an unexpected price.Logic error$0
- NextGen: Bidder Funds Can Become Unrecoverable Due to 1 second Overlap in `participateToAuction()` and `claimAuction()`Logic error$0
- NextGen: Auction winner can prevent payments via `safeTransferFrom` callbackLogic error$0
- NextGen: If an airdrop happens before a mint the price could skyrocketLogic error$0
- NextGen: Attacker can reenter to mint all the collection supplyReentrancy$0
- NextGen: Attacker can drain all ETH from `AuctionDemo` when `block.timestamp == auctionEndTime`Reentrancy$0
- Open Dollar: Vault721.tokenURI does not comply with ERC721 - Metadata specificationLogic error$0
- Maia DAO: All tokens can be stolen from `VirtualAccount` due to missing access modifierAccess control$0
- Tapioca DAO: twAML::participate - reentrancy via _safeMint can be used to brick reward distributionReentrancy$0
- Tapioca DAO: User can give himself approval for all assets held by `MagnetarV2` contractGovernance attack$0
- Maia DAO Ecosystem: `BoostAggregator` owner can set fees to 100% and steal all of the user's rewardsAccess control$0