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 about 1 month 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.