Bid Beasts

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

WithdrawAllFailedCredits Function Allows Anyone to Steal Other Users' Failed Transfer Credits

BidBeastsNFTMarketPlace.sol - line 238-246

Description

  • In the normal behavior, the withdrawAllFailedCredits function should allow a user to withdraw their own failed transfer credits by transferring the funds to the correct recipient and resetting the credits balance.

  • The specific issue is that the function incorrectly transfers _receiver's credits to msg.sender instead of _receiver, and it resets msg.sender's credits instead of _receiver's credits, allowing anyone to steal other users failed transfer credits.

// Root cause in the codebase with @> marks to highlight the relevant section
function withdrawAllFailedCredits(address _receiver) external {
uint256 amount = failedTransferCredits[_receiver];
require(amount > 0, "No credits to withdraw");
// @> Resets msg.sender's credits instead of _receiver's credits
failedTransferCredits[msg.sender] = 0;
// @> Transfers _receiver's funds to msg.sender instead of _receiver
(bool success, ) = payable(msg.sender).call{value: amount}("");
require(success, "Withdraw failed");
}

Risk

Likelihood: High

  • This will occur whenever any user calls withdrawAllFailedCredits with another user's address as the _receiver parameter

  • This will occur in any scenario where users have accumulated failed transfer credits and malicious actors discover this vulnerability

Impact: High

  • The victim's credits are permanently lost as they are transferred to the attacker

  • This is a critical vulnerability that allows direct theft of user funds

Proof of Concept

​

Recommended Mitigation

The function now properly transfers the credits to the intended recipient and user's credit balance is reset after withdrawal

function withdrawAllFailedCredits(address _receiver) external {
uint256 amount = failedTransferCredits[_receiver];
require(amount > 0, "No credits to withdraw");
- failedTransferCredits[msg.sender] = 0;
+ failedTransferCredits[_receiver] = 0;
- (bool success, ) = payable(msg.sender).call{value: amount}("");
+ (bool success, ) = payable(_receiver).call{value: amount}("");
require(success, "Withdraw failed");
}
Updates

Lead Judging Commences

cryptoghost Lead Judge 12 months ago
Submission Judgement Published
Validated
Assigned finding tags:

BidBeast Marketplace: Unrestricted FailedCredits Withdrawal

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.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!