Bid Beasts

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

CRITICAL ISSUE: Fund Theft in withdrawAllFailedCredits

Root + Impact

Description

  • The withdrawAllFailedCredits function checks the balance of _receiver but clears the balance and sends funds to msg.sender, allowing anyone to steal failed transfer credits.

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

Risk

Likelihood:

  • Any user can call this function with any address that has failed transfer credits

  • The vulnerability is easily exploitable with a simple function call

  • No access control prevents unauthorized withdrawal

Impact:

  • Complete theft of all failed transfer credits from any user

  • Users lose funds that should be rightfully theirs

  • Contract becomes untrustworthy for handling failed transfers

Proof of Concept

function testStealFailedCredits() public {
// Alice has failed transfer credits
vm.deal(address(marketplace), 1 ether);
marketplace.failedTransferCredits[alice] = 1 ether;
// Attacker Bob steals Alice's credits
vm.prank(bob);
marketplace.withdrawAllFailedCredits(alice);
// Bob received Alice's funds
assertEq(bob.balance, 1 ether);
assertEq(alice.balance, 0);
}

Recommended Mitigation

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

Lead Judging Commences

cryptoghost Lead Judge 30 days 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.