Normal behavior: withdrawAllFailedCredits should let the credited user pull ETH that failed to transfer to them.
Issue: The function in src/BidBeastsNFTMarketPlace.sol:238 pays msg.sender and zeroes the wrong slot, so any address can steal another user’s credits and repeat the theft forever.
Likelihood:
Credits appear whenever _payout hits a reverting recipient during routine auctions, so vulnerable balances arise in normal operation.
Attackers only need the victim address and a transaction; they can immediately invoke the function and repeat without restriction.
Impact:
Attacker seizes victims’ failed credits, causing instant loss of funds.
Because the victim’s slot never resets, the attacker can loop withdrawals until the marketplace’s ETH balance is fully drained.
Set up contracts and actors: Deploy BidBeasts and BidBeastsNFTMarket, mint token ID 0 to a helper contract failSink whose receive()/fallback() always reverts so it can’t accept ETH.
Create failed credits: failSink lists token 0. Bidder A bids 0.02 ETH and becomes the high bidder. Bidder B overbids with 0.03 ETH; _payout tries to refund Bidder A (the reverting failSink), records the refund in failedTransferCredits[address(failSink)], and leaves the ETH in the marketplace.
Exploit: An unrelated attacker calls withdrawAllFailedCredits(address(failSink)). Funds go to the attacker instead of failSink, and failedTransferCredits[address(failSink)] still holds the same amount. The attacker can repeat the call to drain the marketplace balance.
Example Forge test skeleton:
The fix enforces that only the credited address can withdraw, clears the correct storage slot, and keeps the payout destination aligned with the credited user.
withdrawAllFailedCredits allows any user to withdraw another account’s failed transfer credits due to improper use of msg.sender instead of _receiver for balance reset and transfer.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.