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
- 148
- 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: 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: The contract serves as a flashloan pool without fee
PuttyV2's fillOrder and exercise functions lacked reentrancy protections, allowing a malicious user acting as both maker and taker to re-enter the contract from a malicious base-asset transfer callback. That re-entry exercises a short call to pull real ERC20/ERC721 balances out of PuttyV2, deploy them for profit on other venues, and repay before fillOrder completes. Because the protocol's 3% option fee is assessed in the base asset—an attacker-controlled custom token—the attack amounts to free, unrestricted use of all assets held by the contract. Sponsor and judge acknowledged the validity, agreeing flashloans are a feature but fee evasion is a bug, with no easy mitigation beyond nonReentrant guards at a gas cost.
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: Malicious Token Contracts May Lead To Locking Orders
Putty lets a maker construct an option whose erc20Assets, erc721Assets, and floorTokens fields point at arbitrary token contracts. Because PuttyV2.exercise() performs external transfer calls to each of those addresses, a maker who controls one of those token contracts can flip it into a permanently-reverting state, making the option impossible to exercise for its entire life. Since the long position is already burned to 0xdead before the transfer step, a failed transfer permanently traps the position. A short maker benefits by freezing an option when the price moves against them, then re-enabling transfers once expiry or a favorable price arrives. The judge upheld the finding at Medium severity because a user only becomes exposed by voluntarily filling an option that already contains the malicious asset, and the sponsor chose to mitigate with UI warnings rather than a contract-level whitelist.
All reports in this group
- Putty: Zero strike call options can be systemically used to steal premium from the takerReentrancy$0
- Putty: Putty position tokens may be minted to non ERC721 receiversReentrancy$0
- Putty: Unbounded loops may cause `exercise()`s and `withdraw()`s to failLogic error$0
- Rigor Protocol: Owner of project NFT has no purposeLogic error$0
- stNXM by EaseDeFi: The vault can be drainedAccess control$0
- stNXM by EaseDeFi: Expired tranche cannot be extended due to lack of token allowanceLogic error$0
- Ammplify: NFTManager will break NFT metadata for users as tokenURI() will revertLogic error$0
- Coded Estate: Token owner can burn their token with active rental leading to renters' funds being stuckLogic error$0
- Coded Estate: Adversary can use `send_nft` to bypass the payment and steal seller's token in auto-approve scenarioLogic error$0
- Coded Estate: Insufficient price validation in `transfer_nft` function enables theft of listed tokensLogic error$0
- Coded Estate: Attakers can steal the funds from long-term reservationLogic error$0
- Coded Estate: Users can't cancel reservation due to out-of-gasLogic error$0
- Coded Estate: `setbidtobuy` allows token purchase even when sale is no longer listedLogic error$0
- Coded Estate: Can impersonate another high value rental because `token_uri` is arbitrary and supplied by userLogic error$0
- Debita Finance V3: After the buyOrder is completed, the order creator does not receive the NFTLogic error$0
- Superposition: `update_emergency_council_7_D_0_C_1_C_58()` updates nft manager instead of emergency councilLogic error$0
- Superposition: `bytes data` param is not passed to ERC721 recipient as expected by EIP-721Logic error$0
- Superposition: Unrevoked approvals allow NFT recovery by previous ownerLogic error$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: Forced `endTime` extension in `updateArtSettings()` allows attacker to mint more tokensAccess control$0
- Phi: Incorrect fee handling prevents protocol from updating feesAccess control$0
- Phi: Signature replay in `signatureClaim` results in unauthorized claiming of rewardsAccess control$0
- Phi: Signature replay in `createArt` allows to impersonate artist and steal royaltiesReentrancy$0
- Phi: Unrestricted changes to token settings allow artists to alter critical featuresLogic error$0
- Phi: Contract `PhiNFT1155` can't be pausedReentrancy$0
- Saffron Lido Vaults: The incorrect accounting of protocol fee will cause double charging fee and wrong distribution of earnings for variable usersLogic error$0
- Boost Core Incentive Protocol: Boost creator can collect all the fees by setting referralFee to 9_000 and give claimants his address as referrer_ addressLogic error$0
- Boost Core Incentive Protocol: Unable to call some functions in the incentive contracts with onlyOwner modifier because of incorrect initialization leading to stuck fundsLogic error$0
- Flayer: Malicious user can bypass execution of `CollectionShutdown` functionLogic error$0
- Flayer: Stale shutdown params can be reused to drain all funds from `CollectionShutdown` contractLogic error$0
- Flayer: Incorrect index handling in checkpoint creation leads to incorrect initial checkpoint retrieval and potential DoSLogic error$0
- Flayer: If a collection has been shutdown but later re-initialized, it cannot be shutdown againLogic error$0
- Flayer: Frequency-dependent `TaxCalculator.sol::calculateCompoundedFactor` leads to interest loss either for users or for protocolLogic error$0
- Flayer: Quorum overflow in `CollectionShutdown` leads to complete drain of contract's fundsInteger overflow/underflow$0
- Flayer: The attacker will prevent eligible users from claiming the liquidated balanceLogic error$0
- Flayer: The Users who voted for collection shutdown will lose their collection tokens by cancelling the shutdownLogic error$0
- Flayer: ERC1155 cannot claim royalities on L2.Logic error$0
- Flayer: Donation fees are sandwichable in one transactionFront-running / MEV$0
- TraitForge: NFTs mature too slowly under default settings.Logic error$0
- TraitForge: A dev will lose rewards if after claiming his rewards he mints an NFTLogic error$0
- TraitForge: Number of entities in generation can surpass the 10k numberLogic error$0
- TraitForge: Incorrect percentage calculation in NukeFund and EntityForging when `taxCut` is changed from default valueLogic error$0
- TraitForge: Each generation should have 1 "Golden God" NFT, but there could be 0Logic error$0
- TraitForge: `Golden God` tokens can be minted twice per generationLogic error$0
- TraitForge: There is no slippage check in the `nuke()` functionLogic error$0
- TraitForge: `mintToken()`, `mintWithBudget()`, and `forge()` in the `TraitForgeNft` contract will fail due to a wrong modifier used in `EntropyGenerator.initializeAlphaIndices()`Logic error$0
- TraitForge: Users' ability to nuke will be DoSed for three days after putting NFTs up for sale and canceling the saleLogic error$0
- TraitForge: Pause and unpause functions are inaccessibleLogic error$0
- TraitForge: Duplicate NFT generation via repeated forging with the same parentLogic error$0
- TraitForge: TraitForgeNft: Generations without a golden god are possibleLogic error$0
- TraitForge: Griefing attack on seller's airdrop benefitsLogic error$0
- TraitForge: Incorrect `isApprovedForAll` check in the `NukeFund.nuke()` functionAccess control$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: Miscalculation in `_farmPlots` function could lead to a user unable to unstake all NFTsInteger overflow/underflow$0
- Munchables: in `farmPlots()` an underflow in edge case leading to freeze of funds (NFT)Integer overflow/underflow$0
- Olas: Staked service will be irrecoverable by owner if not an ERC721 receiverReentrancy$0
- Olas: Blocklisted or paused state in staking token can prevent service owner from unstakingReentrancy$0
- Vultisig: Transfer of `ILOPool` NFT token to different account allows for users to bypass the pool's `maxCapPerUser` invariantLogic error$0
- Velocimeter: poke() may be dosLogic error$0
- Velocimeter: VotingEscrow MAX_DELEGATES value can lead to DOS on certain EVM-compatible chainsLogic error$0
- Velocimeter: User can make their `veNFT` unpokeable by voting for a to-be-killed gaugeLogic error$0
- Krystal DeFi: The Protocol breaks the Allowance Mechanism of the NFTsLogic error$0
- Andromeda – Validator Staking ADO and Vesting ADO: is_permissioned() It doesn't make sense to have permissions by default after Blacklisted expires.Logic error$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
- Munchables: Invalid validation allows users to unlock earlyLogic error$0
- Munchables: Malicious User can call `lockOnBehalf` repeatedly extend a users `unlockTime`, removing their ability to withdraw previously locked tokensAccess control$0
- Tapioca DAO: Adversary can steal user's NFT's if they have set Magnetar as `isApprovedForAll == true`Access control$0
- Tapioca DAO: `TapiocaOptionBroker.participate()` with the approve authorization, it still cannot be executedLogic error$0
- Tapioca DAO: Adversary can steal approved `tOLP`s to Magnetar via `_paricipateOnTOLP`Logic error$0
- Revert Lend: Users's tokens stuck in `AutoCompound` after Vault is deactivatedReentrancy$0
- AI Arena: NFTs can be transferred even if StakeAtRisk remains, so the user's win cannot be recorded on the chain due to underflow, and can recover past losses that can't be recovered (steal protocol's token)Logic error$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: Constraints of `dailyAllowanceReplenishTime` and `allowanceRemaining` during `mint()` can be bypassed by using alias accounts & `safeTransferFrom()`Logic error$0
- AI Arena: Non-transferable `GameItems` can be transferred with `GameItems::safeBatchTransferFrom(...)`Logic error$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: `FighterFarm::reRoll` won't work for nft id greater than 255 due to input limited to uint8Logic error$0
- AI Arena: Can mint NFT with the desired attributes by reverting transactionOracle manipulation$0
- AI Arena: Fighters cannot be minted after the initial generation due to uninitialized `numElements` mappingLogic error$0
- AI Arena: A locked fighter can be transferred; leads to game server unable to commit transactions, and unstoppable fightersAccess control$0
- AI Arena: Player can mint more fighter NFTs during claim of rewards by leveraging reentrancy on the `claimRewards() function`Reentrancy$0
- AI Arena: Fighter created by `mintFromMergingPool` can have arbitrary weight and elementLogic error$0
- TITLES Publishing Protocol: New creators unable to update the royalty target and the fee route for their worksLogic error$0
- TITLES Publishing Protocol: Broken batch minting featureLogic error$0
- TITLES Publishing Protocol: TitlesGraph::acknowledgeEdge() methods do not write acknowledgments to storageLogic error$0
- TITLES Publishing Protocol: Users can exploit the batch minting feature to avoid paying minting fees for tokensReentrancy$0
- TITLES Publishing Protocol: `Edition.supportsInterface` is not EIP1155 compliantLogic error$0
- Phala Network: A cache that times out can be recoveredLogic error$0
- Althea Liquid Infrastructure: Holders array can be manipulated by transferring or burning with amount 0, stealing rewards or bricking certain functionsLogic error$0
- Althea Liquid Infrastructure: Malicious users can prevent holders from claiming their rewards during a reward cycle by skipping it.Front-running / MEV$0
- Althea Liquid Infrastructure: Withdrawal from NFTs can be temporarily blockedLogic error$0
- Althea Liquid Infrastructure: Distribution can be bricked, and double claims by a few holders are possible when owner calls `LiquidInfrastructureERC20::setDistributableERC20s`Access control$0
- Althea Liquid Infrastructure: `LiquidInfrastructureERC20.sol` disapproved holders keep part of the supply, diluting approved holders revenue.Logic error$0
- RadicalxChange: Currently auctioned NFTs can be transferred to a different address in a specific edge caseLogic error$0
- reNFT: The owners of a rental safe can continue to use the old guard policy contract for as long as they want, regardless of a new guard policy upgradeLogic error$0
- reNFT: `Guard::checkTransaction` restricts native ETH transfer from user's safesLogic error$0
- reNFT: Blacklisted extensions can't be disabled for rental safesLogic error$0
- reNFT: Escrow contract can be drained by creating rentals that bypass execution invariant checksLogic error$0
- reNFT: Protocol does not implement EIP712 correctly on multiple occasionsLogic 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
- reNFT: DoS of Rental stopping mechanismLogic error$0
- reNFT: Risk of DoS when stoping large rental orders due to block gas limitLogic error$0
- reNFT: Incorrect ordering for deletion allows to flash steal rented NFT'sLogic error$0
- reNFT: Incorrect `gnosis_safe_disable_module_offset` constant leads to removing the rental safe's `module` without verificationAccess control$0
- reNFT: Malicious actor can steal any actively rented NFT and freeze the rental payments (of the affected rentals) in the `escrow` contractLogic error$0
- reNFT: paused ERC721/ERC1155 could cause stopRent to revert, potentially causing issues for the lender.Logic error$0
- reNFT: DOS possible while stopping a rental with erc777 tokensLogic error$0
- reNFT: Attacker can lock lender NFTs and ERC20 in the safe if the offer is set to partialLogic error$0
- reNFT: Upgrading modules via `executeAction()` will brick all existing rentalsLogic error$0
- Tapioca: exerciseOptionsReceiver() Lack of Ownership Check for oTAP, Allowing Anyone to Use oTAPTokenIDAccess control$0
- Napier: Benign esfrxETH holders incur more loss than expectedLogic error$0
- Collective: Since art pieces' size is not limited, attacker may block AuctionHouse from creating and settling auctionsLogic error$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
- Collective: `CultureIndex.sol#dropTopVotedPiece()` - Malicious user can manipulate topVotedPiece to DoS the whole CultureIndex and AuctionHouseLogic error$0
- Collective: Malicious delegatees can block delegators from redelegating and from sending their NFTsInteger overflow/underflow$0
- Collective: It may be possible to DoS AuctionHouse by specifying malicious creatorsGovernance attack$0
- Collective: `VerbsToken.tokenURI()` is vulnerable to JSON injection attacksLogic error$0
- Collective: Anyone can pause AuctionHouse in `_createAuction`Reentrancy$0
- Collective: The quorumVotes can be bypassedReentrancy$0
- Collective: Bidder can use donations to get VerbsToken from auction that already endedGovernance attack$0
- Collective: Violation of ERC-721 Standard in VerbsToken:tokenURI ImplementationLogic error$0
- Telcoin Platform: Wrong parameter when retrieving causes a complete DoS of the protocolLogic error$0
- PartyDAO: `PartyGovernanceNFT` advertises but does not honor the ERC-4906 standardGovernance attack$0
- PartyDAO: `PartyGovernanceNFT#rageQuit()` can lead to token loss for users when dealing with zero-balance ERC20 during a `rageQuit()`Governance attack$0
- PartyDAO: Single host can unfairly skip veto period for proposal that does not have full host supportGovernance 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: `PartyGovernance.sol#accept` - `passThresholdBps` isn't cached for each proposal which can lead to problems if changed through another proposalGovernance attack$0
- NextGen: Auction winner can prevent payments via `safeTransferFrom` callbackLogic error$0
- NextGen: Attacker can reenter to mint all the collection supplyReentrancy$0
- NextGen: If an airdrop happens before a mint the price could skyrocketLogic error$0
- NextGen: Bidder Funds Can Become Unrecoverable Due to 1 second Overlap in `participateToAuction()` and `claimAuction()`Logic error$0
- NextGen: Adversary can block `claimAuction()` due to push-strategy to transfer assets to multiple biddersLogic error$0
- NextGen: Auction payout goes to `AuctionDemo` contract owner, not the token ownerLogic error$0
- NextGen: Attacker can drain all ETH from `AuctionDemo` when `block.timestamp == auctionEndTime`Reentrancy$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
- 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: User can give himself approval for all assets held by `MagnetarV2` contractGovernance attack$0
- Tapioca DAO: twAML::participate - reentrancy via _safeMint can be used to brick reward distributionReentrancy$0
- Maia DAO Ecosystem: `BoostAggregator` owner can set fees to 100% and steal all of the user's rewardsAccess control$0