Reentrancy vulnerabilities in disclosed bug bounty reports
Reentrancy lets an external call re-enter a contract before its own state has settled, so the same balance or position can be spent twice.
- Reports indexed
- 105
- Total paid
- $1.2M
- Critical
- 1
- Largest payout
- $1.2M
Reentrancy is the oldest bug class in smart contract security and it keeps paying out because the shape of it changes faster than the mitigations do. The core mechanic never moves: a contract hands control to an untrusted address before it has finished writing its own state, and the callee re-enters through a second entrypoint that still reads the stale value.
The modern variants are what make it interesting. Cross-function reentrancy re-enters a different method that shares storage. Cross-contract reentrancy routes through a sibling contract in the same system. Read-only reentrancy never writes anything at all — it simply calls a view function mid-callback and hands a corrupted price or share value to an integrating protocol, which is why the largest recent payouts in this class landed on lending markets and vault wrappers rather than on the vulnerable contract itself.
The disclosures collected here span ERC-777 and ERC-721 callback hooks, native transfer callbacks, and Cosmos and Solana equivalents where reentrancy shows up as unfinalized account state rather than a callback.
What reviewers look for
- State written after an external call rather than before it
- View functions that read a mid-transaction balance or share price
- Token standards with transfer hooks (ERC-777, ERC-721, ERC-1155)
- A reentrancy guard on some entrypoints but not on every one that touches the same storage
- Integrating protocols that price a position by calling into the vulnerable contract
Curated highlights
The largest disclosed payouts in this group, with our own summary of each. Every report links back to the original disclosure.
Read-only reentrancy in LP price oracle drains lending market
A lending market relied on a liquidity pool's raw virtual price function to value LP tokens deposited as collateral. During a liquidity removal operation, ETH transfers to the caller occurred before internal balance and supply states were reconciled, allowing an execution callback while state was inconsistent. An attacker used this callback to fetch an artificially inflated virtual price, enabling them to over-borrow against their collateral and drain the protocol's reserves in a single transaction.
PoolTogether: Unintended or malicious use of prize winners' hooks
In PoolTogether v5, the Vault contract allows prize winners to configure arbitrary hooks via the setHooks function. During the prize claiming process, the contract executes these user-defined hooks prior to and after prize distribution. Because the hook calls lack gas consumption caps and state-change restrictions, a user can configure a malicious hook that conducts unconstrained external operations, griefs claimers paying for transaction gas, or causes claiming transactions to revert. This results in potential gas exhaustion and denial of service for third-party prize claimers.
Rigor Protocol: New subcontractor can be set for a SCConfirmed task without current subcontractor consent
Rigor Protocol's subcontractor management lets a builder or contractor reassign a task's subcontractor through inviteSC() without any signature check, whereas changing terms mid-task normally requires consent from all parties via checkSignatureTask(). Although the direct path (replacing a subcontractor on an already-confirmed, active task) is blocked by inviteSubcontractor()'s onlyInactive modifier, the warden showed the check is bypassed in changeOrder() budget-increase flows: when added funds are not yet lent, the task is unapproved and reset to inactive, after which a dishonest contractor can invite their own subcontractor who then collects the full task budget on completion, divesting the subcontractor who actually performed the work of their payment.
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: 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
- Centrifuge Protocol V3.1: Malicious adapters can exploit message batching via adapter-side reentrancy to cause message loss for any other poolReentrancy$0
- Ammplify: All taker collateral and collected fees can be stolen by re-entering via `RFTLib.settle` to manipulate uniswap spot price when adding Maker liquidityReentrancy$0
- Burve: Incorrect tax distribution when adding value single-sidedReentrancy$0
- Rubicon: REENTRANCY ATTACK POSSIBLE IF THE `_feeTo` IS A MALICIOUS CONTRACT IN `FeeWrapper._chargeFeePayable()` FUNCTIONReentrancy$0
- LoopFi: `CDPVault.sol#liquidatePositionBadDebt()` should not set profit `= 0` when calling `pool.repayCreditAccount()`Reentrancy$0
- Autonomint Colored Dollar V1: Cross-Contract Reentrancy Vulnerability in CDS Withdraw FunctionReentrancy$0
- Autonomint Colored Dollar V1: Reentrant call in `Treasury::withdrawFromExternalProtocol` during the `Borrowing::redeemYields` flow allows theft of `Treasury` ETHReentrancy$0
- Kakarot: Reentrancy check in `account_contract` can be easily circumventedReentrancy$0
- Teller Lender Groups Update Audit: ERC20.approve Used Instead of Safe Approvals, Causing Pool Failures with Some ERC20sReentrancy$0
- Teller Lender Groups Update Audit: Not updating state before making custom external call can cause borrower's to loose assets due to re-entrancyReentrancy$0
- Oku's New Order Types Contract: attacker can drain StopLimit contract funds through Bracket contract because it gives type(uint256).max allowance to bracket contract for input token in performUpkeep functionReentrancy$0
- Superfluid Locker System: An attacker may DoS user Fluid balance increases by frontrunning `FluidLocker::claim()` calls and calling `EP_PROGRAM_MANAGER::batchUpdateUserUnits()` directlyReentrancy$0
- HatsSignerGate v2: Signer can avoid restrictions and change `safe` state variablesReentrancy$0
- The Wildcat Protocol: Inconsistency across multiple repaying functions causing lender to pay extra feesReentrancy$0
- Fenix Finance: `dettachFromManagedNFT` might revert and temporarily prevent users from detaching in certain situationsReentrancy$0
- Phi: Reentrancy in creating Creds allows an attacker to steal all Ether from the Cred contractReentrancy$0
- Phi: Signature replay in `createArt` allows to impersonate artist and steal royaltiesReentrancy$0
- Phi: Contract `PhiNFT1155` can't be pausedReentrancy$0
- Reserve: The `tradeEnd` in `BackingManager` isn't updating correctlyReentrancy$0
- TraitForge: Lack of ability to make an some external function calls makes the DAO stage unreachableReentrancy$0
- BendDAO: Incorrect `unwrapNativeTokenInWallet` receiver addressReentrancy$0
- Olas: Unstake function reverts because of use of outdated/stale `serviceIds` arrayReentrancy$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
- Thorchain: ThorChain will be informed wrongly about the unsuccessful ETH transfers due to the incorrect events emissionsReentrancy$0
- Thorchain: Due to the use of `msg.value` in for loop, anyone can drain all the funds from the `THORChain_Router` contractReentrancy$0
- Gondi: Borrower signature could be reused in `emitLoan()`Reentrancy$0
- Gondi: `mergeTranches()`/`refinancePartial()` lack of `nonReentrant`Reentrancy$0
- Gondi: `validateOffer()` reentry to manipulate `exchangeRate`Reentrancy$0
- Curves Protocol: A subject creator within a single block can claim holder fees without holding due to unprotected reentrancy pathReentrancy$0
- Predy: Reallocation depends on the `slot0` price, which can be manipulatedReentrancy$0
- Union Finance Update #2: Possible loss of funds, transfer functions can silently failReentrancy$0
- Notional Leveraged Vaults: Pendle PT and Vault Incentives: Malicious users can steal reward tokens via re-entrancy attackReentrancy$0
- BakerFi: Rounding-down of `flashFee` can result in calls to flash loan to revertReentrancy$0
- Panoptic: Premium owed can be calculated as a very big number due to reentrancy on uninitialized poolsReentrancy$0
- Panoptic: Removed liquidity can overflow when calling `SemiFungiblePositionManager.mintTokenizedPosition` functionReentrancy$0
- Panoptic: Attacker can steal all fees from SFPM in pools with ERC777 tokensReentrancy$0
- Panoptic: The Main Invariant "Fees paid to a given user should not exceed the amount of fees earned by the liquidity owned by that user." can be broken due to slight difference when computing collected feeReentrancy$0
- Renzo: Fetched price from the oracle is not stored in `xRenzoDeposit`Reentrancy$0
- Renzo: Not handling the failure of cross chain messagingReentrancy$0
- Renzo: ETH withdrawals from EigenLayer always fail due to `OperatorDelegator`'s nonReentrant `receive()`Reentrancy$0
- Renzo: Deposits will always revert if the amount being deposited is less than the `bufferToFill` valueReentrancy$0
- Renzo: Withdrawals logic allows MEV exploits of TVL changes and zero-slippage zero-fee swapsReentrancy$0
- Revert Lend: Risk of reentrancy `onERC721Received` function to manipulate collateral token configs sharesReentrancy$0
- Revert Lend: Owner of a position can prevent liquidation due to the `onERC721Received` callbackReentrancy$0
- Revert Lend: Users's tokens stuck in `AutoCompound` after Vault is deactivatedReentrancy$0
- AI Arena: Player can mint more fighter NFTs during claim of rewards by leveraging reentrancy on the `claimRewards() function`Reentrancy$0
- Wise Lending: Exploitation of the receive Function to Steal FundsReentrancy$0
- Abracadabra Money: Users who deposited MIM and USDB tokens into BlastOnboarding may incur losses when the pool is created via bootstrapReentrancy$0
- Abracadabra Money: Attacker can amplify a rounding error in MagicLP to break the I invariant and cause malicious pricingReentrancy$0
- TITLES Publishing Protocol: Users can exploit the batch minting feature to avoid paying minting fees for tokensReentrancy$0
- Amphora Protocol: Reentrancy issue with the `withdraw` method of USDC. All tokens could be drained.Reentrancy$0
- Salty.IO: Creation of token whitelisting proposals can be DOS'dReentrancy$0
- Salty.IO: No proposal time limit traps sponsors of unpopular proposalsReentrancy$0
- Salty.IO: User can evade `liquidation` by depositing the minimum of tokens and gain time to not be liquidatedReentrancy$0
- PoolTogether: The winner can steal claimer fees, and force him to pay for the gasReentrancy$0
- reNFT: An attacker can hijack any ERC1155 token he rents due to a design issue in reNFT via reentrancy exploitationReentrancy$0
- Perpetual: Funding Fee Rate is calculated based only on the Oracle Maker's skew but applied across the entire market, which enables an attacker to generate an extreme funding rate for a low cost and leverage that to their benefitReentrancy$0
- zkSync: Synchronization Issue Between L1 and L2 UpgradesReentrancy$0
- zkSync: Loss of funds for the sender when ``L1->L2`` TX fails in the bootloader on L2Reentrancy$0
- Arcadia: Reentrancy in flashAction() allows draining liquidity poolsReentrancy$0
- Paladin: Changes of `questRewardsPerPeriod` didn't reflected on LootCreator's `totalQuestPeriodRewards`Reentrancy$0
- Collective: Incorrect amounts of ETH are transferred to the DAO treasury in `ERC20TokenEmitter::buyToken()`, causing a value leak in every transactionReentrancy$0
- Collective: Anyone can pause AuctionHouse in `_createAuction`Reentrancy$0
- Collective: The quorumVotes can be bypassedReentrancy$0
- Collective: `ERC20TokenEmitter::buyToken` function mints more tokens to users than it should doReentrancy$0
- Flat Money: A malicious user can bypass limit order trading fees via cross-function re-entrancyReentrancy$0
- Particle Protocol: Excess tokens that are not accounted in the token premium portion stuck in the `ParticlePositionManager`Reentrancy$0
- LooksRare YOLO: Rounds can not be immediately drawn after fulfillRandomWords due to VRF contracts reentrancy guardReentrancy$0
- INIT Capital: `collateralizeWLp` can be bypassed even when collateralization is pausedReentrancy$0
- INIT Capital: `setPosMode` should not allow changing the mode when the new mode's `canRepay` status is disabledReentrancy$0
- INIT Capital: Malicious user can steal native tokens of MoneyMarketHook callerReentrancy$0
- PartyDAO: `ETHCrowdfundBase.sol#_processContribution` - Possible DoS on finalization of crowdfund under certain conditionsReentrancy$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
- NextGen: Vulnerability in `burnToMint` function allows double use of NFTReentrancy$0
- Kelp DAO: Protocol mints less rsETH on deposit than intendedReentrancy$0
- Wildcat Protocol: When `withdrawalBatchDuration` is set to zero lenders can withdraw more then allocated to a batchReentrancy$0
- Wildcat Protocol: Lenders can escape the blacklisting of their accounts because they can move their MarketTokens to different accounts and gain the `WithdrawOnly` Role on any account they wantReentrancy$0
- Maia DAO: Incorrect source address decoding in RootBridgeAgent and BranchBridgeAgent's `_requiresEndpoint` breaks LayerZero communicationReentrancy$0
- Tapioca DAO: CompoundStrategy attempts to transfer out a greater amount of ETH than will actually be withdrawn, leading to DoSReentrancy$0
- Tapioca DAO: Reentrancy in `USDO.flashLoan()`, enabling an attacker to borrow unlimited USDO exceeding the max borrow limitReentrancy$0
- Tapioca DAO: Usage of `BalancerStrategy.updateCache` will cause single sided Loss, discount to Depositor and to OverBorrow from SingularityReentrancy$0
- Tapioca DAO: `LidoEthStrategy._currentBalance` is subject to price manipulation, allows overborrowing and liquidationsReentrancy$0
- Tapioca DAO: twAML::participate - reentrancy via _safeMint can be used to brick reward distributionReentrancy$0
- Maia DAO Ecosystem: Removing more gauge weight than it should be while transferring `ERC20Gauges` tokenReentrancy$0
- Maia DAO Ecosystem: `Rerange`/`rebalance` should not use `protocolFee` as an asset for adding liquidityReentrancy$0
- Maia DAO Ecosystem: Incorrect flow of adding liquidity in `UlyssesRouter.sol`Reentrancy$0
- Maia DAO Ecosystem: `setWeight()` Logic errorReentrancy$0
- Maia DAO Ecosystem: `_decrementWeightUntilFree()` has a possible infinite loopReentrancy$0
- Maia DAO Ecosystem: An attacker can redeposit gas after `forceRevert()` to freeze all deposited gas budget of `Root Bridge Agent`Reentrancy$0
- Maia DAO Ecosystem: A malicious user can set any contract as a local `hToken` for an underlying token since there is no access control for `_addLocalToken`Reentrancy$0
- Maia DAO Ecosystem: `redeem()` in `beforeRedeem` is using the wrong owner parameterReentrancy$0
- Maia DAO Ecosystem: A user can call `callOutSigned` without paying for gas by reentering `anyExecute` with Virtual AccountReentrancy$0
- Maia DAO Ecosystem: `TalosBaseStrategy#init()` lacks slippage protectionReentrancy$0
- Maia DAO Ecosystem: Reentrancy attack possible on `RootBridgeAgent.retrySettlement()` with missing access control for `RootBridgeAgentFactory.createBridgeAgent()`Reentrancy$0
- Asymmetry Finance: DoS due to external call failureReentrancy$0
- Ethos Reserve: User can lose up to whole stake on vault withdrawal when there are funds locked in the strategyReentrancy$0
- Biconomy: `FeeRefund.tokenGasPriceFactor` is not included in signed transaction data allowing the submitter to steal fundsReentrancy$0